简而言之,Docker 是一个可供开发者通过容器(container)来构建,运行和共享应用(application)的平台。用容器来部署应用被称为集装箱化(containerization)。
想了解更多信息可到docker官网查看。
Get Started with Docker
下载完成后,按照引导提示一步步安装完即可。
注册一个阿里云阿里云账号。
进入管理控制台界面。
点击左上角的菜单栏,选择产品与服务->弹性计算->容器镜像服务,复制加速器地址。
打开安装好的docker的主界面:在设置界面找到Docker Engin,将复制好的加速器地址填入即可。
windows下启动docker打开桌面的docker图标启动即可。
启动成功后,在Win + R 输入cmd进入windows命令行界面,
输入docker -v,查看docker版本:
C:\Users\lynnh>docker -v
Docker version 19.03.12, build 48a66213fe
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
$ sudo yum install -y yum-utils
# 1. 默认使用国外源,非常非常非常慢!
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 2. 推荐用国内源,丝滑!
$ sudo yum-config-manager \
--add-repo \
https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
非root权限:
$ sudo systemctl enable docker
$ sudo systemctl start docker
root权限:
$ systemctl enable docker
$ systemctl start docker
若不报错,说明启动成功。
简单说一下linux下切换用权限:输入以下命令即可切换到root用户。
$ su root
$ sudo apt-get remove docker docker-engine docker.io containerd runc
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 1. 默认使用国外源,非常非常非常慢!
$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 2. 推荐使用国内源,顺畅!
$ sudo curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 1. 默认使用国外源,非常非常非常慢!
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 2. 推荐使用国内源,顺畅!
$ sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 更新apt包索引
$ sudo apt-get update
# 安装docker
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo systemctl enable docker
sudo systemctl start docker
在docker启动的前提下,在命令行输入以下指令:
docker run hello-world
Linux中同理。
C:\Users\lynnh>docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
输出以上信息,说明docker安装成功!
docker run hello-world
会先从本地搜索名为hello-world的镜像,若没有找到,则先从docker hub中pull该镜像,拉取镜像到本地成功后,再通过run指令来启动容器运行该镜像。
镜像是一种轻量级、 可执行的独立软件包,来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
声明:后面提到的指令若无特殊说明,说明在windows和linux下都是一样的,除非指明在linux使用。
docker pull
docker pull 用于从仓库(例如,Docker Hub)中拉去镜像到本地。现在我们尝试获取一个pytorch的镜像:
到Docker Hub中搜索pytorch,这里我们就尝试获取一个pytorch1.4, cuda10.1的镜像。
在命令行中输入:docker pull pytorch/pytorch:1.4-cuda10.1-cudnn7-runtime
docker pull 是通过分层机制进行镜像下载:
C:\Users\lynnh>docker pull pytorch/pytorch:1.4-cuda10.1-cudnn7-runtime
1.4-cuda10.1-cudnn7-runtime: Pulling from pytorch/pytorch
2746a4a261c9: Pull complete
4c1d20cdee96: Pull complete
0d3160e1d0de: Pull complete
c8e37668deea: Pull complete
32fa2b829f7e: Pull complete
318af50219b4: Pull complete
bf0f45e8a37a: Pull complete
5e1bc716e4bb: Pull complete
358186ffb22b: Pull complete
Digest: sha256:ee783a4c0fccc7317c150450e84579544e171dd01a3f76cf2711262aced85bf7
Status: Downloaded newer image for pytorch/pytorch:1.4-cuda10.1-cudnn7-runtime
docker.io/pytorch/pytorch:1.4-cuda10.1-cudnn7-runtime
docker images
或 docker image ls
C:\Users\lynnh>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos centos8 0d120b6ccaa8 9 days ago 215MB
pytorch/pytorch 1.4-cuda10.1-cudnn7-runtime 37b81722dadc 7 months ago 4.16GB
hello-world latest bf756fb1ae65 7 months ago 13.3kB
C:\Users\lynnh>docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
centos centos8 0d120b6ccaa8 9 days ago 215MB
pytorch/pytorch 1.4-cuda10.1-cudnn7-runtime 37b81722dadc 7 months ago 4.16GB
hello-world latest
参数解释:
# REPOSITORY :镜像名称
# TAG :镜像标签(版本)
# IMAGE ID :镜像ID
# CREATED :创建时间
# SIZE : 镜像大小
docker run
启动镜像可以通过docker run 镜像名:tag
或者 docker run 镜像id
。
现在我们来启动刚刚下载的pytorch镜像吧。
C:\Users\lynnh>docker run -it 37b81722dadc /bin/bash
root@8cd9c9935d2a:/workspace# cd /
root@8cd9c9935d2a:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var workspace
root@8cd9c9935d2a:/# exit
exit
C:\Users\lynnh>
解释:
# -it是-i和-t的合并,表示通过交互式启动进入容器内部进行操作
# /bin/bash 表示启动的容器基于bash命令行进行操作
# 8cd9c9935d2a 为启动镜像后生成的容器id,每个镜像启动后都会有相应的容器
# 容器用来将镜像内部的环境和外部进行隔离,因此我们可以同时启动多个镜像,而相互之间不受影响
# 在容器中输入exit即可退出容器
docker rmi
docker rmi -f 镜像id # 删除指定镜像, -f表示强制删除
docker rmi -f 镜像id 镜像id 镜像id # 同时删除多个镜像
# 骚操作,linux下有效
docker rmi -f $(docker images -aq) # 全部删除
容器是打包代码及其所有依赖项的软件的标准单元,因此应用程序可以从一个计算环境快速可靠地运行到另一个计算环境。Docker容器映像是一个轻量级的,独立的,可执行的软件软件包,其中包含运行应用程序所需的一切:代码,运行时,系统工具,系统库和设置。
镜像在运行时会成为容器,对于Docker容器,镜像会在Docker Engine上运行时成为容器。不论基础架构如何,容器化软件都可用于基于Linux和Windows的应用程序,始终运行相同。容器将软件与其环境隔离开来,并确保尽管开发和登台之间存在差异,但软件仍可以均匀运行。
前面说过,启动镜像的时候会生成相应的容器。
docker ps
C:\Users\lynnh>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
C:\Users\lynnh>docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8cd9c9935d2a 37b81722dadc "/bin/bash" 14 minutes ago Exited (0) 9 minutes ago jolly_jennings
45ab1548e84f hello-world "/hello" 3 hours ago Exited (0) 3 hours ago agitated_almeida
C:\Users\lynnh>docker ps -aq
8cd9c9935d2a
45ab1548e84f
8cd9c9935d2a
是我们之前运行过的pytorch镜像的容器id。
docker ps # 列出当前正在运行的容器信息
-a # 列出当前正在运行的容器和历史运行过的所有容器信息
-q # 只显示容器id
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
docker exec -it 容器id /bin/bash
docker attach 容器id
# 区别
# docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach # 进入容器正在执行的终端,不会开启新的终端
测试:我们重启之前的容器8cd9c9935d2a
并进入。
C:\Users\lynnh>docker restart 8cd9c9935d2a
8cd9c9935d2a
C:\Users\lynnh>docker attach 8cd9c9935d2a
root@8cd9c9935d2a:/workspace#
exit # 直接停止容器并退出
ctrl+p+q # 不停止容器,只退出,在linux下有效
docker rm 容器id # 删除指定容器,不能删除正在运行的容器,可用 rm -f 强制删除
# 骚操作,linux下有效
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q|xargs docker rm -f # 删除所有容器
以前面的pytorch镜像为基础。
C:\Users\lynnh>docker attach 8cd9c9935d2a
root@8cd9c9935d2a:/workspace# cd /
root@8cd9c9935d2a:/# pip list
Package Version
---------------------- ----------
asn1crypto 1.2.0
backcall 0.1.0
beautifulsoup4 4.8.2
certifi 2019.11.28
cffi 1.13.0
chardet 3.0.4
conda 4.8.1
conda-build 3.18.11
conda-package-handling 1.6.0
cryptography 2.8
decorator 4.4.1
filelock 3.0.12
glob2 0.7
idna 2.8
ipython 7.11.1
ipython-genutils 0.2.0
jedi 0.15.2
Jinja2 2.10.3
libarchive-c 2.8
lief 0.9.0
MarkupSafe 1.1.1
mkl-fft 1.0.15
mkl-random 1.1.0
mkl-service 2.3.0
numpy 1.17.4
olefile 0.46
parso 0.5.2
pexpect 4.7.0
pickleshare 0.7.5
Pillow 7.0.0
pip 19.3.1
pkginfo 1.5.0.1
prompt-toolkit 3.0.2
psutil 5.6.7
ptyprocess 0.6.0
pycosat 0.6.3
pycparser 2.19
Pygments 2.5.2
pyOpenSSL 19.0.0
PySocks 1.7.1
pytz 2019.3
PyYAML 5.2
requests 2.22.0
ruamel-yaml 0.15.46
setuptools 41.4.0
six 1.12.0
soupsieve 1.9.5
torch 1.4.0
torchvision 0.5.0
tqdm 4.36.1
traitlets 4.3.3
urllib3 1.24.2
wcwidth 0.1.7
wheel 0.33.6
进入容器,发现该镜像已经安装好了pytorch环境所需要的一些基础包。
假设除了这些基础包,现在我们需要一些额外的包怎么办呢?比如我们还需要scikit-learn
和scikit-image
这两个包。
因为该镜像中已经有了pip工具,在容器中我们可以直接通过pip来安装我们额外需要的包。
pip install scikit-learn scikit-image -i https://pypi.douban.com/simple
root@8cd9c9935d2a:/# pip install scikit-learn scikit-image -i https://pypi.douban.com/simple
Looking in indexes: https://pypi.douban.com/simple
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f9b37a34c50>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/scikit-learn/
Collecting scikit-learn
Downloading https://pypi.doubanio.com/packages/f4/cb/64623369f348e9bfb29ff898a57ac7c91ed4921f228e9726546614d63ccb/scikit_learn-0.23.2-cp37-cp37m-manylinux1_x86_64.whl (6.8MB)
|████████████████████████████████| 6.8MB 1.5MB/s
Collecting scikit-image
Downloading https://pypi.doubanio.com/packages/d7/ee/753ea56fda5bc2a5516a1becb631bf5ada593a2dd44f21971a13a762d4db/scikit_image-0.17.2-cp37-cp37m-manylinux1_x86_64.whl (12.5MB)
|████████████████████████████████| 12.5MB 640kB/s
Requirement already satisfied: numpy>=1.13.3 in /opt/conda/lib/python3.7/site-packages (from scikit-learn) (1.17.4)
Collecting joblib>=0.11
Downloading https://pypi.doubanio.com/packages/51/dd/0e015051b4a27ec5a58b02ab774059f3289a94b0906f880a3f9507e74f38/joblib-0.16.0-py3-none-any.whl (300kB)
|████████████████████████████████| 307kB 3.1MB/s
Collecting scipy>=0.19.1
Downloading https://pypi.doubanio.com/packages/65/f9/f7a7e5009711579c72da2725174825e5056741bf4001815d097eef1b2e17/scipy-1.5.2-cp37-cp37m-manylinux1_x86_64.whl (25.9MB)
|████████████████████████████████| 25.9MB 1.6MB/s
Collecting threadpoolctl>=2.0.0
Downloading https://pypi.doubanio.com/packages/f7/12/ec3f2e203afa394a149911729357aa48affc59c20e2c1c8297a60f33f133/threadpoolctl-2.1.0-py3-none-any.whl
Requirement already satisfied: pillow!=7.1.0,!=7.1.1,>=4.3.0 in /opt/conda/lib/python3.7/site-packages (from scikit-image) (7.0.0)
Collecting matplotlib!=3.0.0,>=2.0.0
Downloading https://pypi.doubanio.com/packages/f1/b9/712584f12f840968a14969a1fe298ffdeaa9c4b484b3bfd973c74c4a481d/matplotlib-3.3.1-cp37-cp37m-manylinux1_x86_64.whl (11.6MB)
|████████████████████████████████| 11.6MB 2.8MB/s
Collecting imageio>=2.3.0
Downloading https://pypi.doubanio.com/packages/6e/57/5d899fae74c1752f52869b613a8210a2480e1a69688e65df6cb26117d45d/imageio-2.9.0-py3-none-any.whl (3.3MB)
|████████████████████████████████| 3.3MB 1.4MB/s
Collecting PyWavelets>=1.1.1
Downloading https://pypi.doubanio.com/packages/62/bd/592c7242fdd1218a96431512e77265c50812315ef72570ace85e1cfae298/PyWavelets-1.1.1-cp37-cp37m-manylinux1_x86_64.whl (4.4MB)
|████████████████████████████████| 4.4MB 1.5MB/s
Collecting networkx>=2.0
Downloading https://pypi.doubanio.com/packages/41/8f/dd6a8e85946def36e4f2c69c84219af0fa5e832b018c970e92f2ad337e45/networkx-2.4-py3-none-any.whl (1.6MB)
|████████████████████████████████| 1.6MB 15.1MB/s
Collecting tifffile>=2019.7.26
Downloading https://pypi.doubanio.com/packages/3f/51/151f2c5b89af5a3ebbe9d1078ce598abeeb6802b6cf568350914746d1c4c/tifffile-2020.8.13-py3-none-any.whl (146kB)
|████████████████████████████████| 153kB 9.9MB/s
Collecting python-dateutil>=2.1
Downloading https://pypi.doubanio.com/packages/d4/70/d60450c3dd48ef87586924207ae8907090de0b306af2bce5d134d78615cb/python_dateutil-2.8.1-py2.py3-none-any.whl (227kB)
|████████████████████████████████| 235kB 11.9MB/s
Collecting kiwisolver>=1.0.1
Downloading https://pypi.doubanio.com/packages/31/b9/6202dcae729998a0ade30e80ac00f616542ef445b088ec970d407dfd41c0/kiwisolver-1.2.0-cp37-cp37m-manylinux1_x86_64.whl (88kB)
|████████████████████████████████| 92kB 4.1MB/s
Collecting certifi>=2020.06.20
Downloading https://pypi.doubanio.com/packages/5e/c4/6c4fe722df5343c33226f0b4e0bb042e4dc13483228b4718baf286f86d87/certifi-2020.6.20-py2.py3-none-any.whl (156kB)
|████████████████████████████████| 163kB 3.0MB/s
Collecting pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3
Downloading https://pypi.doubanio.com/packages/8a/bb/488841f56197b13700afd5658fc279a2025a39e22449b7cf29864669b15d/pyparsing-2.4.7-py2.py3-none-any.whl (67kB)
|████████████████████████████████| 71kB 1.7MB/s
Collecting cycler>=0.10
Downloading https://pypi.doubanio.com/packages/f7/d2/e07d3ebb2bd7af696440ce7e754c59dd546ffe1bbe732c8ab68b9c834e61/cycler-0.10.0-py2.py3-none-any.whl
Requirement already satisfied: decorator>=4.3.0 in /opt/conda/lib/python3.7/site-packages (from networkx>=2.0->scikit-image) (4.4.1)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.7/site-packages (from python-dateutil>=2.1->matplotlib!=3.0.0,>=2.0.0->scikit-image) (1.12.0)
Installing collected packages: joblib, scipy, threadpoolctl, scikit-learn, python-dateutil, kiwisolver, certifi, pyparsing, cycler, matplotlib, imageio, PyWavelets, networkx, tifffile, scikit-image
Found existing installation: certifi 2019.11.28
Uninstalling certifi-2019.11.28:
Successfully uninstalled certifi-2019.11.28
Successfully installed PyWavelets-1.1.1 certifi-2020.6.20 cycler-0.10.0 imageio-2.9.0 joblib-0.16.0 kiwisolver-1.2.0 matplotlib-3.3.1 networkx-2.4 pyparsing-2.4.7 python-dateutil-2.8.1 scikit-image-0.17.2 scikit-learn-0.23.2 scipy-1.5.2 threadpoolctl-2.1.0 tifffile-2020.8.13
接下来,退出容器,提交我们增加了内容的镜像。
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[tag]
C:\Users\lynnh>docker commit -m="add scikit packages" -a="lynnh" 8cd9c9935d2a pytorch_diy:1.4.0
sha256:b285a729c32b3a20411dcd09bc39acfdef93054e5091b0054bef08d665c27643
C:\Users\lynnh>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
pytorch_diy 1.4.0 b285a729c32b 26 seconds ago 4.43GB
centos centos8 0d120b6ccaa8 9 days ago 215MB
pytorch/pytorch 1.4-cuda10.1-cudnn7-runtime 37b81722dadc 7 months ago 4.16GB
hello-world latest
至此,我们自己的docker镜像就做好了。接下来可以选择将该镜像发布到云端(如docker hub 或者阿里云仓库),或者保存到本地。
首先在自己阿里云的容器镜像服务中创建命名空间,创建好命名空间后创建镜像仓库。
点击仓库名称进入,安装下图的步骤进行操作即可将镜像发布到阿里云。
docker save -o xxx.tar 镜像id
下面仅介绍在linux上如何操作。
如果我们数据都在容器中,当容器删除的时候,数据就会丢失!
需求:数据持久化,比如mysql,当容器被删除的时候不就意味着删库跑路了。
需求: mysql数据存储在本地!
容器之间可以有一个数据共享的技术! Docker容器中产生的数据,同步到本地!
这就是卷技术!即目录的挂载,将容器中的目录,挂载到linux上!
总结:容器的持久化和同步操作!容器间也可以数据共享!
使用命令挂载 -v
docker run -it -v 主机目录:容器内目录
docker run -it -v 主机目录:容器内目录 -v 主机目录:容器内目录 ...
# 测试
# 1. 挂载
[root@localhost home]# docker run -it -v /home/ceshi:/home centos /bin/bash
# 2. 查看挂载是否成功
[root@localhost home]# docker inspect 115880798a20
...
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi", # 主机内地址
"Destination": "/home", # docker容器内地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
...
# 3. 在容器内新建文件,查看主机内是否同步
[root@115880798a20 home]# ls
[root@115880798a20 home]# touch test.java
[root@115880798a20 home]# ls
test.java
[root@115880798a20 home]#
[root@localhost home]# ls
ceshi lynn
[root@localhost home]# cd ceshi
[root@localhost ceshi]# ls
[root@localhost ceshi]# ls
test.java
[root@localhost ceshi]#
# 4. 停止容器,并修改主机中test.java中的内容,查看在容器中是否变化
[root@115880798a20 home]# exit
exit
[root@localhost home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost ceshi]# vim test.java
[root@localhost ceshi]# cat test.java
hello world!
[root@localhost home]# docker restart 115880798a20
115880798a20
[root@localhost home]# docker attach 115880798a20
[root@115880798a20 /]# cd home
[root@115880798a20 home]# ls
test.java
[root@115880798a20 home]# cat test.java
hello world!
# 5. 删除容器内的文件,主机上也会被删除。但删除容器,主机上的文件依然在
依旧同步!!!
好处:只需在本地修改配置,容器内会自动同步!
# 1. 匿名挂载
-v 容器内路径 # 不加主机路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有卷的情况
docker volume ls
local 5b6b9ff93dc8ea2c34e706e707d7db5d2aa6373faf1a9d4a8ab4
# 这里发现,这种匿名挂载,我们在 -v 只写了容器内的路径, 没有写容器外的路径
# 2. 具名挂载, 注意juming-nginx前面没有/, 不表示路径,只是起名
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
[root@localhost home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
a7e97f4512dc67fe30463838aa2d5f838d9f1013fa440114d5f02a41c9302ea7
[root@localhost home]# docker volume ls
DRIVER VOLUME NAME
local 5b6b9ff93dc8ea2c34e706e707d7db5d2aa6373faf1a9d4a8ab44ebeb388dd2d
local b5e0bf6cdf6fcf5b7a469dc3ca9b16cd2873a398ff63381482c7adeec0b61cac
local juming-nginx
local portainer_data
# 查看卷
[root@localhost home]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2020-08-04T20:30:08+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定目录的情况下都在 /var/lib/docker/volumes/xxx/_data
我们通过具名挂载可以方便的找到卷,大多数情况使用具名挂载
#如何确定是具名挂载还是匿名挂载,还是指定路径挂载?
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
目前关于Docker的介绍到此结束,后面有新内容会进行补充!