1 - 介绍

Docker的介绍,以及Docker的资料收集

1.1 - Docker是什么?

解释Docker是什么

Docker介绍

Docker is a platform that allows you to “build, ship, and run any app, anywhere.” It has come a long way in an incredibly short time and is now considered a standard way of solving one of the costliest aspects of software: deployment.

Docker是一个平台,允许“build, ship, and run any app, anywhere”。它在极短的时间内走了很长一段路,现在被认为是用于解决软件部署问题的标准方法,而部署是软件最昂贵的方面之一。

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

Docker的比喻

备注:来自书籍 “Docker In Practice” chapter 1.1.1 What is Docker? 这个例子很有意思,特意摘录过来。

要了解Docker是什么,从隐喻开始比使用技术解释更容易,而Docker本身是一个强大的隐喻:Docker的本意是码头工人。码头工人是这样的劳动者:当船只停靠在港口时,码头工人将商品移入和移出船只。箱子和物品的大小和形状各不相同,经验丰富的码头工人因其能够以经济有效的方式手工将货物装入船舶而受到重视。雇人搬东西并不便宜,但别无选择。

在有Docker之前,不同团队的码头工人被要求装载不同形状的物体到船上去:

有Docker之后:

  • 船被设计为可以更有效的携带,装载和卸载预设形状的物品
  • 不同的物品放在同样一个简单的容器中。载体不关心容器里面是什么
  • 载体可以装载到其他地方,减少了港口装载的瓶颈
  • 仅需一个码头工人来操作设计用来移动容器的机器

对于工作在软件方面的人来说,这应该是熟悉的。花费了大量时间和智力,将隐喻奇怪形状的软件变成了不同大小的异形船,其中包含其他形状奇特的软件,因此它们可以出售给其他地方的用户或企业。

下图显示了如何使用Docker概念来节约时间和金钱:

在Docker之前,将软件部署到不同的环境需要付出巨大的努力。即使您不是手动运行脚本来在不同的计算机上配置软件(并且很多人仍然这样做),您仍然需要与配置管理工具搏斗,这些工具可以在日益快速发展而缺乏资源的环境上管理状态。即使将这些工作封装在VM中,也花费了大量时间来管理这些VM的部署,等待它们启动,以及管理它们创建的资源使用开销。

有了Docker,配置工作与资源管理分离,从而使得部署工作非常简单:运行docker run,环境镜像被拉下并准备运行,消耗更少的资源,不干扰其他环境。

无需担心容器是否将被运送到RedHat机器,Ubuntu机器或Cent OS VM映像; 只要它上面有Docker,就可以了。

在有docker之前,需要管理不同的环境下的部署:

有docker之后只需要一次努力就可以管理在多个环境下的部署:

##不同于传统虚拟化

下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

传统虚拟化:

Docker:

参考资料

1.2 - Docker的历史

Docker的历史发展进程

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)

Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目已经超过 4 万 6 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroupnamespace,以及AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runCcontainerd

参考资料

1.3 - 为什么使用 Docker?

解释为什么要使用 Docker?

统一开发测试运行环境

在Docker出现之前,开发流程通常包括用于管理软件移动的各种技术的组合,例如虚拟机,配置管理工具,不同的包管理系统以及复杂的库依赖关系网。 所有这些工具都需要由专业工程师进行管理和维护,而且大多数都有自己独特的配置方式。

Docker改变了所有这一切,允许参与此过程的不同工程师有效地说一种语言,使一起工作变得轻而易举。 所有东西都通过一个公共管道连接到可以在任何目标上使用的单个输出 - 不需要继续维护一系列令人眼花缭乱的工具配置,如下图所示:

优势所在

作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。

更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。

持续交付和部署

对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

对比传统虚拟机总结

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个

参考资料

1.4 - Docker资料收集

收集Docker的各种资料

官方资料

社区资料

学习资料

书籍

电子书

  • Docker —— 从入门到实践: 基于最新的 Docker CE v18.X 特性进行讲解,书的内容非常新。不过内容深度不足,只能做简单了解。
  • Docker入门实战: 一本社区合作编写的电子书,就是太老了点,最后更新于 2015-06-11。有些观点基本过时,有些知识太老,可以简单扫一遍。

学习笔记

2 - 安装

Docker在各个操作系统下的安装

2.1 - 安装概述

Docker安装概述

Docker 目前分为 Community Edition (CE) 和 Enterprise Edition (EE) 两个版本。日常学习开发考虑使用CE版本。

而 Docker Community Edition (CE) 又分为 Stable / Test / Nightly 三个版本,如果不需要最新的特性,那么 Stable 是比较合适的选择。

以下安装都是选择 Docker Community Edition Stable 版本, 参考docker官网的文章:

https://docs.docker.com/install/

2.2 - Ubuntu下安装Docker

Docker在Ubuntu20.04/22.04/23.04下的安装

参考官网文档:

https://docs.docker.com/install/linux/docker-ce/ubuntu/

适用于以下版本:

  • Ubuntu Lunar 23.04
  • Ubuntu Kinetic 22.10
  • Ubuntu Jammy 22.04 (LTS)
  • Ubuntu Focal 20.04 (LTS)

准备工作

清除老版本:

for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

安装需要的工具:

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg

添加 GPG key:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

准备用于 apt 的仓库:

echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

此时打开 /etc/apt/sources.list.d/docker.list 文件:

sudo vi /etc/apt/sources.list.d/docker.list

就能看到如下内容:

deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu   jammy stable

其中 jammy 是ubuntu版本代码名称 VERSION_CODENAME ,其内容来自文件 /etc/os-release:

PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

执行 apt update 之后:

sudo apt-get update

就可以安装了。

安装

一般 不推荐 安装最新版本,尤其是和 k8s 一起使用时:

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

可以先执行

apt-cache madison docker-ce
# apt-cache madison docker-ce | awk '{ print $3 }'

查看当前可选版本:

 docker-ce | 5:24.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:24.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:24.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:23.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:23.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:23.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:23.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:23.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:23.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:23.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.24~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.23~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.22~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.21~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.20~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.19~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.18~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.17~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.16~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.15~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.14~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
 docker-ce | 5:20.10.13~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages

这里先固定使用 20.10.21 版本, 执行安装命令:

VERSION_STRING=5:20.10.21~3-0~ubuntu-jammy
sudo apt-get install docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin

安装完成后检验一下:

sudo docker run hello-world

查看安装的版本:

$ docker --version
Docker version 20.10.21, build baeda1f

设置

设置权限避免每次sudo

为了以非 root 用户使用 docker, 可以将用户加入 “docker” 组.

sudo usermod -aG docker sky

重新登录之后生效。验证一下:

docker run hello-world

取消 apt source 更新

docker 安装之后,没有必要时刻保持更新,因此可以取消 apt source的设置,加速 apt update 的执行:

sudo vi /etc/apt/sources.list.d/docker.list

将内容注释即可。

修改 containerd 的配置

containerd 的默认配置文件中 disable 了 CRI ,可以打开文件 /etc/containerd/config.toml 看到这行:

disabled_plugins = ["cri"]

将这行注释之后,重启 containerd:

sudo systemctl restart containerd.service

如果不做这个修改,k8s 安装时会报错 “CRI v1 runtime API is not implemented”。

2.3 - Macos下安装Docker

Docker在MacOS下的安装

参考:

下载

m1安装

对于 m1 芯片的用户,先安装 rosetta 2:

softwareupdate –install-rosetta

正常安装,过程简单。

验证一下安装,看一下版本信息:

$ docker version                                     
Client:
 Cloud integration: v1.0.22
 Version:           20.10.12
 API version:       1.41
 Go version:        go1.16.12
 Git commit:        e91ed57
 Built:             Mon Dec 13 11:46:56 2021
 OS/Arch:           darwin/arm64
 Context:           default
 Experimental:      true

Server: Docker Desktop 4.5.0 (74594)
 Engine:
  Version:          20.10.12
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.12
  Git commit:       459d0df
  Built:            Mon Dec 13 11:43:07 2021
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.4.12
  GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d
 runc:
  Version:          1.0.2
  GitCommit:        v1.0.2-0-g52b36a2
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

验证一下:

  sudo docker run hello-world

输出如下:

docker run hello-world 
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
93288797bd35: Pull complete 
Digest: sha256:4c5f3db4f8a54eb1e017c385f683a2de6e06f75be442dc32698c9bbe6c861edd
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

intel芯片安装

TBD:准备放弃黑苹果,专心用m1。

2.4 - Docker安装后的设置

Docker安装后的设置

镜像加速

为了加速拉取 Docker ,需要配置镜像地址:

mac下修改

任务栏点击 Docker for mac 应用图标 -> Perferences… -> Daemon -> Registry mirrors。

linux下修改

针对Docker客户端版本大于 1.10.0 的用户

通过修改daemon配置文件/etc/docker/daemon.json来使用加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://****.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

参考文章:

2.5 - [归档]ubuntu 16.04下安装Docker

Docker在Linux下的安装

归档原因:不再使用ubuntu 16.04.

以 ubuntu 为例,参考官网文档:

https://docs.docker.com/install/linux/docker-ce/ubuntu/

安装准备

看一下自己的Linux机器版本和内核信息:

  • uname --all

    Linux skywork 4.15.0-38-generic #41~16.04.1-Ubuntu SMP Wed Oct 10 20:16:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
    
    
    
  • cat /proc/version

    Linux version 4.15.0-38-generic (buildd@lcy01-amd64-023) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)) #41~16.04.1-Ubuntu SMP Wed Oct 10 20:16:04 UTC 2018
    
    
    
  • lsb_release -a

    No LSB modules are available.
    Distributor ID:	LinuxMint
    Description:	Linux Mint 18.3 Sylvia
    Release:	18.3
    Codename:	sylvia
    
    
    

这台机器是Linux Mint 18.3 升级到非常新的Linux内核4.15.0-38了,Linux Mint 18.3 是基于 Ubuntu 16.04,但是有些系统参数不一样,比如这里 Codename 是 sylvia,而不是 Ubuntu 16.04 的 xenial。后面安装时要小心,需要修改为 Ubuntu 16.04 的参数。

安装步骤

  1. 卸载旧版本

    sudo apt-get remove docker docker-engine docker.io
    
  2. 安装docker

    简单起见,使用 docker 仓库安装。

    sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    # 官方给的是这样,但是`lsb_release -cs`在Linux Mint下取值会不对,因此手工修改
    # Linux Mint 18是基于ubuntu 16.04,为 xenial
    # Linux Mint 19是基于ubuntu 18.04,为 bionic
    # sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    # for ubuntu 16.04 / linuxmint 18.*
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
    # for ubuntu 18.04 / linuxmint 19.*
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
    sudo apt-get update
    sudo apt-get install docker-ce
    

    如果不想安装最新版本,则可以先查看当前可选版本:

    $ apt-cache madison docker-ce
     docker-ce | 5:18.09.2~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
     docker-ce | 5:18.09.1~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
     docker-ce | 5:18.09.0~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
     docker-ce | 18.06.2~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
     docker-ce | 18.06.1~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
     docker-ce | 18.06.0~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
     docker-ce | 18.03.1~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
    

    然后执行 :

        sudo apt-get install docker-ce=18.06.2~ce~3-0~ubuntu
    

    ``

  3. 验证安装

    安装完成之后,看一下版本信息:

    $ docker version
    Client:
    Version:           18.06.1-ce
    API version:       1.38
    Go version:        go1.10.3
    Git commit:        e68fc7a
    Built:             Tue Aug 21 17:24:56 2018
    OS/Arch:           linux/amd64
    Experimental:      false
    
    Server:
    Engine:
    Version:          18.06.1-ce
    API version:      1.38 (minimum version 1.12)
    Go version:       go1.10.3
    Git commit:       e68fc7a
    Built:            Tue Aug 21 17:23:21 2018
    OS/Arch:          linux/amd64
    Experimental:     false
    
    

    验证一下:

    sudo docker run hello-world
    

    输出如下:

    $ sudo docker run hello-world
    Unable to find image 'hello-world:latest' locally
    
    latest: Pulling from library/hello-world
    78445dd45222: Pull complete
    Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
    Status: Downloaded newer image for hello-world:latest
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    ...
    
  4. 设置权限避免每次sudo

    为了以非root用户使用docker, 可以将用户加入"docker"组.

    sudo usermod -aG docker sky
    

    重新登录之后生效。

  5. 安装 docker client

    从下列地址下载到对应的 docker client 安装包:

    https://mirrors.ustc.edu.cn/docker-ce/linux/static/stable/x86_64/

    tar -zxvf docker-18.09.2.tgz
    cd docker
    sudo cp * /usr/local/bin/
    

    ``

2.6 - [归档]Ubuntu20.04下安装Docker

Docker在Ubuntu20.04下的安装

以 ubuntu 20.04(也包括作为桌面使用的 Linux Mint 21) 为例,参考官网文档:

https://docs.docker.com/install/linux/docker-ce/ubuntu/

安装准备

