【树莓派不吃灰】基础篇⑱ 从0到1搭建docker环境,顺便安装一下emqx MQTT Broker、HomeAssistant、portainer

在这里插入图片描述

目录

  • ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️
  • ❤️ 本篇创建记录 2022-11-12 ❤️
  • ❤️ 本篇更新记录 2022-11-12 ❤️
  • 🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言 📝
  • 🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!
  • 🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志🔥

1. 前言

docker作为现阶段一个非常有名的虚拟化容器技术,深受开发者喜爱。而树莓派作为一款Linux主机,本质上也可以在上面试玩一下docker。

折腾树莓派自然少不了各种软件,安装过程往往多于应用(看我之前搭建HomeAssistant环境就知道了),尝试在树莓派上使用 Docker 未尝不是一种思路。

在这里插入图片描述

2. 搭建docker环境

  • 下载docker官方提供的便捷脚本

sudo curl -fsSL https://get.docker.com -o get-docker.sh
在这里插入图片描述

  • 运行脚本进行下载

sudo sh get-docker.sh
在这里插入图片描述
在这里插入图片描述
至此,这里就搭建好docker环境了。真的非常简单快捷。

同时,我们也查看一下docker的版本。
在这里插入图片描述

3. docker简介

docker官方文档

  • Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
  • Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
  • 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socker从客户端访问!Docker Server接收到Docker-Client的指令,就会执行这个指令!

3.1 docker解决什么问题?

一款产品从开发到上线,从操作系统,到运行环境,再到应用配置
作为开发 + 运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题。
特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验。

Docker为了解决这个问题,给出了一个 “软件是可以带环境安装” 的一个标准化的解决方案,并且它是区别于虚拟机技术容器虚拟化技术

  • 🎅示例1
    你在金鱼店的鱼缸里买一条小金鱼回去,养在家里的盆子里,那么小金鱼有可能水土不服XX,如果你把连鱼带缸的买回去就不会出现这种情况了,因为生存环境没有改变。
  • 🎅夸张示例2
    如果我们搬家,一般是把家具之类的一件一件的搬到新房子里去,然后到新房子里有重新布置。,"Docker"的理念就是直接把房子铲起来放置到新的住址,那么里面的配置都不用动了,直接可以入住。

docker理念:一次构建处处运行。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。

3.2 docker VS vm虚拟机

在这里插入图片描述

3.2.1 vm虚拟机
  • 在一个操作系统之上运行 / 安装另一种操作系统,虚拟出一堆硬件, 运行一个完整的操作系统
  • 应用程序, 操作系统和硬件三者之间的关系不变,在该系统上再运行一系列的应用程序

缺点:

  • 资源占用多(玩过VM的同学肯定深有同感)
  • 启动慢(分钟级,一些低端主机可能更慢)
3.2.2 docker
  • 不是模拟一个完整的操作系统, 他是将软件运行所需要的所有资源打包到一个隔离的容器,容器内的应用进程直接运行在宿主的内核, 容器内没有机子的内核
  • 只需要软件工作所需要的库资源和设置,并且没有进行硬件的虚拟,因此更轻便
  • 每个容器之间相互隔离, 每个容器都有自己的文件系统, 容器之间不会相互影响, 能区分计算资源

优点:

  • 由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
  • docker利用的是宿主机的内核,而不像虚拟机在宿主机上再运行一个内核。当新建一个容器时,docker不需要和虚拟机一样重新加载这个操作系统内核进而避免寻找、加载操作系统内核比较费时费资源的过程
  • 当新建个虚拟机时,虚拟机软件需要加载Centos,这个新建过程是"分钟级别的"。docker由于直接利用宿主机的操作系统,则省略了这个个过程因此新建一个docker容器只需要"几秒钟"。

在这里插入图片描述

3.3 docker如何解决问题?

Docker理念 :一次构建处处运行

  • 解决更快的应用交付和部署问题

🎅传统的应用开发完成后,需要提供一堆安装程序和配置说明文档,安装部署后需根据配置文档进行繁杂的配置才能正常运行
🎅Docker化之后只需要交付少量容器镜像文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像里已经内置好,大大节省部署配置和测试验证时间

  • 解决便捷的升级和扩缩容问题

🎅随着微服务架构和Docker的发展,大量的应用会通过微服务方式架构,应用的开发构建将变成搭乐高积木一样,每个"Docker容"器将变成一块"积木",“应用的升级将变得非常容易”
🎅当现有的容器不足以支撑业务处理时,可通过镜像运行"新的容器进行快速扩容",使应用系统的扩容从原先的天级变成分钟级甚至秒级

  • 解决简单的系统运维修复问题

🎅应用容器化运行后,生产环境运行的应用可与开发、测试环境的应用"高度一致",容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的BUG
🎅当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复

  • 解决更高效的计算资源利用问题

🎅Docker是内核级虚拟化,其不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上"可以运行很多个容器实例",可大大"提升物理服务器的CPU和内存的利用率"
在这里插入图片描述

3.4 docker运行架构

在这里插入图片描述
docker中包含了几个重要的角色:

  • images 镜像
  • container 容器
  • repository 仓库
  • docker host 宿主机
  • client docker客户端

Docker 本身是一个容器运行载体或称之为管理引擎。

image 文件用来生成容器实例,本身也是一个文件,称为镜像文件。

同一个 image 文件,可以生成多个同时运行的容器实例。

一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器。

至于仓库,就是放了一堆镜像的地方,我们可以把镜像发布到仓库中,需要的时候从仓库中拉下来就可以了。

3.4.1 镜像 : image
  • 一个只读模板, 一个镜像可以创建出来很多个容器
  • 相当于Python当中类与对象的概念,一个类可以实例化出来许多的 obj
3.4.2 容器 : container
  • 独立运行的一个或一组应用, 是由镜像实例化出来的
  • 可以把它看成是一个迷你版的Linux环境, 基础镜像170M (我们装的一般4个多G)
  • 它可以被启动开始停止删除。每个容器都是相互隔离的
3.4.3 仓库 : repository
  • 集中存放镜像文件的场所

