docker学习笔记

310 阅读9分钟

Docker

Dockfile

Dockfile是一个用来构建镜像的文本文件,包含了构建镜像所需的指令和说明, 使用docker build即可执行脚本构建镜像。

Docker Compose

Docker Compose是用于定义和运行多容器 Docker 应用程序的工具。Docker Compose 使用 YAML 文件来定义多服务的应用, YAML 是 JSON 的一个子集,因此也可以使用JSON。

Docker Compose 的 YAML 文件包含的: versionservicesnetworksvolumes;

常用命令

  1. docker-compose create 为服务创建容器
  2. docker-compose logs 查看容器日志
  3. docker-compose config 查看项目容器配置
  4. docker-compose ps 列出所有运行容器。
  5. docker-compose up -d 启动容器。
    docker-compose up -d # 启动容器后进入后台
    
  6. docker-compose down 关闭并删除容器。
  7. docker-compose kill 机制停止容器
  8. docker-compose rm 删除容器
  9. docker-compose [start | stop | pause | restart] 启动/停止/暂停/重启 容器
  10. docker-compose scale 设置服务运行的容器个数
  11. docker-compose exec NAME /bin/bash 进入指定容器
  12. docker-compose port NAME 端口号 显示某个容器端口所映射的公共端口
  13. docker-compose bulid 构建项目中的容器
  14. docker-compose push 推送镜像
  15. docker-compose pull 拉取依赖镜像

示例

  1. 在项目目录下docker-compose.yml 文件
  2. 构建镜像
    docker-compose build
    
  3. 运行
    docker-compose up -d
    

Docker Machine

Docker Machine是用于定义和运行多容器 Docker 应用程序的工具

docker volume

volume:独立于容器的生存周期,不会在容器删除时删除其挂载的数据卷,用来实现数据的持久化和数据共享。默认位于 /var/lib/docker/volumes 目录中。

示例

docker volume create test-nginx # 可省略 用docker run -v 直接创建。
# 新建容器文件,并挂载卷宗
# 卷宗名test-nginx,卷宗源/usr/share/nginx/html,创建后的位置 /var/lib/docker/volumes/test-nginx/_data;
docker run -d -it --name test-nginx -p 8080:80 -v test-nginx:/usr/share/nginx/html nginx

# 查看
docker volume ls
=>
DRIVER VOLUME NAME
local  test-nginx
# 创建时未指定卷宗名,Docker会默认创建匿名卷(一堆很长ID名👇)卷
local d35c144786ouh88888hhgsghw...

# 删掉容器后,卷宗依然存在
docker rm test-nginx                 

数据卷操作指令

docker volume ls # 查看所有容器卷 
docker volume inspect volumeName # 查看指定容器卷详情信息
docker volume create volumeName # 创建一个自定义容器卷
docker volume rm volumeName [volumeName...] # 删除容器数据卷

操作数据卷读写权利

-v <xxx>:容器内路径:ro # 容器内只能读挂载的文件
-v <xxx>:容器内路径:rw # 容器内能读写挂载的文件

示例: docker run -d -it --name test-nginx -p 8080:80 -v test-nginx:/usr/share/nginx/html:ro nginx

当容器上的volume有变动时,宿主机也会跟着变动,反之亦然;

# /usr/share/nginx/html文件夹下新增文件newfile
pwd # 获取当前路径
=>
/usr/share/nginx/html
mkdir newfile

# 查看/var/lib/docker/volumes/test-nginx/_data文件夹下,也增加了文件夹newfile。
ll /var/lib/docker/volumes/test-nginx/_data
=>
newfile ...

镜像

Docker 把应用程序及其依赖,打包在 image 文件里面。Docker 根据 image 文件生成容器的实例同一个 image 文件,可以生成多个同时运行的容器实例。

Docker Image可以理解成多个只读文件叠加而成,因此Docker Image是只读的。

