Docker容器学习总结(超全)

Docker容器学习总结(超全)

前言:

由于公司业务需求,所以最近才开始学之前一直想学的Dokcer容器

文章目录

什么是容器?
  1. 一种虚拟化的方案
  2. 操作系统级别的虚拟化
  3. 只能运行相同或相似内核的操作系统
  4. 依赖于Linux内核特性:Namespace和Cgroups (Control Group)
什么是Docker?

将应用程序自动部署到容器

Go语言开源引擎 Github地址: https://github.com/docker/docker

2013年初 dotCloud 基于Apache2.0开源授权协议发行

Docker的目标
  • 提供简单轻量的建模方式
  • 职责的逻辑分离
  • 快速高效的开发声明周期
  • 鼓励使用面向服务的架构
Docker的使用场景
  • 使用Docker容器开发,测试,部署服务。
  • 创建隔离的运行环境
  • 搭建测试环境
  • 构建多用户的平台即服务(PaaS)基础设施
  • 提供软件即服务(SaaS)应用程序
  • 高性能,超大规模的宿主机部署
Docker的基本组成

Docker客户端/守护进程

C/S架构

本地 / 远程

Docker Image 镜像:容器的基石,层叠的只读文件系统 , 联合加载(union Mount)

Docker Container容器:通过镜像启动,写时复制(copy on write)

Docker Registry仓库 : 公有: Docker Hub(有丰富的镜像),私有。


Docker容器相关技术简介

Docker依赖的Linux内核特性
Namespaces 命名空间:
  • PID(Process ID) 进程隔离

  • NET(Network) 管理网络接口

  • IPC(InterProcess Communication) 管理跨进程通信的访问

  • MNT(Mount) 管理挂载点

  • UTS(Unix Timesharing System) 隔离内核和版本标识

Control groups (cgroups) 控制组:
  • 资源限制
  • 优先级设定
  • 资料计量
  • 资源控制
Docker容器的能力
  • 文件系统的隔离:每个容器都有自己的Root文件系统
  • 进程隔离:每个容器都运行在自己的进程环境中
  • 网络隔离:容器间的虚拟网络接口和Ip地址都是分开的
  • 资源隔离和分组:使用cgroups将CPU和内存之类的资源独立分配给每个Docker容器

Docker的安装与部署

Centos7上安装docker

Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE。

社区版是免费提供给个人开发者和小型团体使用的,企业版会提供额外的收费服务,比如经过官方测试认证过的基础设施、容器、插件等。

社区版按照stable和edge两种方式发布,每个季度更新stable版本,如17.06,17.09;每个月份更新edge版本,如17.09,17.10。

一、安装docker

1、Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。

通过 uname -r 命令查看你当前的内核版本

 $ uname -r

2、使用 root 权限登录 Centos。确保 yum 包更新到最新。

$ sudo yum update

3、卸载旧版本(如果安装过旧版本的话)

$ sudo yum remove docker  docker-common docker-selinux docker-engine

4、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的

$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2

5、设置yum源

$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

img

6、可以查看所有仓库中所有docker版本,并选择特定版本安装

$ yum list docker-ce --showduplicates | sort -r

img

7、安装docker

$ sudo yum install docker-ce  #由于repo中默认只开启stable仓库,故这里安装的是最新稳定版17.12.0
$ sudo yum install <FQPN>  # 例如:sudo yum install docker-ce-17.12.0.ce

img

8、启动并加入开机启动

$ sudo systemctl start docker
$ sudo systemctl enable docker

9、验证安装是否成功(有client和service两部分表示docker安装启动都成功了)

$ docker version

img

二、问题

1、因为之前已经安装过旧版本的docker,在安装的时候报错如下:

Transaction check error:
  file /usr/bin/docker from install of docker-ce-17.12.0.ce-1.el7.centos.x86_64 conflicts with file from package docker-common-2:1.12.6-68.gitec8512b.el7.centos.x86_64
  file /usr/bin/docker-containerd from install of docker-ce-17.12.0.ce-1.el7.centos.x86_64 conflicts with file from package docker-common-2:1.12.6-68.gitec8512b.el7.centos.x86_64
  file /usr/bin/docker-containerd-shim from install of docker-ce-17.12.0.ce-1.el7.centos.x86_64 conflicts with file from package docker-common-2:1.12.6-68.gitec8512b.el7.centos.x86_64
  file /usr/bin/dockerd from install of docker-ce-17.12.0.ce-1.el7.centos.x86_64 conflicts with file from package docker-common-2:1.12.6-68.gitec8512b.el7.centos.x86_64

2、卸载旧版本的包

$ sudo yum erase docker-common-2:1.12.6-68.gitec8512b.el7.centos.x86_64

img

3、再次安装docker

$ sudo yum install docker-ce

Docker容器的基本操作

docker run IMAGE [COMMAND 命令] [ARG… 参数]

run 在新容器中执行命令

启动交互式容器:
$ docker run -i -t IMAGE /bin/bash

-i -interactive = true | false 默认是false  :守护进程是否打开标准输入

-t -tty = true | false 默认是false   : 是否为容器打开-tty终端
查看容器:
$docker ps [-a] [-l] : -a是指列出所有的容器 ; -l是指列出最新创建的容器

$docker inspect : inspect代表的是容器的名字,既可以是容器的名字也可以是容器的id
自定义容器名:

$docker run --name=自定义名 -i -t IMAGE /bin/bash

