Docker入门
推荐博客
docker 系列文章:https://www.jianshu.com/u/aa3d5c41012b
docker容器中使用top、free命令查看容器真实cpu和内存使用情况的实践: https://www.colabug.com/2017/1022/1759782/
五个Docker监控工具的对比: http://dockone.io/article/397
Docker 国内仓库和镜像
原文地址:https://www.cnblogs.com/wushuaishuai/p/9984228.html
Docker 国内仓库和镜像
由于网络原因,我们在pull Image 的时候,从Docker Hub上下载会很慢。。。所以,国内的Docker爱好者们就添加了一些国内的镜像(mirror),方便大家使用。
1. 国内 Docker 仓库
2. 国外 Docker 仓库
配置 Docker 镜像加速
国内加速站点
- https://registry.docker-cn.com
- http://hub-mirror.c.163.com
- https://3laho3y3.mirror.aliyuncs.com
- http://f1361db2.m.daocloud.io
- https://mirror.ccs.tencentyun.com
使用命令来配置加速站点
对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)
mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["<your accelerate address>"] }
样例
$ cat /etc/docker/daemon.json { "registry-mirrors": [ "https://dockerhub.azk8s.cn", "https://reg-mirror.qiniu.com", "https://quay-mirror.qiniu.com" ], "exec-opts": [ "native.cgroupdriver=systemd" ] }
使用脚本来配置加速站点
该脚本可以将 --registry-mirror 加入到你的 Docker 配置文件 /etc/docker/daemon.json 中。适用于 Ubuntu14.04、Debian、CentOS6 、CentOS7、Fedora、Arch Linux、openSUSE Leap 42.1,其他版本可能有细微不同。更多详情请访问文档。
curl -sSL https://raw.githubusercontent.com/wss434631143/xiaoshujiang/master/articles/Docker/shell/set_mirror.sh | sh -s <your accelerate address>
配置 /etc/default/docker, DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"
cat /etc/default/docker # Docker Upstart and SysVinit configuration file # # THIS FILE DOES NOT APPLY TO SYSTEMD # # Please see the documentation for "systemd drop-ins": # https://docs.docker.com/engine/admin/systemd/ # # Customize location of Docker binary (especially for development testing). #DOCKERD="/usr/local/bin/dockerd" # Use DOCKER_OPTS to modify the daemon startup options. DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 --registry-mirror=https://registry.docker-cn.com" # If you need Docker to use an HTTP proxy, it can also be specified here. #export http_proxy="http://127.0.0.1:3128/" # This is also a handy place to tweak where Docker's temporary files go. #export DOCKER_TMPDIR="/mnt/bigdrive/docker-tmp"
通过修改启动脚本配置加速站点
# 直接修改 /usr/lib/systemd/system/docker.service 启动脚本 vim /usr/lib/systemd/system/docker.service # 在dockerd后面加参数 ExecStart=/usr/bin/dockerd --registry-mirror=<your accelerate address>
以上操作后重启一下 Docker
sudo systemctl daemon-reload sudo systemctl restart docker
临时使用
可能会出现修改仓库失败的问题,如果排查不到原因,也可以用手动指定仓库的凡是pull镜像,命令如下
docker pull registry.docker-cn.com/library/kong:0.13
docker hub
1、Supported tags and respective Dockerfile
links
2、How to use this image
。。。
地址如下:https://hub.docker.com/r/library/
Docker安装
安装
sudo apt install docker.io
启动docker服务
sudo service docker start
测试docker
sudo docker pull hello-world
sudo docker run hello-world
搜索包
sudo docker search caffe
拉取包
sudo docker pull caffe
Docker使用Portainer搭建可视化界面
https://www.cnblogs.com/ExMan/p/11657069.html
docker-compose安装
sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o docker-compose sudo mv docker-compose /usr/local/bin/ sudo chmod 755 docker-compose docker-compose -version
docker指令
拉取镜像Ubuntu18.04
sudo docker pull ubuntu:18.04
查看镜像是否拉取成功
sudo docker image ls ubuntu
运行镜像
sudo docker run ubuntu:18.04 # 运行镜像 sudo docker run -it ubuntu:18.04 /bin/bash # 运行Ubuntu18.04镜像,并进入bash环境
查看当前正在运行的容器
docker ps
查看所有容器
sudo docker container ls -a
exec:Run a command in a running container
docker exec -it CONTAINERID /bin/bash
查看某个容器的日志
docker logs container_id
查看docker-compose日志:
docker-compose logs -f -t
如何获取 docker 容器(container)的 ip 地址
docker inspect 容器名称或 id
进入容器内部后
cat /etc/hosts
docker 访问宿主机网络
方法一:
原文地址:https://www.cnblogs.com/m-finder/p/11592716.html
运行在 docker 容器中的一个项目需要访问宿主机的某个端口,也就是容器 A 中的项目访问宿主机项目 B。
之前是可以通过下边的方式正常访问的,最近不知道动了哪里突然出现 500 ,一番折腾,总算是解决了,这里记录一下,预防以后遇到同样问题。
正常的访问方式
在 A 的项目中以下边的地址来访问即可:
http://host.docker.internal
问题解决
重启电脑后,在容器中 ping 这个地址:
PING host.docker.internal (192.168.65.2) 56(84) bytes of data.
64 bytes from 192.168.65.2: icmp_seq=1 ttl=37 time=2.09 ms
64 bytes from 192.168.65.2: icmp_seq=2 ttl=37 time=1.05 ms
64 bytes from 192.168.65.2: icmp_seq=3 ttl=37 time=1.05 ms
64 bytes from 192.168.65.2: icmp_seq=4 ttl=37 time=1.16 ms
64 bytes from 192.168.65.2: icmp_seq=5 ttl=37 time=1.03 ms
可以看到实际访问的是 192.168.65.2 这个地址,那么打开宿主机的 host,果然没了! Σ( ° △ °|||)︴
加上一行:
192.168.65.2 host.docker.internal
再次访问,ok!
在容器内安装 ping
不指定用户进入容器,然后执行:
apt-get update
apt-get install iputils-ping
疑问
正常情况下,host 应该有 docker 自动添加的地址以供访问,但是我的不知道为什么没了。
后来创建了另一套新的容器以后看到 host 有以下新增的地址,所以我猜测这个应该是创建容器时会自动添加,不知道队不对,恳请知道的大佬解惑:
# Added by Docker Desktop
192.168.1.164 host.docker.internal
192.168.1.164 gateway.docker.internal
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section
方法二
使用宿主机IP
在安装Docker的时候,会在宿主机安装一个虚拟网关docker0
,我们可以使用宿主机在docker0
上的IP地址来代替localhost
。
但是,不同系统下宿主机的IP是不同的,例如Linux下一般是172.17.0.1
, macOS下一般是192.168.65.1
,并且这个IP还可以更改。所以不能跨环境通用。
使用host网络
Docker容器运行的时候有host
、bridge
、none
三种网络可供配置。默认是bridge
,即桥接网络,以桥接模式连接到宿主机;host
是宿主网络,即与宿主机共用网络;none
则表示无网络,容器将无法联网。
当容器使用host
网络时,容器与宿主共用网络,这样就能在容器中访问宿主机网络,那么容器的localhost
就是宿主机的localhost
。
在docker中使用--network host
来为容器配置host
网络:
docker run -d --name nginx --network host nginx
上面的命令中,没有必要像前面一样使用-p 80:80 -p 443:443
来映射端口,是因为本身与宿主机共用了网络,容器中暴露端口等同于宿主机暴露端口。
使用host网络仍然可以使用localhost
,因而通用性比上一种方法好。但是,由于host
网络没有bridge
网络的隔离性好,使用host
网络安全性不如bridge
高。
总结
两种方法各有优劣,使用宿主机IP隔离性更好,但通用性不好;使用host网络,通用性好,但带来了暴露宿主网络的风险
其他
版权声明:本文为CSDN博主「在风中的意志」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010416101/article/details/80534013
Question
Docker内需要访问本机的数据库,如何访问。使用127.0.0.1肯定是不行的,因为这个在Docker容器里面指的是容器本身。所以,需要走别动渠道进行解决。
Solution
下面几种办法,根据操作系统的类型,选取其一即可。
DockerFile:
RUN /sbin/ip route|awk '/default/ { print $3,"\tdockerhost" }' >> /etc/hosts
RunTime:
(may not use) docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [my container] (useful) docker run --add-host=dockerhost:`docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge` [IMAGE]
Docker for Mac (17.12+):
docker.for.mac.host.internal MONGO_SERVER=docker.for.mac.host.internal # docker-compose.yml version: '3' services: api: build: ./api volumes: - ./api:/usr/src/app:ro ports: - "8000" environment: - MONGO_SERVER command: /usr/local/bin/gunicorn -c /usr/src/app/gunicorn_config.py -w 1 -b :8000 wsgi
Linux
# Solution 1 /sbin/ip route|awk '/default/ { print $3 }' docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [my container] # Solution 2 -e "DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')"
Principle
想知道原理,需要了解计算机网络的模型和docker实现的模型。docker内部实际上实现了一个虚拟网桥docker0,需要通过网桥找到外部宿主机的在网桥的虚拟地址,也就是docker.for.mac.host.internal,就可以实现容器内访问外部宿主机。感兴趣的话可以了解下Docker的网络原理、计算机网络原理和docker compose等内容。
Reference
[1]. (stackoverflow)insert-docker-parent-host-ip-into-containers-hosts-file
[2]. (stackoverflow)how-to-get-the-ip-address-of-the-docker-host-from-inside-a-docker-container
服务器重启数据丢失
原文作者:wswang
原文地址:https://www.cnblogs.com/wswang/p/11458131.html
服务器重启,使用docker run 镜像,之前数据会丢失
应重新启动容器,而不是重新创建容器
docker start container_name
docker restart container_name
注意:服务器重启了,容器挂掉了(使用docker ps查看,其容器状态是Exited),但其实之前的数据还会在默认的volume下,只有删除掉容器的时候,变动的数据才会丢失。
docker 批量删除无用的容器或镜像
docker rm `docker ps -a | grep Exited | awk '{print $1}'` #删除异常停止的docker容器 docker rmi -f `docker images | grep '<none>' | awk '{print $3}'` #删除名称或标签为none的镜像
参考地址:作者:K1024 链接:https://www.jianshu.com/p/7476824e4bee 来源:简书
docker ps -a|grep "Exited" | awk '{print $1}' | xargs docker stop docker ps -a|grep "Exited" | awk '{print $1}' | xargs docker rm docker images|grep none|awk '{print $3}'|xargs docker rmi
不使用缓存重建
不使用缓存使docker-compose重建,参考地址:https://github.com/docker/compose/issues/1049
docker-compose down &&
docker-compose rm --all &&
docker-compose pull &&
docker-compose build --no-cache &&
docker-compose up -d --force-recreate
删除所有镜像、容器、网络和卷的方法
项目实战 (Django+mysql+uwsgi+nginx)
注意:
mysql推荐使用物理机,而不使用docker,参考:https://www.sohu.com/a/136066935_151779
- docker快速扩展的一个重要特征就是stateless,具有数据状态的都不适合直接放在docker里面
- docker本身就推荐服务挂掉,自动启动新容器,而不是继续重启容器服务
- 建议数据库不要使用docker来部署,而是使用物理机。因为可能遇到因docker引起的未知问题,而且问题很难排查。尤其在集群的情况下,之间的通讯也变得复杂了。
ztf@ubuntu:~/Desktop$ tree -n -L 2 dockerPro dockerPro ├── docker-compose.yml ├── mysql │ ├── conf │ ├── Dockerfile │ └── init ├── nginx │ ├── Dockerfile │ └── nginx.conf ├── uwsgi │ ├── uwsgi.ini │ ├── uwsgi.log │ ├── uwsgi_params │ ├── uwsgi.pid │ └── uwsgi.sock └── zdCloudPlatform ├── api ├── apps ├── config ├── Dockerfile ├── manage.py ├── media ├── __pycache__ ├── requirements.txt ├── static ├── templates ├── utils └── zdCloudPlatform
docker-compose.yml

