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 镜像加速

国内加速站点

使用命令来配置加速站点

对于使用 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容器运行的时候有hostbridgenone三种网络可供配置。默认是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

    
View Code

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
View Code

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;
View Code 

mysql/Dockerfile

# VERSION 1.0
# Author: yxx

#基础镜像8.0.12
FROM mysql:5.7

#作者
MAINTAINER name <邮箱>

#将所需文件放到容器中
#ADD . /mysql

EXPOSE 3306
View Code

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
View Code

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;
    }
}
View Code

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
View Code

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;
View Code

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
View Code

注意:

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 

https://stackoverflow.com/questions/38504257/mysql-scripts-in-docker-entrypoint-initdb-are-not-executed

参考:

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”

参考地址:https://stackoverflow.com/questions/46731766/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" 问题

原文地址:http://ddrv.cn/a/314762

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

posted @ 2019-04-22 19:15  逐梦客!  阅读(541)  评论(0)    收藏  举报