重新启动停止的容器:

$docker start [-i] 容器名 :-i是指它可以以交互的方式来重新启动已经停止的容器

删除停止的容器:

$docker rm 容器名


Docker–守护式容器
什么是守护式容器:
  • 能够长期运行
  • 没有交互式会话
  • 适合运行应用程序和服务
以守护形式运行容器:
$docker run - i -t IMAGE /bin/bash

Ctrl+P   Ctrl+Q :以ctrl+p 加上Ctrl+q的组合键来退出交互式容器的bash,这样容器就会在后台运行

$docker run -d 镜像名 [COMMAND] [ARG...]  :  -d是指以后台的形式运行命令,但是在命令结束后,容器依旧会停止
附加到运行中的容器:

$docker attach 容器名

启动守护式容器:
$docker run -d 镜像名 [COMMAND] [ARG...]  :  -d是指以后台的形式运行命令,但是在命令结束后,容器依旧会停止
查看容器日志:
$docker logs [-f] [-t] [-tail] 容器名

-f --follows = true | false 默认为false   :-f是告诉logs 一直跟踪日志的变化,并返回结果

-t --timestamps=true | false 默认为false  : -t是在返回的结果上加上时间戳

--tail = “all”           : --tail 是选择返回结尾处多少数量的日志,那么如果不指定,logs返回所有的日志
查看容器内运行中进程:

docker top 容器名 :来查看运行中容器的进程

在运行中的容器内启动新进程:
$docker exec [-d] [-i] [-t] 容器名 [COMMAND] [ARG...] 
exec用来在已经运行的容器中启动新进程
如何停止守护式容器:
$docker stop 容器名   stop 发送一个信号给容器,等待容器的停止
$docker kill 容器名   kill 会直接停止容器

在容器中部署静态网站
设置容器的端口映射
run [-p] [-P]

-p, -publish=[]

  1. containerPort

    docker run -p 80 -i -t centos /bin/bash

  2. hostPort:containerPort

    docker run - p 8080:80 -i -t centos /bin/bash

  3. ip::containerPort

    docker run -p 0.0.0.0:80 -i -t centos /bin/bash

  4. ip:hostPort:containerPort

Nginx部署流程
  1. 创建映射80端口的交互式容器

  2. 安装Nginx

  3. 安装文本编译器vim

  4. 创建静态页面

  5. 修改Nginx配置文件

  6. 运行nginx

  7. 验证网站访问


Docker–查看和删除镜像
Docker Image 镜像
  • 容器的基石
  • 层叠的只读文件系统
  • 联合加载(union mount)

存储位置: /var/lib/docker

查看和删除镜像 -列出镜像
$docker images [OPTSIONS] [REPOSITORY]
-a --all=false      显示所有镜像,默认不显示中间层的镜像
-f --filter=[]      显示时的过滤条件,
--no-trunc =false  是指定不使用截断的形式来显示数据,默认情况下我们用images命令查到的列表是会截断镜像的唯一id的。

-q, --quiet=false   只显示镜像的唯一id。
查看和删除镜像-镜像的仓库
REPOSITORY 仓库
REGISTYRY  仓库?
查看和删除镜像-镜像标签
TAG : ubuntu:14.04
ubuntu:latest
查看和删除镜像-查看镜像
$docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...]
-f,--format=""  
查看和删除镜像-删除镜像
$docker rmi [OPTIONS] IMAGE [IMAGE...]
-f--force=false  Force removal of the image :强制移除图像
-no-prune=false   Do not Delete untagged parents :保留被删除镜像中被打标签的父镜像

Docker-获取和推送镜像
获取和推送镜像-查找镜像
几种查找镜像的方式
1.Docker Hub
https://registry.hub.docker.com

2.$docker search [OPTIONS] TERM
--automated=false Only show automated builds :只显示自动构建
--no-trunc=false Dont truncate output  :不截断输出
-s--stars=0 Only displays with at least x stars  :
最多返回25个结果
获取和推送镜像-拉取镜像
¥docker pull [OPTIONS] NAME[:TAG]
-a,--all-tags=false  Download all tagged images in the repository :下载存储库中所有标记的图像

使用 --registry-mirror选项
1.修改: /etc/default/docker
2.添加: DOCKER_OPTS=“ --registry-mirror=http://MIRROR-ADDR”
https://www.daocloud.io
获取和推送镜像-推送镜像
$docker push NAME[:TAG]

Docker–构建镜像
docker-构建镜像的好处:
  • 保存对容器的修改,并再次使用
  • 自定义镜像的能力
  • 以软件的形式打包并分发服务及其运行环境
docker构建镜像的方式:
$docker commit 通过容器构建
$docker build 通过Dockerfile文件构建
docker-使用commit构建镜像
$docker commit [options] container [repository] [:tag]
-a--author=""  Author   
                  e.g.,"chj@qq.com"
                  
-m--message=""  Commit message    : 记录镜像构建的信息

-p --pause=true  Pause container during commit   :指示commit命令可以不暂停正在执行的命令
docker-使用Dockerfile构建镜像
1.创建Dockerfile
2.使用 $ docker build 命令

创建第一个Dockerfile
  #First Dockerfile
  FROM centos:7
  MAINTEINER dormancypress "chj@qq.com"
  RUN yum update
  RUN yum install -y nginx
  EXPOSE 80
  
  $docker build [OPTIONS] PATH | URL | -
  --force-rm=false
  --no-cache=false
  --pull=false
  -q,--quiet=false
  -rm=true
  -t,--tag=""  : 为了指定构建处镜像的名字

