Docker踩坑,又涨知识了

背景

新上线一个批处理功能,基于Docker发布的。上线之后出现一个问题,Docker批处理生成文件目录,别的应用程序无法访问。

之前也在使用Docker,但并未涉及到文件共享的问题,还真没留意到。经过一系列排查,终于找到原因。这篇文章就记录一下排查过程中使用到的技术点,也帮大家重温一下。

涉及的知识点:Docker help命令、Linux用户/组id查看、Docker用户指定、Docker启动失败日志查看等

现象分析

Docker运行的项目定时创建文件目录并进行文件生成等操作,但当其他应用程序来操作Docker应用生成的目录时,会提示“Permission denied”错误

查看Docker生成文件夹权限,竟然是以root用户创建的。执行Docker的启动脚本明明是普通用户生成文件怎么就变成了root用户了?

这里就涉及到通过Docker执行执行时所使用的用户了。如果在执行Docker执行命令时,未指定所使用的用户认以root用户执行。在这生产环境下当然是不允许的了。

问题解决

既然找到问题的原因解决起来就比较容易了,下面记录一下解决问题及涉及到的一些Docker命令和Linux操作。

查询帮助文档

先来通过help命令查看一下Docker的命令参数,如何来指定执行命令的用户

先尝试了docker --help命令,结果并未找到指定用户的命令参数:

$ sudo docker --help

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default "/root/.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 "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v,--version            Print version information and quit

后来才意识到,查找的应该是docker的run命令的帮助文档:

$ sudo docker run --help
...
  -u,--user string                    Username or UID (format: <name|uid>[:<group|gid>])
      --userns string                  User namespace to use
      --uts string                     UTS namespace to use
...

其中便有指定run命令操作的所属用户参数,通过-u可指定执行命令的用户和组。

docker指定用户

参照帮助手册,整理了docker的运行命令(伪代码):

$ sudo docker run -itd -u testuser -p 8080:8080 -v /log/:/log xxx-job:latest

上述指令中通过-u username指定了执行命令的用户,按理说可以正常执行的,但执行时抛出了以下异常信息

docker: Error response from daemon: unable to find user testuser: no matching entries in passwd file.'

虽然当前用户是testuser,但docker貌似并未在passwd文件中找到它,此时直接通过用户的UID来替换Username。

获得Linux用户UID

获得Linux用户的UID有两种方法

方法一:执行命令。

获得UID命令:

$ id -u
1002

当前用户的UID便是1002。

获得组ID命令:

$ id -g
1002

当前用户所属组ID便是1002。

方法二:查看/etc/passwd获取UID和组ID。

执行cat /etc/passwd命令,显示/etc/passwd中的内容

图片来源于网络

在/etc/passwd中找到当前用户后面对应的UID和组ID。

调整Docker命令

获得了当前用户的UID和组ID之后,Docker运行命令修改如下:

$ sudo docker run -itd -u 1002:1002 -p 8080:8080 -v /log/:/log xxx-job:latest

正常来说,问题到此便解决了,可正常启动应用程序。

Docker日志查看

但笔者又遇到另外一个问题,就是Docker中应用的日志,由于之前的失误认通过root用户创建的,此时使用了testuser来启动应用程序,发现Docker无法启动,原因很简单testuser启动的应用无法向root创建的日志文件写日志。

排查启动失败时用到了查看Docker失败日志的命令:

docker logs 97069f94437b

此时,或将原来的日志备份,让系统重新生成日志文件,或直接修改日志文件权限为testuser即可。

至此,关于Docker生成目录权限问题解决完毕。

小结

其实,导致上面问题的原因很小,就是漏了一个参数的事。但不经一事,不长一智。可能很多朋友在使用Docker的过程中可能都没留意到这一问题。

而问题的排查过程也很有意思,不仅涉及到了Docker的操作命令,也涉及到了Linux的一些基础知识,知识和技能就是在出现问题、解决问题的过程中增长的。