version: "3" services: nginx: container_name: nginx build: ./nginx ports: - 80:80 volumes: - ./zdCloudPlatform:/zdCloudPlatform - ./nginx:/etc/nginx/conf.d - ./uwsgi:/uwsgi networks: extnetwork: ipv4_address: 192.168.27.151 links: - django depends_on: - django restart: always # 若容器运行出现问题,会自动重启容器 django: container_name: django build: ./zdCloudPlatform ports: - "8000:8000" volumes: - ./uwsgi:/uwsgi command: - /bin/sh - -c - | uwsgi --ini /uwsgi/uwsgi.ini networks: extnetwork: ipv4_address: 192.168.27.152 links: - db depends_on: - db restart: always # 若容器运行出现问题,会自动重启容器 db: container_name: mysql image: mysql:5.7 ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=123456 volumes: - ./mysql/db:/var/lib/mysql - ./mysql/conf/my.cnf:/etc/my.cnf - ./mysql/init:/docker-entrypoint-initdb.d/ networks: extnetwork: ipv4_address: 192.168.27.153 restart: always # 若容器运行出现问题,会自动重启容器 networks: # docker网络设置 extnetwork: # 自定义网络名称 ipam: # 要使用静态ip必须使用ipam插件 #driver: Bridge config: - subnet: 192.168.27.0/24
mysql/conf/my.conf