Docker客户端与守护进程
Docker的C/S模式

server-client

docker的C/S模式结构可以如下图:

这里写图片描述

docker 的守护进程即server端运行在宿主机上,守护进程在启动后一直在后端运行,而用户不会直接和守护进程交互,而是和docker的客户端即docker命令行接口交互,从用户接受命令传递给守护进程。守护进程接受到命令后执行并返回运行结果。


server-RemoteAPI

除了使用docker命令行接口与server端进行通信外,还可以使用Remote API进行通信。它是一种RESTful风格的API,即可自行编写程序与docker进行集成。这样的C/S架构的模式如下图:

这里写图片描述

C/S模式的连接方式

docker客户端和守护进程间通过socket进行连接,docker提供了三种连接模式:

unix:///var/run/docker.sock
tcp://host:port
fd://socketfd

其中,unix:///var/run/docker.sock是默认的连接方式们可以通过配置修改为其他的连接方式。

这里写图片描述

这样意味着docker的client和server可以在一台服务器上或不同服务器上

实验:

通过执行ps -ef | grep docker来查看docker是否运行,如果docker在运行,name执行docker version查看docker的版本

这里写图片描述

这里执行的docker version命令就是利用docker的client端来和server端进行交互的

想要通过RemoteAPI来和docker进行交互,则通过nc -U /var/run/docker.sock来连接docker的socket,然后通过输入GET请求来获取server端信息:

这里写图片描述

docker的远程访问
环境准备

两台虚拟机,安装docker,确保docker的client和version的版本一致。

修改服务端启动文件

在centos7下docker的启动文件为/etc/sysconfig/docker,打开这个文件,加入如下的一行:

OPTIONS=‘–label name=docker_server_1 -H tcp://0.0.0.0:2375’
1
-H 在启动中指定docker的socket连接方式,远程连接指定tcp连接。

修改完后重启服务端docker服务:

service docker restart

然后查看本机的ip地址,这里我的是:192.168.177.138,在客户端使用curl命令进行远程连接:

curl http://192.168.177.138:2375/info

这里写图片描述

可以看到成功显示出了info接口的信息,且label的名字是在server端设置的label名,说明客户端成功远程连接了server端。

上边的通过curl的方式连接其实是RESTfulAPI的连接,也可以通过docker的client命令行连接,同样通过-H指定连接方式,命令如下:

docker -H tcp://192.168.177.138:2375/ info
同样输出了第一台服务器docker的info信息

简化连接命令

上述的连接命令都要使用-H来制定连接的服务端ip,docker提供了默认的环境变量DOCKER_HOST,通过设置它的值为需要连接的服务端ip来在命令中省去-H参数,设置如下:

export DOCKER_HOST=“tcp://192.168.177.138:2375/”

这样,现在使用命令docker info连接的就是服务端的docker的info信息了。

当使用完毕,可以将这个环境变量置空:export DOCKER_HOST=“”,这样再连接就是本地docker了。

设置docker远程连接的主机可以连接本机
在设置了远程连接的服务器上运行docker info会发现:

这里写图片描述

这时可以这样设置,修改启动配置文件中刚增加的OPTIONS为:

OPTIONS=‘–label name=docker_server_1 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock’

可以看出-H指定的连接方式可以是多个

然后重启docker服务就可以本地连接了。


Docker守护进程的配置和操作
查看守护进程
$ ps -ef | grep docker
$ sudo status docker
使用service命令管理
$ sudo service docker start
$ sudo service docker stop
$ sudo service docker restart
Docker的启动选项
docker -d [options]  : -d代表以守护进程来运行docker的程序

运行相关:
-D,--debug=false   :debug模式的开启
-e,--exec-driver="native"  
-g,--graph="/var/lib/docker"  
-icc=true      :
-l,-log-level="info"     
--label=[]   :
-p,--pidfile="/var/run/docker.pid"   

Docker服务器连接相关:
-G --group="docker"  :用户组
-H --host=[]         :对连接socket的配置
--tls=false          :安全性相关的一系列选项
--tlscacert="/home/sven/.docker/ca.pem"
--tlscert="/home/sven/.docker/cert.pem"
--tlskey="/home/sven/.docker/key.pem"
--tlsverify=false

RemoteAPI相关:
-api-enable-cors=false    :包含了RemoteAPI相关的选项

存储相关:
-s,--storage-driver=""      :存储驱动选项
--selinux-enabled=false     :
--storage-opt=[]            :

Registry相关:
--insecure-registry=[]   :Registry仓库设置相关的选项
--registry-mirror=[]     :

网络设置相关:
-b,--bridge=""
--bip=""
--fixed-cidr=""
--fixed-cidr-v6=""
--dns=[]
--dns-search=[]

--ip=0.0.0.0
--ip-forword=true
--ip-masq=true
--iptables=true
--ipv6=false
--mtu=0
启动配置文件
ubuntu的配置文件路径: /etc/default/docker
centos7的配置文件路径: /etc/docker/daemon.json
Docker的远程访问
环境准备

1.第二台安装Docker的服务器

2.修改Docker守护进程启动选项,区别服务器

3.保证Client API 与Server API版本一致

