docker容器二探—docker网络、存储卷和Dockerfile

---------------------------------------------------------------------------------------------------------------------------------------------

一、docker网络

    创建一组虚拟网卡

    一半在虚拟机或容器上,作为通信接口

    另一半在宿主机上,并且被关联到一个选定的桥设备

    要想docker内的某个服务被外网访问,需要将该docker做dnat

    容器之间虽然可以隔离,不过可以通过网络回环连接起来 

二、docker四种网络模式

docker network ls

bridge:桥接网络,docker0桥默认172.17.0.0/16网段,网关是172.17.0.1,NAT模式

host:共享宿主机的网络

none:回环网络

注意:作为vmware宿主机的windows应该可以ping通docker0,如果ping不通,windows以管理员身份运行cmd,添加路由:route add -p 172.17.0.0 mask 255.255.255.0 192.168.239.1

其中172.17.0.0是我docker0的网段,192.168.239.1是我windows连接vmware的ip

三、docker容器可加入的4种网络演示:

1、封闭式容器,回环网络,--net none

docker run --name bbox1 -it --network none busybox

进入ifconfig -a只有lo网卡,是个完全式的隔离容器

2、桥接式网络,--net bridge

docker run --name bbox -it --network bridge  --rm busybox

docker run --name bbox2 -it --network bridge  --rm busybox

进入交互界面两个可以互ping通

3、联盟式容器:独立的运行空间,但底层网络共享

还是刚才的网络,退出bb2,此时bb2会自动被删除,继续建立bb2,不过更换--net选项

docker run --namebb2 -it --net container:bb2

在bb1上执行以下指令

注:wget -O - -q:此命令可以将wget当做浏览器使用,-O - 表示输入到当前终端,-q 表示静默输出

4、容器之间共享宿主机的网络,监听宿主机IP地址

docker run --name bb2 -it --network host --rm busybox

在bb2上mkdir /data,vi /data/index.html,输入内容,之后httpd -h /data,完成后在windows浏览器输入dokcer0的ip可以打开看到bb2编写的index.html

四、暴露服务

示例

1、docker port :查看docker端口

docker port -p 80

docker port tiny-web1

然后,32768是系统随机选择的一个端口


2、docker容器内的80映射到宿主机的11800,宿主机的80不能被占用

docker run --name tiny-web11 --rm -p 11800:80 tiny-httpd:v0.0.5

如果是已建好镜像添加端口映射,有两种方法:

(1)将容器提交为镜像,docker commit -a "container id" -m "a NEWIMAGE" web aaa:v1,之后再新建并添加端口(不推荐)

(2)修改/var/lib/docker/containers/CONTAINERID/hostconfig.json,CONTAINERID使用命令docker inspect NAME来查看,

"PortBindings": {

    "888/tcp": [

      {

        "HostIp": "",

        "HostPort": "12888"

      }

    ],

    "21/tcp": [                                            #此行新添映射端口

      {

        "HostIp": "",

        "HostPort": "21"

      }

    ]

}

这里888是容器端口, 12888是本地端口

相同的目录下找到config.v2.json,该文件中有两处需要修改

"ExposedPorts": {

  "888/tcp": {},

  "21/tcp": {}

}


"Ports": {

    "888/tcp": [

        {

          "HostIp": "0.0.0.0",

          "HostPort": "12888"

        }

    ],

    "21/tcp": [                                             #此行新添映射端口

        {

          "HostIp": "0.0.0.0",

          "HostPort": "21"

        }

    ]

}

修改完重启docker服务,启动docker容器

3、建立一个容器,容器80端口号映射到宿主机172.20.0.66的8080端口上,该容器关闭后自动删除

4、一个容器映射多个端口

docker run --name tiny-web1 --rm -p 80 -p 445 -p 22 -p 139 httpd:2.4

三、docker network相关命令

docker network -h

1、docker network create -d bridge --gateway 10.0.0.1 --subnet 10.0.0.0/16 mynet0

改名 ifconfig br......down

ip link set br.... name docker1

docker run --name c1 --network mynet0 -it busybox,此时该容器就在mynet0网段

不过目前为止,更改名称后无法建立docker,系统报错找不到br-xxxxxxxx,但未改名称就可以建立容器,之后有结果

2、将容器加入网络

将容器上剥离网络

3、移除网络

docker network rm mynet0

四、docker的存储卷

1、联合挂载

关闭并重启容器,其数据不受影响,但删除Docker容器,则其修改的数据全部丢失

新增在可写层新增

修改复制上一层到本层进行修改