解决了上述问题之后,不仅感慨“纯学究式的技术学习,终究还是有缺陷的,必须实践,必须临床实践!

原文地址:https://hello.blog.csdn.net" target="_blank" rel="noopener" title="程序新视界">程序新视界</a> <img class="article-time-img article-heard-img" src="https://csdnimg.cn/release/blogv2/dist/pc/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


docker 查看容器内的进程的操作命令 docker top:查看指定容器中所有正在运行的进程1.直接查看容器内的运行进程
docker network connect 网络ID 容器ID。注意:请使用第三步返回的容器ID替换命令中的【容器ID】,使用第二步中的IP Address替换命令中的【容器IP】。注意:请使用第一步返回的网络ID替换命令中的【网络ID】,使用第三步返回的容器ID替换命令中的容器ID。说明:当容器使用host网络模型,容器和宿主机共享网络命名空间,因此网络信息完全一致。注意:请使用前一步返回的网络ID替换命令中的【网络ID】。④验证第三步中的容器和第二步中的容器互通性。如图所示,返回网络ID。
但笔者又遇到另外一个问题,就是Docker中应用的日志,由于之前的失误默认通过root用户创建的,此时使用了testuser来启动应用程序,发现Docker无法启动,原因很简单testuser启动的应用无法向root创建的日志文件写日志。而问题的排查过程也很有意思,不仅涉及到了Docker的操作命令,也涉及到了Linux的一些基础知识,知识和技能就是在出现问题、解决问题的过程中增长的。既然找到问题的原因解决起来就比较容易了,下面记录一下解决问题及涉及到的一些Docker命令和Linux操作。
docker安装的方式可参考:linux(centos)中部署docker(步骤超全,含带一些发展史和一些概念)更换docker的镜像源:重启完可用docker info命令查看是否添加上等待拉取即可;拉取完成之后查看镜像3 创建Jenkins挂载目录并赋予权限3.1 稍后可以将docker内的目录挂载到此目录上,方便操作容器内文件夹而不需要进入容器3.2 为挂载目录赋予权限4 创建Jenkins容器并运行5 页面访问jenkinsjenkins运行中页面访问ip:port如:遇到
docker是云原生的入门知识,本文是博主云原生知识学习的开篇,讲解了docker的安装过程,其中遇到的问题也给出了具体的解决方案,希望能帮到自己和粉丝朋友们。
Docker官方的Docker Registry是一个基础版本的Docker镜像仓库,具备仓库管理的完整功能,但是没有图形化界面。
RabbitMQ官网地址如下图官网提供了两种安装RabbitMQ的方式,一种是docker版本,一种是各个操作系统下的安装方式,本文将演示Linux(centos)环境和docker两种方式!准备安装有Linux环境的服务器或者虚拟机,本文使用阿里云服务器,Linux版本为centos 7。
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件代理服务器,在BSD-like协议下发行。Nginx的特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。到这里我们Docker的相关文章就差不多完结了,接下来是Kubernetes的系列文章了,欢迎大家继续关注。
一)基本知识:Docker安装时会自动在 host上创建三个网络:none,host,和bridge;详细说明可参考其它文档。我们可用 docker network ls命令查看:基于DRIVER是bridge的网络都会有一个对应的linux bridge被创建:在默认环境中,一个名为docker0的linux bridge自动被创建好了,其上有一个 docker0内部接口,IP地址为172.17.0.1/16:再用docker network inspect指令查看brid...
原文连接:https://www.cnblogs.com/iiiiher/p/8135024.htmldocker0网络模型step by step将docker的ns软链到linux ns$ ln -s /var/run/docker/netns /var/run/netns查看ns,无$ ip netns $ 启动b1$ docker run -itd --...
背景在使用 docker 运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,小的来说会导致容器资源使用不公平;大的来说,可能会导致主机和集群资源耗尽,服务完全不可用。docker 作为容器的管理者,自然提供了控制容器资源的功能。正如使用内核的 namespace 来做容器之间的隔离,docker 也是通过内核的 cgroups 来
原文链接:http://www.cnblogs.com/itech/p/5220122.htmlhttp://my.oschina.net/huangyong/blog/372491?fromerr=kHrZPM01 1 Docker与虚拟机   2 搭建过程2.1 准备宿主系统准备一个 CentOS 7操作系统,具体要求如下: 必须是 64 位操作系统 ...
Dockerfile中RUN,CMD和ENTRYPOINT都能够用于执行命令,下面是三者的主要用途:RUN命令执行命令并创建新的镜像层,通常用于安装软件包 CMD命令设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换 ENTRYPOINT配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令)Shell格式和Exec格式运行命令我们可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运
开始之前在本教程中,我们将学习如何使用Docker创建、备份和还原SQLite数据库。Linux 机器和 Docker 将需要学习本教程。创建 Docker SQLite Docker 映像Dockerfile:FROM alpine:3.10RUN apk add --update sqliteRUN mkdir /dbWORKDIR /dbENTRYPOINT ["sqlite3"]CMD ["test.db"]使用以前的 Dockerfile 构建映像的命令。注.
Docker是一个容器化系统,它打包并运行应用程序及其在容器内的依赖项。在使用 Docker 时,您必须了解几个 Docker 命令。这篇文章就是关于这一点的。查看版本您想知道的第一件事就是如何查看已安装的 Docker 版本。# docker versionClient: Docker Engine - Community Version: 20.10.11 API version: 1.41 Go version: go1.16.9
Kubernetes 是一个开源平台,用于管理容器化应用程序。它允许您在集群环境中管理、扩展和自动部署容器化应用程序。使用 Kubernetes,我们可以跨多个主机编排容器,动态扩展包含所有资源的容器化应用程序,并拥有集中的容器管理环境。在本教程中,我将逐步向您展示如何在 CentOS 7 上安装和配置 Kubernetes。我们将使用 1 个服务器“k8s-master”作为 Kubernetes Host Master,使用 2 个服务器作为 Kubernetes 节点“node01”和'node0
在本文中,我们将使用 Docker compose安装WordPress,这是一种更简洁、更系统的方法。就是这样:安装Python3.8 # yum install -y centos-release-scl# yum install -y rh-python38# scl enable rh-python38 bash 安装Docker Compose: pip install docker-compose 检查 Docker ..
对于 Docker 初学者来说,Docker start、docker run 和 docker create 等术语可能会令人困惑。本文通过示例解释了其中的区别。目录Docker 运行、Docker 启动和 Docker 创建之间的区别如果您不熟悉 Docker 并通过学习各种教程来学习它,则可能会遇到诸如启动 docker 容器、运行 docker 容器或创建 docker 容器之类的术语。这些术语足以使 Docker 初学者感到困惑,因为所有三个 docker 命令看起来都很相似。事
Docker工具是大多数全球公司配置管理工具的重要组成部分。Docker 工具在 dockerfile 的帮助下运行应用程序,具有高度的抽象性和安全性。因此,许多公司正在广泛采用该工具来实现高网络可用性,服务连续性和具有高可扩展性的服务提供。Docker如此受欢迎的原因是Docker镜像,Docker容器和Dockerfile。但是,Docker 映像只能在 Dockerfile 的帮助下创建。展望未来,让我们详细了解 Docker 和 dockerfile。什么是 Docker?Docker
了解 Docker 容器的各种状态对于任何认真的 Docker 用户都至关重要。我将解释容器生命周期,然后显示生命周期每个阶段的 Docker 命令。但在学习所有这些东西之前,让我们再次回顾一下容器的概念。同样,什么是 Docker 容器?容器的大多数传统定义如下:容器是操作系统虚拟化的一种形式。虽然传统的基于虚拟机管理程序的虚拟化需要单独的内核用于单独的虚拟机,但容器共享相同的主机内核,因此,它更轻量级,启动速度更快定义因来源而异,但要点是相同的。我发现它很无聊,而且.