当我们将其运行起来,就相当于在只读的Image外包裹了一层读写层变成了容器。

当你删除容器之后,使用这个镜像重新创建一个容器,此时的镜像的只读层还和原来的一样,但是你在读写层的修改全部都会丢失。

  1. 查看

    1. docker images [OPTIONS] [REPOSITORY[:TAG]]: 列出本机的所有 image 文件。
      • OPTIONS说明:
        • -a : 列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);
        • --digests : 显示镜像的摘要信息;
        • -f : 显示满足条件的镜像;
        • --format : 指定返回值的模板文件;
        • --no-trunc : 显示完整的镜像信息;
        • -q : 只显示镜像ID。
    2. docker image ls: 列出本机的所有 image 文件。
    3. docker history [OPTIONS] IMAGE: 查看指定镜像的创建历史。
  2. 创建

    1. docker build [OPTIONS] PATH | URL | -: 使用 Dockerfile创建镜像。
      • OPTIONS说明:
        • --build-arg=[] : 设置镜像创建时的变量;
        • --rm:设置镜像成功后删除中间容器;
        • -t/--tag:镜像的名字及标签;
          docker build -t test/myapp .
          
        • -f : 指定要使用的Dockerfile路径;
          docker build -f /path/to/a/Dockerfile . #  相当于Dockerfile 路径为 ./path/to/a/Dockerfile
          
        • . : Dockerfile文件所在目录, 可以指定绝对路径。如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置
        • 查看更多
    2. docker pull [OPTIONS] NAME[:TAG|@DIGEST]: 从镜像仓库拉取或者更新指定镜像。
      • OPTIONS说明:
        • -a : 拉取所有 tagged 镜像
        • --disable-content-trust : 忽略镜像的校验,默认开启
      • 示例
        docker pull java // 默认tag为latest
        
  3. 删除

    1. docker rmi [OPTIONS] IMAGE [IMAGE...]: 删除 image 文件。
      • OPTIONS说明:
        • -f : 强制删除;
        • --no-prune : 不移除该镜像的过程镜像,默认移除;
    2. docker image rm ${imageName}: 删除 image 文件
    3. docker image prune [OPTION]: 删除所有未被tag标记和未被容器使用的镜像。
      • OPTIONS说明:
        • -a: 删除所有未被容器使用的镜像
  4. 保存tar包

    • docker save [OPTIONS] IMAGE [IMAGE...]: 将指定镜像保存成 tar 归档文件。
      • OPTIONS说明:
        • -o : 输出到的文件。
      • 示例:
        docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3
        
    • docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]: 用镜像文件恢复成为一个镜像
      • OPTIONS说明:
        • -c : 应用docker 指令创建镜像;
        • -m : 提交时的说明文字;
        docker import  my_ubuntu_v3.tar runoob/ubuntu:v4 
        
    • docker load: 导入使用docker save命令导出的镜像。
      • OPTIONS说明:
        • --input / -i : 指定导入的文件,代替 STDIN。
        • --quiet / -q : 精简输出信息。
      • 示例
        docker load --input fedora.tar
        docker images
        
      • 和import的区别
        1. import导入的是容器快照,将会丢弃所有的历史记录和元数据信息,但可以重新指定标签等元数据。
        2. load导入的是镜像存储文件,将保存完整记录,体积也会更大。
  5. 其他

    • docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG] 标记本地镜像,将其归入某一仓库。或为镜像添加一个新的标签。
      docker tag ubuntu:15.10 runoob/ubuntu:v3 # 将镜像ubuntu:15.10标记为 runoob/ubuntu:v3 镜像。
      