修改服务器端配置
修改Docker守护进程启动选项
-H     unix:///var/run/docker.sock
       tcp://host:port
       fd://socketfd
       守护进程默认配置:
       -H unix:///var/run/docker.sock

Dockerfile指令 -指令格式

FROM

功能为指定基础镜像,并且必须是第一条指令。

如果不以任何镜像为基础,那么写法为:FROM scratch。

同时意味着接下来所写的指令将作为镜像的第一层开始

语法:

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest> 

三种写法,其中和 是可选项,如果没有选择,那么默认值为latest

RUN

功能为运行指定的命令

RUN命令有两种格式

1. RUN <command>  (shell模式)
2. RUN ["executable", "param1", "param2"]  (exec模式)

第一种后边直接跟shell命令

  • 在linux操作系统上默认 /bin/sh -c
  • 在windows操作系统上默认 cmd /S /C

第二种是类似于函数调用。

可将executable理解成为可执行文件,后面就是两个参数。

两种写法比对:

  • RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME
    
  • RUN ["/bin/bash", "-c", "echo hello"]
    

注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层.

多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。

RUN书写时的换行符是\

CMD

功能为容器启动时要运行的命令

语法有三种写法

1. CMD ["executable","param1","param2"]
2. CMD ["param1","param2"]
3. CMD command param1 param2

第三种比较好理解了,就时shell这种执行方式和写法

第一种和第二种其实都是可执行文件加上参数的形式

举例说明两种写法:

  • CMD [ "sh", "-c", "echo $HOME" 
    
  • CMD [ "echo", "$HOME" ]
    

补充细节:这里边包括参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。

原因是参数传递后,docker解析的是一个JSON array

RUN & CMD

不要把RUN和CMD搞混了。

RUN是构件容器时就运行的命令以及提交运行结果

CMD是容器启动时执行的命令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子

LABEL

功能是为镜像指定标签

语法:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

一个Dockerfile种可以有多个LABEL,如下:

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号

如下:

LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"

说明:LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖

MAINTAINER

指定作者

语法:

MAINTAINER <name>

EXPOSE

功能为暴露容器运行时的监听端口给外部

但是EXPOSE并不会使容器访问主机的端口

如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P参数

ENV

功能为设置环境变量

语法有两种

1. ENV <key> <value>
2. ENV <key>=<value> ...

两者的区别就是第一种是一次设置一个,第二种是一次设置多个

ADD

ADD包含类似tar的解压功能

一个复制命令,把文件复制到镜像中。

如果把虚拟机与容器想象成两台linux服务器的话,那么这个命令就类似于scp,只是scp需要加用户名和密码的权限验证,而ADD不用。

语法如下:

1. ADD <src>... <dest>
2. ADD ["<src>",... "<dest>"]

路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径

可以是一个本地文件或者是一个本地压缩文件,还可以是一个url

如果把写成一个url,那么ADD就类似于wget命令

如以下写法都是可以的:

  • ADD test relativeDir/ 
    
  • ADD test /relativeDir
    
  • ADD http://example.com/foobar /
    

尽量不要把写成一个文件夹,如果是一个文件夹了,复制整个目录的内容,包括文件系统元数据

COPY

看这个名字就知道,又是一个复制命令

语法如下:

1. COPY <src>... <dest>
2. COPY ["<src>",... "<dest>"]

与ADD的区别

COPY的只能是本地文件,其他用法一致

ENTRYPOINT

功能是启动时的默认命令

语法如下:

1. ENTRYPOINT ["executable", "param1", "param2"]
2. ENTRYPOINT command param1 param2

如果从上到下看到这里的话,那么你应该对这两种语法很熟悉啦。

第二种就是写shell

第一种就是可执行文件加参数

与CMD比较说明(这俩命令太像了,而且还可以配合使用):

\1. 相同点:

  • 只能写一条,如果写了多条,那么只有最后一条生效
  • 容器启动时才运行,运行时机相同

\2. 不同点:

  • ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖
  • 如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数

如下:

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
  • 如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效

如下:

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ls -al

那么将执行ls -al ,top -b不会执行。

Docker官方使用一张表格来展示了ENTRYPOINT 和CMD不同组合的执行情况

(下方表格来自docker官网)

img

VOLUME

可实现挂载功能,可以将内地文件夹或者其他容器种得文件夹挂在到这个容器中

语法为:

VOLUME ["/data"]

说明:

[“/data”]可以是一个JsonArray ,也可以是多个值。所以如下几种写法都是正确的

VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db

一般的使用场景为需要持久化存储数据时

容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。

所以当数据需要持久化时用这个命令。

USER

设置启动容器的用户,可以是用户名或UID,所以,只有下面的两种写法是正确的

  • USER daemo
    
  • USER UID
    

注意:如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行

USER user

USER user:group

USER user:gid

USER uid

USER uid:gid

USER uid:group

如果不使用user指令指定用户,会默认用使用root用户

WORKDIR

语法:

WORKDIR /path/to/workdir

设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次。

如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

pwd执行的结果是/a/b/c

WORKDIR也可以解析环境变量

如:

ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

pwd的执行结果是/path/$DIRNAME

ARG

语法:

ARG <name>[=<default value>]

设置变量命令,ARG命令定义了一个变量,在docker build创建镜像的时候,使用 --build-arg =来指定参数

如果用户在build镜像时指定了一个参数没有定义在Dockerfile中,那么将有一个Warning

提示如下:

[Warning] One or more build-args [foo] were not consumed.

我们可以定义一个或多个参数,如下:

FROM busybox
ARG user1
ARG buildno
...

也可以给参数一个默认值:

FROM busybox
ARG user1=someuser
ARG buildno=1
...

如果我们给了ARG定义的参数默认值,那么当build镜像时没有指定参数值,将会使用这个默认值

ONBUILD

语法:

ONBUILD [INSTRUCTION]

这个命令只对当前镜像的子镜像生效。

比如当前镜像为A,在Dockerfile种添加:

ONBUILD RUN ls -al

这个 ls -al 命令不会在A镜像构建或启动的时候执行

此时有一个镜像B是基于A镜像构建的,那么这个ls -al 命令会在B镜像构建的时候被执行。

STOPSIGNAL

语法:

STOPSIGNAL signal

STOPSIGNAL命令是的作用是当容器推出时给系统发送什么样的指令

HEALTHCHECK

容器健康状况检查命令

语法有两种:

1. HEALTHCHECK [OPTIONS] CMD command
2. HEALTHCHECK NONE

第一个的功能是在容器内部运行一个命令来检查容器的健康状况

第二个的功能是在基础镜像中取消健康检查命令

[OPTIONS]的选项支持以下三中选项:

–interval=DURATION 两次检查默认的时间间隔为30秒

–timeout=DURATION 健康检查命令运行超时时长,默认30秒

–retries=N 当连续失败指定次数后,则容器被认为是不健康的,状态为unhealthy,默认次数是3

注意:

HEALTHCHECK命令只能出现一次,如果出现了多次,只有最后一个生效。

CMD后边的命令的返回值决定了本次健康检查是否成功,具体的返回值如下:

0: success - 表示容器是健康的

1: unhealthy - 表示容器已经不能工作了

2: reserved - 保留值

例子:

HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1

健康检查命令是:curl -f http://localhost/ || exit 1

两次检查的间隔时间是5秒

命令超时时间为3秒


DockerFile构建过程
  1. 从基础镜像运行一个容器
  2. 执行一条指令,对容器做出修改
  3. 执行类似docker commit的操作, 提交一个新的镜像层
  4. 再基于刚提交的镜像运行一个新容器
  5. 执行Dockerfile中的下一条指令,知道所有指令执行完毕

Docker容器的网络基础
Docker容器的网络基础-docker0

Linux虚拟网桥:OSI七层模型中的网桥:数据链路层

Linux虚拟网桥的特点

  • 可以设置ip地址
  • 相当于拥有一个隐藏的虚拟网卡

Docker的地址划分:

  • IP:172.17.42.1
  • 子网掩码:255.255.0.0
  • MAC:02:42:ac:11:00:00 到 02:42:ac:11:ff:ff
  • 总共提供了65534个地址
docker容器的网络基础-自定义docker0

修改docker0地址:

$ sudo ifconfig docker0 192.168.200.1 netmask 255.255.255.0

Docker容器的网络基础-自定义虚拟网桥
添加虚拟网桥
$ sudo brctl addbr br0
$ sudo ifconfig br0 192.168.100.1 netmask 255.255.255.0
更改centos7中docker守护进程的启动配置:
/etc/docker/daemon.json 中添加DOCKER——OPS的值 
-b=bro
MAC是什么?

MAC地址英语:Media Access Control Address),直译为媒体存取控制位址,也称为局域网地址(LAN Address),MAC位址以太网地址(Ethernet Address)或物理地址(Physical Address),它是一个用来确认网络设备位置的位址。在OSI模型中,第三层网络层负责IP地址,第二层数据链路层则负责MAC位址 [1] 。MAC地址用于在网络中唯一标示一个网卡,一台设备若有一或多个网卡,则每个网卡都需要并会有一个唯一的MAC地址 。

