经验拾忆(纯手工)=> Docker语法全面回忆

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种挂载参数使用":
           一、 "-v 参数"        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,共享成功
  • 细节注意事项

       一、若将 "空数据卷"   挂载到 容器非空目录中,则"此容器目录下的内容 会copy一份到 数据卷中"
       二、若将 "非空数据卷" 挂载到 容器任意目录中,则"数据卷的数据 会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
  • 上传镜像

       一、先把要上传的镜像改名
           docker tag   mypython:latest    127.0.0.1:6006/mython_hub
           注: 目标名固定格式(需注意,必须此格式):   IP:Port/新镜像名
       二、开始上传
           docker push 127.0.0.1:6006/mython_hub    # docker push 镜像名,注意这里用ID不好使,必须用这名
       三、验证
           同上面搭建仓库时的验证方法, 可看见结果 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机制:
           一、若在结尾每"追加"一条新命令,重新构建Dockerfile时,"只会执行这个新命令,其他旧命令都会使用缓存"
           二、若新命令 是在"中间插入编写的",则此条新命令"之前的命令用缓存", "之后"的命令都会重新执行一遍,
           三、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种书写方式:
           一、(exec)格式--当前进程执行
               eg:  python -V        # 就是玩linux的命令正常写
           二、(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认知

       一、Dockerfile 可以看作是 Docker命令的组合
       二、Docker-Compose 可以看作是 Dockerfile的组合(也称作 容器编排工具)
       三、Docker-Compose 文件默认名为  docoker-compose.yaml
       四、docoker-compose.yaml 文件指令中间都有空格  eg:  version: 3.7(3.7之前是有空格的)
       五、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

    原文作者:Cython_lin
    原文地址: https://segmentfault.com/a/1190000020039341
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