一、安装

官网下载社区版,下载对应的win10专业版,点击get Docker即可,链接:https://download.docker.com/win/stable/Docker for Windows Installer.exe
1.虚拟机和镜像文件位置的更改(重要,C盘吃不消玩儿的)
安装完会发现默认安装到C盘,所以需要进行一定的基本配置,Docker for windows点击后就会启动Docker,默认的HV虚拟机安装在了C:\Users\Public\Documents\Hyper-V\Virtual hard disks,通过小娜打卡Hyper-V管理器,下面点击Hyper-V管理器下面的菜单,即自己笔记本的名字,右侧会出现虚拟机,对,这货默认叫MobyLinuxVM,右击移动,按照移动向导选择其他盘的位置即可(当然这里网上大部分的教程都是通过将上述虚拟机复制到自己想要移动到的磁盘文件夹中)。但是在后来过程中,发现上述的方法并不能真正更改,查看Docker的客户端,Settings中Advanced的位置还是一样C盘,网上教程基本不能真正引用,后来终于找到解决办法,在做完上述更改之后,还需要配置一下默认的Hyper-V中的默认文件夹(就是上述移动的目标文件夹),右击电脑名(我这里是MR-LIUS-COMPUTE)–>Hyper-V设置–>更改虚拟硬盘如下:
这里写图片描述

2.资源镜像仓库的配置
docker默认是从dockerhub上下载镜像,由于在中国,所以速度上不去,需要进行远程仓库位置的更改,这里使用阿里云的docker仓库,进入后使用淘宝账号登录,点击右上角的管理中心进入docker镜像服务–>镜像加速器,右侧的内容框中就会出现类似于下图的加速器的地址:
这里写图片描述
复制这个地址,然后打开docker中的Settings,配置Daemon中的Registry mirrors,对,就是它,粘贴到这里,Apply后Docker自动重启,这里在使用的时候不要忘了进行阿里云的登录,在PowerShell中进行如下的登录操作:

# 后面的地址就是刚刚加速器的地址
docker login https://xxxx.mirror.aliyuncs.com

按照它提示输入用户名密码进行登录即可,这个时候就可以使用镜像了,比如这里我需要下载redis镜像,在dev.aliyun.com上搜索,就可以看到类似于这样的镜像地址,如下:
这里写图片描述
直接复制它的镜像地址获取的指令,这里是docker pull redis,执行这个指令即可:

# 直接下载最新版的redis版本
docker pull redis

# 也可以指定下载的redis的版本号,追加:version
docker pull redis:4.0.5-apline

可以发现速度正常。docker在仓库拉取的镜像文件是存在于Docker中的,简单的讲就是存在于HV虚拟机中的,不要妄想去找镜像文件,除非是Linux系统或者另外用连接windows上的HV虚拟机进行查看(未实践)。

3.测试
经过上述配置基本完成,运行helloworld的案例,

docker run hello-world

如果本地虚拟机没有hello-world这个docker镜像,会自动从配置的阿里云docker的镜像仓库进行下载运行,会出现如下的结果:
这里写图片描述

4.配置脚本文件模块(可省略)
在完成上述配置后,docker基本配完成,但是由于我们实在powershell或者cmd中操作,但是它们只能识别win系统命令的自动补全而不能对docker命令的自动补全,下面脚本的配置就是完成这样的任务。
首先以管理身份运行PowerShell.

# 1.检查权限,如果返回RemoteSigned转第3步
Get-ExecutionPolicy

# 2.设置权限,全部选择Y
Set-ExecutionPolicy RemoteSigned

# 3.安装模块,全部选择Y
Install-Module posh-docker

# 4.只为PowerShell启用该模块
Import-Module posh-docker

# 5.设置全局作用(所有的PowerShell会话都在作用范围)
if (-Not (Test-Path $PROFILE)) {
    New-Item $PROFILE –Type File –Force
}

Add-Content $PROFILE "`nImport-Module posh-docker"

# 6.查看文件是否写入成功
Notepad $PROFILE

在第6步完成后,应该会出现如下的文本文件
这里写图片描述
完成上述配置后,Docker基本配置完成(我是这样的),注意不要将Docker杀掉,如果不小心杀掉,可以管理员启动CMD启动服务:

net start com.docker.service

二、Docker指令的使用