通俗解释:

身份证就是用来证明一个人的身份。平日身份证的作用并不是很大,但是到了有的关键时刻,必须有身份证来说明一个人的一切。那么,IP地址与MAC地址绑定,就如同在日常生活中一个人与身份证的关系。因为,IP地址可以随意的,但MAC地址是唯一说明IP地址身份的。例如,为防止IP地址被盗用,通常交换机的端口绑定(端口的MAC表使用静态表项),可以在每个交换机端口只连接一台主机的情况下防止修改MAC地址的盗用,如果是三层设备还可以提供交换机端口、IP地址和MAC地址三者的绑定

MAC与IP地址区别:

IP地址和MAC地址相同点是它们都唯一,不同的特点主要有:

  1. 对于网络上的某一设备,如一台计算机或一台路由器,其IP地址是基于网络拓扑设计出的,同一台设备或计算机上,改动IP地址是很容易的(但必须唯一),而MAC则是生产厂商烧录好的,一般不能改动。我们可以根据需要给一台主机指定任意的IP地址,如我们可以给局域网上的某台计算机分配IP地址为192.168.0.112 ,也可以将它改成192.168.0.200。而任一网络设备(如网卡,路由器)一旦生产出来以后,其MAC地址不可由本地连接内的配置进行修改。如果一个计算机的网卡坏了,在更换网卡之后,该计算机的MAC地址就变了 [5] 。

  2. 长度不同。IP地址为32位,MAC地址为48位 [5] 。

  3. 分配依据不同。IP地址的分配是基于网络拓扑,MAC地址的分配是基于制造商 [8] 。

  4. 寻址协议层不同。IP地址应用于OSI第三层,即网络层,而MAC地址应用在OSI第二层,即数据链路层。 数据链路层协议可以使数据从一个节点传递到相同链路的另一个节点上(通过MAC地址),而网络层协议使数据可以从一个网络传递到另一个网络上(ARP根据目的IP地址,找到中间节点的MAC地址,通过中间节点传送,从而最终到达目的网络)