[mysqld] user=mysql default-storage-engine=INNODB character-set-server=utf8 [client] default-character-set=utf8 [mysql] default-character-set=utf8
mysql/init/privileges.sql

use mysql; select host, user from user; -- 因为mysql版本是5.7,因此新建用户为如下命令: create user docker identified by '123456'; -- 将docker_mysql数据库的权限授权给创建的docker用户,密码为123456: grant all on db_zdcloud_base.* to docker@'%' identified by '123456' with grant option; grant all on db_zdcloud_devices.* to docker@'%' identified by '123456' with grant option; -- 这一条命令一定要有: flush privileges;
mysql/Dockerfile

# VERSION 1.0 # Author: yxx #基础镜像8.0.12 FROM mysql:5.7 #作者 MAINTAINER name <邮箱> #将所需文件放到容器中 #ADD . /mysql EXPOSE 3306
nginx/Dockerfile

# nginx镜像,最好是先拉取到本地 FROM nginx:1.14.2 # 删除原有配置文件 RUN rm /etc/nginx/conf.d/default.conf # 添加配置文件 ADD ./nginx.conf /etc/nginx/conf.d/ # 对外暴露端口 EXPOSE 80
nginx/nginx.conf

#负载均衡配置 upstream backend { #upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。 #server unix:///uwsgi/uwsgi.sock; # 文件socket server django:8000 weight=3; } #虚拟主机的配置 server { #监听端口 listen 80; #域名可以有多个,用空格隔开 server_name localhost; client_max_body_size 100M; # Django media location /media { alias /zdCloudPlatform/media; # your Django project's media files - amend as required } location /static { alias /zdCloudPlatform/static; # your Django project's static files - amend as required } # Finally, send all non-media requests to the Django server. location / { uwsgi_pass backend; include /uwsgi/uwsgi_params; # the uwsgi_params file you installed #proxy_pass http://backend; #proxy_set_header Host $host:$server_port; #proxy_set_header X-Forwarded-Host $server_name; #proxy_set_header X-Real-IP $remote_addr; #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
uwsgi/uwsgi.ini