删除给该文件加隐藏标签

因此所有操作不影响底层镜像

2、数据卷特定:

容器之间可以共享数据卷,并且也可以重复利用

对于存储卷的改变是直接保存在数据卷上

当更新一个镜像不会影响更改存储卷

删除容器时并不会删除存储卷

五、存储卷类型

一个存储器可以创建多个存储卷,即-v多指定几个

1、绑定挂载卷:手工建立容器的目录与宿主机目录的对应关系

2、docker管理卷,非固定的动态卷,docker自行决定

docker run --name v1 -it -v /data busybox

-v指明容器内的路径,不存在则自动创建

宿主机docker volume ls可看到有宿主机,看到VOLUMENAME

docker volume inspect VOLUMENAME,可以看到对应的路径

docker container inspect bb1,查看该容器卷目录

删除容器后,存储卷内容依然存在,此时如果用一个同样的指令创造容器,将不会显示存储卷内容

3、删除容器后再建立一个同位于卷目录的容器,容器内容依然存在,

4、如果建立多个容器,但它们的卷一样,则这两个容器共享存储卷

或者复制使用其它容器的卷,使用命令--volumes-from

使用b2容器输入指令

新建b4容器启动后验证

6、查看container inspect信息中,引用Mounts中的内容,.代表根

命令执行效果

注:一个存储器可以用多个存储卷,不过就是命令选项中多加几次-v

六、配置容器化应用

1、docker run 时通过自定义要运行的命令,并向传递命令行参数,从而达到配置它的目的

docker run --name ap1 -it httpd:latest /bin/bash

2、自定义镜像,将修改好的配置文件直接写进镜像层,做成镜像

3、通过环境变量更改配置

docker run -e

4、存储卷,将/etc/目录做成存储卷,容器使用存储卷启动

5、容器应该对自己进行周期性健康状态监测,并在不健康时通过restart自愈,或者其它操作来实现自愈的目的

七、Dockerfile注意点

Dockerfile是用来建立docker镜像的源码

1、第一条指令必须有FROM,需要基于基础镜像做,因此必须需要基础镜像

2、因为输入一条指令镜像便会啊向上生成一层,因此指令越少越好,能合成一条指令就不要用两条三条来完成

3、容器中的命令只基于基础镜像,和宿主机操作系统无关

八、Dockfile格式

1、文件格式

#后是注释,否则就会认为是指令+参数的格式

指令使用全大写,用来区别指令和参数

执行顺序:自上而下依次执行,不支持判断和循环

第一条指令必须用FROM 跟随基础镜像

2、环境变量

需要用ENV定义

定量表示:$variable_name或者${variarble_name}

${variable:-word},如果变量未声明或为空,则返回word的字符串值,即variable有值就返回它,没值就返回word

${variable:+word},如果变量variable有值就返回word,否则就为返回空

3、dockerignore file

九、Dockerfile介绍

1、FROM IMAGE:VERSION

FROM IMAGE@校验码

2、LABEL = = = ...

LABEL maintainer="chenux "

3、COPY

用户从Docker主机复制文件至创建的新映像文件

COPY

COPY ["",... ""]

示例:

mkdir /docker

vim /docker/Dockerfile

FROM alpine:3.6

LABEL maintainer="chenux "

COPY virt.repo /etc/yum.repos.d/  ------->拷贝workdir内的文件到容器内目录下

COPY httpd /etc/httpd/  -------->复制目录

cp /etc/yum.repos.d/virt.repo /docker

cp -r /etc/httpd /docker/

vim /docker/.dockerignore,排除复制时候拷贝的目录

docker image build -t testapp:v0.0.1 /docker ------>构建根据Dockerfile做出配置的镜像

启动容器查看

4、ADD类似于COPY指令,ADD支持使用TAR文件和URL路径,ADD自动将.tar文件展开到容器目标目录,将URL链接指向的文件自动下载到容器目录

5、WORKDIR

(1)当容器内目录太长时可用此选项,之后目标目录的可以用相对路径表示,为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录

(2)WORKDIR可使用多次,每次路径的表示都以最近的WORKDIR为参考

6、VOLUME,不支持绑定挂载

用于在image中传建一个挂载点目录,以挂载Docker host上的卷或者其它容器上的卷

VOLUME

VOLUME [""]

结果查看

7、EXPOSE

用于指定要暴露的端口

EXPOSE 80/tcp 8080/tcp

docker build -t bbi .

docker container run --name bmw -it -P --rm bbi

-P,暴露对应的容器镜像当中,暴露所有使用EXPOSE命令镜像的端口

