Hello Docker
官方安装教程:https://docs.docker.com/install/linux/docker-ce/ubuntu/
进去选好对应系统/发行版, 照着命令复制-粘贴-运行。 就能够安装成功(根本不须要多余操做)
Image(镜像)
-
docker search
docker search python # 列出dockerhub 提供的 image
-
docker pull(下载)
docker pull python:3.7 # 从 dockerhub下载 image 冒号:数字 用来指定版本(不指定就是最新版本)
-
docker images(列出)
docker images # 列出本地镜像 (或 docker image ls)
docker images py* # 也能够经过名称来筛选查看 image, 也可以使用通配符
-
docker rmi(删除)
docker rmi "image名" 或 "imageID" # 删除 image
docker rmi python -f # 强制删除(当image内有容器运行没法删除时,可经过-f强制删除)
若是两个image有相同 "imageID",会删除失败, 这时能够考虑用 "image名" 来删除
若是两个image有相同的 "image名", 那么能够考虑用 "image名:Tag" 来删除
-
docker save(保存备份)
方式1:docker save python > python.tar # 可追加多个image来 把多个image打包保存
方式2: docker save python -o python.tar
python.tar文件 可分享传输,给别人还原加载使用
注: 上令为例,若是有多个python版本, 那么会将全部python images 都会打包在一块儿保存
若是你有多个镜像, 为了不混淆,必定要指定一下版本号 docker save python:latest
-
docker load(还原)
方式1: docker load -i python.tar
方式2: docker load < python.tar
-
docker tag(更名,改版本号)
docker tag python:latest py:3.7 # 把 "python:latest" 改成 "py:3.7 "
注1: 若image名不为<none>, 那么首先会将 image 复制建立一份,而后更名
注2: 若原image名为 <none> ,那么 更名后,会直接在原有image上直接更名
-
docker inspect(查看详细信息)
docker inspect python
-
docker history(查看分层历史信息)
docker history mypython:3.7
Container(容器)
-
docker create(建立)
docker create --name py-con python:latest # --name后自定义名字, 最后指定哪个镜像
docker create -it python:latest python # 建立带有标准输入环境的容器,并执行python命令
-t 为了给容器建立一个 terminal
-i 为了给容器提供一个 标准输入流 (不然,容器终端里没法输入)
注:建立默认是 created状态, 须要下面 docker start 命令来启动
-
docker start(开启)
docker start -ai 容器ID # 以标标准环境开启容器
-a 表明提供标准输出
-i 同create -i ,提供标准输入
-
docker run(建立+启动, 推荐)
docker run -it python:latest python # 一套搞定 create+start 的繁杂过程, -it同上不解释
# 命令防混淆解释: 根据python:latest镜像 ,建立并执行容器,同时执行 python命令
docker run -d -it python:latest python
# 其余不变,多加一个 -d, 能够建立并放入 "后台" 执行 (不加-d , 默认"前台")
docker run -dit --rm python:latest python
# --rm 参数表明 容器中止,即(exited状态), 就会自动删除。
docker run --network bridge -itd mypython:latest python
# --network 表明指定网络(若不指定,默认也是bridge,见下面 网络章节)
docker run -dit -p 6006:6379 redis
# 端口映射, 宿主机(6006):容器(6379) (-P表明容器内部全部端口 与宿主机随即映射)
docker run --restart always
# --restart always 表明 docker服务重启时, 里面的容器也会跟着重启
-
docker stop(终止,结束)
docker ps # 查看一下 "运行中容器ID"
docker stop 容器ID # 中止 "运行中" 的容器 ( 默认 10秒钟后 才中止)
docker stop -t 0 374 # -t指定时间 0秒后, 即瞬间就能够中止
扩展(中止全部正在运行的容器):
docker stop $(docker ps -q) # -q参数表明只显示容器ID
-
docker restart(重启)
docker restart -t 0 281 # 0秒重启
-
docker pause(暂停)
docker pause 281 # 暂停容器内的全部进程, 注意是暂停, 不是终止
-
docker unpause(继续)
docker unpause 281 # 把暂停的容器,继续开启
-
docker ps(查看)
docker ps # 列出全部 "运行中" 的容器
docker ps -a # 列出全部 容器
-
docker logs(查看输出日志)
docker logs 281 # 查看容器内部输出日志
docker logs -f 281 # -f 表明阻塞监控, (和 tail -f 一个道理)
-
docker rename(重命名)
docker rename 281 python # 把 281的容器 更名为 python
-
docker inspect(查看容器详细信息)
docker inspect 374 # 查看容器全部信息
-
docker rm(删除)
docker rm 容器ID # 删除已中止的容器
docker rm 容器ID -f # 强制删除(运行中)等特殊状况的容器
-
docker attach(进入到容器命令执行处)
docker run -itd python:latest python # 新建立容器,名执行 python命令
docker attach 281 # 直接进入281这个容器,并直接跳到 python控制台内部
"注: 进入python控制台后,再退出去,就意味着, 容器的退出。"
-
docker exec(执行命令)
docker exec -it 281 python # 在"容器外部", 执行"内部容器"的 python命令
"注: 与上一条attach不一样的是,退出python控制台后,容器依旧运行!(由于是在容器外面执行的python命令)"
Container and Images(容器与镜像关联)
-
docker commit (把容器"封装"成一个新镜像)
docker commit 4d mypython:3.7 # 把4d这个容器全部内容,封装为一个"名字:版本"叫"mypython:3.7"的镜像
-
docker export (容器导出为一个文件)
docker export fc8 -o mypython.tar # 把此容器导出为一个.tar文件 ,和前面说过的 image的 save相似
-
docker import (把export导出的文件导出,并"生成"一个镜像)
docker import mypython.tar mypython:latest
注: 把export导出的 mypython.tar文件导入 并 直接建立一个 mypython:latest 的 镜像
-
docker commit & docker import区别
前面说过:
docker commit 是 直接把一个container 封装为一个image
docker import 是 把export导出的container.tar文件 再 导入进来,并从新生成一个 新 image
docker commit 是继承封装的,并建立具备分层历史记录 (docker history imageID 便可查看)
docker import 是直接生成的,不具备分层记录 (docker history imageID 便可查看)
网络
-
docker network ls (查看)
docker network ls
bridge(网桥):容器默认网络模式
容器-容器网络链接:
container1(etho0)--veth1--Docker(bridge)--veth2--container2(etho0)
容器-宿主机网络链接:
container1(etho0)--veth1--Docker(bridge)--宿主机(etho0)
注: veth是建立网络时,自动建立的,不须要手动管理
host(主机): 容器网络和主机使用同一个网络
容器-容器网络链接:
container1(etho0)--宿主机--container2(etho0)
容器-宿主机网络链接:
container1(etho0)--宿主机
容器网络(特殊host):
container1--container2 # 就是 ‘每一个容器互相把对方认做为 宿主机’ 这个意思
使用方法:
docker run -it --network container:24f1 mypython:latest ls
# container:24f1 的container是语法关键词 24f1是链接的对方容器()
null(无网络):全部容器无网络
-
docker network create (建立)
docker network create -d bridge mybridge # 可建立多个bridge
docker network create -d host myhost # 只可建立一个host(默认就有一个,故没法建立)
docker network create -d null mynull # 只可建立一个null(默认就有一个,故没法建立)
-
docker network rm (删除)
docker network rm ab5
注:默认自带的网络不能够删除(null host 和 自带的一个 bridge)
-
docker network connect (给容器绑定网络)
docker network connect mybridge 4c4 # 给4c4这个容器绑定一个 mybridge网络(自定义的bridge)
docker inspect 4c4 # 查看一下容器信息,最下面就是网络
注:一个container 能够绑定 多个bridge 网络,
-
docker network disconnect (给容器 解除绑定的网络)
docker network disconnect mybridge 4c4 # 给容器解除绑定网络mybridge
注: 一个container 中 bridge 和 none 网络不能够共存, (若冲突,则先disconnect再connect)
注2:host 网络不能 connect 和 disconnect
数据卷 (volume)
-
docker volume create(建立数据卷)
docker volume create myvolume
注: myvolume为数据卷名
-
docker volume ls(列出数据卷)
docker volume ls
注: 若数据卷未指定名字,当 使用docker run -v 方式时,则会新建数据卷ID,并以此ID命名。
-
docker volume prune(删除未被容器使用的 全部 数据卷)
docker volume prune
注:容器占用的数据卷,删不了
-
docker volume rm (删除 一个 或 多个 指定数据卷)
docker volume rm myvolume
注: 删除 myvolume这个数据卷,固然也能够连续参数,追加删除多个数据卷
-
挂载数据卷
"""意义: 可让 宿主机 与 容器 数据联通共享"""
方式1 (-v参数)
-v使用方式1:(指定路径映射挂载)
docker run -itd -v /root:/root mypython:latest python # -v 宿主机路径:容器路径
测试:
cd /root
touch aaa.txt # 宿主机建立文件 aaa.txt
docker exec -it cfb ls /root # 结果可看见容器里面也有 aaa.txt 文件
-v使用方式2:(指定数据卷对象 映射挂载)
docker run -itd -v myvolume:/root mypython:latest python # 冒号前面 变成了myvolume
注1: 这个myvolume就是一个数据卷对象, 执行上面这条命令,就会为咱们自动建立这个数据卷对象
注2: 因为没有宿主映射路径,那么映射的宿主路径 是什么呢??
docker volume inspect myvolume # 结果Mountpoint后面的就是,宿主机映射的 默认钩子路径
cd /var/lib/docker/volumes/myvolume11/_data # 此路径和volume名有关
touch bbb.txt # 宿主机建立文件 bbb.txt
docker exec -it 916 ls /root # 打印结果可见,容器内部也有bbb.txt,说明成功共享。
方式2:(--mount参数,一样包括 -v的两种使用方式, 另外还新增另外一种 文件"缓存"挂载方式)
docker run -itd --mount type=volume,src=myvolume11,dst=/root mypython:latest python
注:
type: 指定类型(路径映射: bind)或 (数据卷对象映射: volume) 或(内存映射:tmpfs)
src: 对应上面方式1(宿主机路径) 或 对应上面方式2(数据卷名) 或 省略此项(对应新增)
dst: 容器路径
逗号分隔,其余没变
docker run -itd --mount type=tmpfs,dst=/root mypython:latest python (tmpfs"缓存"挂载)
"综上,可总结为3种挂载选择用途":
一. "宿主路径 与 容器路径" 映射挂载
二. "数据卷 与 容器路径" 映射挂载
三. "宿主内存 与 容器路径" 映射挂载
"综上,可总结为2种挂载参数使用":
1、 "-v 参数" 2种用途 (路径映射 和 数据卷对象映射)
2、 "--mount 参数" 3种用途 (路径映射 和 数据卷对象映射 和 内存映射)
-
容器之间共享数据
"""借助已经拥有数据卷的容器 来 建立一个新容器"""
docker run -itd --volumes-from 6252 python:latest # 借助6252容器建立新容器,来共享数据卷
验证:
docker exec -it 97db touch /root/abc # 新容器 建立一个文件abc
docker exec -it 6252 ls /root # 旧容器查看 ,也有新文件abc,共享成功
-
细节注意事项
1、若将 "空数据卷" 挂载到 容器非空目录中,则"此容器目录下的内容 会copy一份到 数据卷中"
2、若将 "非空数据卷" 挂载到 容器任意目录中,则"数据卷的数据 会copy到这个目录中,并将此目录原数据隐藏"
更通俗一点理解就是:
数据卷大哥说:"若是我这里有数据, 你的容器来挂载,你的数据就会被我这里面的数据覆盖。。"
数据卷大哥又说:"若是我这里是空的(没有数据),那么 你的容器来挂载, 你的数据就要提供一份给我"
DockerHub(仓库)
无认证 私有仓库
-
搭建仓库
docker pull registry # 拉取 registry镜像
docker run -itd \
--restart always \ # docker重启时,此容器也跟着重启
--name myregistry \ # 指定容器名
-p 6006:5000 \ # 端口映射 (registry服务默认为5000端口,映射为6006)
-v /root:/var/lib/registry \ # 绑定数据卷 (持久化存储), 冒号后面的容器路径时默认的
registry # 拉取的 registry镜像
验证:(一种web服务,因此经过固定Url访问便可)
外部浏览器验证: 浏览器输入 服务器外网IP:6006/v2/_catalog 便可
服务器内部验证: curl 127.0.0.1:6006/v2/_catalog
-
上传镜像
1、先把要上传的镜像更名
docker tag mypython:latest 127.0.0.1:6006/mython_hub
注: 目标名固定格式(需注意,必须此格式): IP:Port/新镜像名
2、开始上传
docker push 127.0.0.1:6006/mython_hub # docker push 镜像名,注意这里用ID很差使,必须用这名
3、验证
同上面搭建仓库时的验证方法, 可看见结果 repositories列表中多了一个 刚刚上传的镜像
curl 127.0.0.1:6006/v2/_catalog
-
下载镜像
docker pull 127.0.0.1:6006/mython_hub
注: 这个名就是上传时候的 那个名, 同样的
Dockerfile(配置文件式)
-
Dockerfile认知
Docker 与 docker命令的关系就至关于 shell编程 与 单条命令
主要就是把上面讲的全部命令连起来,脚本式执行, 固然dockerfile也有本身的语法关键词。
Dockerfile是基于缓存,因此里面的文件内容(某条命令) "若是未发生改变,则不会从新执行(用的是缓存)"
Dockerfile机制:
1、若在结尾每"追加"一条新命令,从新构建Dockerfile时,"只会执行这个新命令,其余旧命令都会使用缓存"
2、若新命令 是在"中间插入编写的",则此条新命令"以前的命令用缓存", "以后"的命令都会从新执行一遍,
3、FROM 关键字是 Dockerfile的入口。
新命令只要不是 写在 "FROM的下一条", 那么全部新命令及其以后的命令都会在 构建Dockerfile时-->
触发"层层封装"机制 ,即每条"非缓存命令"运行一遍,都会commit封装一层镜像
-
Dockerfile构建
docker build /Dockerfile所在路径 -t mypython:v2
注1: 指定Dockerfile所在路径便可,build会自动帮咱们找到dockerfile文件
注2: 若是Dockerfile就在当前路径下,那么能够用 . 来替代绝对路径
注3: -t 给镜像指定名字
Dockerfile语法
-
FROM
"下载镜像,相似 docker pull"
FROM python:latest # 一样能够指定版本号
-
RUN | CMD | ENTRYPOINT
这三个 命令 都有共同的 2种书写方式:
1、(exec)格式--当前进程执行
eg: python -V # 就是玩linux的命令正常写
2、(shell) 格式--子进程执行
eg: ["python", "-V"] # 命令与做为字符串列表来书写, 和py的scrapy的shell相似
RUN:
"构建镜像过程当中"执行的命令, 好比安装东西之类的。。(可写多个)
CMD:
启动容器时 执行的命令, 就和 以前说过的 docker run 跟的命令是同样的
"可是 docker run 要是指定了一个命令,那么 这个CMD配置就会失效"
ENRTYPOINT:
和CMD相似, 不过 在docker run 指定新命令是, ENTRYPOINT的命令是不会被覆盖的。都会执行
-
ADD | COPY
"""将宿主机文件 拷贝 到镜像的某个目录中"""
COPY aaa.txt /root # 将aaa.txt 拷贝到 镜像的/root目录中
ADD aaa.txt /root # 和COPY同样,不过 ADD能够将压缩文件拷贝进去后,"自动解压"
-
ENV
"""就至关于编程语言的 变量赋值"""
ENV name=python
ENV nickname=$name # $name 意为取出 name变量的值
-
WORKDIR
"""切换目录 相似cd命令"""
WORKDIR /root
-
VOLUME
"""添加数据卷"""
VOLUME /root # 就至关于前面说过的docker run -v /root, 即自动建立一个数据卷映射到 容器的/root
-
EXPOSE
"""暴露端口"""
EXPOSE 6379
EXPOSE 3306 # 能够用多个 EXPOSE 暴露多个端口
注1: 暴露端口后,能够经过 前面说的 docker run -P 来作自动端口映射
注2: 或者不暴露端口,直接使用手动映射-p,都是能够的。
-
官方模板参考网址
官方文档:https://docs.docker.com/engine/reference/builder/
各类开源Dockerfile模板:https://github.com/docker-library/docs/tree/master/
Docker Compose
-
Docker-Compose认知
1、Dockerfile 能够看做是 Docker命令的组合
2、Docker-Compose 能够看做是 Dockerfile的组合(也称做 容器编排工具)
3、Docker-Compose 文件默认名为 docoker-compose.yaml
4、docoker-compose.yaml 文件指令中间都有空格 eg: version: 3.7(3.7以前是有空格的)
5、docoker-compose.yaml 采用缩进对格式语法进行区分
-
Docker-Compose安装
官方安装教程:https://docs.docker.com/compose/install/
从上往下,命令复制-粘贴-运行。。。Easy略
-
Docker-Compose文件指令
version: "3.7" # 必有
# 此版本号与docker版本对应地址: https://docs.docker.com/compose/compose-file/
services: # services关键字,写上就行, 必有
mypython: # mypython是我随便起个名
build: . # Dockerfile的路径位置, build是构建Dockerfile文件的
ports:
-"6006:3003" # 注意-后面是有空格的,markdown语法充冲突,我就没写空格
command: xxxx # 覆盖Dockerfile中的 CMD
depends_on: # 依赖的服务, (被依赖的先执行,也就是myredis先执行)
-myredis # -后有空格
myredis: # 同理 myredis 也是我随便起的名
image: redis # 指定一个成品镜像 相似DockerfilE的 FROM指令
container_name: myredis # 指定容器名
networks: # 使用下面建立的mynet网络
-mynet # (同-后有空格,避免markdown语法冲突)
volumes: # 使用下面建立的myvolume数据卷,并映射到容器的/root目录
-myvolume:/root # -后有空格,(特别注意 :后面不容许有空格)
hostname: myredis
# 由于容器建立时IP可能动态改变,指定名称,则可经过名称来代替IP
# 若不指定 hostname, 则默认为服务名, 即 myredis
networks: # 建立网络
mynet: # 给网络起名为 mynet
driver: "bridge" # 指定为桥接模式
volumes: # 建立数据卷
myvolume: # 给数据卷起名为 myvolume
driver: "local" # 默认就是local,即数据卷存储在宿主机的目录下
-
预检查docker-compose.yml文件语法格式是否有误
docker-compose config
注:须要在 docker-compose.yml 所在目录下执行
-
启动/中止 docker comopse
docker-compose up # 前台终端阻塞执行(就是执行以后,你不能在终端输入东西了)
docker-compose up -d # 后台终端非阻塞执行 (做为服务同样后台执行)
docker-compose stop # 中止编排(即中止 全部 编排运行的容器)
END