​ ------百度百科


Docker容器的互联
Docker容器的互联-环境准备
用于测试的Docker镜像Dockerfile:
FROM centos:7
RUN yum install -y ping
RUN yum update
RUN yum install -y nginx
RUN yum install -y curl
EXPOSE 80
CMD /bin/bash
Docker容器的互联 -允许所有容器间互联
Docker守护进程的启动选项
--link
$ docker run --link=[CONTAINER_NAME]:[ALIAS]  [IMAGE] [COMMOND]
Docker容器的互联-拒绝所有容器间互联
Docker守护进程的启动选项
 -icc=false
Docker容器互联-允许特定容器间互联
Docker守护进程的启动选项
--icc=false 
--iptables=true
--link

Docker容器与外部网络的 连接
Docker容器与外部网络的 连接-ip_forward
--ip=forward=true
$ sysctl net.ipv4.conf.all.forwarding
Docker容器与外部网络的 连接-ip_tables

什么是iptables
iptables是与Linux内核集成的包过滤防火墙系统,几乎所有的Linux发行版本都会包含iptables的功能。

Iptables

表(table)
链(chain)
规则(rule)
ACCEPT、REJECT、DROP

每一个大的方块中,就是iptables中的一个链(chain),每一个链实际上就是数据处理中的一个环节,而在每个环节中又包含了不同的操作。

  • 允许端口映射访问

  • 限制IP访问容器

实质都是通过iptables的规则来控制的。


Docker容器的数据管理
Docker-Docker容器的数据卷-什么是数据卷

什么是数据卷(Data Volume)

  1. 数据卷是经过特殊设计的目录,可以绕过联合文件系统(UFS),为一个或多个容器提供访问。

  2. 其设计目的在于数据的永久化,数据卷是存在于宿主机中的文件或者目录,因此它与Docker容器的生命周期是完全分离的,Docker不会在容器删除时删除其挂载的数据卷,也不会存在类似的垃圾收集机制,对容器引用的数据卷进行处理。

数据卷的架构:

img

数据卷的特点:

  1. 数据卷在容器启动时初始化,如果容器使用的镜像再挂载点包含了数据,这些数据会拷贝到新初始化的数据卷中。
  2. 数据卷可以在容器之间共享和重用
  3. 可以对数据卷里的内容直接进行修改
  4. 数据卷的变化,不会影响镜像的更新
  5. 卷会一直存在,即使挂载数据卷的容器已经被删除
Docker-Docker容器的数据卷-数据卷的使用
在容器启动时,为容器添加数据卷需要用到 docker run 命令的 -v 选项:
docker run -v <宿主机文件或目录>:<对应的容器目录>[:ro ] [image]
$docker run -v ~/container_data:/data -it centos:7 /bin/bash

为数据卷添加访问权限
$ docker run -v ~/datavolume:/data:ro -it centos:7 /bin/bash  : ro只读权限


使用Dockerfile构建包含数据卷的镜像
Dockerfile指令:
VOLUME["/data"]
Docker的是数据卷容器-数据卷容器

什么是数据卷容器:

命名的容器挂载数据卷,其它容器通过挂载这个容器实现数据共享,挂载数据卷的容器,就叫做数据卷容器。

使用数据卷容器共享数据的架构:

img

挂载数据卷容器的方法:

$docker run --volumes from [CONTAINER NAME]
Docker数据卷的备份和还原-数据备份
数据卷的备份和还原本质上就是系统文件的备份和还原。
数据备份方法
docker run --volumes-from [container name] -v $(pwd):/backup centos:7 tar cvf /backup/backup.tar [container data volume]

 数据备份实例:
 
[root@localhost dockerfiles]# docker run --volumes-from volume1 -v ~/backup:/backup --privileged=true centos tar cvf backup/volume.tar usr/local/volume


数据还原方法
docker run --volumes-from [container name] -v $(pwd):/backup centos:7 tar xvf /backup/backup.tar [container data volume] 

数据还原实例:
[root@localhost dockerfiles]# docker run --volumes-from volume1 -v ~/backup:/backup --privileged=true centos tar xvf backup/volume.tar usr/local/volume
 

Docker-Docker容器的跨主机连接
Docker-Docker容器的跨主机连接 - 使用网桥实现跨主机容器连接

​ 在同一宿主机下的Docker的容器之间是默认互相联通的。在容器内通过ifconfig可以查看到ip地址。在不同的容器中来执行ping是可以ping通的。

但我们通过观察发现,每一个启动容器的ip地址不是固定的,所以如果我们通过ip地址来实现互连明显是不靠谱的。但我们发现这些ip又处于同一网段中而且默认是172.17.0.X,这就是Docker容器默认跨主机之间的链接方法的第一种:网桥实现

在docker宿主机上运行ifconfig命令可以看的存在一个docker0的网桥。Docker容器通过docker0 网桥实现同一主机间中,容器的ip地址分配和访问,所以,如果希望Docker跨主机访问,最简单的方式就是将不同主机的docker0 设置为同一网段。

