Featured image of post 容器(6):使用Docker时的一些误区、坏习惯和问题

容器(6):使用Docker时的一些误区、坏习惯和问题

使用Docker时的一些误区、坏习惯和问题

缘起

这是关于docker容器的第六篇文章,这个系列的其他文章链接如下:

在用了这么长时间docker之后,通过跟ChatGPT的交流,我从最开始几乎不懂docker的运行逻辑,到现在比较熟练地使用docker,渐渐发现了之前的一些误区和坏习惯。为了避免其他人也犯同样的错误,我决定把这些误区和坏习惯记录下来,供大家参考。之后再遇到什么问题也将继续在这里更新。

误区

1. Docker与容器的关系

最开始时我以为Docker和容器是同一个概念,但实际上容器是一个更广泛的概念,Docker只是实现容器化的一种工具。正是Docker的出现,才让容器化变得如此简单和流行,可以说Docker是容器化的代表。

然而,Docker并不是唯一的容器化工具,还有其他一些工具和平台也可以实现容器化,比如Podman、LXC、rkt等。它们各自有自己的优缺点和适用场景,但Docker无疑是目前最流行和最成熟的容器化工具。我之前在从源码编译Proton时曾简单用过Podman,但没有深入了解过它的使用方法和原理,所以这里就不展开了。以后如果深入使用Podman或其他容器化工具时,我会发布相关的文章。

2. Docker的安装

我之前在安装Docker时,使用的是apt install docker命令,这种方式安装的Docker是Ubuntu官方源中的Docker版本,可能不是最新的版本。而且这种方式安装的Docker可能会缺少一些功能或特性,因为它是由Ubuntu官方维护的,而不是Docker官方维护的。

为了使用最新的Docker版本和功能,建议的安装方式是使用Docker官方社区源提供的Docker,具体可以参见官方文档。一般来说,安装流程如下(以Ubuntu为例):

  1. 卸载旧版本的Docker

    1
    
    sudo apt-get remove docker docker-engine docker.io containerd runc
    
  2. 安装依赖项

    1
    2
    3
    4
    5
    6
    
    sudo apt-get update
    sudo apt-get install \
        ca-certificates \
        curl \
        gnupg \
        lsb-release
    
  3. 添加Docker官方社区源

    1
    2
    3
    
    echo "deb [arch=$(dpkg --print-architecture) ] https://download.docker.com/linux/ubuntu \
        $(lsb_release -cs) \
        stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
  4. 安装Docker

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

3. docker-composedocker compose

我在第一篇文章容器(1):容器相关知识简介——容器化、docker、docker-compose、Kubernetes / K8s等中就提到了docker-composedocker compose的区别。当时我的建议是使用docker-compose,它是一个独立的命令行工具。这是因为我之前在使用docker compose创建某个容器时,无论如何都不成功,最后还是使用docker-compose创建的容器成功了。忘了具体原因是什么了,但我当时的确是遇到了问题。

后来发现docker-compose并非由Docker官方维护,Docker官方维护的是作为docker插件的docker compose。而且docker compose的更新速度更快,支持的功能也更多。所以现在我建议使用docker compose,而不是docker-compose

坏习惯

1. Docker数据

之前我没有搞懂Docker中几种不同数据卷的区别,导致数据管理比较混乱。为了避免容器出问题时不会相互相应,或者方便地清理不用的容器,我的做法是为每一个容器创建一个单独的分区,这个容器的所有数据都放在这个分区里。这样做的好处是可以很方便地清理不用的容器,只需要删除这个分区即可。但是这样做的坏处是会浪费很多空间,因为每个分区都需要一定的空间来存放数据,而实际上这些分区中的数据可能并不多。例如给某个容器分配了20G的空间,但实际上这个容器只用了1G的空间,这样就浪费了19G的空间。

后来在理解了Docker中各种不同的数据卷之后(具体可参见本系列第三篇文章容器(3):docker最佳实践指南——数据卷volume的管理),我开始使用新的方案:

  • 将所有容器的docker配置文件(如docker-compose.yml和各种config.yml文件)放在一个目录下,便于使用git管理。
  • 将所有容器需要持久化的数据放在一个大容量的硬盘或者分区中,这样既防止占用过多系统空间,又不会浪费空间。

2. Docker镜像管理

以前我在使用Docker时,虽然养成了使用docker-compose.yml文件来管理容器的好习惯,但习惯性地使用latest标签来拉取最新的镜像。这样做的坏处就是时间长了就忘记了之前拉取的镜像是什么版本了,如果过的时间比较长,镜像跨过了较多的版本,再更新时很可能更新失败。而且用latest标签也很难意识到镜像的版本更没更新。

所以后来我开始在docker-compose.yml文件中指定镜像的版本号,例如:

1
2
3
4
version: '3'
services:
  nginx:
    image: nginx:1.23.3

这样做的好处是可以清晰地知道当前使用的镜像版本号,对比官方新发布的镜像版本号,就知道差了多少个版本了。这样在更新时就可以有针对性地更新了。

另外,我最近还开始使用WUD(What’s Up Docker)来监测容器的更新情况,具体可参见本系列第五篇文章容器(5):docker最佳实践指南——容器更新监测工具WUD(What’s Up Docker)

3. Docker的权限

我最开始使用Docker时,使用的是Ubuntu社区源中的Docker版本,安装时没有添加当前用户到docker组中,所以每次使用Docker时都需要加上sudo命令。后来开始使用docker-compose,依然需要加上sudo命令才能正确运行,否则会提示没有读写权限。

后来我意识到了这个问题,新建了一个docker组,并将当前用户添加到docker组中。这样就可以在不使用sudo命令的情况下运行Docker了。

1
2
sudo groupadd docker
sudo usermod -aG docker $USER

记得登出后再重新登录,或者运行

1
newgrp docker

以后再使用docker或者docker compose命令时,就不需要加上sudo命令了。

comments powered by Disqus