Hi I’m Shendi
Docker详解,windows上安装与使用
Docker 容器是一个开源的应用容器引擎,让开发者可以以统一的方式打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何安装了docker引擎的服务器上(包括流行的Linux机器、windows机器),也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架包括系统。
可以用船和货物来理解,不同货物需要不同的船来运输,比如化学品,食品,不同货物不能混装
为了节省开销,可以用装货物的集装箱,有了集装箱,就可以一艘船上运输食品又运输化学品了,并且互不影响
虚拟机/操作系统就是一艘艘的船,而Docker是集装箱
例如虚拟机运行一个windows软件,光操作系统就会占用1G左右内存,20G左右磁盘空间,为了运行稳定,甚至需要更多。
如何使应用运行在同一个操作系统上减少资源浪费,但又能避免环境冲突呢?操作系统层虚拟化,容器概念的提出,就是为了解决这个问题
与虚拟机相比,比虚拟机更轻量,更简单,更快速。相对于传统虚拟化技术,Docker有以下几点优势:
Docker的三大核心概念
Docker的基本组成包括:
当人们说 “Docker” 时,他们通常指的是Docker Engine,上面的组成也是Docker Engine的组成
win10的build 19043及以上,具体参考官方文档,反正装Desktop弹出版本比较旧就不行了
为了在Windows上安装和使用Docker,需要按照以下几个步骤:
下载和安装Docker桌面应用程序,在以下网址下载:
https://docs.docker.com/docker-for-windows/install/
下载完成是一个exe文件,以管理员运行安装,等待安装完成即可
直接安装在了 C:\Program Files\Docker 下
安装好后运行docker会显示 Docker Desktop stopped… 然后闪退
需要启用 Hyper-V 和 容器,如果还不行就需要开启 适用于Linux 系统的 windows 子系统和安装WSL
如果还不行,而且不是系统版本问题,那就卸载重装试试吧
打开控制面板,选择程序和功能,启用或关闭windows功能,勾选Hyper-V和容器确认即可
打开PowerShell,输入以下命令:docker --version 如果输出了版本号,则证明安装成功。
打开命令行,输入以下命令:
docker run hello-world
这条命令将会下载一个Docker镜像,并在其中运行一个程序来打印“Hello World”。
如果看到输出了“Hello from Docker! ”,就证明成功了。
现在,您已经在Windows上成功安装Docker并成功运行一个Docker镜像了。
可以用 docker-toolbox,是一种替代方案
Docker Toolbox是一个适用于Windows和Mac OS X操作系统的工具箱,可以方便地在本地主机上使用Docker容器。它包含了Docker客户端工具,Docker Machine、Docker Compose、VirtualBox等多个组件,提供一个完整的Docker开发环境。通过Docker Toolbox,开发人员可以更加方便、快捷地进行Docker容器的开发和部署等工作。
在任务管理器检查虚拟化是否打开,没有打开则要先去打开
docker-toolbox 可以在阿里镜像下载
http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/
next,选择安装路径
next,根据需求选择比如已经有Git则可以取消勾选Git for windows
next,勾选Install VitualBox with NDIS5 driver
install,等待安装完成,期间会有弹窗询问是否安装驱动,选择是即可
安装完成会在桌面多出以下三个图标
运行第一个图标,quickstart
如果安装时没有勾选 Git 则需要更改下快捷方式内的目标,右键属性,目标,在最前方的Git地址改为自己的Git安装地址
出现以下这种情况则在安装目录找到 start.sh,打开更改
将下图的 virtualbox
改为 virtualbox --virtualbox-no-vtx-check
即可
在控制面板,程序
->
程序和功能->
启用或关闭Windows功能,找到
Hyper-V并取消勾选
再次启动,会提示下载 boot2docker
,网速好可以直接等待(Github),不然就自行去Github下载
点击下载boot2docker.iso
也可以微信搜一搜 sddxsck,发送 100003 直接获取
下载完成后,将文件复制到 C:\Users\Administrator.docker\machine\cache 下,没有目录则新建
然后继续启动,安装完默认会新建一个虚拟机
出现以下画面就证明ok了,如果不是,可以复制Error或者Fail部分报错信息百度解决
接下来就可以正常使用docker了,可以使用 docker-machine ls
查看当前虚拟机的状态
如果没有default虚拟机的话可以用以下命令来创建一个Docker虚拟机
docker-machine create --driver=virtualbox default
默认虚拟机文件在 C:\Users\Administrator.docker\machine\machines\default 下,如果C盘存储不足,可以考虑转移到其他盘,操作如下
关闭虚拟机,执行 docker-machine stop default
打开安装出现的三个图标第三个的 VirtualBox
选中 disk.vmdk 点击复制,复制到想要放到的盘内
返回主界面,右键虚拟机,设置,存储,将disk.vmdk删除,然后加上复制到新的磁盘的disk.vmdk
配置完成,开启虚拟机
docker-machine start default
在国内使用 Docker Hub 很慢,可以配置镜像地址
需要获取镜像地址,可以选择阿里云的(需要登录),个人版免费
进入以下获取阿里云加速:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
也可以选择中科大的:https://docker.mirrors.ustc.edu.cn/
移除默认虚拟机,创建一个新的
docker-machine rm -y default
docker-machine create --engine-registry-mirror=地址 -d virtualbox default
查看机器的环境配置,并配置到本地,并通过Docker客户端访问Docker服务。
docker-machine env default
eval "$(docker-machine env default)"
docker info
至此,镜像加速就配置完成了
在上面使用到了 Docker-Machine 这么一个东西,下面介绍一下docker-Machine是什么
Docker Machine是一种官方的Docker工具,它是一种用于管理Docker主机的命令行工具。通过Docker Machine,您可以使用不同的虚拟化引擎(如VirtualBox、VMware、Hyper-V等)在不同的平台上创建、配置和管理Docker主机。它还可以简化在云平台上创建和管理Docker主机的过程,并提供了与Docker Swarm集群自动化部署和管理的支持。
其作用就是快速帮助我们搭建 Docker(DockerEngine) 主机环境
DockerMachine和DockerEngine的区别
DockerMachine是一个工具,用于在各种环境中创建和管理Docker主机。DockerEngine是Docker的核心组件,用于创建和运行Docker容器。
具体来说,DockerMachine可以帮助用户在本地计算机上、在云中或在虚拟机中创建Docker主机。一旦创建,可以使用DockerMachine来连接到该主机并管理其状态。DockerMachine还允许用户在不同的主机之间交换容器。
DockerEngine是Docker的主要组件,用于创建和运行Docker容器。它负责容器的生命周期管理、容器的网络连接管理、存储卷的管理等。DockerEngine是构建和运行容器化应用程序的核心组件。
因此,DockerMachine和DockerEngine是不同的工具,各自有其独特的功能。DockerMachine使Docker主机的创建和管理更加容易,而DockerEngine是Docker容器化应用程序的核心组件。
我们使用的 docker run
等命令都是发送到默认的Docker主机,而Docker容器是运行在宿主机上
Docker允许在容器内运行应用程序,使用 docker run
命令
例如运行 hello-world项目
通过 docker run hello-world
从网络中下载hello-world镜像
运行结果如下
Dockerfile 是自定义镜像的一套规则,每一行代表一个指令,包含了构建镜像所需的指令和说明
Dockerfile镜像分层指的是Docker镜像构建过程中,每一条命令都是在上一条命令的基础上进行的,每一层都可以看作一个增量的变化,最终形成一个完整的镜像文件。
常用指令
名称 | 描述 | 语法 | 语法描述 | 示例 |
---|---|---|---|---|
FROM | 指定基础镜像,只能出现一次 | FROM [镜像名称]:[标签] | 其中,镜像名称是指要使用的Docker镜像的名称,标签用于指定具体的版本号。Docker镜像名称和标签可以使用官方Docker Hub上的镜像,也可以使用本地的镜像 | FROM openjdk:8-jdk-alpine |
MAINTAINER | 维护者信息,可选 | MAINTAINER maintainer_name |
maintainer_name 表示维护者的姓名,maintainer_email 表示维护者的邮箱。这个信息将会在docker image inspect命令输出中显示 |
MAINTAINER Shendi “[email protected]” |
LABEL | 用以取代MAINTAINER,键值对 | LABEL |
key名称,value内容,可以定义多个元数据 | LABEL author=“Shendi” \ description=“Docker test” \ version=“1.0” |
RUN | 执行命令,多个使用&&,每一个命令代表一层,所以不要过多无意义的层,会造成镜像膨胀过大 | RUN command | RUN echo test && echo test2 | |
ADD | 将文件添加到镜像,压缩文件会自动解压,支持从远程地址下载文件。仅复制推荐用COPY | ADD |
src指本地主机上要复制的文件或目录路径,可多个,dest指容器中要复制到的文件或目录路径 | ADD target/*.jar test.jar |
COPY | 将本地文件或目录复制到Docker容器中 | COPY [–chown= |
--chown= :指定复制后的文件或目录的所属用户和所属组。 :要复制的本地文件或目录的路径,支持使用通配符。 :复制到Docker容器中的路径,可以是相对路径或绝对路径。 |
COPY app/* /app/ |
WORKDIR | 指定Docker容器的工作目录,相当于cd到了指定目录 | WORKDIR path | 在使用Docker容器时,可以通过-w 选项来指定容器的工作目录例如docker run -w /path/to/work/dir myimage |
WORKDIR /path/to/work/dir |
VOLUME | 用于为容器添加卷,相当于硬盘 | VOLUME [“/path/to/dir”] | /path/to/dir 指定了需要挂载的目录,可以在启动容器时使用-v 参数将该目录挂载到本地主机 |
VOLUME “/path/to/dir” |
EXPOSE | 用于标识容器运行的服务端口,相当于防火墙开放指定端口 | EXPOSE |
port表示需要暴露的端口号。可以指定多个端口号,用空格隔开。 需要注意的是,EXPOSE 指令并不会自动将容器的端口映射到宿主机上,而是仅仅声明容器会使用指定的端口号。如果需要将容器的端口映射到宿主机上,需要使用 docker run 命令的 -p 或 -P 参数。 |
EXPOSE 80 |
CMD | 用于定义容器启动时默认执行的命令 | CMD 或 CMD [“executable”, “param1”, “param2”] |
只能在Dockerfile文件中出现一次,如果多次使用,则会覆盖前一个CMD。同时,如果在Dockerfile中指定了ENTRYPOINT,则CMD会被作为ENTRYPOINT的参数 | CMD “nginx” |
ENTRYPOINT | 指定在运行容器时要执行的默认命令,它与CMD一起构成了容器的启动命令 | ENTRYPOINT [“executable”, “param1”, “param2”] | 该命令是不可被覆盖的,即使在 docker run 命令中指定了其他命令也会被忽略 | ENTRYPOINT [“java”, “-jar”, “/app.jar”] |
ARG | 在构建镜像过程中传递参数。这些参数可以用于设置环境变量、默认值和镜像版本等信息 | ARG |
name表示参数的名称,default-value表示默认值。 | ARG VERSION=latest 可以在FROM或者RUN命令中引用,例如 FROM node:$VERSION 在构建镜像时,可以通过–build-arg参数传递参数的值 |
根据上面的指令,编写 Dockerfile,将需要的文件全部放到一个文件夹内
例如运行一个java jar包,files是配置文件的文件夹,使用jdk17
FROM openjdk:17-jdk-alpine
COPY app.jar /
COPY files /files
ENTRYPOINT ["java","-jar","app.jar"]
提示:
当不是根目录时需要在结尾加斜杠,例如复制files到 app 文件夹内,COPY files /app/files/
并且需要设置工作目录 WORKDIR,这样项目获取根目录就为工作目录,否则为 / 导致找不到文件
目录结构为
|-files
|-config.properties
|-app.jar
|-Dockerfile
将docker命令行用cd命令到目录,通过以下命令构建镜像
docker build -t test:1.0 .
test代表镜像名称,1.0代表版本(镜像名称:镜像标签),版本可选,后面那个点代表当前目录(Dockerfile所在目录)
创建完成可以用 docker images
命令查看
用 docker run test:1.0
来运行刚刚创建的镜像
可以通过 docker ps
来查看正在运行的容器,通过 docker stop 容器id
来停止指定容器运行
如果程序有端口需要访问,则需要通过增加 -p 参数,例如让容器内的899端口关联到本机的889端口
docker run -p 889:899 镜像名
然后可以直接通过端口访问了
在 Dockerfile 内要增加 EXPORT 指定端口
需要注意的是,在Windows中运行docker,实际上是在Windows下先安装了一个Linux环境,然后在这个系统中运行的docker,所以“本机”指的是Linux的地址(这个坑坑死我了,导致我一直在找为什么无法访问的问题)
通过 docker-machine ip default
查看Docker主机IP,default为主机名称,一般为 192.168.99.100
访问效果如下
当容器关闭后,容器内的所有内容都会被清空,对于日志这些需要保存下来的,就需要使用到挂载目录
Docker挂载目录是将本地主机的目录或文件夹与Docker容器内的目录或文件夹进行映射,使得容器内的数据可以被持久化保存并能够进行共享。
Dockerfile中可以使用VOLUME来指定挂载目录,也可以在 run 的时候使用 -v 指定
例如上面自定义镜像的例子,运行起来会在工作目录生成日志文件及文件夹,使用以下命令启动增加挂载目录
docker run -p 889:899 -v 宿主机地址:容器内工作目录地址 镜像名
需要注意的是,挂载目录优先于容器内目录,所以容器内的路径不能与挂载目录重名,否则导致找不到文件
上面的例子使用的是Java,所以还需要调整一下镜像Dockerfile重新构建
FROM openjdk:17-jdk-alpine
COPY app.jar /
COPY files /app/files
WORKDIR /app/
EXPOSE 899
ENTRYPOINT ["java","-jar","../app.jar"]
如果配置文件有动态修改的需求,可以不一起打包成镜像(例如去掉COPY files),而是放到挂载目录,程序找文件是从工作目录查找,挂载目录与工作目录一致即可
如果本机是windows,宿主机实际上是Linux,可以通过之前说过的VirtualBox或者 docker-machine ssh default
进入Linux虚拟机操作
当然还有更简便的方法,给Linux虚拟机增加挂载目录挂载到本机
打开 VirtualBox,选择 default 虚拟机,点击设置 - 共享文件夹
上面的共享文件夹路径为本机要共享的文件夹地址,共享文件夹名称为虚拟机内地址,勾选自动挂载,固定分配
重启虚拟机,即可在虚拟机内看到新增的目录
例如 容器挂载 /app 目录,linux内就有 app 目录与容器共享
然后windows将linux内的app目录挂载到H:/tmp,那么 H:/tmp 等同于容器内的 /app 目录
至此,Docker的基本使用已经OK,其余就就是一些命令之类的了,可以随时查阅
END