【注意】:在对docker容器进行操作的时候,可以通过容器的名字或者ID来指定某个特定的容器实例,值得一说的是(Docker说它因此很酷),通过名字指定的话名字一定要是全称,而通过ID来指定的话,只需要写ID的前面的部分的ID字符,不需要写全(前提你要保证在你发布的Docker容器中这个ID是唯一,否则一直写到它是唯一为止,比如有容器ID为hjgasd5sa,那么可以直接指定hj就可以定位到这个容器,但是如果此时Docker中还有另一个容器叫做hjhgs4,那么不能指定上述的字符,必须指定到hjg才可以),因为通过ps指令查看各个容器实例的时候显示ID只有12位字符也不是全的,而实际的CONTAINER ID是64位字符,这技术是啥忘了,隐约记得有这么一种记录识别方式。

1.docker images查看本次运行虚拟机上所有的docker镜像;

2.docker search xxx在线查找镜像文件,xxx是查找的镜像关键字,但是国内好像没法用(好像是需要配置一下代理)。但是可以直接在dev.aliyun.com上直接找需要的镜像然后直接pull拉取,前提是你已经登录了一个Docker镜像仓库,比如阿里云

3.docker login xxx登录docker镜像仓库,可以用自带的dockerhub(xxx表示Docker ID),也可以使用配置的aliyun(加速器地址,输入用户名、密码),如果不指定xxx默认是官方仓库 Docker Hub,同样的登出Docker镜像仓库为:docker logout xxx,如果使用阿里云必须指定仓库加速器的地址。

4.docker run [OPTIONS] xxx [ARGS]运行由xxx镜像创建的容器中并执行相关ARGS指令后终止并退出该容器,容器运行后可以通过exit指令来终止运行并退出容器,其中OPTIONS是Docker指令的可选参数(Docker自己的指令,比如-i),而后面的ARGS是指运行容器的指令(比如Linux中的ls指令)比如:

# 运行一个ubuntu容器,并且执行ubuntu的bash命令
docker run -it ubuntu bash
# 终止并且退出当前所在的容器
exit

可选参数有很多,比如:
-d 表示和终端分离后台创建容器并打印容器ID
-P 表示将所有暴露的容器端口发布到Docker主机上
-e 表示你如何将环境变量传递到容器中
–name 表示允许你指定一个容器的名字

【注意】:run指令在执行交互shell完成任何脚本后都会退出并终止run的这个容器,除非在交互终端进行才不会终止退出。如果想要实现交互终端的功能就必须在启动容器的时候带上-it参数,此时如果要退出,exit指令可以帮助你退出当前的容器。

其中-i表示允许你对容器内的标准输入 (STDIN) 进行交互,即可以操作此镜像容器的指令,如Linux中ls指令;-t表示在新容器内指定一个伪终端或终端,指定这两个参数才能进入Linux的终端控制台

【附加的福利】在Docker中,每个容器镜像运行的时候都会至少经过以下隐形的4个步骤:
1.Docker客户端连接Docker的守护线程
2.Docker守护线程从Docker仓库中寻找对应的镜像文件,先本地再远程
3.Docker守护线程为对应的镜像创建一个新的容器并运行进行输出
4.Docker守护线程将容器的输出内容输出到Docker客户端,Docker客户端将它输出到你的终端
以上就是在跑hello-world镜像的内容

5.docker pull xxx拉取镜像xxx,可以追加“:版本号”方式,当然一般可以先在阿里云的Docker镜像仓库中找到需要的镜像文件然后复制它的docker拉取地址,最后回到PowerShell中粘贴命令即可下载镜像;除此以外Docker也提供了在线搜索的镜像的功能,可以使用

# 在线查找与关键字xxx相关的镜像信息
docker search xxx

然后可以通过pull命令拉取相应的镜像到HV虚拟机中

6.docker ps [OPTIONS]可以查看所有正在运行中的容器列表,然后可以通过docker inspect xxx查看具体某个容器xxx的详细信息(这里的xxx表示是容器的ID,可以只写容器ID前面部分的字符,也可以写全,比如有一个容器ID为:asgdhas3sa78a,那么可以用docker inspect asg来查看),可选参数如下:
-a显示所有容器,包括未运行的
-q静默模式,只显示容器编号
-l显示最近创建的容器
-n显示最近创建的n个容器
-f根据条件过滤显示的内容
-s显示总的文件大小