8、ENV

用于为镜像定义所需的环境变量,-e选项用来传递环境变量

ENV 或者

ENV =

9、RUN,位于docker build的阶段中

用于指定docker build过程中运行的程序,这个程序可以是任何命令

RUN

RUN ["","",""]

本着能执行一条命令,就不执行两条命令的原则,可改成

结果

10、CMD,运行在docker container run阶段中,RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时

CMD

CMD ["","",""]

CMD ["",""]

11、ENTRYPOINT,运行在docker container run阶段中,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序

ENTRYPOINT

ENTRYPOINT ["","",""]

既有CMD,又有ENTRYPOINT的话,CMD的参数将会传递给ENTRYPOINT,如果ENTRYPOINT和CMD都有很多条,将以最后一条为准。二者同时有命令,会先执行ENTRYPOINT的,之后将CMD指令传给ENTRYPOINT的结果

如果默认使用一个命令或者镜像或者一个应用程序自身是不支持加载环境变量的,我们也能通过ENTRYPOINT脚本环境变量来获取新配置

简单举例

结果

Dockerfile中RUN、CMD、ENTRYPOINT区别:

1、RUN指令通常用于安装应用和软件包,在构建镜像时就已经执行了命令

2、CMD指令允许用户指定容器的默认执行的命令,此命令在容器启动且开启容器docker run没有指定其它命令时运行,如果镜像中写入的是CMD httpd -f /data,而在启动镜像时用命令docker run --name xxx -it xx:xx /bin/bash,此时进入镜像后/bin/bash便会覆盖掉CMD的指令httpd -f /data

3、ENTRYPOINT指令与CMD类似,只不过它的指令不会被docker run指令后的参数覆盖

第2条说明演示:

CMD结果

第3条说明演示:

结果

如果想覆盖ENTRYPOINT,加入--entrypoint

12、user

用于指定运行image时的或运行Dockerfile中任何RUN、CMD、ENTryPOINT指令指定的程序时的用户名或UID

默认情况下,container的运行身份为root用户

USER UID,UID必须为/etc/passwd中某用户的有效UID

USER UserName

13、HEALTHCHECK

健康状态监测

HEALTHCHECK [OPTIONS] CMD commad

--interval=30,默认30秒,间隔时长,每多长时间检测一次

--timeout=30,超时时长

--start-period=0,默认0秒,容器启动多久后开始检测

--retries=3,默认3此,重新尝试次数

退出码

0:success,容器健康

1:unhealthy,容器工作异常

2:reserved,不使用退出码

举例:

HEALTHCHECK --interval=5m --timeout=3s \

CMD curl -f http://localhost/ || exit 1

HEALTHCHECK NONE,不检测健康状态

14、SHELL,改变系统要调用的默认的shell程序,Linux默认["/bin/sh","-c"],windows默认["cmd","/S","/C"]

15、STOPIGNAL:停止信号

16、ARG,参数

17、ONBUILD,用于在Dockerfile中定义一个触发器,镶嵌在第二层中

演示有

将此作为镜像trig:1后,在此目录内继续建立一个目录,进入目录并再写一个Dockerfile,

之后建立镜像trig:2,启动后有

九、建立私有镜像仓库

1、yum -y install docker-registry,但包名叫做docker-distribution,查询相关安装路径rpm -ql docker-distribution,默认5000端口

2、vim /etc/docker-distribution/registry/config.yml,配置docker-distrubution服务

3、配置好后systemctl start docker-distribution,修改标签

此时直接推会报错,因为registry需要https协议的地址

4、关闭本地registry仓库的https安全要求,vim /etc/docker/daemon.json

保存退出后systemctl restart docker,再推送就成功了

十、在docker容器安装wordpress

1、由于wordpress已经被官方和热心网友做成了镜像,因此可以直接拿来使用

docker pull wordpress:4.9-php7.2-fpm-alpine,完成之后按照数据库

2、开启数据库

docker run --name wpdb -d -v /data/mydata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=chenux mysql:5.5.62

3、进入数据库容器授权

新建wpuser用户,对本机和网桥的设备进行授权

4、因为容器每一次的访问ip都会改变,因此这里最好指定容器的主机名

docker container run --name wordpress -d \

> -e WODPRESS_DB_HOST=localhost \

> -e WORDPRESS_DB_USER=wpuser \

> -e WORDPRESS_DB_PASSWORD=wppass \

> -e WORDPRESS_DB_NAME=wpdb \

> --network container:wpdb \

> wordpress:4.9-php7.2-fpm-alpine