镜像仓库

  1. docker login [option] [server]: 登录到docker镜像仓库,默认官方仓库 Docker Hub;

    • OPTIONS:
      • -u : 登陆的用户名
      • -p : 登陆的密码
    docker login -u 用户名 -p 密码
    
  2. docker logout [option] [server]): 登录到docker镜像仓库,默认官方仓库 Docker Hub;配置同docker login

  3. docker push: 将本地的镜像上传到镜像仓库,要先登录到镜像仓库。

    • OPTIONS说明:
      • --disable-content-trust : 忽略镜像的校验,默认开启
    • 示例:
      # 登录
      docker login -u 用户名 -p 密码
      
      # 打tag
      docker tag ubuntu:18.04 username/ubuntu:18.04
      
      # 查看
      docker image ls
      
      REPOSITORY      TAG        IMAGE ID            CREATED           ...  
      ubuntu          18.04      275d79972a86        6 days ago        ...  
      username/ubuntu 18.04      275d79972a86        6 days ago        ... 
      
      # push到仓库
      docker push username/ubuntu:18.04
      
  4. docker search [OPTION] TERM: 从Docker Hub查找镜像。

    • OPTIONS说明:

      • --automated : 只列出 automated build类型的镜像;
      • --no-trunc : 显示完整的镜像描述;
      • -f : 过滤条件;
    • 示例:

      docker search -f stars=10 java #从 Docker Hub 查找所有镜像名包含 java,并且收藏数大于 10 的镜像
      

