使用Docker时遇到的坑与解决方法

1. Docker 服务启动串台

使用 docker-compose 命令各自启动两组服务,发现服务会串台!

[问题起因] 在两个不同名称的目录目录下面,使用 docker-compose 来启动服务,发现当 A 组服务启动完毕之后,再启动 B 组服务的时候,发现 A 组当中对应的一部分服务又重新启动了一次,这就非常奇怪了!因为这个问题的存在会导致,A 组服务和 B 组服务无法同时启动。之前还以为是工具的 Bug,后来才知道了原因,恍然大悟。

# 服务目录结构如下所示
A: /data1/app/docker-compose.yml
B: /data2/app/docker-compose.yml

[解决方法] 发现 A 和 B 两组服务会串台的原因,原来是 docker-compose 会给启动的容器加 label 标签,然后根据这些 label 标签来识别和判断对应的容器服务是由谁启动的、谁来管理的,等等。而这里,我们需要关注的 label 变量是 com.docker.compose.project,其对应的值是使用启动配置文件的目录的最底层子目录名称,即上面的 app 就是对应的值。我们可以发现, A 和 B 两组服务对应的值都是 app,所以启动的时候被认为是同一个,这就出现了上述的问题。如果需要深入了解的话,可以去看对应源代码。

# 可以将目录结构调整为如下所示
A: /data/app1/docker-compose.yml
B: /data/app2/docker-compose.ymlA: /data1/app-old/docker-compose.yml
B: /data2/app-new/docker-compose.yml

或者使用 docker-compose 命令提供的参数 -p 手动指定标签,来规避该问题的发生。

# 指定项目项目名称
$ docker-compose -f ./docker-compose.yml -p app1 up -d

2.Docker 命令调用报错

在编写脚本的时候常常会执行 docker 相关的命令,但是需要注意使用细节!

[问题起因] CI 更新环境执行了一个脚本,但是脚本执行过程中报错了,如下所示。通过对应的输出信息,可以看到提示说正在执行的设备不是一个 tty。


随即,查看了脚本发现报错地方是执行了一个 exec 的 docker 命令,大致如下所示。很奇怪的是,手动执行或直接调脚本的时候,怎么都是没有问题的,但是等到 CI 调用的时候怎么都是有问题。后来好好看下,下面这个命令,注意到 -it 这个参数了。

# 脚本调用docker命令
docker exec -it <container_name> psql -Upostgres ......

我们可以一起看下 exec 命令的这两个参数,自然就差不多理解了。

编号 参数 解释说明
1 -i/-interactive 即使没有附加也保持 STDIN 打开;如果你需要执行命令则需要开启这个选项
2 -t/–tty 分配一个伪终端进行执行;一个连接用户的终端与容器 stdin 和 stdout 的桥梁

[解决方法] docker exec 的参数 -t 是指 Allocate a pseudo-TTY 的意思,而 CI 在执行 job 的时候并不是在 TTY 终端中执行,所以 -t 这个参数会报错

3.Docker 定时任务异常

在 Crontab 定时任务中也存在 Docker 命令执行异常的情况!

[问题起因] 今天发现了一个问题,就是在备份 Mysql 数据库的时候,使用 docker 容器进行备份,然后使用 Crontab 定时任务来触发备份。但是发现备份的 MySQL 数据库居然是空的,但是手动执行对应命令切是好的,很奇怪。

# Crontab定时任务
0 */6 * * * \docker exec -it <container_name> sh -c \'exec mysqldump --all-databases -uroot -ppassword ......'

[解决方法] 后来发现是因为执行的 docker 命令多个 -i 导致的。因为 Crontab 命令执行的时候,并不是交互式的,所以需要把这个去掉才可以。总结就是,如果你需要回显的话则需要 -t 选项,如果需要交互式会话则需要 -i 选项。

4.Docker 变量使用引号

compose 里边环境变量带不带引号的问题!

