先说下Docker,Docker是一个开源的容器引擎,它有助于更快地交付应用。Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用Docker可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。
Docker包含的组件:
- Docker daemon:Docker守护进程,是一个运行在宿主机的后台进程,可通过Docker客户端与之通信。
- Client:Docker客户端时Docker的用户界面,它可以接受用户命令和配置标识,并与Docker daemon通信。
- Images:Docker镜像时一个只读模板,它包含创建Docker容器的说明。Docker镜像可以运行Docker镜像中的程序。
- Container:容器时镜像可运行的实例。可通过Docker API或者CLI命令来启停止、移动、删除容器。
- Registry:Docker Registry是一个集中存储与分发镜像的服务。构建完Docker镜像后,就可再当前宿主机上运行。但如果想要在其他机器上运行这个镜像,就需要手动复制,Docker Registry可用来避免手动复制。
国内访问Docker Hub的速度很不稳定,有时甚至出现连接不上的情况。可使用阿里云加速器解决这个问题。网上记录win10版本及以上推荐安装Docker For Windows版, 并确保开启Hyper-V(可在控制面板查看并更改开启状态),安装后,在setting中替换文字即可配置镜像加速器。
Docker镜像常用命令:
- 搜索镜像:docker search(例如:docker search java)。
- 下载镜像:docker pull(例如:docker pull java)。
- 列出镜像:docker images(直接输入执行即可查看当前本地镜像列表)
- 删除本地镜像:docker rmi(例如:docker rmi java),其中,加 -f 表示强制删除,例如 :docker rmi -f java。
- 新建并启动一个容器:docker run 。该命令时最常用的命令。它有很多选项,常用的如下:
- -d 选项:表示后台运行;
- -P 选项:随机端口映射;
- -p 选项:指定端口映射,有以下四种格式:
- ip : hostPort : containerPort
- ip :: containerPort
- hostPort : containerPort
- containerPort
- --network 选项:指定网络模式,该选项有以下可选参数:
- --network=bridge:默认选项,表示连接到默认的网桥
- --network=host:容器使用宿主机的网络
- --network=container:NAME_or_ID:告诉Docker让新建的容器使用已有容器的网络配置。
- --network=none:不配置该容器的网络,用户可自定义网络配置
示例1:
docker run java /bin/echo 'Hello World',终端最终会打印Hello World字样,这个在本地执行/bin/echo ‘Hello World’一样。
示例2:
docker run -d -p 91:80 nginx,这样就能启动一个Nignx容器,并为其指定了端口号,在浏览器输入:http://localhost:91/,就会看到nginx的欢迎页。
docker run命令创建容器时,会先检查本地是否存在指定镜像,如果本地不存在该名称的镜像,Docker就会自动下载镜像并启动一个Docker容器。
- 列出容器:docker ps(直接输入执行即可查看当前运行的容器),加-a 可查看所有容器,例如: docker ps -a。
- 停止容器:docker stop,可以通过容器ID或容器名称来停止,例如:docker stop edf4b70fc36e 或 docker stop admiring_lamarr。
- 强制停止容器:docker kill,发送SIGKILL信号来强制停止容器,例如:docker kill edf4b70fc36e。
- 启动已停止容器:docker start,例如: docker start edf4b70fc36e。
- 重启容器:docker restart,例如:docker restart edf4b70fc36e。
- 进入容器:docker attach,例如:docker attach edf4b70fc36e。但在win10上操作后进不去。。尝试了另一种办法,使用nsenter,但由于其包含在util-linux 2.23,所以还是未成功,但在此记录一个nsenter完整的例子:
[root@localhost ~]# docker ps -- 取得容器ID
[root@localhost ~]# docker inspect --format "{{.State.Pid}}" edf4b70fc36e -- 获取PID,假设获取的PID为 3361
[root@localhost ~]# nsenter --target 3361 --mount --uts --ipc --net --pid
上述的命令也可封装成一个Shell,从而简化进入容器的流程。
- 删除容器:docker rm,例如:docker rm edf4b70fc36e。这种办法只能删除已停止的容器,如果需要删除正在运行的容器,需要使用-f参数,例如:docker rm -f edf4b70fc36e。
使用Dockerfile构建Docker镜像,Dockerfile是一个文本文件,其中包括了若干条指令,指令描述了构建镜像的细节。更改nginx首页的示例如下:
- 新建目录,在目录下新建二进制文件Dockerfile,相关指令如下:
- cd desktop --回到桌面
- md testdocker --创建文件夹
- cd testdocker --来到刚创建好的文件夹目录下
- type nul>Dockerfile --创建二进制文件并命名
- 在文件内写入下列内容:
FROM nginx --指定基础镜像为nginx MAINTAINER Dou <bluecoolcool@qq.com> --指定镜像的创建者和联系方式 RUN echo '<h1>Hello World</h1>' > /usr/share/nginx/html/index.html --容器内部执行的命令
- 在Dockerfile所在路径下执行 " docker build -t nginx:my . " 构建镜像。命令最后的点要注意,它用于路径参数传递,表示当前路径。
- 执行" docker run -d -p 92:80 nginx:my " 启动Docker容器。
- 访问本地:http://localhost:92/ ,即可看到修改好的页面。
Dockerfile的命令一般的格式为:指令名称 参数。常用的指令命令如下:
- ADD复制文件,从src目录复制到容器的dest。其中src可以是Dockerfile所在目录的相对路径,也可以是一个URL,还可以是一个压缩包,其格式为:
- ADD<src>...</dest>
- ADD ["<src>",..."<dest>"]
- src必须在构建的上下文内,docker build命令首先会将上下文路径和其子目录发送到docker daemon;
- 如果src是一个URL,同时dest不以斜杠结尾,dest将会被视为文件,src对应内容文件将会被下载到dest;
- 如果src是一个URL,同时dest以斜杠结尾,dest将被视为目录,src对应内容将会被下载到dest目录;
- 如果src是一个目录,那么整个目录下的内容将会被复制,包括文件系统元数据。
- 如果文件是可识别的压缩包格式,则docker会自动解压。
- ARG设置构建参数,ARG设置的是构建时的环境变量,在容器运行时是不会存在这些变量的。
- CMD容器启动命令,每个Dockerfile只有一个CMD命令,如果制定了多个CMD命令,那么只有最后一条会被执行,如果启动容器时制定了运行的命令,则会覆盖掉CMD指定的命令,支持下列三种格式:
- CMD ["executable","param1","param2"](推荐使用)
- CMD ["param1","param2"](为ENTRYPOINT指令提供预设参数)
- CMD command param1 param2(在shell中执行)
- COPY复制文件,复制本地端的src到容器的dest。COPY指令和ADD指令类似,COPY不支持URL和压缩包,其格式如下:
- COPY <src>...<dest>
- COPY ["<src>",..."<dest>"]
- ENTRYPOINT入口点和CMD指令的目的一样,都是指定Docker容器启动时执行的命令,可多次设置,但只有最后一个有效,其格式如下:
- ENTRYPOINT ["executable","param1","pparam2"]
- ENTRYPOINT command param1 param2
- ENV设置环境变量,格式如下:
- ENV <key> <value>
- ENV <key>=<value> ...
- EXPOSE声明暴漏的端口,用于声明在运行时容器提供服务的端口,格式为:EXPOSE <port> [<port>...]。这是一个声明,运行时不会因为改声明就打开相应端口,该指令的作用主要是帮助镜像使用着理解该镜像服务的守护端口;其次是当运行时使用随机映射时,会自动映射EXPOSE的端口,其示例如下:
# 声明暴漏一个端口示例 EXPOSE port1 # 相应的运行容器使用的命令 docker run -p port1 image # 也可使用-P选项启动 docker run -P image # 声明暴漏多个端口示例 EXPOSE port1 port2 port3 # 相应的运行容器使用的命令 docker run -p port1 -p port2 -p port3 image # 也可指定需要映射到宿主机上的端口号 docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
- FROM指定基础镜像,有些像java中的extends关键字,FROM指令必须指定且需要卸载其他指令前。FROM指令后的所有指令都依赖于该指令所指定的镜像,支持的格式如下:
- FROM <image>
- FROM <image>:<tag>
- FROM <image>@<digest>
- LABEL为镜像添加元数据,格式为:LABEL <key>=<value> <key>=<value> <key>=<value>...。可使用“"”和“\”转换命令行。
- MAINTAINER指定维护者的信息,用于为Dockerfile署名,格式为:MAINTAINER <name>。
- RUN执行命令的两种格式如下:
- RUN <command>
- RUN ["executable","param1","param2"]
- USER设置用户,该指令用于设置启动镜像时的用户或者UID,写在该指令后的RUN、CMD以及ENTRYPOINT指令都将使用该用户执行命令,示例:USER daemon。
- VOLUME指定挂载点,该指令是同其中的一个目录具有持久化存储的功能,该目录可被容器本身使用,也可共享给其他容器,其格式为:VOLUME ["/data"]。
- WORKDIR指定工作目录,切换目录命令,类似于cd命令,写在该指令后的RUN,CMD以及ENTRYPOINT指令都将该目录作为当前目录。并执行相应的命令。
- 其他Dockerfile还有一些其他的指令,由于不常用,在此略过。
使用Dockerfile构建镜像具体步骤如下:
- 准保好相应jar包,使用maven打包项目:mvn clean package;
- jar包所在目录,创建名为Dockerfile的文件;
- 编写Dockerfile文件;
- 使用docker build命令构建镜像;
- 启动镜像并访问查看结果。
总结:
手动实践后发现对于自己来说Windows上操作Docker还是有诸多不变,建议使用Linux版,结合习惯,丝滑顺畅。
本文参考于周立的《Spring Cloud与Docker微服务架构实战》,是读后的记录笔记。