看一下自己的Linux机器版本和内核信息:

  • uname --all

    Linux skywork 5.15.0-53-generic #59-Ubuntu SMP Mon Oct 17 18:53:30 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
    
    
    
  • cat /proc/version

    Linux version 5.15.0-53-generic (buildd@lcy02-amd64-047) (gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #59-Ubuntu SMP Mon Oct 17 18:53:30 UTC 2022
    
  • lsb_release -a

    No LSB modules are available.
    Distributor ID:	Linuxmint
    Description:	Linux Mint 21
    Release:	21
    Codename:	vanessa
    
    
    

这台机器是Linux Mint 21 升级到非常新的Linux内核5.15.0-53了,Linux Mint 21 是基于 Ubuntu 20.04,但是有些系统参数不一样,比如这里 Codename 是 vanessa,而不是 Ubuntu 20.04 的 Focal Fossa。后面安装时要小心,需要修改为 Ubuntu 20.04 的参数。

ubuntu各个版本的codename 请见:https://download.docker.com/linux/ubuntu/dists/

安装步骤

卸载旧版本

sudo apt-get remove docker docker-engine docker.io containerd runc

安装docker

简单起见,使用 docker 仓库安装。

$ sudo apt-get install ca-certificates curl gnupg lsb-release

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 官方给的是这样,
# echo \
#  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
# https://download.docker.com/linux/ubuntu \
#  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 但是`lsb_release -cs`在Linux Mint下取值会不对,因此手工修改
# for ubuntu 20.04 / linuxmint 20.02,$(lsb_release -cs)替代为 focal
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu focal stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

如果不想安装最新版本,则可以先查看当前可选版本:

$ apt-cache madison docker-ce
docker-ce | 5:20.10.21~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.20~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.19~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.18~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.17~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.16~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.15~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.14~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.13~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.12~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.11~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.10~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.9~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.8~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.7~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.6~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.5~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.4~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.3~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.2~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.1~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:20.10.0~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.15~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.14~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.13~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.12~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.11~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.10~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.9~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages

然后执行 :

sudo apt-get install docker-ce=20.10.21~3-0~ubuntu

验证安装

安装完成之后,看一下版本信息:

$ docker --version
Docker version 20.10.21, build baeda1f

验证一下:

sudo docker run hello-world

输出如下:

$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally

latest: Pulling from library/hello-world
2db29710123e: Pull complete 
Digest: sha256:faa03e786c97f07ef34423fccceeec2398ec8a5759259f94d99078f264e9d7af
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

设置权限避免每次sudo

为了以非root用户使用docker, 可以将用户加入"docker"组.

sudo usermod -aG docker sky

重新登录之后生效。

设置docker的cgroup driver

备注: 发现 docker 20.10.21~3-0~ubuntu 版本已经修改为默认 systemd ,因此新版本可以不用这么设置。

docker 默认的 cgroup driver 是 cgroupfs,可以通过 docker info 命令查看:

$ docker info | grep "Cgroup Driver"
Cgroup Driver: cgroupfs

而 kubernetes 在v1.22版本之后,如果用户没有在 KubeletConfiguration 下设置 cgroupDriver 字段,则 kubeadm 将默认为 systemd

为了保持一致,需要修改 docker 的 cgroup driver 为 systemd, 方式为打开 docker 的配置文件(如果不存在则创建)

sudo vi /etc/docker/daemon.json

增加内容:

{
	"exec-opts": ["native.cgroupdriver=systemd"]
}

修改完成后重启 docker:

sudo systemctl restart docker

# 重启后检查一下
docker info | grep "Cgroup Driver"

设置swap limit

如果遇到如下的 “No swap limit support” 警告:

docker info | grep "Cgroup Driver"
 Cgroup Driver: systemd
WARNING: No swap limit support

则说明 swap limit 功能没能开启。解决方法是 grub

$ sudo vi /etc/default/grub
......
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
......

执行下面命令生效并重启。

$ sudo update-grub2
$ sudo reboot

参考资料:

3 - Docker命令

Docker命令

3.1 - Docker命令概述

Docker命令概述

Docker 分为客户端和服务端两部分, docker 为客户端调用的命令, dockerd 为服务端调用的命令, 这里着重介绍客户端的用法。

Docker主要用法:docker [docker命令选项] [子命令] [子命令选项]

备注:使用 docker [子命令] --help 可查看每个子命令的详细用法。

命令选项列表

选项 说明 其他
–config [string] 客户端本地配置文件路径 默认为 ~/.docker
-D, –debug 启用调试模式
–help 打印用法
-H, –host list 通过socket访问指定的docker守护进程(服务端) unix:// , fd:// , tcp://
-l, –log-level [string] 设置日志级别 (debuginfowarnerrorfatal) 默认为 info
–tls 启用TLS加密
–tlscacert [string] 指定信任的CA根证书路径 默认为 ~/.docker/ca.pem
–tlscert [string] 客户端证书路径 默认为 ~/.docker/cert.pem
–tlskey [string] 客户端证书私钥路径 默认为 ~/.docker/key.pem
–tlsverify 启用TLS加密并验证客户端证书
-v, –version 打印docker客户端版本信息

命令列表

本地镜像相关命令

  • docker images:

镜像仓库相关命令

  • docker search: 查找镜像
  • docker pull: 获取镜像
  • docker push: 推送镜像到仓库
  • docker login: 登录第三方仓库
  • docker logout: 退出第三方仓库

参考资料

3.2 - Docker基础命令

Docker基础命令

3.2.1 - Docker基础命令概述

Docker基础命令概述

Docker基础命令:

命令 命令描述
info 显示 Docker 详细的系统信息
version 显示docker客户端和服务端版本信息
inspect 查看容器或镜像的配置信息, 默认为json数据
events 实时打印服务端执行的事件

3.2.2 - info命令

Docker的info命令

介绍

https://docs.docker.com/engine/reference/commandline/info/

此命令显示有关Docker安装的系统范围信息。 显示的信息包括内核版本,容器和镜像的数量。 显示的镜像数量是唯一镜像的数量。以不同名称标记的相同镜像仅计算一次。

如果指定了格式,则将执行给定模板而不是默认格式。 Go的文本/模板包描述了格式的所有细节。

根据所使用的存储驱动程序,可以显示其他信息,例如池名称,数据文件,元数据文件,使用的数据空间,总数据空间,使用的元数据空间以及总元数据空间。

数据文件存储镜像,元数据文件是存储和这些镜像相关的元数据。当第一次运行时,Docker从挂载了 /var/lib/docker 的卷上的可用空间分配一定数量的数据空间和元数据空间。

使用

$ docker info
Containers: 4 # 容器数量
 Running: 0
 Paused: 0
 Stopped: 4
Images: 39   # 镜像数量
Server Version: 18.09.1  # 服务器版本
Storage Driver: overlay2 # 存储驱动程序
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file # 日志驱动程序
Cgroup Driver: cgroupfs # cgroup驱动程序
Plugins: # 插件
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive # swarm信息
Runtimes: runc # runtimes信息
Default Runtime: runc # 默认runtime
Init Binary: docker-init
containerd version: 9754871865f7fe2f4e74d43e2fc7ccd237edcbce
runc version: 96ec2177ae841256168fcf76954f7177af9446eb
init version: fec3683
Security Options: # 安全选项
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.15.0-38-generic # linux内核版本
Operating System: Linux Mint 18.3 # 操作系统
OSType: linux
Architecture: x86_64
CPUs: 12 # 硬件信息
Total Memory: 15.12GiB
Name: skywork
ID: CICY:F7VQ:DKBG:IEG4:SY75:A6IK:DV52:GIXI:F3P5:VPIM:QMU3:ZXK2
Docker Root Dir: /var/lib/docker # docker根目录
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/ # 镜像仓库
Labels:
Experimental: false
Insecure Registries: # 非安全镜像仓库
 127.0.0.0/8
Registry Mirrors: # 镜像仓库
 https://××××.mirror.aliyuncs.com/
Live Restore Enabled: false
Product License: Community Engine # docker的产品license

WARNING: No swap limit support 

其中的警告 “WARNING: No swap limit support ” 可以忽略,除非帧的需要这个能力。

格式化输出

可以通过 -f 选项格式化输出:

$ docker info --format '{{json .}}'

{
    "ID":"CICY:F7VQ:DKBG:IEG4:SY75:A6IK:DV52:GIXI:F3P5:VPIM:QMU3:ZXK2",
    "Containers":4,
    "ContainersRunning":0,
    "ContainersPaused":0,
    "ContainersStopped":4,
    "Images":39,
    "Driver":"overlay2",
    "DriverStatus":[
        [
            "Backing Filesystem",
            "extfs"
        ],
        [
            "Supports d_type",
            "true"
        ],
        [
            "Native Overlay Diff",
            "true"
        ]
    ],
    "SystemStatus":null,
    "Plugins":{
        "Volume":[
            "local"
        ],
        "Network":[
            "bridge",
            "host",
            "macvlan",
            "null",
            "overlay"
        ],
        "Authorization":null,
        "Log":[
            "awslogs",
            "fluentd",
            "gcplogs",
            "gelf",
            "journald",
            "json-file",
            "local",
            "logentries",
            "splunk",
            "syslog"
        ]
    },
    "MemoryLimit":true,
    "SwapLimit":false,
    "KernelMemory":true,
    "CpuCfsPeriod":true,
    "CpuCfsQuota":true,
    "CPUShares":true,
    "CPUSet":true,
    "IPv4Forwarding":true,
    "BridgeNfIptables":true,
    "BridgeNfIp6tables":true,
    "Debug":false,
    "NFd":21,
    "OomKillDisable":true,
    "NGoroutines":36,
    "SystemTime":"2019-01-26T21:02:24.681737152+08:00",
    "LoggingDriver":"json-file",
    "CgroupDriver":"cgroupfs",
    "NEventsListener":0,
    "KernelVersion":"4.15.0-38-generic",
    "OperatingSystem":"Linux Mint 18.3",
    "OSType":"linux",
    "Architecture":"x86_64",
    "IndexServerAddress":"https://index.docker.io/v1/",
    "RegistryConfig":{
        "AllowNondistributableArtifactsCIDRs":[

        ],
        "AllowNondistributableArtifactsHostnames":[

        ],
        "InsecureRegistryCIDRs":[
            "127.0.0.0/8"
        ],
        "IndexConfigs":{
            "docker.io":{
                "Name":"docker.io",
                "Mirrors":[
                    "https://****.mirror.aliyuncs.com/"
                ],
                "Secure":true,
                "Official":true
            }
        },
        "Mirrors":[
            "https://****.mirror.aliyuncs.com/"
        ]
    },
    "NCPU":12,
    "MemTotal":16233955328,
    "GenericResources":null,
    "DockerRootDir":"/var/lib/docker",
    "HttpProxy":"",
    "HttpsProxy":"",
    "NoProxy":"",
    "Name":"skywork",
    "Labels":[

    ],
    "ExperimentalBuild":false,
    "ServerVersion":"18.09.1",
    "ClusterStore":"",
    "ClusterAdvertise":"",
    "Runtimes":{
        "runc":{
            "path":"runc"
        }
    },
    "DefaultRuntime":"runc",
    "Swarm":{
        "NodeID":"",
        "NodeAddr":"",
        "LocalNodeState":"inactive",
        "ControlAvailable":false,
        "Error":"",
        "RemoteManagers":null
    },
    "LiveRestoreEnabled":false,
    "Isolation":"",
    "InitBinary":"docker-init",
    "ContainerdCommit":{
        "ID":"9754871865f7fe2f4e74d43e2fc7ccd237edcbce",
        "Expected":"9754871865f7fe2f4e74d43e2fc7ccd237edcbce"
    },
    "RuncCommit":{
        "ID":"96ec2177ae841256168fcf76954f7177af9446eb",
        "Expected":"96ec2177ae841256168fcf76954f7177af9446eb"
    },
    "InitCommit":{
        "ID":"fec3683",
        "Expected":"fec3683"
    },
    "SecurityOptions":[
        "name=apparmor",
        "name=seccomp,profile=default"
    ],
    "ProductLicense":"Community Engine",
    "Warnings":[
        "WARNING: No swap limit support"
    ]
}



3.2.3 - version命令

Docker的version命令

介绍

https://docs.docker.com/engine/reference/commandline/version/

默认情况下,这将以易于阅读的布局呈现所有版本信息。 如果指定了格式,则将执行给定的模板。

使用

$ docker version
Client:
 Version:           18.09.1
 API version:       1.39
 Go version:        go1.10.6
 Git commit:        4c52b90
 Built:             Wed Jan  9 19:35:23 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.1
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       4c52b90
  Built:            Wed Jan  9 19:02:44 2019
  OS/Arch:          linux/amd64
  Experimental:     false

格式化输出

$ docker version --format '{{json .}}'

则输出格式(https://www.json.cn/ 转格式)为:

{
    "Client":{
        "Platform":{
            "Name":""
        },
        "Version":"18.09.1",
        "ApiVersion":"1.39",
        "DefaultAPIVersion":"1.39",
        "GitCommit":"4c52b90",
        "GoVersion":"go1.10.6",
        "Os":"linux",
        "Arch":"amd64",
        "BuildTime":"Wed Jan 9 19:35:23 2019",
        "Experimental":false
    },
    "Server":{
        "Platform":{
            "Name":"Docker Engine - Community"
        },
        "Components":[
            {
                "Name":"Engine",
                "Version":"18.09.1",
                "Details":{
                    "ApiVersion":"1.39",
                    "Arch":"amd64",
                    "BuildTime":"Wed Jan 9 19:02:44 2019",
                    "Experimental":"false",
                    "GitCommit":"4c52b90",
                    "GoVersion":"go1.10.6",
                    "KernelVersion":"4.15.0-38-generic",
                    "MinAPIVersion":"1.12",
                    "Os":"linux"
                }
            }
        ],
        "Version":"18.09.1",
        "ApiVersion":"1.39",
        "MinAPIVersion":"1.12",
        "GitCommit":"4c52b90",
        "GoVersion":"go1.10.6",
        "Os":"linux",
        "Arch":"amd64",
        "KernelVersion":"4.15.0-38-generic",
        "BuildTime":"2019-01-09T19:02:44.000000000+00:00"
    }
}

可以单独获取其中某个数据,如:

docker version --format '{{.Server.Version}}'

18.09.1

3.2.4 - inspect命令

Docker的inspect命令

介绍

https://docs.docker.com/engine/reference/commandline/inspect/

返回有关Docker对象的低层信息。

Docker inspect 命令提供被其控制的各种结构的详细信息。

使用

docker inspect [OPTIONS] NAME|ID [NAME|ID...]

需要给出目标对象的name或者id。

如果要查看镜像,可以先用 docker images 命令看到本地所有镜像

docker images
REPOSITORY                                 TAG                                        IMAGE ID            CREATED             SIZE
k8s.gcr.io/kube-proxy                      v1.12.2                                    15e9da1ca195        3 months ago        96.5MB
k8s.gcr.io/kube-apiserver                  v1.12.2                                    51a9c329b7c5        3 months ago        194MB

然后通过ID 来使用 inspect 命令:

docker inspect 15e9da1ca195

默认是返回完整信息,json格式:

[
    {
        "Id": "sha256:15e9da1ca195086627363bb2e8f5bfca7048345325287d307afd317bab2045b0",
        "RepoTags": [
            "k8s.gcr.io/kube-proxy:v1.12.2"
        ],
        "RepoDigests": [
            "k8s.gcr.io/kube-proxy@sha256:b77f615c0a914efbf4c66b37011b0f87e28498af6cc71590ecbd67b6be005a60"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2018-10-24T07:43:58.286868924Z",
        "Container": "",
        "ContainerConfig": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ADD file:5e8feab95fcebf67c56cc114f6ec97cfb09bcfedacb175bb1951cb5d6e385574 in /usr/local/bin/kube-proxy "
            ],
            "ArgsEscaped": true,
            "Image": "sha256:e1f02e54b200d3a4f3b46b6f0ec4995d92c33707a3c2edf6fb5162c7c406fab5",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "DockerVersion": "18.06.1-ce",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:e1f02e54b200d3a4f3b46b6f0ec4995d92c33707a3c2edf6fb5162c7c406fab5",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 96469663,
        "VirtualSize": 96469663,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/e35f184dc38f9107e8bdaafd718e61a2e4251879d81a33ed59a884ced01b7b8e/diff:/var/lib/docker/overlay2/b1237288693892b66dcaee6b47625303b7814844a93c71bd2fd5d7bb49fbefaa/diff",
                "MergedDir": "/var/lib/docker/overlay2/229d3a5fb18ee157fc6b3b3a8d11d3adfb5b6cefa9d81a5e9332b345816de10c/merged",
                "UpperDir": "/var/lib/docker/overlay2/229d3a5fb18ee157fc6b3b3a8d11d3adfb5b6cefa9d81a5e9332b345816de10c/diff",
                "WorkDir": "/var/lib/docker/overlay2/229d3a5fb18ee157fc6b3b3a8d11d3adfb5b6cefa9d81a5e9332b345816de10c/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:0c1604b64aedf4f5060a25da1b96b21aa803a878ce475633d02a4aba854252a7",
                "sha256:dc6f419d40a27032570a3bd2813f10abd09620e68974f3d74e09ecf6a3a4113c",
                "sha256:2d9b7a4a23dd71483150c1b9bfb136e2a1196897efb8191e4aafdc78eb7bcb4e"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

格式化输出

同样可以通过格式化输出获取特定的属性值。

$ docker inspect --format='{{.Id}}'  15e9da1ca195
sha256:15e9da1ca195086627363bb2e8f5bfca7048345325287d307afd317bab2045b0
$ docker inspect --format='{{.RootFS.Type}}'  15e9da1ca195
layers

更多案例参看官方文档: https://docs.docker.com/engine/reference/commandline/inspect/

3.2.5 - events命令

Docker的events命令

介绍

https://docs.docker.com/engine/reference/commandline/events/

使用 docker events 命令从服务器获取实时事件。这些事件因Docker对象类型而异。

使用

docker events

然后接受各种事件。

具体用法见官方文档:

  • 用时间过滤事件
  • 用标准规范过滤事件
  • 格式化输出

https://docs.docker.com/engine/reference/commandline/events/

3.3 - Docker镜像命令

Docker镜像命令

3.3.1 - Docker的镜像命令

Docker的镜像命令

镜像仓库类的Docker命令:

命令 命令描述
images 查看本地镜像(列出本地所有镜像)
inspect 查看镜像详情
search 查找镜像
tag 修改镜像tag
history 显示镜像每层的变更内容
rmi 删除本地镜像
pull 获取镜像
push 推送镜像到仓库
login 登录第三方仓库
logout 退出第三方仓库
save 打包本地镜像, 使用压缩包来完成迁移
load 导入镜像压缩包
commit 将容器保存为镜像
build 使用Dockerfile构建镜像
import 导入本地容器快照文件为镜像

3.3.2 - Docker的images命令

Docker的images命令

介绍

https://docs.docker.com/engine/reference/commandline/images/

默认的docker images 命令将显示所有顶级镜像,其存储库和标签,以及它们的大小。

Docker image具有中间层,通过允许缓存每个步骤来提高可重用性,减少磁盘使用并加速docker build。 默认情况下不显示这些中间层。

SIZE是镜像及其所有父镜像占用的累积空间。 这也是Docker save命令制作镜像时创建的Tar文件内容使用的磁盘空间。

如果镜像具有多个存储库名称或标记,则会多次列出该镜像。 此单个镜像(可通过其匹配的IMAGE ID识别)仅使用一次列出的SIZE。

使用

$ docker images
REPOSITORY                                 TAG                                        IMAGE ID            CREATED             SIZE
k8s.gcr.io/kube-proxy                      v1.12.2                                    15e9da1ca195        3 months ago        96.5MB
k8s.gcr.io/kube-apiserver                  v1.12.2                                    51a9c329b7c5        3 months ago        194MB
k8s.gcr.io/kube-controller-manager         v1.12.2                                    15548c720a70        3 months ago        164MB
<none>                                     <none>                                     b8988e488a42        6 months ago        733MB
envoyproxy/envoy-build-ubuntu              7f7f5666c72e00ac7c1909b4fc9a2121d772c859   936ba3592a5c        8 months ago        2.31GB

通过name和tag来列出镜像

docker images 命令有可选的 [REPOSITORY[:TAG]] 参数,该参数将列表限制为与参数匹配的镜像。

如果指定 REPOSITORY 但没有 TAG,则 docker images 命令会列出给定存储库中的所有图像。

$ docker images istio/pilot
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
istio/pilot         0.7.1               6223c9364df7        10 months ago       51.9MB

$ docker images istio/*
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
istio/istio-ca                           0.7.1               5c82fea42c78        10 months ago       42.7MB
istio/mixer                              0.7.1               251b0d3d2b93        10 months ago       54MB
6223c9364df7        10 months ago       51.9MB
istio/examples-bookinfo-reviews-v3       1.5.0               7301fee7c9cb        12 months ago       431MB
istio/examples-bookinfo-reviews-v2       1.5.0               

$ docker images istio/*:0.7.1
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
istio/istio-ca           0.7.1               5c82fea42c78        10 months ago       42.7MB
istio/mixer              0.7.1               251b0d3d2b93        10 months ago       54MB
istio/sidecar_injector   0.7.1               1db980725edb        10 months ago       33.4MB

过滤

过滤标志(-f--filter)格式为"key=value"。 如果有多个过滤器,则传递多个标志(例如,--filter "foo=bar" --filter "bif=baz"

目前支持的过滤器是:

  • dangling悬空 (boolean - true or false)
  • label (label=<key> or label=<key>=<value>)
  • before (<image-name>[:<tag>], <image id> or <image@digest>) - filter images created before given id or references
  • since (<image-name>[:<tag>], <image id> or <image@digest>) - filter images created since given id or references
  • reference (pattern of an image reference) - filter images whose reference matches the specified pattern

具体看官方文档。

dangling镜像的处理

dangling镜像就是images命令中出现的,REPOSITORY 和 TAG 都显示为 <none> 的镜像,如:

$ docker images
REPOSITORY                                 TAG                                        IMAGE ID            CREATED             SIZE
......
<none>                                     <none>                                     b8988e488a42        6 months ago        733MB

可以通过过滤器将dangling镜像都找出来:

$ docker images --filter "dangling=true"
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              b8988e488a42        6 months ago        733MB

这将显示未标记的镜像,这些镜像是镜像树的叶子(不是中间层)。 当镜像的新构建从这个镜像ID取走 repo:tag ,而留下 <none>:<none> 或 untagged 时,会出现这些的镜像。如果在容器当前正在使用镜像时尝试移除镜像,则会发出警告。通过使用此标志,允许批量清理。

可以联合docker rmi 命令一起使用来批量删除dangling镜像:

docker rmi $(docker images -f "dangling=true" -q)
Deleted: sha256:b8988e488a42c652492c6b488f44469245d2088f793c1e6448777afcedb34ca1

3.3.3 - Docker的search命令

Docker的search命令

介绍

https://docs.docker.com/engine/reference/commandline/search/

在Docker Hub中搜索镜像。

搜索查询默认最多返回25个结果。

使用

通过镜像名字搜索:

$ docker search busybox
NAME                        DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
busybox                     Busybox base image.                             1494                [OK]                
progrium/busybox                                                            68                                      [OK]
hypriot/rpi-busybox-httpd   Raspberry Pi compatible Docker Image with a …   45                                      
radial/busyboxplus          Full-chain, Internet enabled, busybox made f…   21                                      [OK]
......

过滤

当前支持的过滤器有:

  • stars (int - number of stars the image has)
  • is-automated (boolean - true or false) - is the image automated or not
  • is-official (boolean - true or false) - is the image official or not

3.3.4 - Docker的tag命令

Docker的tag命令

介绍

https://docs.docker.com/engine/reference/commandline/tag/

创建一个引用到 SOURCE_IMAGE 的 tag TARGET_IMAGE

镜像名称由斜杠分隔的名称组件组成,可选地以仓库主机名为前缀。主机名必须符合标准DNS规则,但可能不包含下划线。如果存在主机名,则可以选择后跟端口号如以下格式的 :8080。如果不存在,该命令默认使用位于 registry-1.docker.io 的Docker公共注册表。名称组件可能包含小写字母,数字和分隔符。分隔符定义为句点,一个或两个下划线,或一个或多个破折号。 名称组件不能以分隔符开头或结尾。

Tag名称必须是有效的ASCII,并且可以包含小写和大写字母,数字,下划线,句点和短划线。 Tag名称不能以句点或短划线开头,最多可包含128个字符。

使用

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

3.3.5 - Docker的history命令

Docker的history命令

介绍

https://docs.docker.com/engine/reference/commandline/history/

显示镜像的历史,显示镜像每层的变更内容

使用

docker history [OPTIONS] IMAGE

如:

$ docker history istio/mixer:0.7.1 --no-trunc
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
251b0d3d2b93        10 months ago       /bin/sh -c #(nop)  CMD ["--configStoreURL=fs…   0B                  
<missing>           10 months ago       /bin/sh -c #(nop)  ENTRYPOINT ["/usr/local/b…   0B                  
<missing>           10 months ago       /bin/sh -c #(nop) ADD file:04fbcb926d6c80af5…   53.7MB              
<missing>           10 months ago       /bin/sh -c #(nop) ADD file:f74cafb0f2a94a0b9…   252kB  

3.3.6 - Docker的rmi命令

Docker的rmi命令

介绍

https://docs.docker.com/engine/reference/commandline/rmi/

删除本地镜像

使用

docker rmi [OPTIONS] IMAGE [IMAGE...]

可以使用镜像的短ID或长ID,Tag或digest删除镜像。

如果镜像有一个或多个引用它的Tag,则必须在删除镜像之前删除所有Tag。通过Tag删除镜像时,将自动删除Digest引用。

或者使用 “-f” 标记来强制删除(包括所有tag的镜像)。

清理镜像

通过 docker system df 命令可以看到当前本地镜像的磁盘使用情况:

$ docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              38                  1                   7.314GB             7.314GB (99%)
Containers          4                   0                   0B                  0B
Local Volumes       0                   0                   0B                  0B
Build Cache         0                   0                   0B                  0B

可以通过 docker images 命令查看当前本地镜像情况,然后手工删除不需要的镜像。

docker system prune 命令可以帮助删除不需要使用的各种资源。

可以配合 docker images 命令来进行批量删除,如:

$ docker rmi $(docker images istio/* -q)
Untagged: istio/istio-ca:0.7.1
Untagged: istio/istio-ca@sha256:744e7a4426474d10f7984c601590ee6dab304f5cf6677a80b37c3025993dbd4e
Deleted: sha256:5c82fea42c7850f7f42e3b6326bc35b2a8941e77532210d925770eb501c6de1b
Deleted: sha256:8ccea48ceaaffc2fab84cc0d579948a221249d384156f6cfbdbcc9341ec59be7
Deleted: sha256:6ecf4e847360cffdcfe3a5d1b5de4e27b227aa5688c0ed63170cff2ecf7e43f6
Untagged: istio/mixer:0.7.1
......

如果要清空本地镜像,可以执行命令 docker rmi -f $(docker images -q)

3.4 - Docker容器命令

Docker容器命令

3.4.1 - Docker容器命令概述

Docker容器命令概述

容器类的Docker命令:

命令 命令描述
create 根据镜像生成一个新的容器
start 启动一个新的容器
run 创建、启动容器并执行相应的命令
rename 重命名容器名
ps 查看运行中的容器
top 显示容器的运行进程
stop 关闭容器
kill 强制关闭容器
restart 重启容器
pause 暂停容器
unpause 恢复暂停的容器
exec 在已运行的容器中执行命令
attach 进入运行中的容器, 显示该容器的控制台界面。
logs 打印容器的控制台输出内容
port 容器端口映射列表
rm 删除已停止的容器
diff 展示容器相对于构建它的镜像内容所做的改变
export 导出容器到本地快照文件
cp 在容器和宿主机之间复制文件
wait 阻塞当前命令直到对应的容器被关闭, 容器关闭后打印结束代码

3.4.2 - Docker的create命令

Docker的create命令

介绍

https://docs.docker.com/engine/reference/commandline/create/

根据镜像生成一个新的容器

docker create命令在指定的映像上创建可写容器层,并准备运行指定的命令。 然后将容器ID打印到STDOUT。 这类似于docker run -d,但容器从未启动过。 然后,您可以使用 docker start <container_id> 命令在任何位置启动容器。

当您想要提前设置容器配置,以便在需要时启动容器已经准备好,这非常有用。 新容器的初始状态已经创建。

使用

docker create [OPTIONS] IMAGE [COMMAND] [ARG...]

常用的命令行参数:

参数 描述
–attach , -a Attach to STDIN, STDOUT or STDERR
–env , -e Set environment variables
–env-file Read in a file of environment variables
–expose Expose a port or a range of ports
–interactive , -i Keep STDIN open even if not attached
–label , -l Set meta data on a container
–label-file Read in a line delimited file of labels
–mount Attach a filesystem mount to the container
–name Assign a name to the container
–publish , -p Publish a container’s port(s) to the host
–read-only Mount the container’s root filesystem as read only
–rm Automatically remove the container when it exits
–tty , -t Allocate a pseudo-TTY
–user , -u Username or UID (format: <name|uid>[:<group|gid>])
–volume , -v Bind mount a volume
–volumes-from Mount volumes from the specified container(s)
–workdir , -w Working directory inside the container

3.4.3 - Docker的启停命令

Docker的启停命令,包括start / stop / kill / restart / pause / unparse

start命令

https://docs.docker.com/engine/reference/commandline/start/

启动一个或者多个停止的容器

docker start [OPTIONS] CONTAINER [CONTAINER...]

命令行参数:

参数 描述
–attach , -a Attach to STDIN, STDOUT or STDERR
–interactive , -i Keep STDIN open even if not attached
date: 2019-01-27T07:30:00+08:00
title: start命令
weight: 342
menu:
  main:
    parent: "command-container"
description : "Docker的start命令"

stop命令

https://docs.docker.com/engine/reference/commandline/stop

停止一个或者多个运行的容器

容器内的主进程将先接收到 SIGTERM 信号,并在优雅关闭限期后,接收到 SIGKILL 信号。

docker stop [OPTIONS] CONTAINER [CONTAINER...]

命令行参数:

参数 描述
–time , -t Seconds to wait for stop before killing it

kill命令

https://docs.docker.com/engine/reference/commandline/kill

杀死一个或者多个运行的容器

容器内的主进程将先接收到 SIGTERM 信号,并在优雅关闭限期后,接收到 SIGKILL 信号。

docker kill [OPTIONS] CONTAINER [CONTAINER...]

命令行参数:

参数 描述
–signal , -s Signal to send to the container

restart命令

https://docs.docker.com/engine/reference/commandline/restart

重新启动一个或者多个运行的容器

docker restart [OPTIONS] CONTAINER [CONTAINER...]

命令行参数:

参数 描述
–time , -t Seconds to wait for stop before killing the container

pause命令

https://docs.docker.com/engine/reference/commandline/pause

暂停一个或多个容器中的所有进程

docker pause命令挂起(suspend)指定容器中的所有进程。 在Linux上,它使用cgroups freezer。 传统上,当暂停进程时,使用SIGSTOP信号,该进程被暂停可观察到。 使用cgroups freezer,该过程无感知,无法捕获它被暂停和随后的恢复。 在Windows上,只有Hyper-V容器可以被暂停。

docker pause CONTAINER [CONTAINER...]

unpause命令

恢复一个或多个容器中的所有暂停进程

docker unpause CONTAINER [CONTAINER...]

3.4.4 - Docker的run命令

Docker的run命令

介绍

https://docs.docker.com/engine/reference/commandline/run/

创建、启动容器并执行相应的命令。

在新的容器中运行命令。

docker run命令首先在指定的镜像上创建一个可写容器层,然后使用指定的命令启动它。 也就是说,docker run相当于API /containers/create/containers/(id)/start。 可以使用 docker start 重新启动已停止的容器,并使其先前的所有更改保持不变。 请参阅 docker ps -a 以查看所有容器的列表。

docker run 命令可与 docker commit 结合使用,以更改容器运行的命令。

更多资料:

使用

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

和 docker create 命令相同。

常用的命令行参数:

参数 描述
–attach , -a Attach to STDIN, STDOUT or STDERR
–env , -e Set environment variables
–env-file Read in a file of environment variables
–expose Expose a port or a range of ports
--hostname , -h Container host name
–interactive , -i Keep STDIN open even if not attached
–label , -l Set meta data on a container
–label-file Read in a line delimited file of labels
–mount Attach a filesystem mount to the container
–name Assign a name to the container
–publish , -p Publish a container’s port(s) to the host
–read-only Mount the container’s root filesystem as read only
–rm Automatically remove the container when it exits
–tty , -t Allocate a pseudo-TTY
–user , -u Username or UID (format: <name|uid>[:<group|gid>])
–volume , -v Bind mount a volume
–volumes-from Mount volumes from the specified container(s)
–workdir , -w Working directory inside the container

分配名字和伪TTY (–name, -it)

$ docker run --name test -it debian

连接到STDIN/STDOUT/STDERR (-a)

-a标志告诉 docker run 绑定到容器的STDIN,STDOUT或STDERR。 这使得可以根据需要操纵输出和输入。

$ docker run -a stdout ubuntu echo test
test

完整容器能力 (–privileged)

特权容器?

默认情况下,大多数潜在危险的内核功能都会被删除; 包括 cap_sys_admin(挂载文件系统所需)。 但是,–privileged标志将允许它运行。

$ docker run -t -i --privileged ubuntu bash

--privileged 标志为容器提供了所有功能,它还解除了设备cgroup控制器强制执行的所有限制。 换句话说,容器几乎可以完成主机可以执行的所有操作。 此标志存在以允许特殊用例,例如在Docker中运行Docker。

设置工作目录 (-w)

$ docker  run -w /path/to/dir/ -i -t  ubuntu pwd
/path/to/dir

-w 允许命令在给定的目录中执行,这里是 /path/to/dir/。 如果路径不存在,则在容器内创建。

挂载卷 (-v, –read-only)

docker  run  -v `pwd`:`pwd` -w `pwd` -i -t  ubuntu pwd

-v标志将当前工作目录挂载到容器中。 -w 让命令在当前工作目录中执行,方法是将工作目录更改为pwd返回的值。所以这个组合使用容器执行命令,但在当前工作目录中。

发布或者暴露端口 (-p, –expose)

docker run -p 127.0.0.1:80:8080/tcp ubuntu bash

这将容器的端口8080绑定到主机的127.0.0.1上的TCP端口80。还可以指定udp和sctp端口。

docker run --expose 80 ubuntu bash

这会暴露容器的端口80,而不会将端口发布到主机系统接口。

设置环境变量(-e, –env, –env-file)

可以通过-e, --env, --env-file 设置容器的环境变量:

docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash

本地已经export的环境变量,可以不用=号和值:

export VAR1=value1
export VAR2=value2

$ docker run --env VAR1 --env VAR2 ubuntu env | grep VAR
VAR1=value1
VAR2=value2

在容器上设置元数据(-l, –label, –label-file)

可以通过-l, --label, --label-file 设置容器的label:

$ docker run -l my-label --label com.example.foo=bar ubuntu bash

将容器连接到网络(–network)

docker run -itd --network=my-net busybox
docker run -itd --network=my-net --ip=10.10.9.75 busybox

也可以使用 docker connect 命令

从容器挂载卷(–volumes-from)

docker run --volumes-from 777f7dc92da7 --volumes-from ba8c0c54f0f2:ro -i -t ubuntu pwd

3.4.5 - Docker的ps命令

Docker的ps命令

介绍

https://docs.docker.com/engine/reference/commandline/ps/

列出容器

使用

docker ps [OPTIONS]

常用的命令行参数:

参数 描述
–all , -a Show all containers (default shows just running)
--filter , -f Filter output based on conditions provided
--last , -n Show n last created containers (includes all states)
–latest , -l Show the latest created container (includes all states)
–size , -s Display total file sizes

过滤

过滤标志(-f或--filter)格式是 key=value 对。 如果有多个过滤器,则传递多个标志(例如 --filter "foo=bar" --filter "bif=baz"

支持多种过滤方式,如 id,name,label,status等,具体看官方文档

docker ps --filter "label=color"
docker ps --filter "label=color=blue"
docker ps --filter "name=nostalgic_stallman"
docker ps --filter "name=nostalgic" # name可以使用substring
docker ps -a --filter 'exited=0'
docker ps -a --filter 'exited=137'
docker ps --filter status=running
docker ps --filter status=paused
docker ps --filter ancestor=ubuntu
docker ps --filter network=net1
docker ps --filter publish=80
docker ps --filter expose=8000-8080/tcp
docker ps --filter publish=80/udp

格式化输出

docker ps --format "{{.ID}}: {{.Command}}"
docker ps --format "table {{.ID}}\t{{.Labels}}"

看官方文档

3.4.6 - Docker的exec命令

Docker的exec命令

介绍

https://docs.docker.com/engine/reference/commandline/exec/

在运行的容器内运行命令

docker exec 命令在正在运行的容器中运行新命令。

使用docker exec启动的命令仅在容器的主进程(PID 1)运行时运行,如果重新启动容器则不会重新启动。

COMMAND将在容器的默认目录中运行。 如果底层镜像在其Dockerfile中使用WORKDIR指令指定有自定义目录,则将使用此目录。

COMMAND应该是可执行文件,链接或带引号的命令不起作用。 例:

docker exec -ti my_container "echo a && echo b" 不会工作, 但是 docker exec -ti my_container sh -c "echo a && echo b" 可以.

使用

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

常用的命令行参数:

参数 描述
–detach , -d Detached mode: run command in the background
–env , -e Set environment variables
–interactive , -i Keep STDIN open even if not attached
–privileged Give extended privileges to the command
–tty , -t Allocate a pseudo-TTY
–user , -u Username or UID (format: <name|uid>[:<group|gid>])
–workdir , -w Working directory inside the container

启动命令

先启动一个容器:

$ docker run -it --rm --name exectest  ubuntu bash
root@f13ee9356da6:/# 

用docker ps命令确认一下:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f13ee9356da6        ubuntu              "bash"              24 seconds ago      Up 22 seconds                           exectest

运行简单命令:

$ docker exec exectest pwd
/
$ docker exec exectest ls /
bin
boot
dev
etc
......

如果想后台执行:

$ docker exec -d exectest pwd

也可以用进到容器里面,打开bash,再慢慢执行命令:

$ docker exec -it exectest bash
root@f13ee9356da6:/# pwd
/

这会在容器 exectest 里面创建一个新的bash session。

可以在进入容器时定义一些环境变量,通过 -e 参数传递进去:

$ docker exec -it -e var1=v1 exectest bash
root@f13ee9356da6:/# echo $var1
v1

注意这个环境变量只有在这个新的bash session里面才能看到,在原来打开这个容器的bash里面是无法看到的。

默认新的 bash session 的工作目录是在当前容器被创建时设置的工作目录,可以通过 -w 参数修改:

$ docker exec -it -w /root exectest bash
root@f13ee9356da6:~# pwd
/root

3.4.7 - Docker的top命令

Docker的top命令

介绍

https://docs.docker.com/engine/reference/commandline/top/

显示容器的运行进程

使用

docker top CONTAINER [ps OPTIONS]

命令行参数可以参考ps命名。

# 在一个终端中启动容器
$ docker run -it --rm --name toptest  ubuntu bash
root@7493e17d1238:/# 
# 在另一个终端中查看
$ docker top toptest
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                21872               21848               0                   11:46               pts/0               00:00:00            bash

3.4.8 - Docker的attach命令

Docker的attach命令

介绍

https://docs.docker.com/engine/reference/commandline/attach/

将本地标准 input,output 和 error 流附加到正在运行的容器。

使用 docker attach 将终端的标准 input,output 和 error (或三者的任意组合)通过容器的ID或名称附加到正在运行的容器中。这允许您查看其正在进行的输出或以交互方式控制它,就像命令直接在您的终端中运行一样。

注意:attach命令将显示 ENTRYPOINT/CMD 进程的输出。这可能看起来好像挂起命令被挂起,而实际上该进程实际上可能根本就没有与终端进行交互。

您可以从Docker主机上的不同会话同时多次附加到同一个容器进程。

要停止容器,请使用CTRL-c。 此键序列将SIGKILL发送到容器。 如果–sig-proxy为true(默认值),则CTRL-c将SIGINT发送到容器。 您可以使用CTRL-p CTRL-q键序列从容器中分离并使其保持运行。

注意:在容器内作为PID 1运行的进程由Linux专门处理:它忽略具有默认操作的任何信号。 因此,除非进行编码,否则进程不会在SIGINT或SIGTERM上终止。

在附加到启用tty的容器(即:使用-t启动)时,禁止重定向docker attach命令的标准输入。

当客户端使用docker attach连接到容器的stdio时,Docker使用~1MB内存缓冲区来最大化应用程序的吞吐量。 如果填充此缓冲区,API连接的速度将开始影响过程输出写入速度。 这类似于SSH等其他应用程序。 因此,建议不要运行性能关键型应用程序,这些应用程序通过慢速客户端连接在前台生成大量输出。 相反,用户应使用docker logs命令来访问日志。

使用

docker attach [OPTIONS] CONTAINER

常用的命令行参数:

参数 描述
–no-stdin Do not attach STDIN
–sig-proxy Proxy all received signals to the process

启动命令

先启动一个容器:

$ docker run -it --rm --name attachtest  ubuntu bash
root@f13ee9356da6:/# 

然后再在另外一个终端中运行:

docker attach attachtest

之后在两个终端中输入命令,都可以看到同样的输出。

备注:当第二个终端用 exit 命令退出时,第一个终端(也就是启动容器的终端)也会同样因为stdin里面输入了exit 命令而退出,容器关闭。

如果不想影响原有容器的工作,可以用 –no-stdin 参数:

docker attach  --no-stdin attachtest

这样不附加 stdin ,也就不会有输入影响容器的运行,这个终端需要推出时,ctrl + c 即可。

3.4.9 - Docker的logs命令

Docker的logs命令

介绍

https://docs.docker.com/engine/reference/commandline/logs/

docker logs命令批量检索执行时存在的日志。

注意:此命令仅适用于使用 json-file 或 journald 日志记录驱动程序启动的容器。

docker logs --follow 命令将持续从容器的 STDOUT 和 STDERR 流式传输新输出。

将负数或非整数传递给 --tail 无效,并且在该情况下将值设置为all。

docker logs --timestamps 命令将为每个日志条目添加 RFC3339 Nano时间戳,例如 2014-09-16T06:17:46.000000000Z 。为了确保时间戳对齐,时间戳的纳秒部分将在必要时填充为零。

docker logs --details 命令将添加在创建容器时提供给 --log-opt 的额外属性,例如环境变量和标签。

--since 选项仅显示在给定日期之后生成的容器日志。您可以将日期指定为RFC 3339日期,UNIX时间戳或Go duration string(例如1m30s,3h)。除RFC3339日期格式外,您还可以使用RFC3339Nano, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00, and 2006-01-02。如果在时间戳结束时未提供Z或 +-00:00 时区偏移,则将使用客户端上的本地时区。提供Unix时间戳时输入秒[.nanoseconds],其中秒是自1970年1月1日(午夜UTC / GMT)以来经过的秒数,不计算闰秒(也称为Unix纪元或Unix时间)和可选项。纳秒字段是一秒的一小部分,不超过九位数。您可以将–since选项与–follow或–tail选项中的任何一个或两者结合使用。

使用

docker logs [OPTIONS] CONTAINER

常用的命令行参数:

参数 描述
--details Show extra details provided to logs
--follow , -f Follow log output
--since Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
--tail Number of lines to show from the end of the logs
–timestamps , -t Show timestamps
--until Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)

示例

先启动一个容器,这里会每秒钟打印一条日志:

docker run -it --rm --name logstest  ubuntu sh -c "while true; do $(echo date); sleep 1; done"

然后再在另外一个终端中运行:

docker logs -f logstest

就可以在第二个终端中看到输出。

3.4.10 - Docker的port命令

Docker的port命令

介绍

https://docs.docker.com/engine/reference/commandline/port/

列出容器的端口映射或特定映射

使用

docker port CONTAINER [PRIVATE_PORT[/PROTO]]

示例

$ docker port test
$ docker port test 7890/tcp
$ docker port test 7890/udp
$ docker port test 7890

3.4.11 - Docker的rm命令

Docker的rm命令

介绍

https://docs.docker.com/engine/reference/commandline/rm/

删除一个或者多个容器

使用

docker rm [OPTIONS] CONTAINER [CONTAINER...]

命令行参数:

参数 描述
--force , -f Force the removal of a running container (uses SIGKILL)
--link , -l Remove the specified link
--volumes , -v Remove the volumes associated with the container

示例

$ docker rm test
$ docker rm --force redis
$ docker rm $(docker ps -a -q) # 删除所有停止运行的容器
$ docker rm -v redis

3.5 - Docker资源类命令

Docker资源类命令

3.5.1 - Docker资源类命令概述

Docker资源类命令概述

资源类的Docker命令:

命令 命令描述
stats 显示容器硬件资源使用情况
update 更新容器的硬件资源限制
system 管理系统资源

3.5.2 - Docker的stats命令

Docker的stats命令

介绍

https://docs.docker.com/engine/reference/commandline/stats/

显示容器资源使用情况统计信息的实时流。

docker stats命令返回用于运行容器的实时数据流。要将数据限制为一个或多个特定容器,请指定由空格分隔的容器名称或ID列表。您可以指定已停止的容器,但已停止的容器不会返回任何数据。

如果您想了解有关容器资源使用情况的更多详细信息,请使用 /containers/(id)/stats API端点。

注意:在Linux上,Docker CLI通过从总内存使用量中减去页面缓存使用情况来报告内存使用情况。 API不执行此类计算,而是提供总内存使用量和页面缓存中的金额,以便客户端可以根据需要使用数据。

注意:PIDS列包含该容器创建的进程数和内核线程数。线程是Linux内核使用的术语。其他等效术语是“轻量级进程”或“内核任务”等.PIDS列中的大量数据与少量进程(由ps或top报告)可能表明容器中的某些内容正在创建许多线程。

使用

docker stats [OPTIONS] [CONTAINER...]

常用命令行参数

参数 描述
–all , -a Show all containers (default shows just running)

示例

如果没有运行的容器,用下面命令启动一个:

docker run -it --rm --name statstest  ubuntu sh -c "while true; do $(echo date); sleep 1; done"

然后在另外一个终端中执行 docker stats

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
0412e567f426        statstest           0.32%               1.801MiB / 15.12GiB   0.01%               2.85kB / 0B         0B / 0B             2

更多用法和格式化输出见官方文档。

3.5.3 - Docker的system命令

Docker的system命令

介绍

https://docs.docker.com/engine/reference/commandline/system/

管理docker系统

使用

docker system COMMAND

df 子命令

显示docker的磁盘使用

https://docs.docker.com/engine/reference/commandline/system_df/

docker system df
docker system df -v

events 子命令

和docker events命令有何差异?看输出是一样。

info 子命令

和docker info命令有何差异?看输出是一样。

prune 子命令

删除不再使用的资源。

https://docs.docker.com/engine/reference/commandline/system_prune/

4 - Docker镜像

Docker镜像

4.1 - 通过Dockerfile制作Docker镜像

通过Dockerfile制作Docker镜像

4.1.1 - Dockerfile概述

Dockerfile概述

Dockerfile

参考资料

4.2 - Docker镜像仓库

镜像仓库

5 - Docker网络

Docker网络

5.1 - Docker网络概述

Docker网络概述

内容摘要自: https://docs.docker.com/network/

网络驱动

Docker的网络子系统是可插拔的,使用驱动程序。默认情况下存在多个驱动程序,并提供核心网络功能:

  • bridge:默认网络驱动程序。如果未指定驱动程序,则这是您要创建的网络类型。当您的应用程序在需要通信的独立容器中运行时,通常会使用桥接网络。
  • host:对于独立容器,移除容器和Docker主机之间的网络隔离,直接使用主机的网络。host 仅适用于Docker 17.06及更高版本的swarm service。
  • overlay:覆盖网络将多个Docker守护程序连接在一起,并使swarm service能够相互通信。您还可以使用覆盖网络来促进swarm service和独立容器之间的通信,或者在不同Docker守护程序上的两个独立容器之间进行通信。此策略消除了在这些容器之间执行OS级别路由的需要。
  • macvlan:Macvlan网络允许您为容器分配MAC地址,使其显示为网络上的物理设备。Docker守护程序通过其MAC地址将流量路由到容器。macvlan 在处理期望直接连接到物理网络的传统应用程序时是最佳选择,而不是通过Docker主机的网络堆栈进行路由。
  • none:对于此容器,禁用所有网络。通常与自定义网络驱动程序一起使用。none不适用于swarm service。
  • 网络插件:您可以使用Docker安装和使用第三方网络插件。这些插件可从 Docker Hub 或第三方供应商处获得。有关安装和使用给定网络插件的信息,请参阅供应商的文档。

网络驱动摘要

  • 当您需要多个容器在同一个Docker主机上进行通信时,用户定义的桥接网络/User-defined bridge networks是最佳选择。
  • 当网络堆栈不应与Docker主机隔离时,但您希望隔离容器的其他方面,主机网络/host network是最好的。
  • 当您需要在不同Docker主机上运行的容器进行通信时,覆盖网络/Overlay networks是最佳选择。
  • 当您从VM设置迁移或需要容器看起来像网络上的物理主机时,Macvlan网络是最佳的,每个主机都具有唯一的MAC地址。
  • 第三方网络插件允许您将Docker与专用网络堆栈集成。

5.2 - Docker容器网络

Docker容器网络

摘要自: https://docs.docker-cn.com/engine/userguide/networking/

默认网络

安装docker时自动创建的网络,可以通过 docker network ls 命令查看:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
19b2dd70e44d        bridge              bridge              local
68b80f077f8b        host                host                local
0f94ce7160cf        none                null                local

运行容器时,可以通过 --network 标记指定容器要连接到的网络。

桥接网络代表所有Docker安装中存在的docker0网络。 除非您使用docker run –network = 选项另行指定,否则Docker守护程序默认情况下将容器连接到此网络。 您可以通过在主机上使用ifconfig命令将此桥接器视为主机网络堆栈的一部分。

6 - Docker Compose

Docker Compose

6.1 - Docker Compose概述

Docker Compose概述

Docker Compose 是一个用来定义和运行复杂应用的Docker工具。

使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

Docker Compose 的文档:

https://docs.docker.com/compose/overview/

安装

安装方式参考官方文档:

https://docs.docker.com/compose/install/

建议还是直接从github发布地址手工下载最新版本的 docker-compose-Linux-x86_64

https://github.com/docker/compose/releases

然后手工复制到目标路径,增加运行权限:

sudo mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

验证安装:

docker-compose version
docker-compose version 1.23.1, build b02f1306
docker-py version: 3.5.0
CPython version: 3.6.7
OpenSSL version: OpenSSL 1.1.0f  25 May 2017

错误处理

如果遇到执行docker-compose up命令时报错:

$ docker-compose up --build -d
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?

If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.

请检查是否有将当前用户加入docker组,如果已经有加入,则可能是加入后还没有重新登录。建议退出当前用户再重新登录,或者重启,如果不想退出当前用户,可以用一个取巧的方案:

sudo su  # 先su到root用户
su sky   # 再su当当前用户
docker-compose up -d    # 再执行命令

参考资料