容器

  1. 创建
    • docker create [OPTIONS] IMAGE [COMMAND] [ARG...]: 创建一个新的容器,但不启动它。用法同docker run
  2. 运行
    • docker run [OPTIONS] IMAGE [COMMAND] [ARG...]: 命令会从 image 文件,生成一个正在运行的容器实例。

      如果发现本地没有指定的 image 文件,就会从仓库自动抓取, 所以 docker image pull 命令并不是必需的步骤。

      • 示例

        # 生成nginx容器实例并命名为mynginx并且终端打印hello world, 可用docker logs [containerId]打印
        docker run --name mynginx -d nginx:latest /bin/sh -c "while true; do echo hello world; sleep 1; done" 
        
        # 生成nginx容器实例,并将其终端映射到当前终端 ctrl+d/输入exit退出
        docker run -it nginx:latest /bin/bash
        
         # 将容器的 8080 端口映射到本地主机 127.0.0.1 的 80 端口上。
        docker run -p 127.0.0.1:80:8080/tcp ubuntu bash
        
      • docker run -d 讲解

        加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec

        示例

        # 生成ubuntu-test容器实例,并指定容器的运行模式。
        docker run -itd --name ubuntu-test ubuntu /bin/bash
        docker ps
        

        image.png command下为/bin/bash: 即容器启动后,执行了 COMMAND 的命令后直接关闭进入后台。另COMMAND的默认值是/bin/bash

      • -p 讲解

        • -P : 是容器内部端口随机映射到主机的端口。
        • -p : 是容器内部端口绑定到指定的主机端口。
        docker run -d -p 5000:5000 training/webapp python app.py
        
        # 127.0.0.1:5001 => 5000端口
        docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
        
    • docker start:启动已经生成、终止的容器文件。

      docker container run 命令会新建容器,同样的命令运行两次,就会生成两个一模一样的容器实例。而 docker container start 不会。

    • docker restart:重启容器文件。

    • docker unpause CONTAINER [CONTAINER...]: 恢复容器中所有的进程。

  3. 终止
    • docker kill [OPTIONS] CONTAINER [CONTAINER...]: 终止容器的运行。
      • OPTIONS说明:
        • -s : 向容器发送一个信号
        docker kill -s KILL mynginx
        
    • docker container stop ${containID}: 终止容器的运行。
      • docker stop,支持“优雅退出”。先发送SIGTERM信号,然后做一些“退出前工作”,比如保存状态、处理当前请求等, 再发送(默认发出 SIGTERM 信号后10s)SIGKILL信号,直接退出。
      • docker kill,发送SIGKILL信号,应用程序直接退出
    • Docker pause CONTAINER [CONTAINER...]: 暂停容器中所有的进程。
  4. 删除
    • docker rm [OPTIONS] CONTAINER [CONTAINER...]:删除容器文件。

      docker container kill 仍会占据内盘空间, 可以使用 docker container rm 删除。

      • OPTIONS说明:
        • -f : 通过 SIGKILL 信号强制删除一个运行中的容器。
        • -l : 移除容器间的网络连接,而非容器本身。
        • -v : 删除与容器关联的卷。
    • docker container prune:删除所有停止运行的容器。相当于docker rm $(docker ps -a -q)
  5. 查看
    • docker ps [OPTION]: 查看容器
      • OPTIONS说明:
        • -a : 显示所有的容器,包括未运行的。

        • -f : 根据条件过滤显示的内容。

          image.png

        • --format : 指定返回值的模板文件。

        • -l : 显示最近创建的容器。

        • -n : 列出最近创建的n个容器。

          docker ps -a -n 5 #展示最近创建的5个容器
          
        • --no-trunc : 不截断输出。

        • -q : 静默模式,只显示容器编号。

          docker ps -a -p # 展示所有容器的containerId
          
        • -s : 显示总的文件大小。

    • docker container ls: 列出本机正在运行的容器。
    • docker container ls --all: 列出本机所有容器,包括终止的容器, 但不包括 docker container rm 删除的容器。
    • docker logs [OPTIONS] CONTAINER:查看 docker 容器的输出,即容器里面 Shell 的标准输出。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令查看输出。
      • OPTIONS说明:
        • -f : 跟踪日志输出
        • --since : 显示某个开始时间的所有日志
        • -t : 显示时间戳
        • --tail : 仅列出最新N条容器日志
    • docker inspect [OPTIONS] NAME|ID [NAME|ID...]: 获取容器/镜像的元数据, 包括Docker 容器的配置和状态信息等。
    • docker top [OPTIONS] CONTAINER [ps OPTIONS]: 查看查看容器内部运行的进程,支持 ps 命令参数
      docker top CONTAINER
      
      UID     PID         PPID          ...       TIME                CMD
      root    23245       23228         ...       00:00:00            python app.py
      
    • docker events [OPTIONS]:从服务器获取实时事件。
      • OPTIONS说明:
        • -f : 根据条件过滤事件;
        • --since : 从指定的时间戳后显示所有事件;
        • --until : 流水时间显示到指定的时间为止;
  6. 进入容器
    • docker exec [OPTIONS] CONTAINER COMMAND [ARG...](推荐): 命令用于进入一个正在运行的 docker 容器。一旦进入了容器,就可以在容器的 Shell 执行命令了。
      • OPTIONS说明:
        • -d : 分离模式: 在后台运行
        • -i : 即使没有附加也保持STDIN 打开
        • -t : 分配一个伪终端
      • 示例
        docker exec -it 9df70f9a0714 /bin/bash
        
        # 不会导致容器的停止
        exit 
        
    • docker attach [OPTIONS] CONTAINER: 连接到正在运行中的容器。
      docker attach ${containerId}
      
      # 会导致容器的停止
      exit 
      
  7. 其他
    • docker wait [OPTIONS] CONTAINER [CONTAINER...]: 阻塞运行直到容器停止,然后打印出它的退出代码。
    • docker export: 打包成tar包,导出到STDOUT。
      # 将id为a404c6c174a2的容器按日期保存为tar文件。
      docker export -o mysql-`date +%Y%m%d`.tar a404c6c174a2 
      
      # 将id为a404c6c174a2的容器快照到本地文件ubuntu.tar
      docker export 1e560fca3906 > ubuntu.tar
      
      # 将文件my-tomcat.tar生成对应的docker镜像
      docker import --message “this is a testing tomcat” my-tomcat.tar tomcat:1.0.1
      
    • docker port [OPTIONS] CONTAINER [PRIVATE_PORT[/PROTO]]: 列出指定的容器的端口映射,或者查找将PRIVATE_PORT NAT到面向公众的端口。
      docker port mymysql
      
      3306/tcp -> 0.0.0.0:3306
      
    • docker netword: 创建一个docker网络;
      # 创建一个docker网络
      # -d bridge: 指定 Docker网络类型
      docker network create -d bridge test-net
      
      # 查看
      docker network ls
      
      # 容器接入网络,test1和test2建立互联关系
      docker run -itd --name test1 --network test-net ubuntu /bin/bash
      docker run -itd --name test2 --network test-net ubuntu /bin/bash
      
      
    • docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]: 从容器创建一个新的镜像.
      • OPTIONS说明:
        • -a : 提交的镜像作者;
        • -c : 使用Dockerfile指令来创建镜像;
        • -m : 提交时的说明文字;
        • -p : 在commit时,将容器暂停。
      • [REPOSITORY[:TAG]]:要创建的目标镜像名:tag
      • 示例:
        docker commit -a "runoob.com" -m "my apache" a404c6c174a2  mymysql:v1
        docker images # 查看新创建的镜像
        
    • docker copy: 用于容器与主机之间的数据拷贝。
      1. docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-: 容器之间的数据拷贝。
        docker cp  96f7f14e99ab:/www /tmp/ # 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。
        
      2. docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH: 主机到容器之间的数据拷贝。
        docker cp /www/runoob 96f7f14e99ab:/www # 将主机/www/runoob目录拷贝到容器96f7f14e99ab中,目录重命名为www。
        
    • docker diff [OPTIONS] CONTAINER:检查容器里文件结构的更改。

