zoukankan      html  css  js  c++  java
  • Docker 学习笔记(一):基础命令

    仅为个人查阅使用,要学习 Docker 的话,推荐看这份文档:《Docker — 从入门到实践》

    P.S. 大多数的 docker container xxx/docker image xxx 命令,都有相对应的缩写方式:docker xxx

    零、安装 docker

    参见 《Docker — 从入门到实践—安装》,包括各 Linux 发行版、Windows、MacOS

    国内加速器: https://get.daocloud.io/#install-compose,包含 Linux 安装加速、Hub 镜像仓库加速。(但它的 Windows 加速版本太老,别用)

    一、基本概念

    要构建并运行一个 Docker 容器,有这样几个步骤:

    1. 编写 Dockerfile,然后通过 build 命令从 Dockerfile 构建镜像
      1. 镜像是分层构建,分层存储。这使得镜像的复用、定制变的更为容易。
      2. 镜像不包含任何动态数据,其内容在构建之后就不会被改变。因此它对运维很友好,可以实现一次 build 到处运行。
    2. 通过 run 命令启动该容器。(镜像仓库后面再记)
      1. 镜像内容是静态的,而容器是动态的!
      2. 每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层。可以称这个为容器运行时读写而准备的存储层为 容器存储层
      3. 容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。
      4. 所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
    3. 用 login 命令登录到 Docker 的镜像仓库(私人的或者公共的),然后通过 push 命令将构建好的镜像推送上去。
    4. 在别的机器上 pull 镜像下来,通过 docker run xxx 命令运行。

    二、Docker 基础命令

    1. 获取镜像

    通过 pull 命令从仓库中获取镜像:

    # 格式
    docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
    
    # e.g. 1:从公共仓库拉 nginx 的镜像
    # 下列两条命令效果相同,默认从 library (官方镜像)找镜像,tag 默认为 latest(最新版本)
    docker pull library/nginx:latest
    docker pull nginx
    
    # e.g. 2:从公共仓库中,拉取个人上传的镜像
    docker pull <username>/myblog:latest
    
    # e.g. 3:从私人仓库拉取 ryan 项目下,名为 myblog 的镜像
    docker login reg.myharbor.com:4321  # 私人仓库一般都需要先登录,会将登录信息保存到本地
    docker pull reg.myharbor.com:4321/ryan/myblog
    

    自己编写 Dockerfile,然后通过 Dockerfile 构建镜像(Dockerfile 的语法后面再细说):

    # --tag 可以缩写成 -t,用于指定镜像的 [镜像名:<tag>],其中 <tag> 可省略。
    docker build --tag friendlyhello .  # 使用当前目录下的 Dockerfile 构建镜像,并且`镜像名:tag`为 `friendlyhello:latest`
    

    2. 查看/删除镜像

    查看镜像列表:

    docker image ls -a     # 列出当前机器上的所有镜像
    docker images -a       # 上一条命令的缩写
    
    docker images -a <image name>  # 查找名为 <image name> 的镜像
    

    删除镜像:

    docker image rm <image id>
    docker image rm <image name>:<tag>  # 删除 <image name> 镜像的一个 tag
    
    docker rmi <xxx>  # `docker image rm <xxx>` 的缩写
    
    docker image ls -f dangling=true  # 列出所有虚悬镜像(即仓库名和 tag 都为 none 的镜像)
    docker image prune  # 清除所有未被使用的虚悬镜像(被依赖了的虚悬镜像无法直接清除,见后)
    
    docker image rm $(docker image ls -a -q)  # 删除本机的所有镜像(危险操作)
    docker system prune  # 删除所有停止的容器+虚悬镜像+未被使用 network+构建缓存
    docker system prune --all # 除了上述数据之外,还要删除所有未被容器使用的镜像
    

    如果一个正常的镜像,或者某个容器依赖了某些虚悬镜像,那这些虚悬镜像就不能被直接删除。你需要先删除掉那个上层的镜像或者容器。

    删除该上层镜像时,所有只被它依赖了的虚悬镜像也会被自动清除掉。但是删除上层容器后,还需要手动用 docker image prun 清除被它使用了的虚悬镜像。

    3. 启动容器

    1. docker run: 从指定镜像新建一个容器并运行命令,然后终止运行。标准流程如下:
      • 检查本地是否存在指定的镜像,不存在就从公有仓库下载(对应 docker image pull
      • 利用镜像创建并启动一个容器(对应 docker container create
      • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
      • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
      • 从地址池配置一个 ip 地址给容器
      • 执行用户指定的应用程序(对应 docker container start
      • 执行完毕后容器被终止(对应 docker container stop
    # 在 ubuntu 18.04 中输出 Hello World
    # --rm 表示,容器终止运行后,自动删除该容器
    # 此外,还有 --env 设置环境变量,-p 设置端口映射,--volume 设置数据卷
    # --net 设置网络连接类型
    docker run --rm ubuntu:18.04 /bin/echo 'Hello world'
    
    docker run -it --user=root <image:tag> bash # 以 root 身份运行 bash(不要去用 su root,然后到处找 root 的密码了。。)
    
    # 进入容器的 bash 终端
    # -i 使容器的 stdin 保持打开,-t 为容器分配一个伪 tty。
    # 结合使用上述两个选项 `-it`,效果类似 ssh 远程连接。
    docker run -it ubuntu:18.04 /bin/bash
    
    # P.S. 其实只需要 -i 参数,就能和容器进行交互了,敲命令能得到回复。
    # -t 添加的伪终端,感觉只是在每个命令行开头加了个 `root@25d5c233769b:/# ` 这样的提示符。
    
    1. docker run -d:使新建的容器在后台运行
    # 在后台启动一个 nginx 容器,提供静态网站访问功能,或者做代理
    # -d 表示在后台运行该容器,--rm 使容器在终止后被自动删除
    docker run -d --rm my-nginx:latest
    
    # --restart=always 容器意外退出时,总是自动重启。以保证服务总是可用。
    # --name my-blog  为容器取个有意义的名字,可在任何命令中,用该名字替换 container id 使用
    docker run --rm -d -restart=always --name my-blog my-nginx:latest
    
    # 前台运行的容器,stdout 会被定向到本机的 stdout,所以能直接看到命令的输出
    # 而后台运行的容器,就需要通过下面的命令查看输出了
    docker logs <container id / container name>  # 查看指定容器的 logs,更详细的参数请 man
    docker logs <container id / container name> | vim -  # 通过 vim 查看容器日志,可以方便地按行跳转、全文搜索。
    docker logs -f <container id / container name>  # 持续地输出容器的日志(ctrl-c 退出)
    
    1. 查看容器列表、启动/终止容器、删除容器
    docker container ls -a  # 列出所有容器
    docker ps -a  # 上一条命令的缩写
    
    docker container create --name <container name>  <image>:<tag> [command]  # 从指定镜像新建容器,但是不立即运行。
    
    docker container start <container id / container name>   # 启动一个已经终止运行的容器
    docker container stop <container id / container name>   # 终止一个正在运行的容器(该容器可能在后台工作,也可能是正被别的 shell 运行)
    
    docker container rm  <container id / container name>    # 删除一个未运行的容器
    docker container rm -f <container id / container name>   # 强制删除容器,即使该容器正在运行
    
    docker container prune  # 清理掉所有已终止的容器
    
    docker rm -f $(docker ps -aq)  # 强制删除掉所有的容器!可用于清理系统。
    
    docker [start|stop|rm] <xxx>  # 上述命令的缩写,container 可省略
    
    1. 登入容器:
    # 1. 使用 attach 命令登入(不推荐!!)
    # 将容器的 stdin/stdout/stderr 与当前终端接驳,容器切换到前台运行。
    # 特别注意的是,因为容器切换到了前台运行,退出会导致容器终止!因此才不推荐用此命令。
    docker container attach <container id / container name>`  # 可缩写成 `docker attach xxx`
    
    # 2. 使用 exec 命令登入(推荐方式)
    docker exec -it <container id / container name> bash  # 使用默认用户登录
    docker exec -it --user=root <xxx>  # 以 root 身份登入容器(不要去用 su root,然后到处找 root 的密码了。。)
    
    1. 查看容器的各项数据
    docker container stats  <container id / container name>  # 查看容器的 CPU/RAM 使用率,网络IO速率等参数
    docker container logs  <container id / container name>  # 查看容器日志,一般都是 CMD/ENTRYPOINT 命令的日志
    docker container diff <container id / container name>   # 查看容器层相对镜像的变动(A-added,D-deleted,C-changed)
    
    docker container kill  <container id / container name>  # 强制终止容器,发送终止信号给容器。(只是发信号过去,不一定成功。。)
    
    docker container ls --size  # 列出所有容器,显示各容器的 disk 占用
    

    容器/镜像中数据的导入和导出

    # 1. 将容器中的指定路径(文件夹) copy 出来
    # 可以指定存放路径(若路径不存在,会自动创建),也可以通过管道以流的方式传输给下个程序
    docker container cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-   
    # 2. 将本机的数据拷贝进容器,可以是路径,也可以通过管道以流的方式传输到容器中。(用 tar -ax 就能正确将流转成原来的文件)
    docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
    
    # 3. 存取镜像中的数据
    # 方法一:直接在 Dockerfile 中使用 COPY --from=<image name>:<tag> <src path> <dest path>
    # 方法二:先使用 docker create 为镜像新建容器层,再用 docker cp 命令导入/导出数据。
    

    4. 镜像/容器的导入和导出

    4.1 镜像的导入导出

    镜像可以通过中心仓库进行分享,但是有些情况下,我们只想快速地将镜像分享给某台机器。这就需要用到镜像的导入导出功能了:

    # a. 将指定镜像导出为 tar 文件
    # 注意:如果同名则会覆盖(没有警告)
    docker save <imagename>:<tag> -o <filename>
    
    # 使用 gzip 进一步压缩
    docker save <imagename>:<tag> | gzip > <imagename>-<tag>.tar.gz
    
    # b. 从指定文件加载镜像
    docker load -i <imagename>-<tag>.tar.gz  # 不需要先解压
    

    上述导入导出命令,结合 ssh,就能完成镜像的快速分享:

    docker save <镜像名> | bzip2 | pv | ssh <用户名>@<主机名> 'cat | docker load'
    
    # pv:即 Pipe Viewer,意思是通过管道显示数据处理进度的信息。一般需要自行安装。
    # yay -S pv 或 sudo apt-get install pv 或 yum install pv
    

    4.2 容器的导入和导出(不推荐)

    容器导出后再导入到镜像中,环境变量和一些基本的配置信息丢失了。所以最好还是不用使用这个功能,前后不一致,从镜像入手才是正确的方式。

    虽然说容器层不应该保存任何动态数据,
    但是总有特殊情况(或者说太菜),我们把一些必需的东西放进了容器层,现在要使容器能在另一台机器上运作。

    这时候,就需要做容器的导入导出了:

    # 将容器的当前快照导出为文件
    docker export [container id / container name] > ubuntu.tar
    
    # 从文件将容器快照导入为镜像,
    # 注意!!!是导入成了镜像!并且为这个镜像指定了 [name:tag]
    cat ubuntu.tar | docker import - test/ubuntu:v1.0
    

    容器导出的镜像,环境变量和一些基本的配置信息都会丢失,而且 ENTRYPOINT/CMD 信息也会丢失,运行(run)时还需要手动指定命令。

    感觉是相当不好用。

    Docker 仓库

    docker login <repo-host:port>  # 登录到指定的仓库,默认登录到 docker hub
    docker logout <repo-host:port>   # 登出指定仓库
    
    docker search <image name>  # 在 Docker Hub 中搜索镜像
    

    参考

    遇到过的问题

  • 相关阅读:
    linux中mysql,mongodb,redis,hbase数据库操作
    hbase数据库操作
    hdfs基本操作
    linux及hadoop基本操作
    创建有关hbase数据库的项目时所遇到的问题
    数据科学与大数据
    《TCP/IP详解卷1:协议》——第2章:链路层(转载)
    《TCP/IP详解卷1:协议》——第1章:概述(转载)
    深入理解计算机操作系统——第9章:缓存,存储器管理
    深入理解计算机操作系统——第9章:物理和虚拟寻址,地址空间
  • 原文地址:https://www.cnblogs.com/kirito-c/p/11145888.html
Copyright © 2011-2022 走看看