[问题起因] 使用过 compose 的朋友可能都遇到过,在编写启服务启动配置文件的时候,添加环境变量时到底是使用单引号、双引号还是不使用引号的问题?时间长了,我们可能会将三者混用,认为其效果是一样的。但是后来,发现的坑越来越多,才发现其越来越隐晦。

反正我是遇到过很多问题,都是因为添加引号导致的服务启动异常的,后来得出的结论就是一律不使引号。裸奔,体验前所未有的爽快!直到现在看到了 Github 中对应的 issus 之后,才终于破案了。

# 在Compose中进行引用TEST_VAR变量,无法找到
TEST_VAR="test"# 在Compose中进行引用TEST_VAR变量,可以找到
TEST_VAR=test# 后来发现docker本身其实已经正确地处理了引号的使用
docker run -it --rm -e TEST_VAR="test" test:latest

[解决方法] 得到的结论就是,因为 Compose 解析 yaml 配置文件,发现引号也进行了解释包装。这就导致原本的 TEST_VAR=“test” 被解析成了 ‘TEST_VAR=“test”’,所以我们在引用的时候就无法获取到对应的值。现在解决方法就是,不管是我们直接在配置文件添加环境变量或者使用 env_file 配置文件,能不使用引号就不适用引号。

需要注意的是环境变量配置的是日志格式的话(2022-01-01),如果使用的是 Python 的 yaml.load 模块的话,会被当做是 date 类型的,这是如果希望保持原样信息的话,可以使用 '/" 引起来将其变成字符串格式的。

5.Docker 删除镜像报错

无法删除镜像,归根到底还是有地方用到了!

[问题起因] 清理服器磁盘空间的时候,删除某个镜像的时候提示如下信息。提示需要强制删除,但是发现及时执行了强制删除依旧没有效果。

# 删除镜像
$ docker rmi 3ccxxxx2e862
Error response from daemon: conflict: unable to delete 3ccxxxx2e862 (cannot be forced) - image has dependent child images# 强制删除
$ dcoker rmi -f 3ccxxxx2e862
Error response from daemon: conflict: unable to delete 3ccxxxx2e862 (cannot be forced) - image has dependent child images

[解决方法] 后来才发现,出现这个原因主要是因为 TAG,即存在其他镜像引用了这个镜像。这里我们可以使用如下命令查看对应镜像文件的依赖关系,然后根据对应 TAG 来删除镜像。

# 查询依赖 - image_id表示镜像名称
$ docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=<image_id>)# 根据TAG删除镜像
$ docker rmi -f c565xxxxc87f
# 删除悬空镜像
$ docker rmi $(docker images --filter "dangling=true" -q --no-trunc)

6.Docker 普通用户切换

切换 Docker 启动用户的话,还是需要注意下权限问题的!

[问题起因] 我们知道在 Docker 容器里面使用 root 用户的话,是不安全的,很容易出现越权的安全问题,所以一般情况下,我们都会使用普通用户来代替 root 进行服务的启动和管理的。今天给一个服务切换用户的时候,发现 Nginx 服务一直无法启动,提示如下权限问题。因为对应的配置文件也没有配置 var 相关的目录,无奈