[uwsgi] # 项目目录 chdir = /zdCloudPlatform/ # 指定项目的wsgi文件,我的项目是bsite所以为bsite.wsgi,你自己的对应改 module = zdCloudPlatform.wsgi:application # 进程个数 workers = 1 pidfile = /uwsgi/uwsgi.pid # 指定静态文件,指定在那里就使用哪里,必须和nginx的default文件里配置的路径一样(当然这个目录可以是随意的,在项目之外也可以,只要保证和nginx的静态文件路径一样就行) #static-map =/static=/zdCloudPlatform/static # 启动uwsgi的用户名和用户组 uid=root gid=root # 启用主进程 master=true # 自动移除unix Socket和pid文件当服务停止的时候 vacuum=true # 序列化接受的内容,如果可能的话 thunder-lock=true # 启用线程 enable-threads=true # 设置自中断时间 harakiri=30 # 设置缓冲 post-buffering=4096 # 设置日志目录 #daemonize=/zdCloudPlatform/config/uwsgi.log # 指定sock的文件路径 chmod-socket = 664 #socket=/uwsgi/uwsgi.sock #socket 为上线使用,http为直接作为服务器使用。 socket = 0.0.0.0:8000 #ip和端口号可以改 #http = 0.0.0.0:8000
uwsgi/uwsgi_params