7.docker rmi [OPTIONS] xxxx [IMAGE...]删除镜像文件xxxx(可以是镜像的名字或者镜像的ID),是删除镜像文件(remove image,所以才是rmi),不是运行容器,注意两者的区别(结合7、8两个指令看),下次要用的时候还会从仓库拉取(即下载)。可选参数主要有如下的几个:
-f 表示强制移除镜像
--no-prune 表示不删除未加标签的父级元素
有时在通过docker rmi指令删除镜像文件的时候发现无法删除,比如这里删除测试镜像hello-world的时候,docker会报错:

PS C:\Users\weiguo Liu> docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container 102d39e1bac3 is using its referenced image f2a91732366c

这是因为容器依赖的原因(这些容器可能是活动的也可能是已经停止的状态),即上述的过程,这个时候你必须首先移除依赖待删除镜像的容器,这里可以通过docker -ps -a查看所有的容器,查看依赖此镜像文件的所有哪些,然后通过移除所有依赖该镜像文件的容器,再执行删除镜像文件的操作才能成功,具体过程如下:

# 查看所有的容器
docker ps -a

# 下面是输出
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
0c44af19d764        ubuntu              "bash"              About an hour ago   Exited (0) 22 minutes ago                       hardcore_golick
fa0825a331ba        hello-world         "/hello"            2 hours ago         Exited (0) 2 hours ago                          admiring_engelb
4f6046251a91        hello-world         "/hello"            3 hours ago         Exited (0) 3 hours ago                          eager_allen
102d39e1bac3        hello-world         "/hello"            4 hours ago         Exited (0) 4 hours ago                          sleepy_sinoussi

# 移除依赖hello-world镜像的容器(可以只写容器ID前几个字符)
PS C:\Users\weiguo Liu> docker rm fa
fa
PS C:\Users\weiguo Liu> docker rm 4
4
PS C:\Users\weiguo Liu> docker rm 1
1
PS C:\Users\weiguo Liu> docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
0c44af19d764        ubuntu              "bash"              About an hour ago   Exited (0) 28 minutes ago                       hardcore_golick

# 最后才能删除hello-world的镜像文件
docker rmi hello-world

或者可以方便的使用下面的指令进行删除

docker rmi 

8.docker rm [OPTIONS] xxx [CONTAINER...]移除一个容器,可选参数主要有如下的几个:
-f 表示强制删除正在运行的容器
-l 表示删除指定的链接
-v 表示移除和该容器相关区
注意和上述删除镜像文件的区,这里仅仅是将创建的容器移除,这些容器可以依赖一个镜像文件,容器和镜像文件之间是多对一的关系,也就是说一个镜像文件可以被多个容器依赖,每次通过docker run命令运行一个镜像实例的时候都会自动创建一个容器(这就是为什么一个镜像文件为什么可以被多个容器依赖),这一点非常重要。对于容易移除操作的一般是针对已经停止运行的容器作这种操作,对于当前处于活动状态的容器,先让容器停止运行,然后才能移除:

docker stop hello-world
# xxx表示运行hello-world容器的名字或者ID
docker rm xxx

当然可以直接暴力一些,这样是简单一点:

docker rm -f xxx

或者直接移除所有的容器

# 务必静默方式查找,否则查找出大堆信息无用,只用容器ID即可
docker rm $(docker ps -a -q)

9.docker start/stop xxx启动指定容器xxx(容器ID或者名字,ID可以只是ID的前面部分的字符,名字必须是全称),通常在使用docker run指令跑过镜像的都会自动创建一个容器,下次再想跑这个实例的时候就可以通过这个指令来进行跑,通常情况会首先查看一个对应镜像文件的容器ID(docker ps -a这里必须查看所有的容器,因为很可能之前的容器已经停止了),然后在运行上述的容器,可以通过这样的方式来启动或者终止一个容器,而不是重复创建同一个镜像文件的容器实例(除非真的是需要),因为上面的run指令是直接创建一个新容器来跑的。

【注意】Docker命令是可以嵌套的,用$符号来取每个命令执行的结果,比如移除所有的容器,首先要获取所有的容器ID(docker ps -a -q),然后删除docker rm $(docker ps -a -q)

