使用Docker时遇到的坑与解决方法
使用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时遇到的坑与解决方法相关推荐
- Ionic使用常用插件时遇到的坑与解决方法
一. 什么是Ionic Ionic 是一个强大的 HTML5 应用程序开发框架(HTML5 Hybrid Mobile App Framework ). 可以帮助您使用 Web 技术,比如 HTML. ...
- docker pull下载镜像时的报错及其解决方法
docker pull下载镜像时的报错及其解决方法 参考文章: (1)docker pull下载镜像时的报错及其解决方法 (2)https://www.cnblogs.com/it-artical/p ...
- python打包exe 之打包sklearn模型中的各种坑及其解决方法。
之前学习了如何打包,如何建立虚拟环境打包,以及如何带资源打包exe. python打包成exe 可执行文件 .教程 使用pipenv建立虚拟环境解决python打包exe文件过大的问题(附打包带图标, ...
- mysql5.7.20 sql mode_MySQL5.7中的sql_mode默认值带来的坑及解决方法
在正常项目开发过程中,如果MySQL版本从5.6升级到5.7版本.作为DBA在考虑数据库版本升级带来的影响时,一般会有几个注意点: sql_mode optimizer_switch 本文主要内容是M ...
- vue使用marked解析markdown文本遇到的坑及解决方法
vue使用marked解析markdown文本遇到的坑及解决方法 1. 前言 最近在搭建自己的博客网站 https://lyuanzhi.com,不免遇到了要把markdown文本转化为html代码的 ...
- uniapp(小程序) 配置 海康威视-萤石监控(直播替代方案) 踩坑与解决方法
uniapp(小程序) 配置 海康威视-萤石监控(直播替代方案) 踩坑与解决方法 因为公司业务需求需要获取监控的摄像头,萤石是给出了几种方案去实现. 直播接入:萤石开放平台API文档 小程序接入:萤石 ...
- 安装fastdfs的坑还有解决方法
记录一下安装fastdfs的坑还有解决方法,同时也想帮助一些一样错误,但是找不到解决办法的人,这是一篇综合帖子,基本上所有的问题都有解决办法,先别急,先让我们看一下报错信息. >>> ...
- 神舟战神笔记本(Z7M-KP7Z)双系统安装ubuntu 16.04遇到的坑及解决方法
神舟战神笔记本(Z7M-KP7Z)双系统安装ubuntu 16.04遇到的坑及解决方法 1 坑的列表 2 解决方法 1 坑的列表 1 intel 驱动 2 NVIDIA 驱动 3 显示器分辨率 2 解 ...
- Ubuntu18.04配置carla0.9.11踩坑与解决方法总结,同时解决安装carla-ros-bridge遇到的问题,并复现OpenCDA成功与ros关联
Ubuntu18.04配置carla0.9.11踩坑与解决方法总结,同时解决安装carla-ros-bridge遇到的问题,并复现OpenCDA成功与ros关联 背景: 主要是为了复现叶小飞的Open ...
最新文章
- GAITC 2020 演讲实录丨张立华:机器智能的发展现状
- 用友现存量和可用量_护肤品用量不对,不仅变相浪费还有可能……
- Android NDK JNI 的简单使用
- Matplotlib实例教程 | markers表
- 7、Linux中文件类型、文件属性
- git 常用别名设置
- jquery插件 --- 图表 表格
- python参数_python 参数
- C51单片机————中断系统
- 阿里大文娱:不存在“优酷自制团队转入阿里影业”一说
- php 读取多个文件,使用PHPExcel读取多个文件
- steamvr自定义按键_SteamVR SDK更新:带来运动平滑、自定义控制器键等多项功能
- TRNSYS 内区之间通风原理试验
- 代理 傲澜智伴机器人_机器人厂家_智伴机器人代理,莆田智伴机器人,傲澜智伴机器人(查看)_一呼百应网...
- 剩余方差matlab,matlab 统计基本函数 var方差
- ai俄罗斯方块java_俄罗斯方块 AI 算法讲解
- 用优盘装系统看不到计算机本身的硬盘,给电脑装系统!的时候找不到硬盘只能看到u盘数据我怀疑硬盘坏了主机? 爱问知识人...
- 腾讯云 mysql远程访问_远程连接腾讯云的mysql
- uni-app云开发的网盘助手微信小程序源码
- Cemu模拟铁拳TT2高清设置