uwsgi_param QUERY_STRING $query_string; uwsgi_param REQUEST_METHOD $request_method; uwsgi_param CONTENT_TYPE $content_type; uwsgi_param CONTENT_LENGTH $content_length; uwsgi_param REQUEST_URI $request_uri; uwsgi_param PATH_INFO $document_uri; uwsgi_param DOCUMENT_ROOT $document_root; uwsgi_param SERVER_PROTOCOL $server_protocol; uwsgi_param REQUEST_SCHEME $scheme; uwsgi_param HTTPS $https if_not_empty; uwsgi_param REMOTE_ADDR $remote_addr; uwsgi_param REMOTE_PORT $remote_port; uwsgi_param SERVER_PORT $server_port; uwsgi_param SERVER_NAME $server_name;
django/Dockerfile

# 选择基础镜像,这里的基础镜像也可以选择ubuntu,centos等,但是下面的配置就会发生变化 FROM python:3.6.5 # 创建工作目录 RUN mkdir /zdCloudPlatform #将当前目录加入到工作目录中 ADD ./ /zdCloudPlatform #设置工作目录 WORKDIR /zdCloudPlatform RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip && \ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt && \ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple uwsgi
注意:
mysql数据库初始化
docker-entrypoint-initdb.d目录下的sql文件会被自动执行
问题1:
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/db.sql
/usr/local/bin/docker-entrypoint.sh: line 54: /docker-entrypoint-initdb.d/db.sql: Permission denied
方案:
sudo chmod -R 777 dockerProject#整个Docker项目
问题2
docker-entrypoint-initdb.d is not working
参考:
Dockerfile构建mysql镜像并实现数据的初始化及权限设置: https://m.jb51.net/article/115422.htm
docker-compose部署mysql: https://blog.csdn.net/hjxzb/article/details/84927567
django开发-在Docker中部署django项目:https://segmentfault.com/a/1190000017034025
问题汇总
多执行几次docker ps,当容器的STATUS是以Restarting开头时,表示这个容器运行时发生了错误。执行docker logs CONTAINERID可以查看容器出错的具体原因。
若上述容器都成功运行,则在浏览器中输入http://127.0.0.1:80/时,视图会返回相应的结果。
以交互方式进入容器:
docker exec -it CONTAINERID /bin/bash
后,进入mysql数据库,会看到在数据库中生成了相应的表。
运行中遇到的问题,在运行3个容器后,web容器一直报错,通过docker logs CONTAINERID查看主要错误信息如下
django.db.utils.OperationalError: (2003, 'Can\'t connect to MySQL server on \'mariadb55\' (111 "Connection refused")')
解决方案在这里 https://stackoverflow.com/que... 主要是在settings.py中,将database配置中的HOST值改成db,而不是127.0.0.1,指向docker-compose.yml中的db服务
Dockerfile文件示例
############################################################ # Dockerfile to build xxx container images # Based on Ubuntu ############################################################ # Set the base image to Ubuntu FROM ubuntu:18.04 # File Author / Maintainer MAINTAINER ztf [邮箱] LABEL version="1.0" LABEL description="This text illustrates that label-values can span multiple lines." # RUN:执行命令行命令 RUN apt-get update && \ apt-get -y upgrade && \ apt-get install python3 && \ apt-get install python3-pip # 对外暴露端口 EXPOSE 3306
Docker-端口映射
docker容器在启动的时候,如果不指定端口映射参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的。亦可使用Dockerfile文件中的EXPOSE指令来配置。
端口映射可使用-p、-P来实现:
- -p指定要映射的端口,一个指定端口上只可以绑定一个容器
- -P将容器内部开放的网络端口随机映射到宿主机的一个端口上
端口映射支持的格式:
ip:hostport:containerport #指定ip、指定宿主机port、指定容器port
ip::containerport #指定ip、未指定宿主机port(随机)、指定容器port
hostport:containerport #未指定ip、指定宿主机port、指定容器port
端口的映射有以下五种方法:
一、将容器暴露的所有端口,都随机映射到宿主机上。
例如:(不推荐使用)
docker run -P -it ubuntu /bin/bash
二、将容器指定端口随机映射到宿主机一个端口上。
例如:
docker run -P 80 -it ubuntu /bin/bash
以上指令会将容器的80端口随机映射到宿主机的一个端口上。
三、将容器指定端口指定映射到宿主机的一个端口上。
例如:
docker run -p 8000:80 -it ubuntu /bin/bash
以上指令会将容器的80端口映射到宿主机的8000端口上。
四、将容器ip和端口,随机映射到宿主机上。
docker run -P 192.168.0.100::80 -it ubuntu /bin/bash
以上指令会将容器的ip192.168.0.100和80端口,随机映射到宿主机的一个端口上。
五、将容器ip和端口,指定映射到宿主机上。
docker run -p 192.168.0.100:8000:80 -it ubuntu /bin/bash
以上指令会将容器的ip192.168.0.100和80端口,映射到宿主机的8000端口。
示例:
#将nginx的80端口映射到宿主机的800端口上 docker run -d -it -p 800:80 nginx
查看映射端口配置
docker port container_ID #容器ID #结果输出 80/tcp -> 0.0.0.0:800
作者:木木mei錦
链接:https://www.jianshu.com/p/b92d4b845ed6
来源:简书
Docker问题集
自定义网桥
除了默认的 docker0
网桥,用户也可以指定网桥来连接各个容器。在启动 Docker 服务的时候,使用 -b BRIDGE
或--bridge=BRIDGE
来指定使用的网桥。
如果服务已经运行,那需要先停止服务,并删除旧的网桥。
$ sudo systemctl stop docker $ sudo ip link set dev docker0 down $ sudo brctl delbr docker0
然后创建一个网桥 bridge0
。
$ sudo brctl addbr bridge0 $ sudo ip addr add 192.168.5.1/24 dev bridge0 $ sudo ip link set dev bridge0 up
查看确认网桥创建并启动。
$ ip addr show bridge0 4: bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state UP group default link/ether 66:38:d0:0d:76:18 brd ff:ff:ff:ff:ff:ff inet 192.168.5.1/24 scope global bridge0 valid_lft forever preferred_lft forever
在 Docker 配置文件 /etc/docker/daemon.json
中添加如下内容,即可将 Docker 默认桥接到创建的网桥上。
{ "bridge": "bridge0", }
启动 Docker 服务。
新建一个容器,可以看到它已经桥接到了 bridge0
上。
docker-compose up with volumes “no such file or directory”
The docker-compose volumes
maps files to the running container (i.e. at runtime when the container is running), not the image. In your docker-compose config, you are saying "Run the run.sh
script when starting up the container", but run.sh
doesn't exist, since it is not part of the image. The run.sh
file needs to be added at build time
ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?
docker-compose up # 有问题 sudo docker-compose up # 没有问题
docker: Got permission denied while trying to connect to the Docker daemon socket
songyanyan@songyanyan:~$ sudo group add docker [sudo] songyanyan 的密码: sudo: group:找不到命令 songyanyan@songyanyan:~$ sudo groupadd docker #添加docker用户组 groupadd:“docker”组已存在 songyanyan@songyanyan:~$ sudo gpasswd -a $USER docker #将登陆用户加入到docker用户组中 正在将用户“songyanyan”加入到“docker”组中 songyanyan@songyanyan:~$ newgrp docker #更新用户组 songyanyan@songyanyan:~$ docker ps #测试当前用户是否可以正常使用docker命令 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES songyanyan@songyanyan:~$
重启docker或重启电脑使配置生效
sudo service docker restart
docker exec 出现 "fork/exec /proc/self/exe: no such file or directory" 问题
docker 容器正常运行,但不能 exec
1、查找出 docker 的容器 id 5d0e262527cf # docker ps | grep rabbitmq 5d0e262527cf rabbitmq:3-management "docker-entrypoint..." 12 months ago Up 3 months 10.168.93.209:4369->4369/tcp, 10.168.93.209:5671-5672->5671-5672/tcp, 10.168.93.209:15671-15672->15671-15672/tcp, 10.168.93.209:25672->25672/tcp mq01 2、根据 docker 容器 id 5d0e262527cf 找到对应的 libcontainerd 的运行pid 7309 # ps -ef|grep libcontainerd | grep 5d0e262527cf root 7309 1136 0 May07 ? 00:00:09 /usr/bin/docker-containerd-shim-current 5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459 /var/run/docker/libcontainerd/5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459 /usr/libexec/docker/docker-runc-current 3、用 nsenter 进入 docker 容器 5d0e262527cf 的 namespace # nsenter -m -t 7309 bash 4、查看 docker 容器 5d0e262527cf 的 DeviceName # docker inspect --format='{{.GraphDriver.Data.DeviceName}}' 5d0e262527cf docker-202:17-4703339-5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459 5、 可以看到 docker 容器 5d0e262527cf 的 /data/docker/devicemapper/mnt/docker容器ID 这个目录不存在 # ll /data/docker/devicemapper/mnt/5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459 ls: cannot access /data/docker/devicemapper/mnt/5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459: No such file or directory 只看到 /data/docker/devicemapper/mnt/docker容器ID-init 这个目录,所以执行 docker exec 时,会报错 \"fork/exec /proc/self/exe: no such file or directory\" # ll /data/docker/devicemapper/mnt/5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459-init total 0 6、对比正常 docker 容器 aa4416c1f1e8 的目录 # ll /data/docker/devicemapper/mnt/aa4416c1f1e8fb192e72b2cf60aae8507cc4bf7bbe69ef2b96d81e29640f7a4a total 8 -rw------- 1 root root 64 Dec 11 2017 id drwxr-xr-x 21 root root 4096 Apr 3 15:35 rootfs 7、创建 docker 容器 5d0e262527cf 对应的目录(去掉 -init 后缀) # mkdir /data/docker/devicemapper/mnt/5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459 8、重新挂载 docker 容器 5d0e262527cf 的 /data/docker/devicemapper/mnt/容器ID 目录 // 用法:mount /dev/mapper/docker容器的DeviceName -o rw,relatime,nouuid,attr2,inode64,sunit=512,swidth=1024,noquota -t xfs /Dockerd服务的数据目录/devicemapper/mnt/容器ID # mount /dev/mapper/docker-202:17-4703339-5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459 -o rw,relatime,nouuid,attr2,inode64,sunit=512,swidth=1024,noquota -t xfs /data/docker/devicemapper/mnt/5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459 # ll /data/docker/devicemapper/mnt/5d0e262527cf7c3c7f459104ac542a45b050d42817d07026e3ce0cd20b7c5459 total 8 -rw------- 1 root root 64 Aug 10 2017 id drwxr-xr-x 17 root root 4096 Dec 10 2017 rootfs 9、退出 docker 容器 5d0e262527cf 的 namespace # exit exit 10、测试此 docker 容器 5d0e262527cf 可以正常执行 docker exec # docker exec -it 5d0e262527cf /bin/bash root@mq01:/# ls bin boot dev docker-entrypoint.sh etc home lib lib32 lib64 libx32 media mnt opt plugins proc root run sbin srv sys tmp usr var root@mq01:/# exit exit
docker exec 出现问题时另一种折衷解决办法,通过 nsenter 进入容器
# docker exec -it 86ffcb615a74 /bin/bash rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "process_linux.go:75: starting setns process caused \"fork/exec /proc/self/exe: no such file or directory\"" # docker inspect -f {{.State.Pid}} 86ffcb615a74 6670 # nsenter -t 6670 -m -u -i -n -p -bash: /var/log/usermonitor/usermonitor.log: No such file or directory root@86ffcb615a74:/# ps -ef UID PID PPID C STIME TTY TIME CMD mysql 1 0 0 May07 ? 02:50:32 mysqld root 60 0 0 14:32 ? 00:00:00 -bash root 67 60 0 14:33 ? 00:00:00 ps -ef -bash: /var/log/usermonitor/usermonitor.log: No such file or director
参考文献:
docker教程:https://yeasy.gitbooks.io/docker_practice/compose/django.html
易百教程:https://www.yiibai.com/docker/docker-dockerfile.html
作者:AlexanderYao 出处:http://alexanderyao.cnblogs.com/
https://www.cnblogs.com/boshen-hzb/p/6400272.html
docker EXPOSE vs publish:https://www.jianshu.com/p/5b58218bab9a
https://blog.csdn.net/boling_cavalry/article/details/78172113