整个网络的拓扑结构图:
这里写图片描述

使用网桥实现跨主机容器连接 - 环境准备
  • 2台ubuntu虚拟机,
  • 在2个虚拟机中分别安装网桥管理工具(apt-get install bridge-utils),
  • 2台机器的ip地址分别是10.211.55.3,10.211.55.5
使用网桥实现跨主机容器连接 - 网络设置

在虚拟机中配置网桥的连接:修改网络配置文件/etc/network/interfaces来实现网桥的配置和添加。这些命令指定了要建立网桥的名称,ip分配的方式,子网掩码,默认的网关,以及指明了将本地的物理网卡连接到新建的网桥上:

auto br0

iface br0 inet static

address 10.211.55.3

netmask 255.255.255.0

gateway 10.211.55.1

bridge_ports eth0
使用网桥实现跨主机容器连接 - Docker设置
在docker端需要为docker的守护进程指定2个启动配置选项:

修改/etc/default/docker文件(这是docker守护进程启动配置文件)

-b指定自定义网桥的名字:-b=br0

--fixed-cidr指定的是自定义网桥为容器分配ip地址时使用的ip段,为了避免在2台主机中的容器的ip地址产生冲突,

HOST1 : 10.211.54.64/26

地址范围:10.211.55.65  ~ 10.211.55.126

HOST2 : 10.211.55.128/26

地址范围:10.211.55.129 ~ 10.211.55.190
两台主机的具体配置如下:

第一台主机:

$sudo apt-get install bridge-utils

$sudo vim /etc/network/interfaces

auto br0

iface br0 inet static

address 10.211.55.3

netmask 255.255.255.0

gateway 10.211.55.1

bridge_ports enp0s25(本机网卡名)

 

$sudo vim /etc/default/docker

DOCKER_OPTS=”-b=br0  --fixed-cidr=10.211.54.64/26”

 

$sudo reboot  :  重启系统

第二台主机:

$sudo apt-get install bridge-utils

$sudo vim /etc/network/interfaces

auto br0

iface br0 inet static

address 10.211.55.5

netmask 255.255.255.0

gateway 10.211.55.1

bridge_ports eth0

 

$sudo vim /etc/default/docker

DOCKER_OPTS=“-b=br0  --fixed-cidr=10.211.55.128/26”

 

$sudo reboot  :  重启系统

验证:

1.分别在两个Host上启动一个容器

$ docker run -it ubuntu /bin/bash

2.在容器中运行ping命令查看连接情况

使用网桥实现跨主机容器连接 - 总结

**优点:**配置简单,不依赖第三方软件

**缺点:**与主机在同网段,需要小心划分IP地址,需要有网段控制权,在生产环境中不易实现,不容易管理,兼容性不佳。


Docker-Docker容器的跨主机连接 - 使用Open vSwitch实现跨主机容器连接

Open vSwitch是什么?

Open vSwitch是一个开源的虚拟的交换机软件,实际上Open vSwitch是一个高质量的、多层虚拟交换机,使用开源Apache2.0许可协议,由Nicira Networks开发,主要实现代码为可移植的c代码。他的目的是让大规模网络自动化可以通过变成扩展,同时仍然支持标准的管理接口和协议(例如:NetFlow,sFlow,SPAN,RSPAN,CLI.802.1ag)

使用Open vSwitch实现跨主机容器连接 - 原理

img

GRE隧道

GRE:通用路由协议封装

隧道技术:是一种通过使用互联网的基础设施在网络的基础设施在网络之间传递数据的方式。使用隧道传递的数据可以是不同协议的数据帧或包。隧道协议将其它协议的数据帧或包重新封装然后通过隧道发送。新的帧头提供路由信息,以便通过互联网传递被封装的负载数据。

环境装备:

a.安装Open vSwitch

sudo apt-get install openvswitch-switch

b.安装网桥

sudo apt-get install bridge-utils

c.IP地址

Host1:192.168.59.103
Host2:192.168.59.104
操作:

1、查看ovs的状态

$sudo ovs-vsctl show

2、建立ovs网桥

$sudo ovs-vsctl add-br obr0(网桥名称)

3、添加GRE接口

$sudo ovs-vsctl add-port obr0 gre0(gre名字)

4、设置GRE接口

$sudo ovs-vsctl set interface gre0(gre名字) type=gre option:remote_ip=192.168.59.104(指定我们需要连接的远程服务器的地址,也就是我们索要连接的另一台虚拟机的地址)

5、查看ovs设置的状态

$sudo ovs-vsctl show

6、建立本机docker容器需要使用的虚拟网桥

$sudo brctl addbr br0(网桥名称)

7、为br0设置网络地址

$sudo ifconfig br0 192.168.1.1 netmask 255.255.255.0

8、为br0网桥添加ovs网桥的连接

$sudo brctl addif br0 obr0

9、查看ovs设置的状态

$sudo ovs-vsctl show

10、配置docker用我们新建的网桥来配置dcoker0

DOCKER_OPTS=" -b=br0"

11、重启docker服务

$sudo service docker restart

12、创建一个容器

$ping另一台主机可以ping通,却ping不通另一个主机的里的容器

这是因为对于不通网段来说,我们需要通过路由表来确定不通网段网络的地址
13、查看当前的路由表

$route

14、添加容器使用网段路由信息

$sudo ip route add 192.168.2.0/24(网段的名) via 192.168.59.104(告诉路由器查找网段的地址) dev eth0(指定查找设备,通过本机的eth0网卡)

