Docker教程

#Docker需要sudo权限,可以把用户加入用户组

1
sudo usermod -aG docker $USER

Docker架构

Docker**(C/S)**架构程序,可以在同一台宿主机上运行 Docker 守护进程和客户端,也可以从本地的 Docker 客户端连接到运行在另一台宿主机上的远程 Docker 守护进程。

镜像与容器

(image)镜像是静态的定义,(container)容器是镜像运行时的实体。通过镜像启动一个容器,一个镜像就是一个可执行的包,其中包括运行应用程序所需要的所有内容:包含代码,运行时间,库,环境变量和配置文件等。

镜像分层

​ 通过扩展现有镜像,创建新的镜像。新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享

Copy-on-Write

容器层可写,镜像层只读。所有镜像层会联合在一起组成一个统一的文件系统(从上到下,会覆盖),容器层(新的可写层被加载到镜像的顶部)中,用户看到的是一个叠加之后的文件系统。容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。

volume数据卷

将宿主机的目录映射到容器中的目录,应用程序在容器中的目录读写数据会同步到宿主机上,这样容器产生的数据就可以持久化。

registry注册中心

Docker 用 Registry 来保存用户构建的镜像。Docker 公司提供了公共的镜像仓库,一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

#<仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

Docker使用

1
2
3
#启动服务
sudo service docker start
sudo systemctl start docker

image文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#抓取image文件
docker image pull <文件组/文件名> #官方提供image都在library组里面,默认组可忽略

#管理
docker image ls #列出本机所有image文件
docker image rm [imageName] #删除image文件

#Dockerfile创建image
docker image build -t <imageName:tag> . #-t指定名字,默认tag为latest,'.'表示当前路径

#发布image
docker login #登录
docker image tag <imageName:tag> <username>/<repository>:<tag> #标注用户名和版本
docker image build -t <username>/<repository>:<tag> #重新构建一下
docker image push <username>/<repository>:<tag> #发布

container

1
2
3
4
5
6
7
8
9
10
11
12
#从image中生成一个运行的容器
docker container run -p <Lport>:<Dport> -it <imageName:tag> /bin/bash #未找到image会自动去仓库抓取,-p 容器端口映射到本机端口,-it 容器shell映射到当前shell,<command> 启动后内部第一个执行的命令,启动shell保证用户使用

#管理
docker container ls --all #列出正在运行虚拟机,-all列出所有(包括终止运行的)
docker container start <containID> #启动已生成/停止运行的程序
docker container rm <containID> #删除
docker container run --rm <containID> #运行终止后自动删除容器文件

#终止
docker container kill <containID> #一般程序运行完自动终止,服务不会,需要手动(SIGKILL强制立即终止,操作可能丢失)
docker container stop <containID> #SIGTERM 资源释放等,再结束

Dockerfile

#Dockerfile 是一个文本文件,用来配置 image。Docker 根据 该文件生成二进制的 image 文件。

1
2
git clone <url>	#下载项目源码
cd <文件路径> #打开此路径

​ /项目根目录

.dockerignore

​ #路径排除,拷贝目录中的文件时排除此文件中的目录

1
2
3
4
5
eg:

.git
node_modules
npm-debug.log

Dokerfile

1
2
3
4
5
6
FROM <imageName>:<tag>
COPY . <dirName> #将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的<dirName>目录。
WORKDIR <dirName> #指定接下来的工作路径为<dir>。
RUN <command> #在<dir>目录下,运行<command>命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件(image构建过程中)。
EXPOSE <port> #将容器<port>端口暴露出来, 允许外部连接这个端口。
CMD <command> #容器启动后自动执行的命令(设置此字段后不用再在生成容器时追加自动执行命令,会覆盖CMD)
1
2
3
4
5
6
eg:
FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000

docker使用

shell

1
2
3
#未使用-it参数时
docker container exec -it <containID> /bin/bash #进入一个正在运行的容器
docker container logs <containID> #查看容器输出

拷贝文件

1
2
docker container cp <containID>:</SRC_path|file> <DEST_PATH|FILE>	#复制容器文件到主机
docker cp <SRC_path|file> <containID>:<DEST_PATH|FILE> #主机复制文件到容器

删除

1
2
3
4
5
6
7
8
#查看所有运行容器
docker ps #-a所有(包括不运行的)

#删除全部容器
docker stop $(docker ps -q)

#停用全部运行中的容器
docker stop $(docker ps -q) #停用并删除加'&'连接

终止

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#列出所有的容器 ID
docker ps -aq

#停止所有的容器
docker stop $(docker ps -aq)
sudo docker stop $(sudo docker ps -aq)

#删除所有的容器
docker rm $(docker ps -aq)
sudo docker rm $(sudo docker ps -aq)

#删除所有的镜像
docker rmi $(docker images -q)

sudo docker rmi $(sudo docker images -q)