制作自己的 Docker 容器

以阮一峰的 koa-demos 为例

  • 下载源码

    git clone https://github.com/ruanyf/koa-demos.git
    cd koa*
    
  • 编写文件

    1. 在项目的根目录下,新建一个文本文件.dockerignore, 内容如下:
      .git
      node_modules
      npm-debug.log
      
    2. 在项目的根目录下,新建一个文本文件Dockerfile, 内容如下:
      FROM node
      COPY . /app
      WORKDIR /app
      RUN npm install --registry=https://registry.npm.taobao.org
      EXPOSE 3000
      
      • COPY . /app: 将当前目录下的所有文件都拷贝进入 image 文件的/app目录,除了.dockerignore排除的路径,
      • WORKDIR /app:指定接下来的工作路径为/app
      • RUN npm install:在/app目录下,运行npm install命令安装依赖,并打包进入 image 文件。
      • EXPOSE 3000:将容器 3000 端口暴露出来, 允许外部连接这个端口。
  • 创建 image 文件

    docker image build -t koa-demo .
    # 或者
    docker image build -t koa-demo:0.0.1 .
    
      - `-t`参数用来指定 image 文件的名字
      - `:0.0.1`指定标签, 默认是 latest
      - `.`: 表示Dockerfile 文件所在的路径,为当前路径。
    
  • 生成容器

    docker container run -p 8000:3000 -it koa-demo /bin/bash
    
    • -p参数:容器的 3000 端口映射到本机的 8000 端口。
    • -it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
    • koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
    • /bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。
  • 运行容器中的文件

    node demos/01.js
    
  • 发布 image 文件

    容器运行成功后,就确认了 image 文件的有效性。这时,我们就可以考虑把 image 文件分享到网上,让其他人使用。

    首先,去 hub.docker.com 或 cloud.docker.com 注册一个账户。然后,用下面的命令登录。

    docker login 接着,为本地的 image 标注用户名和版本。

    docker image tag [imageName] [username]/[repository]:[tag] 实例 docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1

    也可以不标注用户名,重新构建一下 image 文件。

    docker image build -t [username]/[repository]:[tag] .

    最后,发布 image 文件。

    docker image push [username]/[repository]:[tag]

    发布成功以后,登录 hub.docker.com,就可以看到已经发布的 image 文件。

引用