总结:比网桥连接复杂些,但是能够有效的跨越网络中的障碍来实现网络中容器之间的连接。虽然复杂,但是可以将操作写成脚本将操作自动化。

Docker-Docker容器的跨主机连接 - 使用weave实现跨主机容器连接

weave简介

语义:编织

weave:开源的。建立一个虚拟的网络,用于将运行在不同主机的docker容器连接起来。

img

环境准备

IP地址
Host1:192.168.59.103
Host2:192.168.59.104

操作:

1、下载weave

$sudo wget -O /usr/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave

通过github网址下载weave并且保存在本地/usr/bin/weave文件夹下
2、更改weave文件夹的模式,让他可以执行

$sudo chmod a+x /usr/bin/weave

这样weave就可以使用了
3、启动weave

$weave launch

在启动weave时,实际上会在docker上运行一个weave的容器。
4、配dockerhost2
5、dockerHost2中运行

$weave launch 192.168.59.103

这时和第一个不一样,要将dockerHost1的IP地址传入,这是为了使两个dickerhost能够正确的连接在一起。
6、在dockerHost2使用veavw创建一个容器

$c2=$(weave launch 192.168.1.2/24(这个IP地址就是在将要启动的容器中分配的IP地址,这个IP就是weave来维护的) -it ubuntu /bin/bash)

7、在dockerHost1使用veavw创建一个容器

weave launch 192.168.1.10/24 -it --name wec1 ubuntu /bin/bash

8、这时ping另一个容器就很容易ping通了

其他特性

  • 应用隔离:不同子网容器之间默认隔离的,即便它们位于同一台物理机上也相互不通(使用-icc=false关闭容器互通);不同物理机之间的容器默认也是隔离的

  • 安全性:可以通过weave launch -password wEaVe设置一个密码用于weave peers之间加密通信

  • 查看weave路由状态:weave ps

总结:使用weave工具非常容易的为docker容器指定一个我们任意希望分配的IP地址,并且非常方便来划分IP地址段,从而将不同主机的容器划分在不通的网段中。
不但可以实现跨主机的容器连接,而且非常方便的来限定跨主机的方式运用什么样的方式来连接。

后记:

文章持续更新,如果喜欢,请拿起你们可爱的小手,给我点个赞吧!

点赞是一种积极的生活态度,赞一个吧!

show


10、配置docker用我们新建的网桥来配置dcoker0



```bash
DOCKER_OPTS=" -b=br0"

11、重启docker服务

$sudo service docker restart

12、创建一个容器

$ping另一台主机可以ping通,却ping不通另一个主机的里的容器

这是因为对于不通网段来说,我们需要通过路由表来确定不通网段网络的地址
13、查看当前的路由表

$route

14、添加容器使用网段路由信息

$sudo ip route add 192.168.2.0/24(网段的名) via 192.168.59.104(告诉路由器查找网段的地址) dev eth0(指定查找设备,通过本机的eth0网卡)

总结:比网桥连接复杂些,但是能够有效的跨越网络中的障碍来实现网络中容器之间的连接。虽然复杂,但是可以将操作写成脚本将操作自动化。

Docker-Docker容器的跨主机连接 - 使用weave实现跨主机容器连接

weave简介

语义:编织

weave:开源的。建立一个虚拟的网络,用于将运行在不同主机的docker容器连接起来。

[外链图片转存中…(img-7mwRjck6-1591107709122)]

环境准备

IP地址
Host1:192.168.59.103
Host2:192.168.59.104

操作:

1、下载weave

$sudo wget -O /usr/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave

通过github网址下载weave并且保存在本地/usr/bin/weave文件夹下
2、更改weave文件夹的模式,让他可以执行

$sudo chmod a+x /usr/bin/weave

这样weave就可以使用了
3、启动weave

$weave launch

在启动weave时,实际上会在docker上运行一个weave的容器。
4、配dockerhost2
5、dockerHost2中运行

$weave launch 192.168.59.103

这时和第一个不一样,要将dockerHost1的IP地址传入,这是为了使两个dickerhost能够正确的连接在一起。
6、在dockerHost2使用veavw创建一个容器

$c2=$(weave launch 192.168.1.2/24(这个IP地址就是在将要启动的容器中分配的IP地址,这个IP就是weave来维护的) -it ubuntu /bin/bash)

7、在dockerHost1使用veavw创建一个容器

weave launch 192.168.1.10/24 -it --name wec1 ubuntu /bin/bash

8、这时ping另一个容器就很容易ping通了

其他特性

  • 应用隔离:不同子网容器之间默认隔离的,即便它们位于同一台物理机上也相互不通(使用-icc=false关闭容器互通);不同物理机之间的容器默认也是隔离的

  • 安全性:可以通过weave launch -password wEaVe设置一个密码用于weave peers之间加密通信

  • 查看weave路由状态:weave ps

总结:使用weave工具非常容易的为docker容器指定一个我们任意希望分配的IP地址,并且非常方便来划分IP地址段,从而将不同主机的容器划分在不通的网段中。
不但可以实现跨主机的容器连接,而且非常方便的来限定跨主机的方式运用什么样的方式来连接。

后记:

文章持续更新,如果喜欢,请拿起你们可爱的小手,给我点个赞吧!

点赞是一种积极的生活态度,赞一个吧!

  • 10
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值