🎅仓库:

  • 🔰 每个仓库包含多个镜像,每个镜像有不同的标签(‘tag’:类似于版本号)
  • 🔰仓库分为公开仓库(Public)和私有仓库(Private)两种形
  • 🔰最大的公开仓库是 “Docker Hub:(https://hub.docker.com/)”

3.5 国内镜像加速

默认镜像下载是在国外服务器,我们还是需要配置一下国内镜像源。

Docker的国内镜像源的资源站也比较丰富:

Docker中国区官方镜像:https://registry.docker-cn.com
网易:http://hub-mirror.c.163.com
中国科技大学:https://docker.mirrors.ustc.edu.cn
阿里云:https://cr.console.aliyun.com/

  • 创建 /etc/docker/daemon.json文件,并填入以下内容
{
    "registry-mirrors": [
        "http://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://registry.docker-cn.com",
        "https://cr.console.aliyun.com/"
    ]
}

在这里插入图片描述
在这里插入图片描述

  • 加载重启docker

sudo systemctl daemon-reload
sudo systemctl restart docker

  • 查看是否成功

sudo docker info
在这里插入图片描述

我们看看以上操作之后得到哪些内容:

pi@raspberrypi:/etc/docker $ sudo docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Docker Buildx (Docker Inc., v0.9.1-docker)
  compose: Docker Compose (Docker Inc., v2.12.2)

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 20.10.21
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 1c90a442489720eec95342e1789ee8a5e1b9536f
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.15.74-v7l+
 Operating System: Raspbian GNU/Linux 11 (bullseye)
 OSType: linux
 Architecture: armv7l
 CPUs: 4
 Total Memory: 3.749GiB
 Name: raspberrypi
 ID: 45FJ:2Y5U:LNYV:K2GS:AHV7:YVQU:QAVU:3IQC:EO3J:PNGQ:ROXA:JOI7
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  http://hub-mirror.c.163.com/
  https://docker.mirrors.ustc.edu.cn/
  https://registry.docker-cn.com/
  https://cr.console.aliyun.com/
 Live Restore Enabled: false

WARNING: No memory limit support
WARNING: No swap limit support

docker info 里面区分了client和server(server里面也包含了镜像的各种状态),我们优先关注 Registry Mirrors 镜像源,这里设置成功。
在这里插入图片描述

3.6 docker常用命令

#查看 Docker 版本
docker -v
sudo docker pull 仓库/镜像:版本(留空的话默认为 latest)
sudo docker run 加参数,用来创建容器
#查看运行容器
sudo docker ps
#查看所有下载的镜像
sudo docker images
#进入容器终端
sudo docker exec -i -t ha /bin/bash
#实时查看10行的 ha 日志
sudo docker logs -f -t --tail 10 ha
#重启 systemctl 守护进程
sudo systemctl daemon-reload
#设置 Docker 开机启动
sudo systemctl enable docker
#开启 Docker 服务
sudo systemctl start docker

命令帮助文档地址

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

根据命令用途,分为几类:

  • 基础命令
  • 镜像命令
  • 容器命令

当然,还有贴心的docker命令大全中文版本

https://www.runoob.com/docker/docker-command-manual.html
在这里插入图片描述

3.6.1 基础命令
  • 查看docker的版本信息

docker version
在这里插入图片描述

  • 查看docker的系统信息,包括镜像和容器的数量

docker info
在这里插入图片描述

  • 帮助命令(可查看可选的参数)

docker --help

```c
pi@raspberrypi:/var/lib $ docker --help

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default "/home/pi/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default
                           context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/home/pi/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/home/pi/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/home/pi/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  app*        Docker App (Docker Inc., v0.9.1-beta3)
  builder     Manage builds
  buildx*     Docker Buildx (Docker Inc., v0.9.1-docker)
  compose*    Docker Compose (Docker Inc., v2.12.2)
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

To get more help with docker, check out our guides at https://docs.docker.com/go/guides/
pi@raspberrypi:/var/lib $ 

官方更推荐我们加上某一个特别的COMMAND

  • 某条命令对应帮助命令(可查看可选的参数) —— 非常重要

docker COMMAND --help
在这里插入图片描述
这条命令可以说非常重要,一般我们也不会死记硬背命令,那么帮助说明文档就显得非常重要。特别我们接下来学习新命令的时候都可以先执行帮助文档。

3.6.2 镜像命令

说到镜像,肯定要了解镜像商店 —— dockerhub,类似于github。
在这里插入图片描述
找镜像的时候也可以到上面去找,然后点击对应的镜像链接,里面会有详细说明如何使用该镜像。

3.6.2.1 查看本地主机的所有镜像 —— docker images

命令详细说明 https://docs.docker.com/engine/reference/commandline/images/

在这里插入图片描述

pi@raspberrypi:/etc/docker $ docker images --help

Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show image IDs

在这里插入图片描述

pi@raspberrypi:~ $ sudo docker images --all
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
pi@raspberrypi:~ $ 

#解释:
1.REPOSITORY 镜像的仓库源
2.TAG 镜像的标签
3.IMAGE ID 镜像的id
4.CREATED 镜像的创建时间
5.SIZE 镜像的大小

3.6.2.2 搜索镜像 —— docker search

命令详细说明 https://docs.docker.com/engine/reference/commandline/search/

在这里插入图片描述

pi@raspberrypi:~ $ docker search --help

Usage:  docker search [OPTIONS] TERM

Search the Docker Hub for images

Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output

  • 查找所有名字带emqx的镜像
    在这里插入图片描述
    一般我们也是使用stars最多的镜像。

  • 查找名字中带emqx的镜像,并且它的星星要不少于3,并且官方标记
    在这里插入图片描述

当然我们也可以直接在dockerhub里面搜索:
在这里插入图片描述
第一个emqx/emqx 就跟我们用docker search搜索出来的一样。

3.6.2.3 下载镜像 —— docker pull(重要)

命令详细说明 https://docs.docker.com/engine/reference/commandline/pull/

在这里插入图片描述

pi@raspberrypi:~ $ sudo docker pull --help

Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Pull an image or a repository from a registry

Options:
  -a, --all-tags                Download all tagged images in the repository
      --disable-content-trust   Skip image verification (default true)
      --platform string         Set platform if server is multi-platform capable
  -q, --quiet                   Suppress verbose output
pi@raspberrypi:~ $ 

如何下载到合适的适合当前系统的镜像呢?以emqx为例子

https://hub.docker.com/r/emqx/emqx/tags?page=1&name=arm32v7

我们需要过滤出OS/ARCH: linux/arm/V7架构。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里列举了好几个版本,我们直接安装最新的 4.3.10。
在这里插入图片描述

pi@raspberrypi:~ $ sudo docker pull emqx/emqx:4.3.10
4.3.10: Pulling from emqx/emqx
4.3.10: Pulling from emqx/emqx
6b3b5e25c4f5: Pull complete  #分层下载,docker image的核心-联合文件系统
cb45a9863727: Pull complete 
54ab8e0170dc: Pull complete 
de768d6de8c0: Pull complete 
f7da30e464bc: Pull complete 
d12e69899239: Pull complete 
241b064a69ed: Pull complete 
Digest: sha256:0cc667c503c9faa57b6f364e6f0ee3df91d3bf42c376aa1507334876d50be6cd
Status: Downloaded newer image for emqx/emqx:4.3.10
docker.io/emqx/emqx:4.3.10 #下载来源的真实地址
pi@raspberrypi:~ $ 

在这里插入图片描述
这里我们下载了两个tag版本。
在这里插入图片描述

3.6.2.4 移除镜像 —— docker rmi

命令详细说明 https://docs.docker.com/engine/reference/commandline/rmi/

在这里插入图片描述

pi@raspberrypi:~ $ sudo docker rmi --help

Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images

Options:
  -f, --force      Force removal of the image
      --no-prune   Do not delete untagged parents
pi@raspberrypi:~ $ 

在这里插入图片描述

习惯性加上 -f参数,表示强制移除。

3.6.3 容器命令

有了镜像之后,我们就可以开始创建容器了(类模板创建对象实例)。

3.6.3.1 新建容器并启动 —— docker run(重中之重)

命令详细说明 https://docs.docker.com/engine/reference/commandline/run/

pi@raspberrypi:~ $ sudo docker run --help

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

Run a command in a new container

Options:
      --add-host list                  Add a custom host-to-IP mapping (host:ip)
  -a, --attach list                    Attach to STDIN, STDOUT or STDERR
      --blkio-weight uint16            Block IO (relative weight), between 10 and 1000, or 0
                                       to disable (default 0)
      --blkio-weight-device list       Block IO weight (relative device weight) (default [])
      --cap-add list                   Add Linux capabilities
      --cap-drop list                  Drop Linux capabilities
      --cgroup-parent string           Optional parent cgroup for the container
      --cgroupns string                Cgroup namespace to use (host|private)
                                       'host':    Run the container in the Docker host's
                                       cgroup namespace
                                       'private': Run the container in its own private cgroup
                                       namespace
                                       '':        Use the cgroup namespace as configured by
                                       the
                                                  default-cgroupns-mode option on the daemon
                                       (default)
      --cidfile string                 Write the container ID to the file
      --cpu-period int                 Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int                  Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int              Limit CPU real-time period in microseconds
      --cpu-rt-runtime int             Limit CPU real-time runtime in microseconds
  -c, --cpu-shares int                 CPU shares (relative weight)
      --cpus decimal                   Number of CPUs
      --cpuset-cpus string             CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string             MEMs in which to allow execution (0-3, 0,1)
  -d, --detach                         Run container in background and print container ID
      --detach-keys string             Override the key sequence for detaching a container
      --device list                    Add a host device to the container
      --device-cgroup-rule list        Add a rule to the cgroup allowed devices list
      --device-read-bps list           Limit read rate (bytes per second) from a device
                                       (default [])
      --device-read-iops list          Limit read rate (IO per second) from a device (default [])
      --device-write-bps list          Limit write rate (bytes per second) to a device (default [])
      --device-write-iops list         Limit write rate (IO per second) to a device (default [])
      --disable-content-trust          Skip image verification (default true)
      --dns list                       Set custom DNS servers
      --dns-option list                Set DNS options
      --dns-search list                Set custom DNS search domains
      --domainname string              Container NIS domain name
      --entrypoint string              Overwrite the default ENTRYPOINT of the image
  -e, --env list                       Set environment variables
      --env-file list                  Read in a file of environment variables
      --expose list                    Expose a port or a range of ports
      --gpus gpu-request               GPU devices to add to the container ('all' to pass all GPUs)
      --group-add list                 Add additional groups to join
      --health-cmd string              Command to run to check health
      --health-interval duration       Time between running the check (ms|s|m|h) (default 0s)
      --health-retries int             Consecutive failures needed to report unhealthy
      --health-start-period duration   Start period for the container to initialize before
                                       starting health-retries countdown (ms|s|m|h) (default 0s)
      --health-timeout duration        Maximum time to allow one check to run (ms|s|m|h)
                                       (default 0s)
      --help                           Print usage
  -h, --hostname string                Container host name
      --init                           Run an init inside the container that forwards signals
                                       and reaps processes
  -i, --interactive                    Keep STDIN open even if not attached
      --ip string                      IPv4 address (e.g., 172.30.100.104)
      --ip6 string                     IPv6 address (e.g., 2001:db8::33)
      --ipc string                     IPC mode to use
      --isolation string               Container isolation technology
      --kernel-memory bytes            Kernel memory limit
  -l, --label list                     Set meta data on a container
      --label-file list                Read in a line delimited file of labels
      --link list                      Add link to another container
      --link-local-ip list             Container IPv4/IPv6 link-local addresses
      --log-driver string              Logging driver for the container
      --log-opt list                   Log driver options
      --mac-address string             Container MAC address (e.g., 92:d0:c6:0a:29:33)
  -m, --memory bytes                   Memory limit
      --memory-reservation bytes       Memory soft limit
      --memory-swap bytes              Swap limit equal to memory plus swap: '-1' to enable
                                       unlimited swap
      --memory-swappiness int          Tune container memory swappiness (0 to 100) (default -1)
      --mount mount                    Attach a filesystem mount to the container
      --name string                    Assign a name to the container
      --network network                Connect a container to a network
      --network-alias list             Add network-scoped alias for the container
      --no-healthcheck                 Disable any container-specified HEALTHCHECK
      --oom-kill-disable               Disable OOM Killer
      --oom-score-adj int              Tune host's OOM preferences (-1000 to 1000)
      --pid string                     PID namespace to use
      --pids-limit int                 Tune container pids limit (set -1 for unlimited)
      --platform string                Set platform if server is multi-platform capable
      --privileged                     Give extended privileges to this container
  -p, --publish list                   Publish a container's port(s) to the host
  -P, --publish-all                    Publish all exposed ports to random ports
      --pull string                    Pull image before running ("always"|"missing"|"never")
                                       (default "missing")
      --read-only                      Mount the container's root filesystem as read only
      --restart string                 Restart policy to apply when a container exits (default
                                       "no")
      --rm                             Automatically remove the container when it exits
      --runtime string                 Runtime to use for this container
      --security-opt list              Security Options
      --shm-size bytes                 Size of /dev/shm
      --sig-proxy                      Proxy received signals to the process (default true)
      --stop-signal string             Signal to stop a container (default "SIGTERM")
      --stop-timeout int               Timeout (in seconds) to stop a container
      --storage-opt list               Storage driver options for the container
      --sysctl map                     Sysctl options (default map[])
      --tmpfs list                     Mount a tmpfs directory
  -t, --tty                            Allocate a pseudo-TTY
      --ulimit ulimit                  Ulimit options (default [])
  -u, --user string                    Username or UID (format: <name|uid>[:<group|gid>])
      --userns string                  User namespace to use
      --uts string                     UTS namespace to use
  -v, --volume list                    Bind mount a volume
      --volume-driver string           Optional volume driver for the container
      --volumes-from list              Mount volumes from the specified container(s)
  -w, --workdir string                 Working directory inside the container
pi@raspberrypi:~ $ 

这条命令参数说明最多,也是最重要的一条命令。
点击查看常用参数说明

docker run [可选参数] image

#参数说明
--name="名字"           指定容器名字
-d                     后台方式运行
-i: 以交互模式运行容器,通常与 -t 同时使用,进入容器查看内容;
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-P: 大写P,随机端口映射,容器内部端口随机映射到主机的端口
-p: 小写p,指定端口映射,格式为:主机(宿主)端口:容器端口
-P                     随机指定端口(大写的P)
-dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
-h "mars": 指定容器的hostname;
-m :设置容器使用内存最大值;
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
--link=[]: 添加链接到另一个容器(基本上弃用);
-e username="ritchie": 设置环境变量;
--expose=[]: 开放一个端口或一组端口;
--volume , -v: 绑定一个卷
--env-file=[]: 从指定文件读入环境变量;
--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
--privileged: privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。甚至允许你在docker容器中启动docker容器。
  • 使用docker镜像emqx/emqx:4.3.10以后台模式启动一个容器,并将容器命名为emqx4.3.10
    对应命令:sudo docker run -d --name emqx4.3.10 emqx/emqx:4.3.10
    在这里插入图片描述
    如果出现错误提示:Please make sure openssl-1.1.1 (libcrypto) and libncurses are installed.
    需要执行命令:
    sudo apt-get install openssl libssl-dev -y
    注意:这种启动方式外界是无法访问的

  • 使用docker镜像emqx/emqx:4.3.10以后台模式启动一个容器,并将容器命名为emqx4.3.10。将容器的1883端口映射到主机的1883,容器 8081端口映射到主机8081端口 ,容器8083端口映射到主机8083端口,容器8084端口映射到主机8084端口,容器8883端口映射到主机8883,容器18083端口映射到主机18083端口。
    在这里插入图片描述
    对应命令:sudo docker run -d --name emqx -p 1883:1883 -p 8081:8081 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:4.3.10
    在这里插入图片描述
    浏览器访问树莓派ip地址加上18083端口就可以访问emqx后台。

  • 使用docker镜像emqx/emqx:4.3.10以交互模式启动一个容器,并将容器命名为emqx4.3.10。将容器的1883端口映射到主机的1884,容器 8081端口映射到主机8086端口 ,容器8083端口映射到主机8087端口,容器8084端口映射到主机8088端口,容器8883端口映射到主机8889,容器18083端口映射到主机18084端口(避免冲突)。在容器内执行/bin/bash命令。
    对应命令:sudo docker run -it --name emqx-2 -p 1884:1883 -p 8086:8081 -p 8087:8083 -p 8088:8084 -p 8889:8883 -p 18084:18083 emqx/emqx:4.3.10 /bin/bash
    在这里插入图片描述
    在这里插入图片描述
    docker的端口映射并不是在docker技术中实现的,而是通过宿主机的iptables来实现。通过控制网桥来做端口映射,类似路由器中设置路由端口映射。
    sudo iptables -t nat -vnL
    在这里插入图片描述
    浏览器访问树莓派ip地址加上18084端口也可以访问emqx后台,是不是很美妙?

注意点:

在容器内执行/bin/bash命令的这种方式,不会自动启动emqx服务,需要人工再去启动emqx服务。
原因:我们直接查看emqx的DockerFile构建过程。
在这里插入图片描述
CMD用来指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。而我们这里的最后一条 是 CMD ["/opt/emqx/bin/emqx" "foreground"]。如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。所以这种情况下就覆盖了我们原来的命令。

3.6.3.2 查看容器 —— docker ps

命令详细说明 https://docs.docker.com/engine/reference/commandline/ps/

在这里插入图片描述

pi@raspberrypi:~ $ sudo docker ps --help

Usage:  docker ps [OPTIONS]

List containers

Options:
  -a, --all             Show all containers (default shows just running)
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print containers using a Go template
  -n, --last int        Show n last created containers (includes all states) (default -1)
  -l, --latest          Show the latest created container (includes all states)
      --no-trunc        Don't truncate output
  -q, --quiet           Only display container IDs
  -s, --size            Display total file sizes
pi@raspberrypi:~ $ 

docker ps [可选参数]

#常用参数说明
无参    默认显示正在运行的容器
-a     显示所有的容器,包括未运行的
-f     根据条件过滤显示的内容
-n     列出最近创建的n个容器
--no-trunc 不截断输出 (建议加上这个)
-q     静默模式,只显示容器ID
-s     显示总的文件大小
  • 查找所有运行过的容器
    在这里插入图片描述
  • 查找所有运行过的容器id
    在这里插入图片描述
  • 查找名字存在emqx-1的容器
    在这里插入图片描述

结果解析:

  • CONTAINER ID(container id ) :顾名思义 ,容器ID的意思,可以通过这id找到唯一的对应容器
  • IMAGE (image):该容器所使用的镜像
  • COMMAND (command):启动容器时运行的命令(可以查看DockerFile
  • CREATED (created):容器的创建时间,显示格式为”**时间之前创建“
  • STATUS (status):容器现在的状态,状态有7种:created(已创建)|restarting(重启中)|running(Up)(运行中)|removing(迁移中)|paused(暂停)|exited(停止)|dead
  • PORTS (ports):容器的端口信息和使用的连接类型(tcp\udp)
  • NAMES (names):镜像自动为容器创建的名字,也唯一代表一个容器
3.6.3.3 删除容器 —— docker rm

命令详细说明 https://docs.docker.com/engine/reference/commandline/rm/

在这里插入图片描述

pi@raspberrypi:~ $ sudo docker rm --help

Usage:  docker rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers

Options:
  -f, --force     Force the removal of a running container (uses SIGKILL)
  -l, --link      Remove the specified link
  -v, --volumes   Remove anonymous volumes associated with the container
pi@raspberrypi:~ $ 
docker rm [可选参数]

#常用参数说明
-f :通过 SIGKILL 信号强制删除一个运行中的容器。
-l :移除容器间的网络连接,而非容器本身。这个比较特殊
-v :删除与容器关联的数据卷。这里涉及到宿主机容器的共享。
  • 强制移除一个容器
    在这里插入图片描述
    删除指定的容器,不能删除正在运行的容器,强制删除使用 rm -f
  • 也可以移除通过 docker ps 过滤出来的容器。比如移除状态是退出的容器

方式1:docker rm $(docker ps --filter status=exited -q)
方式2:docker ps --filter status=exited -q | xargs docker rm

3.6.3.4 启动、重启、停止 —— docker start/stop/restart

命令详细说明 https://docs.docker.com/engine/reference/commandline/start/
命令详细说明 https://docs.docker.com/engine/reference/commandline/restart/
命令详细说明 https://docs.docker.com/engine/reference/commandline/stop/

这三个命令没太多要讲的内容。

  • docker start :启动一个或多个已经被停止的容器
  • docker stop :停止一个运行中的容器
  • docker restart :重启容器

在这里插入图片描述

3.6.3.5 查看容器/镜像详细信息 —— docker inspect

命令详细说明 https://docs.docker.com/engine/reference/commandline/inspect/

在这里插入图片描述

pi@raspberrypi:~ $ sudo docker inspect --help

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

Return low-level information on Docker objects

Options:
  -f, --format string   Format the output using the given Go template
  -s, --size            Display total file sizes if the type is container
      --type string     Return JSON for specified type
pi@raspberrypi:~ $ 

docker inspect [可选参数] 容器id|镜像

#常用参数说明
-f :指定返回值的模板文件。
-s :显示总的文件大小。
--type :为指定类型返回JSON。
  • 查看镜像emqx:4.3.10的元信息
pi@raspberrypi:~ $ sudo docker inspect  emqx/emqx:4.3.10
[
    {
        "Id": "sha256:4ad27d487b4fa7826ef2b4bd85dc4212393ef3ab1a93b1b39f466665a3132dba",
        "RepoTags": [
            "emqx/emqx:4.3.10"
        ],
        "RepoDigests": [
            "emqx/emqx@sha256:0cc667c503c9faa57b6f364e6f0ee3df91d3bf42c376aa1507334876d50be6cd"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-11-12T05:50:02.256390987Z",
        "Container": "96d72866e05831fe5ce82ab89a8fb2022bf2b21605c661ccf3b2ec22408cbea0",
        "ContainerConfig": {
            "Hostname": "96d72866e058",
            "Domainname": "",
            "User": "emqx",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "11883/tcp": {},
                "18083/tcp": {},
                "1883/tcp": {},
                "4369/tcp": {},
                "4370/tcp": {},
                "5369/tcp": {},
                "6369/tcp": {},
                "6370/tcp": {},
                "8081/tcp": {},
                "8083/tcp": {},
                "8084/tcp": {},
                "8883/tcp": {}
            },
            "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) ",
                "CMD [\"/opt/emqx/bin/emqx\" \"foreground\"]"
            ],
            "Image": "sha256:b54026c75f02a46be0a5eced4bae097103855c204ef77a56782fd0d1b1cf3686",
            "Volumes": {
                "/opt/emqx/data": {},
                "/opt/emqx/etc": {},
                "/opt/emqx/log": {}
            },
            "WorkingDir": "/opt/emqx",
            "Entrypoint": [
                "/usr/bin/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "EMQ X Team <support@emqx.io>",
                "org.label-schema.description": "EMQ (Erlang MQTT Broker) is a distributed, massively scalable, highly extensible MQTT messaging broker written in Erlang/OTP.",
                "org.label-schema.docker.dockerfile": "Dockerfile",
                "org.label-schema.license": "GNU",
                "org.label-schema.name": "emqx",
                "org.label-schema.url": "https://emqx.io",
                "org.label-schema.vcs-type": "Git",
                "org.label-schema.vcs-url": "https://github.com/emqx/emqx",
                "org.label-schema.version": ""
            }
        },
        "DockerVersion": "20.10.10+azure-1",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "emqx",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "11883/tcp": {},
                "18083/tcp": {},
                "1883/tcp": {},
                "4369/tcp": {},
                "4370/tcp": {},
                "5369/tcp": {},
                "6369/tcp": {},
                "6370/tcp": {},
                "8081/tcp": {},
                "8083/tcp": {},
                "8084/tcp": {},
                "8883/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/opt/emqx/bin/emqx",
                "foreground"
            ],
            "Image": "sha256:b54026c75f02a46be0a5eced4bae097103855c204ef77a56782fd0d1b1cf3686",
            "Volumes": {
                "/opt/emqx/data": {},
                "/opt/emqx/etc": {},
                "/opt/emqx/log": {}
            },
            "WorkingDir": "/opt/emqx",
            "Entrypoint": [
                "/usr/bin/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "EMQ X Team <support@emqx.io>",
                "org.label-schema.description": "EMQ (Erlang MQTT Broker) is a distributed, massively scalable, highly extensible MQTT messaging broker written in Erlang/OTP.",
                "org.label-schema.docker.dockerfile": "Dockerfile",
                "org.label-schema.license": "GNU",
                "org.label-schema.name": "emqx",
                "org.label-schema.url": "https://emqx.io",
                "org.label-schema.vcs-type": "Git",
                "org.label-schema.vcs-url": "https://github.com/emqx/emqx",
                "org.label-schema.version": ""
            }
        },
        "Architecture": "arm",
        "Variant": "v7",
        "Os": "linux",
        "Size": 134255745,
        "VirtualSize": 134255745,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/5b2488a0728b27bbac131cf37fda82a2d6114884cda3bde1592decc18ad246f3/diff:/var/lib/docker/overlay2/35b457d1bb41f5d11364766bbe5c5b051c5401f0109281e4176ae37c4394ddc8/diff:/var/lib/docker/overlay2/569c0e4bf963d50cac2ae54c710edd7e7d17dd9f13c8f1eef42a814af327d1c8/diff:/var/lib/docker/overlay2/cf16aded00d659a8ad5944407efcc5b480ce6cee2511e08e0d3d8b7479da4b2e/diff:/var/lib/docker/overlay2/88dc18a13a81feb925c5bcd93e4822e093a63dfb78832eb30e3bfd665c01e1b2/diff:/var/lib/docker/overlay2/d89d800dc02053bdc5436b0036da147588427d1e4e78a4e92995f2058a447d1f/diff",
                "MergedDir": "/var/lib/docker/overlay2/a08eaf205635c5e74ffcffde481a172e1a55782d9da811150cad6f7a0b07aacf/merged",
                "UpperDir": "/var/lib/docker/overlay2/a08eaf205635c5e74ffcffde481a172e1a55782d9da811150cad6f7a0b07aacf/diff",
                "WorkDir": "/var/lib/docker/overlay2/a08eaf205635c5e74ffcffde481a172e1a55782d9da811150cad6f7a0b07aacf/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:f40de01a7174ed86ea75f16821016e79e6466f3e693d75f654c9b98260cf66f7",
                "sha256:6913c99426a5b39b9433428df56201560501a123b6733b4e26e15e8eecde5435",
                "sha256:e16cc8f5e9db11f129682e6968372174c16830c75f6ef868fb3abe2727ab1a03",
                "sha256:e9c67a9348f207bb88a3fac64738f9de48dbe71e3b20a5d59e4c56f82f1047ab",
                "sha256:c6e606daafad3f77f61abbc74b8f34d0894a70fad11bac8cea334ecd958daed8",
                "sha256:c0d9b37951bfdc3495fbdd0b0072d26100d3cb02f4d6349f8cd536069b6fbafe",
                "sha256:e1b522675e4516357c20108fbadfa0462e0f02fecf922a6608911bf2bb63a472"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]
pi@raspberrypi:~ $ 

  • 查看正在运行的emqx容器的元信息
pi@raspberrypi:~ $ sudo docker ps -a
CONTAINER ID   IMAGE              COMMAND                  CREATED       STATUS       PORTS                                                                                                                                                                                                                                                                                                                     NAMES
e813f9e6a04c   emqx/emqx:4.3.10   "/usr/bin/docker-ent…"   9 hours ago   Up 9 hours   4369-4370/tcp, 5369/tcp, 6369-6370/tcp, 11883/tcp, 0.0.0.0:1884->1883/tcp, :::1884->1883/tcp, 0.0.0.0:8086->8081/tcp, :::8086->8081/tcp, 0.0.0.0:8087->8083/tcp, :::8087->8083/tcp, 0.0.0.0:8088->8084/tcp, :::8088->8084/tcp, 0.0.0.0:8889->8883/tcp, :::8889->8883/tcp, 0.0.0.0:18084->18083/tcp, :::18084->18083/tcp   emqx-2
pi@raspberrypi:~ $ sudo docker inspect e813f9e6a04c
[
    {
        "Id": "e813f9e6a04c5ac2ffe126ddc59e99323134955e5793dc20dc194f51475fec34",
        "Created": "2022-11-10T17:39:47.0189499Z",
        "Path": "/usr/bin/docker-entrypoint.sh",
        "Args": [
            "/bin/sh"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 32072,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-11-10T17:39:48.628467696Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:4ad27d487b4fa7826ef2b4bd85dc4212393ef3ab1a93b1b39f466665a3132dba",
        "ResolvConfPath": "/var/lib/docker/containers/e813f9e6a04c5ac2ffe126ddc59e99323134955e5793dc20dc194f51475fec34/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/e813f9e6a04c5ac2ffe126ddc59e99323134955e5793dc20dc194f51475fec34/hostname",
        "HostsPath": "/var/lib/docker/containers/e813f9e6a04c5ac2ffe126ddc59e99323134955e5793dc20dc194f51475fec34/hosts",
        "LogPath": "/var/lib/docker/containers/e813f9e6a04c5ac2ffe126ddc59e99323134955e5793dc20dc194f51475fec34/e813f9e6a04c5ac2ffe126ddc59e99323134955e5793dc20dc194f51475fec34-json.log",
        "Name": "/emqx-2",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {
                "18083/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "18084"
                    }
                ],
                "1883/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "1884"
                    }
                ],
                "8081/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8086"
                    }
                ],
                "8083/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8087"
                    }
                ],
                "8084/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8088"
                    }
                ],
                "8883/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8889"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "private",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": null,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/50e565af5005401f8e924300a84bf97c125c5ab548220cfe40681ce74e59eff2-init/diff:/var/lib/docker/overlay2/a08eaf205635c5e74ffcffde481a172e1a55782d9da811150cad6f7a0b07aacf/diff:/var/lib/docker/overlay2/5b2488a0728b27bbac131cf37fda82a2d6114884cda3bde1592decc18ad246f3/diff:/var/lib/docker/overlay2/35b457d1bb41f5d11364766bbe5c5b051c5401f0109281e4176ae37c4394ddc8/diff:/var/lib/docker/overlay2/569c0e4bf963d50cac2ae54c710edd7e7d17dd9f13c8f1eef42a814af327d1c8/diff:/var/lib/docker/overlay2/cf16aded00d659a8ad5944407efcc5b480ce6cee2511e08e0d3d8b7479da4b2e/diff:/var/lib/docker/overlay2/88dc18a13a81feb925c5bcd93e4822e093a63dfb78832eb30e3bfd665c01e1b2/diff:/var/lib/docker/overlay2/d89d800dc02053bdc5436b0036da147588427d1e4e78a4e92995f2058a447d1f/diff",
                "MergedDir": "/var/lib/docker/overlay2/50e565af5005401f8e924300a84bf97c125c5ab548220cfe40681ce74e59eff2/merged",
                "UpperDir": "/var/lib/docker/overlay2/50e565af5005401f8e924300a84bf97c125c5ab548220cfe40681ce74e59eff2/diff",
                "WorkDir": "/var/lib/docker/overlay2/50e565af5005401f8e924300a84bf97c125c5ab548220cfe40681ce74e59eff2/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "volume",
                "Name": "f3c327c33573599364a88a815c3d95c72e5926c3becbf37bff276d8fed92674a",
                "Source": "/var/lib/docker/volumes/f3c327c33573599364a88a815c3d95c72e5926c3becbf37bff276d8fed92674a/_data",
                "Destination": "/opt/emqx/log",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "5f249c133cc32aa5bc4ebbe8b506153638b6aea7be90b2bd2ed882f26e880214",
                "Source": "/var/lib/docker/volumes/5f249c133cc32aa5bc4ebbe8b506153638b6aea7be90b2bd2ed882f26e880214/_data",
                "Destination": "/opt/emqx/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "1161ab106a54c9af05042202222796707fab1c3041cae1e09706fd6e70b664db",
                "Source": "/var/lib/docker/volumes/1161ab106a54c9af05042202222796707fab1c3041cae1e09706fd6e70b664db/_data",
                "Destination": "/opt/emqx/etc",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "e813f9e6a04c",
            "Domainname": "",
            "User": "emqx",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "ExposedPorts": {
                "11883/tcp": {},
                "18083/tcp": {},
                "1883/tcp": {},
                "4369/tcp": {},
                "4370/tcp": {},
                "5369/tcp": {},
                "6369/tcp": {},
                "6370/tcp": {},
                "8081/tcp": {},
                "8083/tcp": {},
                "8084/tcp": {},
                "8883/tcp": {}
            },
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh"
            ],
            "Image": "emqx/emqx:4.3.10",
            "Volumes": {
                "/opt/emqx/data": {},
                "/opt/emqx/etc": {},
                "/opt/emqx/log": {}
            },
            "WorkingDir": "/opt/emqx",
            "Entrypoint": [
                "/usr/bin/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "EMQ X Team <support@emqx.io>",
                "org.label-schema.description": "EMQ (Erlang MQTT Broker) is a distributed, massively scalable, highly extensible MQTT messaging broker written in Erlang/OTP.",
                "org.label-schema.docker.dockerfile": "Dockerfile",
                "org.label-schema.license": "GNU",
                "org.label-schema.name": "emqx",
                "org.label-schema.url": "https://emqx.io",
                "org.label-schema.vcs-type": "Git",
                "org.label-schema.vcs-url": "https://github.com/emqx/emqx",
                "org.label-schema.version": ""
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "059a506f59a122b414e5ad7e3506c59074899a1a111ac5adbf23a2c4b3945ff5",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "11883/tcp": null,
                "18083/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "18084"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "18084"
                    }
                ],
                "1883/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "1884"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "1884"
                    }
                ],
                "4369/tcp": null,
                "4370/tcp": null,
                "5369/tcp": null,
                "6369/tcp": null,
                "6370/tcp": null,
                "8081/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8086"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "8086"
                    }
                ],
                "8083/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8087"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "8087"
                    }
                ],
                "8084/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8088"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "8088"
                    }
                ],
                "8883/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8889"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "8889"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/059a506f59a1",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "2a7a3e181bea74f0d187227dd7f8f3a61086dc7391f0035db975cf469df3fcb2",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "92c0b30de6823be1f57a616a7451c387b0110d11afafa5085d6e623b154d731a",
                    "EndpointID": "2a7a3e181bea74f0d187227dd7f8f3a61086dc7391f0035db975cf469df3fcb2",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]
pi@raspberrypi:~ $ 

对比镜像信息。容器多了一些端口映射、IP地址信息等等。

上面是直接过滤整个镜像或者容器的所有信息,一般情况下我们也可以过滤我们需要的信息。这里利用了json属性。我们把上面的全部信息折叠一下。
在这里插入图片描述

  • 查看正在运行的emqx容器的镜像信息
    在这里插入图片描述
  • 查看正在运行的emqx容器的IP地址
    在这里插入图片描述
  • 查看正在运行的emqx容器的容器卷
    在这里插入图片描述
    关于元信息的详解,在网上找到一份参考(以mysql容器为例子):
[
    {
        "Id": "572219d3a0ca25a37623a1113f3c8faa6b48d3ab42ae668eac64fcb39cb4dd84", #完整容器id
        "Created": "2022-06-08T08:29:58.542781937Z", #容器创建时间
        "Path": "docker-entrypoint.sh", #启动容器时,通过shell脚本执行些预处理逻辑中shell脚本的名称
        "Args": [
            "mysqld"
        ],
        "State": {
            "Status": "running", #容器状态
            "Running": true, #是否运行
            "Paused": false, #是否暂停
            "Restarting": false, #是否重启中
            "OOMKilled": false, #进程被杀死
            "Dead": false, # 已死亡
            "Pid": 136172, # 容器进程id
            "ExitCode": 0, # 退出状态码
            "Error": "", #错误信息
            "StartedAt": "2022-07-16T01:47:33.598196195Z", #开始启动时间
            "FinishedAt": "2022-07-16T01:47:26.919749746Z" # 上一次结束时间
        },
        "Image": "sha256:3218b38490cec8d31976a40b92e09d61377359eab878db49f025e5d464367f3b", #镜像的sha256算法id
        "ResolvConfPath": "/var/lib/docker/containers/572219d3a0ca25a37623a1113f3c8faa6b48d3ab42ae668eac64fcb39cb4dd84/resolv.conf", # resolv.conf域名系统解析器(DNS Resolver)的配置文件路径
        "HostnamePath": "/var/lib/docker/containers/572219d3a0ca25a37623a1113f3c8faa6b48d3ab42ae668eac64fcb39cb4dd84/hostname", #当前容器所在的位置
        "HostsPath": "/var/lib/docker/containers/572219d3a0ca25a37623a1113f3c8faa6b48d3ab42ae668eac64fcb39cb4dd84/hosts", #容器host文件(域名、IP配置文件)路径
        "LogPath": "/var/lib/docker/containers/572219d3a0ca25a37623a1113f3c8faa6b48d3ab42ae668eac64fcb39cb4dd84/572219d3a0ca25a37623a1113f3c8faa6b48d3ab42ae668eac64fcb39cb4dd84-json.log",#容器运行日志文件路径
        "Name": "/mysql9", #镜像名称
        "RestartCount": 0, #重启个数
        "Driver": "overlay2", #存储驱动,联合文件系统
        "Platform": "linux", # 运行平台
        "MountLabel": "",#挂载标签
        "ProcessLabel": "",#进程标签
        "AppArmorProfile": "", #Linux内核中的强制访问控制系统配置文件
        "ExecIDs": null, #当前容器正在执行 exec的 ID,多个用数组展示
		#主机配置
        "HostConfig": {
			#容器宿主目录绑定
            "Binds": [
                "/home/mysql8/conf/my.cnf:/etc/mysql/my.cnf",
                "/home/mysql8/logs:/logs",
                "/home/mysql8/data:/var/lib/mysql",
                "/etc/localtime:/etc/localtime"
            ],
            "ContainerIDFile": "", #???
			#日志配置
            "LogConfig": {
                "Type": "json-file", #文件类型 json
                "Config": {}
            },
            "NetworkMode": "default", #网络模式
			#端口绑定信息
            "PortBindings": {
                "3306/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "3306"
                    }
                ]
            },
			#重启策略
            "RestartPolicy": {
                "Name": "unless-stopped",#自动重启类似always
                "MaximumRetryCount": 0 #最大重试次数
            },
            "AutoRemove": false, #自动移除
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": true,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": [
                "label=disable"
            ],
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": null,
            "ReadonlyPaths": null
        },
        #镜像管理驱动
        "GraphDriver": {
        #联合系统分层信息
            "Data": {
            #镜像层,目录或者文件是只读的
                "LowerDir":  "/var/lib/docker/overlay2/77f1db351358d953cb1fe55a79e84597d3cbc3844c2dd249a2acdfa15e402627-init/diff:/var/lib/docker/overlay2/b261e67d747a7a769d143f6d4bc9492684b17680256cdf5962f8145acb6b3dab/diff:/var/lib/docker/overlay2/e88c8d60eec4dee423f121636d8b7a560fe2b4739c6c2361d90e290799989120/diff:/var/lib/docker/overlay2/d8f81e30c57461476828fa01d7faad6cc96f893e55684fabf02bf804f76ca2e8/diff:/var/lib/docker/overlay2/b04b2325906657684ef7914d1834a0e510fc7065c78287ce066b0dd5667273c3/diff:/var/lib/docker/overlay2/f09dec6179a52989205fd2931b31996515e06b8048b139f7cc87982df2f497ad/diff:/var/lib/docker/overlay2/c0eab9ee7da29584d4583dd66199346582f1036f69f9989b7da5f8e72f0fa992/diff:/var/lib/docker/overlay2/2a28cd4140717faa03275c600bae785a8a4b0131337bf04267e000f8569aa0f7/diff:/var/lib/docker/overlay2/733a014a49863d79ffb0d86655d8e3b3ceb4a515266e50c09b6cf02d8f81c9c3/diff:/var/lib/docker/overlay2/5da96f62c2672a8590cb920cf541bc3ac636f1aca7babb540d49316c72e7d74a/diff:/var/lib/docker/overlay2/cdf557bd933d8f3809eb2a4b493f376d81e64ee14d0adbd8a74b57d071f63fd6/diff:/var/lib/docker/overlay2/80e0b0ba180d6736e659f56192c214c95d433e59f0aa6d79bfe66d52fb3c7b73/diff:/var/lib/docker/overlay2/4935d32e3ec461a85af88a19fef5872312b4c43a5adf43848b1f3e25353b7ac8/diff",
                #容器的挂载点
                "MergedDir": "/var/lib/docker/overlay2/77f1db351358d953cb1fe55a79e84597d3cbc3844c2dd249a2acdfa15e402627/merged",
                #读写层,在启动一个容器时候会进行创建,所有的对容器数据更改都发生在这里层,upperdir是可读可写的
                "UpperDir": "/var/lib/docker/overlay2/77f1db351358d953cb1fe55a79e84597d3cbc3844c2dd249a2acdfa15e402627/diff",
                #工作目录
                "WorkDir": "/var/lib/docker/overlay2/77f1db351358d953cb1fe55a79e84597d3cbc3844c2dd249a2acdfa15e402627/work"
            },
            "Name": "overlay2"
        },
        #挂载配置
        "Mounts": [
            {
                "Type": "bind", #类型
                "Source": "/home/mysql8/logs", #来源目录
                "Destination": "/logs", #容器目录
                "Mode": "", #模式
                "RW": true, #读写权限
                "Propagation": "rprivate" 
                 #挂载目录实时更新模式 shared、slave、private、rshared、rslave、rprivate
            },
            {
                "Type": "bind",
                "Source": "/home/mysql8/data",
                "Destination": "/var/lib/mysql",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/etc/localtime",
                "Destination": "/etc/localtime",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/home/mysql8/conf/my.cnf",
                "Destination": "/etc/mysql/my.cnf",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "572219d3a0ca", #容器缩写id
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
             #暴露端口
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
             #环境变量配置
            "Env": [
                "MYSQL_ROOT_PASSWORD=431557313",
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.27-1debian10"
            ],
            #设置容器的默认执行的命令,不可以追加命令
            "Cmd": [
                "mysqld"
            ],
            #镜像名 服务名+tag版本
            "Image": "mysql:8.0.27",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            #工作目录
            "WorkingDir": "",
            #设置容器的默认执行的命令,可以追加命令
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,#Dockerfile文件构建
            "Labels": {}
        },
       	#网络设置
 	    "NetworkSettings": {
            "Bridge": "", #网桥
            "SandboxID": "9d8795184ee28e903bb503b42519d5f56a622977f49e4255e771dfcb1c8bdaf3",#沙箱id
            "HairpinMode": false, #是否开启发卡模式
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            #端口映射配置
            "Ports": {
                "3306/tcp": [
                    {
                        "HostIp": "0.0.0.0", 
                        "HostPort": "3306"
                    },
                    {
                        "HostIp": "::", #外网访问
                        "HostPort": "3306" #暴露端口
                    }
                ],
                "33060/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/9d8795184ee2", #沙盒密钥路径
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "826898658eec96e305763ce63e6505c4c0e5d152872bf8ae517f73371a8d015e",
            "Gateway": "172.17.0.1", #网关地址
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:03", #MAC地址
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "376cfaed3501614c09972655643d3d974e434548773d140c0040d9c268294e51",
                    "EndpointID": "826898658eec96e305763ce63e6505c4c0e5d152872bf8ae517f73371a8d015e",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }
            }
        }
    }
]

上面这份配置信息还是可以看到不少内容的,建议认真看看。

3.6.3.6 连接到正在运行中的容器 —— docker attch

命令详细说明 https://docs.docker.com/engine/reference/commandline/attach/

我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置。
在这里插入图片描述
连接到我们当前的emqx容器看看:
在这里插入图片描述
进入了容器内部空间。退出容器终端使用命令 ctrl + P + Q。如果输入exit,直接停止容器运行。

3.6.3.7 在运行的容器中执行命令 —— docker exec

使用docker exec命令可以在运行的容器中执行一条命令,通常COMMAND只能是一条语句,为了支持多个命令的执行,需要将多个命令连接起来交给Shell。

命令详细说明 https://docs.docker.com/engine/reference/commandline/exec/

我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置。
在这里插入图片描述

pi@raspberrypi:~ $ sudo docker exec --help

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

Run a command in a running container

Options:
  -d, --detach               Detached mode: run command in the background
      --detach-keys string   Override the key sequence for detaching a container
  -e, --env list             Set environment variables
      --env-file list        Read in a file of environment variables
  -i, --interactive          Keep STDIN open even if not attached
      --privileged           Give extended privileges to the command
  -t, --tty                  Allocate a pseudo-TTY
  -u, --user string          Username or UID (format: <name|uid>[:<group|gid>])
  -w, --workdir string       Working directory inside the container

在这里插入图片描述

3.6.3.8 容器与主机之间的数据拷贝 —— docker cp

命令详细说明 https://docs.docker.com/engine/reference/commandline/cp/

在这里插入图片描述

  • 把一个 hostFile.txt 文件从主机拷贝到容器内
pi@raspberrypi:~ $ sudo touch hostFile.txt
pi@raspberrypi:~ $ ls -al
total 112
drwxr-xr-x 18 pi   pi   4096 Nov 11 04:44 .
drwxr-xr-x  3 root root 4096 Sep 22 02:02 ..
-rw-r--r--  1 pi   pi      0 Nov 10 12:29 100
-rw-------  1 pi   pi   9864 Nov 11 04:26 .bash_history
-rw-r--r--  1 pi   pi    220 Sep 22 01:05 .bash_logout
-rw-r--r--  1 pi   pi   3523 Sep 22 01:05 .bashrc
drwxr-xr-x  2 pi   pi   4096 Sep 22 01:14 Bookshelf
drwxr-xr-x  5 pi   pi   4096 Nov  5 01:14 .cache
drwx------ 10 pi   pi   4096 Nov  8 14:24 .config
drwx------  2 pi   pi   4096 Nov  5 01:11 .cups
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Desktop
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Documents
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Downloads
drwxr-xr-x  2 pi   pi   4096 Nov  8 15:44 frp_0.45.0_linux_arm
-rw-r--r--  1 root root    0 Nov 11 04:44 hostFile.txt
drwxr-xr-x  3 pi   pi   4096 Sep 22 01:14 .local
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Music
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Pictures
-rw-r--r--  1 pi   pi    807 Sep 22 01:05 .profile
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Public
drwx------  2 pi   pi   4096 Nov  8 15:54 .ssh
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Templates
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Videos
drwx------  3 pi   pi   4096 Nov  5 01:10 .vnc
-rw-r--r--  1 pi   pi    165 Nov  8 15:13 .wget-hsts
-rw-------  1 pi   pi     56 Nov 10 15:22 .Xauthority
-rw-------  1 pi   pi   2358 Nov 10 15:22 .xsession-errors
-rw-------  1 pi   pi   2358 Nov  8 16:18 .xsession-errors.old
pi@raspberrypi:~ $ sudo docker ps -a
CONTAINER ID   IMAGE              COMMAND                  CREATED        STATUS          PORTS                                                                                                                                                                                                                                                                                                                     NAMES
e813f9e6a04c   emqx/emqx:4.3.10   "/usr/bin/docker-ent…"   11 hours ago   Up 46 minutes   4369-4370/tcp, 5369/tcp, 6369-6370/tcp, 11883/tcp, 0.0.0.0:1884->1883/tcp, :::1884->1883/tcp, 0.0.0.0:8086->8081/tcp, :::8086->8081/tcp, 0.0.0.0:8087->8083/tcp, :::8087->8083/tcp, 0.0.0.0:8088->8084/tcp, :::8088->8084/tcp, 0.0.0.0:8889->8883/tcp, :::8889->8883/tcp, 0.0.0.0:18084->18083/tcp, :::18084->18083/tcp   emqx-2
pi@raspberrypi:~ $ sudo docker cp hostFile.txt e813f9e6a04c:/
pi@raspberrypi:~ $ sudo docker attach e813f9e6a04c
/opt/emqx $ cd /
/ $ ls -al
total 68
drwxr-xr-x    1 root     root          4096 Nov 11 04:46 .
drwxr-xr-x    1 root     root          4096 Nov 11 04:46 ..
-rwxr-xr-x    1 root     root             0 Nov 10 17:39 .dockerenv
drwxr-xr-x    1 root     root          4096 Nov 12  2021 bin
drwxr-xr-x    5 root     root           340 Nov 11 03:58 dev
drwxr-xr-x    1 root     root          4096 Nov 10 17:39 etc
drwxr-xr-x    1 root     root          4096 Nov 12  2021 home
-rw-r--r--    1 root     root             0 Nov 11 04:44 hostFile.txt
drwxr-xr-x    1 root     root          4096 Aug 31  2021 lib
drwxr-xr-x    5 root     root          4096 Aug 31  2021 media
drwxr-xr-x    2 root     root          4096 Aug 31  2021 mnt
drwxr-xr-x    1 root     root          4096 Nov 12  2021 opt
dr-xr-xr-x  263 root     root             0 Nov 11 03:58 proc
drwx------    2 root     root          4096 Aug 31  2021 root
drwxr-xr-x    1 root     root          4096 Nov 12  2021 run
drwxr-xr-x    2 root     root          4096 Aug 31  2021 sbin
drwxr-xr-x    2 root     root          4096 Aug 31  2021 srv
dr-xr-xr-x   12 root     root             0 Nov 11 03:58 sys
drwxrwxrwt    2 root     root          4096 Aug 31  2021 tmp
drwxr-xr-x    1 root     root          4096 Aug 31  2021 usr
drwxr-xr-x    1 root     root          4096 Nov 12  2021 var
/ $ 

  • 把一个emqxFile.txt文件从容器内拷贝到主机
pi@raspberrypi:~ $ sudo docker cp e813f9e6a04c:/emqxFile.txt /
pi@raspberrypi:~ $ ls -al
total 112
drwxr-xr-x 18 pi   pi   4096 Nov 11 04:44 .
drwxr-xr-x  3 root root 4096 Sep 22 02:02 ..
-rw-r--r--  1 pi   pi      0 Nov 10 12:29 100
-rw-------  1 pi   pi   9864 Nov 11 04:26 .bash_history
-rw-r--r--  1 pi   pi    220 Sep 22 01:05 .bash_logout
-rw-r--r--  1 pi   pi   3523 Sep 22 01:05 .bashrc
drwxr-xr-x  2 pi   pi   4096 Sep 22 01:14 Bookshelf
drwxr-xr-x  5 pi   pi   4096 Nov  5 01:14 .cache
drwx------ 10 pi   pi   4096 Nov  8 14:24 .config
drwx------  2 pi   pi   4096 Nov  5 01:11 .cups
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Desktop
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Documents
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Downloads
drwxr-xr-x  2 pi   pi   4096 Nov  8 15:44 frp_0.45.0_linux_arm
-rw-r--r--  1 root root    0 Nov 11 04:44 hostFile.txt
drwxr-xr-x  3 pi   pi   4096 Sep 22 01:14 .local
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Music
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Pictures
-rw-r--r--  1 pi   pi    807 Sep 22 01:05 .profile
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Public
drwx------  2 pi   pi   4096 Nov  8 15:54 .ssh
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Templates
drwxr-xr-x  2 pi   pi   4096 Sep 22 02:02 Videos
drwx------  3 pi   pi   4096 Nov  5 01:10 .vnc
-rw-r--r--  1 pi   pi    165 Nov  8 15:13 .wget-hsts
-rw-------  1 pi   pi     56 Nov 10 15:22 .Xauthority
-rw-------  1 pi   pi   2358 Nov 10 15:22 .xsession-errors
-rw-------  1 pi   pi   2358 Nov  8 16:18 .xsession-errors.old
pi@raspberrypi:~ $ cd /
pi@raspberrypi:/ $ ls -al
total 76
drwxr-xr-x  18 root root  4096 Nov 11 04:49 .
drwxr-xr-x  18 root root  4096 Nov 11 04:49 ..
lrwxrwxrwx   1 root root     7 Sep 22 01:02 bin -> usr/bin
drwxr-xr-x   4 root root  4096 Jan  1  1970 boot
drwxr-xr-x  16 root root  3900 Nov 10 15:22 dev
-rw-r--r--   1 root root     0 Nov 11 04:48 emqxFile.txt
drwxr-xr-x 133 root root 12288 Nov 10 15:07 etc
drwxr-xr-x   3 root root  4096 Sep 22 02:02 home
lrwxrwxrwx   1 root root     7 Sep 22 01:02 lib -> usr/lib
drwx------   2 root root 16384 Sep 22 01:59 lost+found
drwxr-xr-x   3 root root  4096 Nov  5 03:00 media
drwxr-xr-x   2 root root  4096 Sep 22 01:02 mnt
drwxr-xr-x   6 root root  4096 Nov  9 15:03 opt
dr-xr-xr-x 261 root root     0 Jan  1  1970 proc
drwx------   5 root root  4096 Nov  8 14:41 root
drwxr-xr-x  31 root root   940 Nov 11 01:11 run
lrwxrwxrwx   1 root root     8 Sep 22 01:02 sbin -> usr/sbin
drwxr-xr-x   2 root root  4096 Sep 22 01:02 srv
dr-xr-xr-x  12 root root     0 Jan  1  1970 sys
drwxrwxrwt  16 root root  4096 Nov 11 04:26 tmp
drwxr-xr-x  11 root root  4096 Sep 22 01:02 usr
drwxr-xr-x  11 root root  4096 Sep 22 02:02 var
pi@raspberrypi:/ $ 

3.6.4 命令小结

除了一些常用命令以外,docker还有不少其他命令,这里引用一个网上图片。
在这里插入图片描述

4. 开机自启动docker

  • 设置开机自启动

sudo systemctl enable docker

在这里插入图片描述

5. 容器网络 —— docker run --net

docker --net详解_Docker网络通信

docker run创建Docker容器时,可以用 --net 选项指定容器的网络模式 :

host模式:使用 --net=host 指定。
none模式:使用 --net=none 指定。
bridge模式:使用 --net=bridge 指定,默认设置。host模式不能使用端口映射和自定义路由规则,这些都与主机一致,-p 与-icc 参数是无效的。
container模式:使用 --net=container:NAME_or_ID 指定

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启动docker engine后,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。
在这里插入图片描述
在这里插入图片描述

为了实现上述功能,docker主要用到了linux的BridgeNetwork Namespace、VETH (虚拟网卡的接口对 Virtual Enternet device)。

  • docker0网关就是通过Bridge实现的。
  • Network Namespace是网络命名空间,通过Network Namespace可以建立一些完全隔离的网络栈。
    比如通过docker network create xxx就是在建立一个Network Namespace。
  • VETH是虚拟网卡的接口对,可以把两端分别接在两个不同的Network Namespace中,实现两个原本隔离的Network Namespace的通信。

所以总结起来就是:

Network Namespace做了容器和宿主机的网络隔离,
Bridge分别在容器和宿主机建立一个网关,
然后再用VETH将容器和宿主机两个网络空间连接起来。

这里也有参考文档

Linux network namespace, veth, birdge与路由

  • Network namespace允许你在Linux中创建相互隔离的网络视图,每个网络名字空间都有自己独立的网络配置,包括:网络设备、路由表、IPTables规则,路由表、网络协议栈等。新建的网络名字空间与主机默认网络名字空间之间是隔离的。我们平时默认操作的是主机的默认网络名字空间。由于network namespace隔离了网络相关的全局资源,因此从网络角度来看,一个network namespace可以看做一个独立的虚机;即使在同一个主机上创建的两个network namespace,相互之间缺省也是不能进行网络通信的。
  • veth和tap/tun类似,也是linux提供的一种虚拟网络设备;但与tap/tun不同的是,veth总是成对出现的,从一端进入的数据包将会在另一端出现,因此又常常称为veth pair。我们可以把veth pair看成一条网线两端连接的两张以太网卡。veth提供了一种连接两个network namespace的方法。如果我们把上图中网线两端的网卡分别放入两个不同的network namespace,就可以把这两个network namespace连起来,形成一个点对点的二层网络。
  • veth实现了点对点的虚拟连接,可以通过veth连接两个namespace,如果我们需要将3个或者多个namespace接入同一个二层网络时,就不能只使用veth了。在物理网络中,如果需要连接多个主机,我们会使用网桥,或者又称为交换机。Linux也提供了网桥的虚拟实现。
+---------------------------------------------------------------------------------------+
|                                       Linux Host                                      |
|                                                                                       |
|  +--------------------------------------+   +--------------------------------------+  |
|  |  network namespace1                  |   |  network namespace1                  |  |
|  | +---------------+  +---------------+ |   | +---------------+  +---------------+ |  |
|  | |network devices|  |  route table  | |   | |network devices|  |  route table  | |  |
|  | +---------------+  +---------------+ |   | +---------------+  +---------------+ |  |
|  | +---------------+  +---------------+ |   | +---------------+  +---------------+ |  |
|  | |    iptables   |  |protocol stack | |   | |    iptables   |  |protocol stack | |  |
|  | +---------------+  +---------------+ |   | +---------------+  +---------------+ |  |
|  +--------------------------------------+   +--------------------------------------+  |
|                                                                                       |
|                       +--------------------------------------+                        |
|                       |        default network namespace     |                        |
|                       | +---------------+  +---------------+ |                        |
|                       | |network devices|  |  route table  | |                        |
|                       | +---------------+  +---------------+ |                        |
|                       | +---------------+  +---------------+ |                        |
|                       | |    iptables   |  |protocol stack | |                        |
|                       | +---------------+  +---------------+ |                        |
|                       +--------------------------------------+                        |
|                                                                                       |
+---------------------------------------------------------------------------------------+
+------------------+              +------------------+
|        ns1       |              |      ns2         |
|                  |  veth pair   |                  |
|                +-+              +-+                |
| 192.168.1.1/24 | +--------------+ | 192.168.1.2/24 |
|   (veth-ns1)   +-+              +-+   (veth-ns2)   |
|                  |              |                  |
|                  |              |                  |
|                  |              |                  |
+------------------+              +------------------+
+------------------+     +------------------+     +------------------+
|                  |     |                  |     |                  |
|                  |     |                  |     |                  |
|                  |     |                  |     |                  |
|       ns1        |     |       ns2        |     |       ns3        |
|                  |     |                  |     |                  |
|                  |     |                  |     |                  |
|                  |     |                  |     |                  |
|  192.168.1.1/24  |     |  192.168.1.2/24  |     |  192.168.1.3/24  |
+----(veth-ns1)----+     +----(veth-ns2)----+     +----(veth-ns3)----+
        +                          +                        +
        |                          |                        |
        |                          |                        |
        +                          +                        +
+--(veth-ns1-br)-------------(veth-ns2-br)------------(veth-ns3-br)--+
|                                                                    |
|                           linux-bridge                             |
|                                                                    |
+--------------------------------------------------------------------+

6. 实战1:docker安装 HomeAssistant —— 智能控制

目标镜像:https://hub.docker.com/r/homeassistant/home-assistant/tags

在这里插入图片描述

6.1 下载镜像

这里我们挑选一个stable稳定版本。
在这里插入图片描述

pi@raspberrypi:~ $ sudo docker pull homeassistant/home-assistant:stable
stable: Pulling from homeassistant/home-assistant
c6556b3b6858: Pull complete 
985a6d05ce0a: Pull complete 
f2c4a4de1e04: Pull complete 
9589c15cda36: Pull complete 
9b9814a4c4e2: Pull complete 
50d309160e30: Pull complete 
029da9f8d762: Waiting 
20d619833a50: Download complete 
3fe0a80a017c: Waiting 
32ad3e20ad79: Download complete 
4f4fb700ef54: Downloading 
92a4ad932391: Waiting 
5acd8c703a15: Waiting 
74f4dda5b878: Waiting 
94038e451e91: Waiting 
1fbbfa337b2e: Waiting 
eb5e59cf8164: Waiting 
defc880aaafc: Waiting 
ec47bcda73cf: Waiting 
e1c0f6097382: Waiting 
85e78e4d4ab0: Waiting 
cf621c15cfc8: Waiting 
5bd681e8bc73: Waiting 
286cffa1f2c1: Waiting 
182504b1686c: Waiting 
de061c9c972f: Waiting 
114297378fee: Waiting 
3ebc4990b899: Waiting 
stable: Pulling from homeassistant/home-assistant
c6556b3b6858: Pull complete 
985a6d05ce0a: Pull complete 
f2c4a4de1e04: Pull complete 
9589c15cda36: Pull complete 
9b9814a4c4e2: Pull complete 
50d309160e30: Pull complete 
029da9f8d762: Pull complete 
20d619833a50: Pull complete 
3fe0a80a017c: Pull complete 
32ad3e20ad79: Pull complete 
4f4fb700ef54: Pull complete 
92a4ad932391: Pull complete 
5acd8c703a15: Pull complete 
74f4dda5b878: Pull complete 
94038e451e91: Pull complete 
1fbbfa337b2e: Pull complete 
eb5e59cf8164: Pull complete 
defc880aaafc: Pull complete 
ec47bcda73cf: Pull complete 
e1c0f6097382: Pull complete 
85e78e4d4ab0: Pull complete 
cf621c15cfc8: Pull complete 
5bd681e8bc73: Pull complete 
286cffa1f2c1: Pull complete 
182504b1686c: Pull complete 
de061c9c972f: Pull complete 
114297378fee: Pull complete 
3ebc4990b899: Pull complete 
Digest: sha256:5e3d2dde141812a4a54c140f3cbf52b9c74168bf25e8560978f499578902a363
Status: Downloaded newer image for homeassistant/home-assistant:stable
docker.io/homeassistant/home-assistant:stable
pi@raspberrypi:~ $ 

6.2 /home/pi/目录下创建一个homeassistant文件夹,挂载容器卷

sudo mkdir homeassistant

在这里插入图片描述
为了方便修改镜像中的配置文件,然后我们就可以直接在宿主机上修改配置,不需要进入到容器里面。

6.3 启动容器

输入命令

docker run -d
–name homeassistant
–privileged
–restart=unless-stopped
-e TZ=Asia/Shanghai
-v /home/pi/homeassistant:/config
–network=host
homeassistant/home-assistant:stable

这里直接使用host网络模式。

6.4 打开http://树莓派ip:8123/

在这里插入图片描述
如果忘记账号,可以查看
在这里插入图片描述

7. 实战2:docker安装 portainer —— 可视化管理Docker镜像容器

Portainer 是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。

目标镜像:https://hub.docker.com/r/portainer/portainer-ce/tags 社区版本

在这里插入图片描述

7.1 下载镜像

docker命令:

sudo docker pull portainer/portainer-ce:linux-arm

pi@raspberrypi:~/homeassistant/.storage $ sudo docker pull portainer/portainer-ce:linux-arm
linux-arm: Pulling from portainer/portainer-ce
772227786281: Downloading 
96fd13befc87: Downloading 
3199d8e66404: Download complete 
69ad73a13c4b: Download complete 
linux-arm: Pulling from portainer/portainer-ce
772227786281: Pull complete 
96fd13befc87: Pull complete 
3199d8e66404: Pull complete 
69ad73a13c4b: Pull complete 
Digest: sha256:6d20b5b53c6edcf2594eb01ee1e68cddc172b864ede84a3bd48b6bcf3b9e7cbf
Status: Downloaded newer image for portainer/portainer-ce:linux-arm
docker.io/portainer/portainer-ce:linux-arm
pi@raspberrypi:~/homeassistant/.storage $ 

7.2 /home/pi/目录下创建一个portainer文件夹,挂载容器卷

sudo mkdir portainer

在这里插入图片描述

7.3 启动容器

docker命令

sudo docker run -p 9000:9000 -p 8000:8000 --name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /home/pi/portainer:/data \
-d portainer/portainer-ce:linux-arm
 

在这里插入图片描述

7.4 打开http://树莓派ip:9000/

第一次登录的时候需要创建管理员账号。
在这里插入图片描述
在这里插入图片描述
有一个本地的Docker环境,可以看到Docker环境的概览信息,比如运行了几个容器,有多少个镜像等;
在这里插入图片描述
在这里插入图片描述
打开Containers菜单,可以看到当前创建的容器,我们可以对容器进行运行、暂停、删除等操作;
在这里插入图片描述
还可以看到容器元信息
在这里插入图片描述
当然还可以看到日志信息
在这里插入图片描述
点击Stats按钮,可以查看容器的内存、CPU及网络的使用情况,性能分析。
在这里插入图片描述

8. 总结

从0到1搭建docker环境,顺便安装一下emqx MQTT Broker、HomeAssistant、portainer。目标还是为了在树莓派上运行成功docker,并把docker的一些好的特性应用到实际开发中。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单片机菜鸟爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值