以上是简单的基本配置和一些常用指令,具体指令参见:https://docs.docker.com/engine/reference/commandline/docker/

三、Docker开启远程访问

 win系统直接启动会开启2375端口,但CentOS7是需要手动配置开启:

修改/lib/systemd/system/docker.service文件:

vim /lib/systemd/system/docker.service
# ExecStart处修改为
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock

# 重启docker
systemctl daemon-reload && systemctl restart docker

【附】

至于Linux 上docker 安装相差不大,主要提一下配置文件:docker守护线程配置文件(daemon.json文件),Linux 中默认位置/etc/docker/daemon.json(但我并没发现,手动添加),该配置文件主要以键值对的形式,下面是一个小栗子:

{
	"authorization-plugins": [], // 它指定了授权插件使用
	"data-root": "",
	"dns": [],
	"dns-opts": [],
	"dns-search": [],
	"exec-opts": [],
	"exec-root": "",
	"experimental": false,
	"features": {}, // 显式地启用或禁用特定功能
	"storage-driver": "",
	"storage-opts": [],
	"labels": [], // 用一组新的标签替换了守护进程标签
	"live-restore": true, // 允许在守护进程停机期间保持容器活动
	"log-driver": "json-file",
	"log-opts": {
		"max-size": "10m",
		"max-file":"5",
		"labels": "somelabel",
		"env": "os,customer"
	},
	"mtu": 0,
	"pidfile": "",
	"cluster-store": "", // 存储地址
	"cluster-store-opts": {}, // 加载存储地址的选项
	"cluster-advertise": "", // 修改重新加载后公布的地址
	"max-concurrent-downloads": 3, // 每次pull的时候最大并发下载量
	"max-concurrent-uploads": 5, // 每次推送的最大并发上载数
	"default-shm-size": "64M",
	"shutdown-timeout": 15, // 守护进程的超时时间(关闭所有容器的超时时间)
	"debug": true,
	"hosts": [], // 添加需要监听的地址
	"log-level": "",
	"tls": true,
	"tlsverify": true,
	"tlscacert": "",
	"tlscert": "",
	"tlskey": "",
	"swarm-default-advertise-addr": "",
	"api-cors-header": "",
	"selinux-enabled": false,
	"userns-remap": "",
	"group": "",
	"cgroup-parent": "",
	"default-ulimits": {
		"nofile": {
			"Name": "nofile",
			"Hard": 64000,
			"Soft": 64000
		}
	},
	"init": false,
	"init-path": "/usr/libexec/docker-init",
	"ipv6": false,
	"iptables": false,
	"ip-forward": false,
	"ip-masq": false,
	"userland-proxy": false,
	"userland-proxy-path": "/usr/libexec/docker-proxy",
	"ip": "0.0.0.0",
	"bridge": "",
	"bip": "",
	"fixed-cidr": "",
	"fixed-cidr-v6": "",
	"default-gateway": "",
	"default-gateway-v6": "",
	"icc": false,
	"raw-logs": false,
	"allow-nondistributable-artifacts": [], // 用一组新的注册表替换守护进程将不可分发的工件推送到的注册表集
	"registry-mirrors": [], // 用一组新的注册表镜像替换了守护进程注册表镜像,如果守护进程配置中已有的注册表镜像不在新重新加载的注册表镜像中,则这些现有镜像将从守护进程的配置中删除
	"seccomp-profile": "",
	"insecure-registries": [], // 用一组新的不安全注册表替换守护进程原有的不安全注册表,如果守护进程配置中某些已有的不安全注册表不在新重新加载的不安全注册表中,则这些已有的注册表将从守护进程的配置中删除
	"no-new-privileges": false,
	"default-runtime": "runc", // 如果在容器创建时未指定,它将更新要使用的运行时,默认为default,即官方Docker包附带的运行时
	"oom-score-adjust": -500,
	"node-generic-resources": ["NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2"],
    // 它更新可用于运行容器的可用OCI运行时列表
	"runtimes": {
		"cc-runtime": {
			"path": "/usr/bin/cc-runtime"
		},
		"custom": {
			"path": "/usr/local/bin/my-runc-replacement",
			"runtimeArgs": [
				"--debug"
			]
		}
	},
	"default-address-pools":[{"base":"172.80.0.0/16","size":24},
	{"base":"172.90.0.0/16","size":24}]
}
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