使用Docker时遇到的坑与解决方法相关推荐

  1. Ionic使用常用插件时遇到的坑与解决方法

    一. 什么是Ionic Ionic 是一个强大的 HTML5 应用程序开发框架(HTML5 Hybrid Mobile App Framework ). 可以帮助您使用 Web 技术,比如 HTML. ...

  2. docker pull下载镜像时的报错及其解决方法

    docker pull下载镜像时的报错及其解决方法 参考文章: (1)docker pull下载镜像时的报错及其解决方法 (2)https://www.cnblogs.com/it-artical/p ...

  3. python打包exe 之打包sklearn模型中的各种坑及其解决方法。

    之前学习了如何打包,如何建立虚拟环境打包,以及如何带资源打包exe. python打包成exe 可执行文件 .教程 使用pipenv建立虚拟环境解决python打包exe文件过大的问题(附打包带图标, ...

  4. mysql5.7.20 sql mode_MySQL5.7中的sql_mode默认值带来的坑及解决方法

    在正常项目开发过程中,如果MySQL版本从5.6升级到5.7版本.作为DBA在考虑数据库版本升级带来的影响时,一般会有几个注意点: sql_mode optimizer_switch 本文主要内容是M ...

  5. vue使用marked解析markdown文本遇到的坑及解决方法

    vue使用marked解析markdown文本遇到的坑及解决方法 1. 前言 最近在搭建自己的博客网站 https://lyuanzhi.com,不免遇到了要把markdown文本转化为html代码的 ...

  6. uniapp(小程序) 配置 海康威视-萤石监控(直播替代方案) 踩坑与解决方法

    uniapp(小程序) 配置 海康威视-萤石监控(直播替代方案) 踩坑与解决方法 因为公司业务需求需要获取监控的摄像头,萤石是给出了几种方案去实现. 直播接入:萤石开放平台API文档 小程序接入:萤石 ...

  7. 安装fastdfs的坑还有解决方法

    记录一下安装fastdfs的坑还有解决方法,同时也想帮助一些一样错误,但是找不到解决办法的人,这是一篇综合帖子,基本上所有的问题都有解决办法,先别急,先让我们看一下报错信息. >>> ...

  8. 神舟战神笔记本(Z7M-KP7Z)双系统安装ubuntu 16.04遇到的坑及解决方法

    神舟战神笔记本(Z7M-KP7Z)双系统安装ubuntu 16.04遇到的坑及解决方法 1 坑的列表 2 解决方法 1 坑的列表 1 intel 驱动 2 NVIDIA 驱动 3 显示器分辨率 2 解 ...

  9. Ubuntu18.04配置carla0.9.11踩坑与解决方法总结,同时解决安装carla-ros-bridge遇到的问题,并复现OpenCDA成功与ros关联

    Ubuntu18.04配置carla0.9.11踩坑与解决方法总结,同时解决安装carla-ros-bridge遇到的问题,并复现OpenCDA成功与ros关联 背景: 主要是为了复现叶小飞的Open ...

最新文章

  1. GAITC 2020 演讲实录丨张立华:机器智能的发展现状
  2. 用友现存量和可用量_护肤品用量不对,不仅变相浪费还有可能……
  3. Android NDK JNI 的简单使用
  4. Matplotlib实例教程 | markers表
  5. 7、Linux中文件类型、文件属性
  6. git 常用别名设置
  7. jquery插件 --- 图表 表格
  8. python参数_python 参数
  9. C51单片机————中断系统
  10. 阿里大文娱:不存在“优酷自制团队转入阿里影业”一说
  11. php 读取多个文件,使用PHPExcel读取多个文件
  12. steamvr自定义按键_SteamVR SDK更新:带来运动平滑、自定义控制器键等多项功能
  13. TRNSYS 内区之间通风原理试验
  14. 代理 傲澜智伴机器人_机器人厂家_智伴机器人代理,莆田智伴机器人,傲澜智伴机器人(查看)_一呼百应网...
  15. 剩余方差matlab,matlab 统计基本函数 var方差
  16. ai俄罗斯方块java_俄罗斯方块 AI 算法讲解
  17. 用优盘装系统看不到计算机本身的硬盘,给电脑装系统!的时候找不到硬盘只能看到u盘数据我怀疑硬盘坏了主机? 爱问知识人...
  18. 腾讯云 mysql远程访问_远程连接腾讯云的mysql
  19. uni-app云开发的网盘助手微信小程序源码
  20. Cemu模拟铁拳TT2高清设置

热门文章

  1. 【转载】一文总结学习 Python 的 14 张思维导图
  2. 国庆将至,我已经为你想好了文案
  3. markdown笔记(源码)
  4. 前端性能检测Performance
  5. android手机通讯录备份还原代码,安卓手机误删联系人恢复及备份技巧总汇
  6. java调用datastage_Datastage重启服务
  7. 基于百度翻译API和python的批量地名翻译的实现
  8. 使用eclipse搭建Python开发环境
  9. java:Cassandra入门与实战——中
  10. 历数微软迈向成功的重大历史事件