docker容器的学习笔记

拟墨画扇 提交于 2020-12-12 19:11:08

[TOC]

Docker入门学习笔记(一)

  1. 什么是Docker?
  2. Docke的目标
  3. Docker通常应用场景
  4. Docker的基本组成
  5. Docker基本操作
  6. 守护式容器
  7. 在容器中部署静态网站

1. 什么是Docker?

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

2. Docke的目标

  • 提供简单轻量的建模方式
  • 职责的逻辑分离
  • 快速高效的开发周期
  • 鼓励面向服务的架构

3. Docker通常应用场景

  • 使用Docker容器开发、测试、部署服务
  • 创建隔离的运行环境
  • 搭建多用户的平台即服务(PaaS)基础设施
  • 提供软件即服务(SaaS)应用程序
  • 高性能、超大规模的宿主机部署

4. Docker的基本组成

  • Docker Client 客户端
  • Docker Daemon 守护进程(c/s架构,守护进程是服务器,可以是本地,也可以是远程)
  • Docker Image 镜像(一些只读层,root文件只有只读权限)
  • Docker Container 容器(通过镜像启动,在只读层上增加一个可写层)
  • Docker Registey 仓库(仓库存储镜像,公有和私有2种,公有的有Docker Hub,可以下载各种镜像)

补:Docker容器相关技术简介

Docker依赖的Linux内核特性

  • Namespaces命名空间
  • Control groups(cgroups)控制组

Namespaces命名空间(5种)

  • PID(Process ID)进程隔离
  • NET(Network)管理网络接口
  • IPC(InterProcess Communication)管理跨进程通信的访问
  • MNT(Mount)管理挂载点
  • UTS(Unix Timesharing System)隔离内核和版本标识

Control groups控制组

用来分配资源
来源于google
linux kernel 2.6.24@2007

  • 资源限制
  • 优先级设定
  • 资源计量
  • 资源控制

Docker容器的能力

  • 文件系统隔离:每个容器都有自己的root文件系统
  • 进程隔离:每个容器都运行在自己的进程环境中
  • 网络隔离:容器间的虚拟网络接口和IP地址都是分开的
  • 资源隔离和分组:使用cgroups将cpu和内存之类的资源独立分配给每个Docker容器

安装Docker

菜鸟教程
我在虚拟机使用的是:

sudo apt-get install docker.io
sudo systemctl start docker
sudo systemctl enable docker
docker version

增加docker用户组使之不需要sudo即可运行docker

sudo groupadd docker
sudo gpasswd -a zg docker
sudo service docker restart
sudo init 6   //或者注销用户在进系统

5. Docker基本操作

启动一个容器(第一次启动ubuntu容器时会从网上下载它的镜像) 这是表示载入容器后运行bash,docker中必须要保持一个进程的运行,要不然整个容器就会退出。这个就表示启动容器后启动bash。此时ubuntu就是下面的IMAGE。

docker run -i -t ubuntu /bin/bash

运行容器

docker run IMAGE [COMMAND] [ARG…]
    run 在新容器中执行命令

启动交互式容器:

# docker run -i -t IMAGE /bin/bash
    -i  --interactive=true|false 默认为false(告诉守护进程,为容器始终打开标准输入)
    -t  --tty=true|false 默认为false(为创建的容器提供一个伪tty终端,类似于terminal终端)

查看容器:

# docker ps [-a] [-l]  (-a 所有的容器,-l 最新的容器)
# docker inspect 容器名/id (返回详细的容器信息)

自定义容器名:

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

重新启动已经停止的容器:

# docker start [-i] 容器名/id

删除停止的容器:(不能用于删除运行中的容器)

# docker rm 容器名/id

6. 守护式容器

  • 能够长期运行
  • 没有交互式会话
  • 适合运行应用程序和服务

以守护形式运行容器

# docker run -i -t IMAGE /bin/bash
Ctrl+P+Q

附加到运行中的容器(重新进入正在运行的容器)

# docker attach 容器名/id

启动守护式容器(最重要的方式)

docker 容器默认会把容器内部第一个进程,也就是pid=1的程序作为docker容器是否正在运行的依据,如果docker 容器pid挂了,那么docker容器便会直接退出。

# docker run -d 镜像名 [COMMAND] [ARG…]
    -d  以后台运行方式启动

查看容器日志(可以看到容器运行的情况)

# docker logs [-f] [-t] [--tail] 容器名/id
    -f --follows=true|false 默认为false 
        一直跟踪日志变化并返回结果,Ctrl+C停止
    -t --timestamps=true|false 默认为false
        返回的结果后附加时间戳
    --tail ="all"
        返回结尾处日志,未指定则返回所有日志,--tail 10 最新的10条日志,--tail 0 最新的一条日志

查看运行中容器的进程情况

# docker top 容器名/id

在运行中的容器内启动新进程

# docker exec [-d][-i][-t] 容器名/id [COMMAND] [ARG…]

停止守护容器

# docker stop 容器名/id     发送信号后等待容器停止
# docker kill 容器名/id     直接终止

使用docker帮助文档

man docker-run
man docker-logs
man docker-exec

7. 在容器中部署静态网站

设置容器的端口映射

run [-P] [-p]
    -P --publish-all=true | false 默认为false
        # docker run -P -i -t ubuntu /bin/bash
        映射所有端口
    -p --publish=[]     指定映射端口
        containerPort            只指定容器端口
            # docker run -p 80 -i -t ubuntu /bin/bash
        hostPort:containerPort   指定宿主机端口和容器端口
            # docker run -p 8080:80 -i -t ubuntu /bin/bash
        ip:containerPort        ip和容器的端口
            # docker run -p 0.0.0.0:80 -i -t ubuntu /bin/bash
        ip:hostPort:containerPort    ip,宿主机,容器端口
            # docker run -p 0.0.0.0:8080:80 -i -t ubuntu /bin/bash

Nginx部署静态网页流程

  • 创建映射80端口的交互式容器
  • 安装Nginx
  • 安装文本编辑器vim
  • 创建静态页面
  • 修改Nginx配置文件
  • 运行Nginx
  • 验证网站访问
# docker run -p 80 --name web -i -t ubuntu /bin/bash
apt-get update
apt-get install -y nginx
apt-get install -y vim

mkdir -p /var/www/html
cd /var/www/html
vim index.html
    <html>
        <head>
            <title>Nginx in Docker</title>
        </head>
        <body>
            <h1>hello, I'm website in docker!</h1>
        </body>
    </html>

whereis nginx
vim /etc/nginx/sites-enabled/default(配置nginx的文件)
    修改 root 的值为 /var/www/html

cd /
nginx
ps -ef
Ctrl+P Ctrl+Q 退出,后台运行

# docker ps     查看运行的容器
# docker port web       查看端口映射情况
# docker top web        查看容器进程情况

# curl http://127.0.0.1:32768     以映射的端口为准,返回的是写的html代码(32768是映射到宿主机的端口号)
在浏览器中查看这个页面:网址:http://127.0.0.1:32768

# docekr inspect web        查看容器对应的IPAddress
# curl 172.17.0.2(这个地址是容器的IP地址,在宿主机上运行,默认是80端口,可以省略)

# 关闭容器
# docker stop web
# docker start -i web
# ps -ef
# nignx并未启动

# docker exec web nginx
# 重新启动Nginx
# 映射的端口和IP地址均已改变

Docker入门学习笔记(二)

  1. 镜像的相关操作
  2. Docker的C/S模式
  3. Docker守护进程的配置和操作

8. 镜像的相关操作

Docker镜像:

    容器的基石
    层叠的只读文件系统
    联合加载(union mount)

    # docker info
    查看docker配置的相关信息

列出镜像:

# docker images [OPTIONS] [REPOSITORY]
    -a  --all=False 显示所有镜像(默认不显示中间层的镜像)
    -f  --filter=[] 显示时的过滤条件
    --no-trunc=false    不使用截断的形式显示命令
    -q  --quiet=false   只显示镜像的v-id
返回的结果中,repository仓库的意思代表一个镜像名,tag代表这个镜像的标签

查看镜像

# docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE……]

删除镜像

# docker rmi [OPTIONS] IMAGE [IMAGE…]
-f  --force=false   强制删除镜像
--no-prune=false    保留删除镜像中未打标签的父镜像
删除多个镜像,docker rmi ubuntu:12.04 ubuntu:14.04
没有直接删除所以镜像的选项,可以使用docker rmi $(docker images ubunru -q)删除所有镜像

查找镜像

方法一:
Docker Hub  访问https://hub.docker.com/
方法二:
# docker search [OPTIONS] TERM
    --automated=false   只显示自动化构建的选项
    --no-trunc=false    以截断方式显示image id
    -s  --stars=0   设置显示结果的最低星级
    一次最多返回25个结果

拉取镜像

# docker pull [OPTIONS] NAME[:TAG]
    -a  --all-tags=false    下载仓库中所有标签镜像
例子:docker pull ubuntu:14.04

提速
    使用--registry-mirror选项
        1.修改:vim /etc/default/docker
        2.添加:DOCKER_OPTS = "--registry-mirror=http://MIRROR-ADDR"
            https://www.daocloud.io

推送镜像

# docker push NAME[:TAG]

构建镜像

保存对容器的修改,并再次使用
自定义镜像的能力
以软件的形式打包并分发服务及其运行环境

方法1.使用commit构建镜像(通过对容器的操作来保存的镜像)
    # docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
    -a  --author="" 指定镜像作者,一般:name@email
    -m  --message=""    提交信息
    -p  --pause=true    在commit过程中不暂停容器

    ********************demo***************
    # docker run -it -p 80 --name commit_test_one ubuntu /bin/bash
    # apt-get update
    # apt-get install -y nginx
    下载vim并新建一个html,运行nginx服务成功
    # exit
    # docker ps -l
    生成镜像
    # docker commit -a "clearloveu" -m "nginx" commit_test_one myimage_one
    # docker images
    用生成的镜像创建一个容器,并执行nginx服务
    可以百度搜索docker运行nginx为什么要使用 daemon off
    # docker run -d --name nginx_web -p 80 myimage_one nginx -g "daemon off;"
    # docker ps
    # curl http://127.0.0.1:32770
    ***************************************

方法2.使用dockerfile构建镜像(文件名为Dockerfile,路径不包括文件名)

    # docker build [OPTIONS] PATH|URL|-
        --force-rm=false
        --no-cache=false
        --pull=false
        -q  --quiet=false     可以设置,表示在构建过程中不会出现中间镜像
        --rm=true
        -t  --tag=""         设置标签

    创建一个Dockerfile
        # first dockerfile
        FROM ubuntu:14.04
        MAINTAINER  name "name@email"
        RUN apt-get update
        RUN apt-get install -y nginx
        EXPOSE 80                    代表暴露的端口号为80

    ********************demo***************
    # mkdir -p dockerfile/df_test1
    # cd dockerfile/df_test1
    # vim Dockerfile
        # first dockerfile
        FROM ubuntu:14.04
        MAINTAINER  name "name@email"
        RUN apt-get update
        RUN apt-get install -y nginx
        EXPOSE 80
    # docker build -t='clearloveu/dockerfile_test1' .
    # docker run -d --name nginx_web3 -p 80 clearloveu/dockerfile_test1 nginx -g "daemon off;"
    # docker ps
    # curl http://127.0.0.1:32770
    ***************************************

9. Docker守护进程的配置和操作

查看守护进程

方法一:
# ps -ef | grep docker
方法二:
# status docker     (ubuntu18.04没有,14.04有)

使用service命令管理

# service docker start|stop|restart

Docker的启动选项(守护进程即服务器的启动选项,详细的选项)

这里是docker守护进程的启动选项,而不是docker客户端的启动选项,所以有些选项不通过命令行来执行,而是在Docker的启动配置文件中添加选项信息,增加一行DOCKER_OPTS="label_name=docker_server1 -H tcp://0.0.0.0:2375"

# docker -d [OPTIONS]
    -d 表示以守护进程形式运行

    运行相关:
    -D  --debug=false
    -e  --exec-drive="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=[]
    --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

    存储相关:
    -s,--storage-drive=""
    --selinux-enabled=false
    --storage-opt=[]

    Registry相关:
    --insecure-registry=[]
    --registry-mirror=[]

    网络设置相关:
    -b,--bridge=""
    --bip=""
    --fixed-cidr=""
    --fixed-cidr-v6=""
    --dns=[]
    --dns-search=[]
    --ip=0.0.0.0
    --ip-forward=true
    --ip-masq=true
    --iptables=true
    --ipv6=false
    --mtu=0

docker启动配置文件:/etc/default/docker

ubuntu18.04使用apt-get下载的docker的启动配置文件不在/etc/default/docker处
在启动配置文件中添加启动选项:DOCKER_OPTS="label_name=docker_server1"

Docker入门学习笔记(三)

  1. Docker的远程访问
  2. Dockerfile指令
  3. Dockerfile构建过程

10. Docker的远程访问

环境准备:

第二台安装Docker的服务器
修改Docker守护进程启动选项,添加label选项,区别服务器
保证Client API和Server API版本一致

# docker version
    查看版本API是否一致

修改服务器端配置以使服务器支持远程访问

修改Docker守护进程启动项
-H  tcp://host:port
    unix:///path/to/socket
    fd://* or fd://socketfd
守护进程默认配置:
-H  unix:///var/run/docker.sock

修改配置文件
vim /etc/default/docker
    DOCKER_OPTS = "-H tcp://0.0.0.0:2375"
    # 一般选择2375端口
重启服务
service docker restart
ifconfig    获取本机IP地址(本机即宿主机就是Docker守护进程即服务器,本机ip地址即docker服务器的ip地址)

远程访问

curl http://服务器IP:配置port/info(返回的是docker服务器的info信息)
例子:curl http://10.211.55.5:2375/info

docker客户端远程访问

修改客户端配置
使用Docker客户端命令选项
-H  tcp://host:port
    unix:///path/to/socket
    fd://* or fd://socketfd
客户端默认配置:
-H  unix:///var/run/docker.sock

客户端远程访问(返回的是docker服务器的info信息)
# docker -H tcp://ip:port info
例子:docker -H tcp://10.211.55.5:2375 info

使用环境变量简化操作DOCKER_HOST(不需要每次连接远程的docker服务器都需要打-H tcp://ip:port info)
export DOCKER_HOST="tcp://ip:port"
例子:
export DOCKER_HOST="tcp://10.211.55.5:2375"
docker info(自动连接上远程的docker服务器,并返回远程服务器的info信息)


将环境变量置空则返回本机服务
export DOCKER_HOST=""

设置了远程访问模式后的服务端不再支持本机连接

方法一:
将本机作为远程客户端,设置环境变量DOCKER_HOST或者通过-H选项模拟远程客户端进行连接
方法二:
再次修改本机的Docker守护进程启动配置文件,添加默认配置,-H可以指定多个连接选项,这里加上默认的socket连接方式-H  unix:///var/run/docker.sock,即可支持本地连接
vim /etc/default/docker
    DOCKER_OPTS = "-H tcp://0.0.0.0:2375 -H  unix:///var/run/docker.sock"

11. Dockerfile指令

指令格式

格式
# Comment(注释)
INSTRUCTION argument(INSTRUCTION大写代表指令,argument小写代表指令参数)

例子:

# first dockerfile
FROM ubuntu:14.04
MAINTAINER  name "name@email"
RUN apt-get update
RUN apt-get install -y nginx
EXPOSE 80

FROM

FROM <image>[:<tag>]

已经存在的镜像
基础镜像
必须是第一条非注释指令

MAINTAINER

MAINTAINER <name>

指定镜像的作者信息,包含镜像的所有者和联系信息

RUN

RUN(镜像构建时运行的命令)

指定当前镜像中运行的命令
shell模式
    RUN <command>
    默认shell   /bin/sh -c command
    可以将多个命令一起执行:RUN apt-get update && apt-get install -y nginx
exec模式
    RUN [ "executable", "param1", "param2"]
    可以指定其他shell   RUN ["/bin/bash", "-c", "echo hello"]

EXPOSE

EXPOSE <port> [<port>…]

指定运行该镜像的容器使用的端口:EXPOSE 80
在使用镜像创建或运行容器时仍需指定端口:docker run -p 80 myimage_one

CMD

CMD(容器运行时运行的默认命令)

提供容器运行时的命令,作为默认设置,会被启动容器时的docker run中的命令覆盖掉
CMD [ "executable", "param1", "param2"] (exec模式)
CMD command param1 param2   (shell模式)
CMD ["param1", "param2"]    (作为ENTRYPOINT指令的默认参数)

ENTRYPOINT

ENTRYPOINT

ENTRYPOINT [ "executable", "param1", "param2"] (exec模式)
ENTRYPOINT command param1 param2   (shell模式)
默认不会被docker run中命令覆盖
可以使用 docker run entrypoint 覆盖:docker run myimage_one entrypoint /bin/bash

可以组合使用,用ENTRYPOINT指定命令,CMD指定命令的参数,在docker run中添加命令参数覆盖CMD的默认参数,这可以解释CMD的第3种用法:作为ENTRYPOINT指令的默认参数

ADD、COPY

ADD、COPY

将文件/目录复制到Dockerfile构建的文件中,源地址(宿主机的相对地址,不推荐使用远程url作为源地址),目标地址(镜像中的绝对地址)
ADD <src>…<dest>
ADD ["<src>"…"<dest>"]  (使用于文件路径中有空格的情况)

COPY <src>…<dest>
COPY ["<src>"…"<dest>"]  (使用于文件路径中有空格的情况)

ADD vs COPY
    ADD包含类似tar的解压功能
    如果单纯复制文件,Docker推荐使用COPY

VOLUME

VOLUME ["/data"]

用于向基于镜像创建的容器添加数据卷,共享数据/数据持久化

WORKDIR

WORKDIR /path/to/workdir

在镜像创建新容器时,指定工作目录,一般使用绝对路径,相对路径会持续传递
例子:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd        --->    /a/b/c

ENV

ENV <key><value> ENV <key>=<value>…

用户设置环境变量

USER

USER daemon

指定镜像运行的用户,默认为root
可以使用user uid group gid的4种组合
例如:USER user;USER uid;USER user:group;USER uid:gid;USER user:gid;USER uid:group

ONBUILD

ONBUILD [INSTRUCTION]

镜像触发器(ONBUILD指定的命令不会在第一次构建镜像时执行)
当一个镜像被其他镜像作为基础镜像时执行(在FROM后面加有ONBUILD指定的命令的镜像,把它作为基础镜像),此时在构建其他镜像时会在构建过程中插入指令

12. Dockerfile构建过程

构建过程

  • 从基础镜像运行一个容器
  • 执行一条指令,对容器做出修改
  • 执行类似docker commit的操作,提交一个新的镜像层
  • 基于刚提交的镜像运行一个新容器
  • 执行Dockefile中的下一条指令,直至所有指令执行完毕
  • 中间层镜像不会被删除,中间层容器会被删除
  • 可以使用中间层镜像调试,用来查找错误

有一个好处是构建过程中会有构建缓存,对同一个Dockerfile文件进行构建时,会使用上一次构建的缓存的中间镜像,这样再次构建效率比较高
然而有些时候并不希望使用上次缓冲的中间镜像,有一个选项可以不使用构建缓存

不使用构建缓存

方法一:
# docker build --no-cache
方法二:
在Dockerfile中设置缓存刷新时间(相当于修改了Dockerfile文件,会在设置缓存刷新时间步骤后构建新的中间镜像)
ENV REFRESH_DATE 2019-8-2

查看镜像构建的过程

# docker history [image]

Docker入门学习笔记(四)

  1. Docker容器的网络连接

13. Docker容器的网络连接

Docker容器的网络基础

Host代表Docker守护进程的宿主机,docker0是宿主机上的网卡

docker0——Linux虚拟网桥

docker0——Linux虚拟网桥

    Linux虚拟网桥:
        可以设置IP地址
        相当于拥有一个隐藏的虚拟网卡

    docker0 地址划分
        IP:172.17.42.1  子网掩码:255.255.0.0
        MAC:02:42:ac:11:00:00到02:42:ac:11:ff:ff
        总共提供了65534个地址
    
    安装网桥管理程序
        yum -y install bridge-utils
        sudo apt-get install bridge-utils
    查看网桥设备
        sudo brctl show
        
    当运行一个容器时,在使用sudo brctl show查看网桥时,docker0的interfaces接口出现一个veth的接口

自定义Docker0

自定义Docker0

    修改docker0地址(不使用默认的172.17.0.0网段)
    sudo ifconfig docker0 192.168.200.1 netmask 255.255.255.0
    此时重启docker服务后再运行容器,则容器中的ip地址发生了改变

自定义虚拟网桥


自定义虚拟网桥

    步骤一:在宿主机中添加虚拟网桥
        sudo brctl addbr br0
        sudo ifconfig br0 192.168.100.1 netmask 255.255.255.0
    步骤二:更改docker守护进程的启动配置
        /etc/default/docker 中添加DOCKER_OPTS值
        -b=br0

Docker容器的互联

环境准备

用于测试的Docker镜像Dockerfile:
    # ./cct/Dockerfile
    # container connection test
    FROM ubuntu:14.04
    RUN apt-get install -y ping
    RUN apt-get update
    RUN apt-get install -y nginx
    RUN apt-get install -y curl
    EXPOSE 80
    CMD /bin/bash

    # docker build -t summer258/cct .

允许所有容器间互联

互联方式:ip地址,--link参数挂载,docker network

默认设置
--icc=true  默认允许所有容器间互联  

演示:
启动第一个容器
# docker run -it --name cct1 summer258/cct
/# nginx
Ctrl+P Ctrl+Q

启动第二个容器
# docker run -it --name cct2 summer258/cct
/# ifconfig
Ctrl+P Ctrl+Q

inet addr:172.17.0.3

连接到第一个容器cct1
# docker attach cct1
/# ifconfig

inet addr:172.17.0.2

测试连接:ping 172.0.3

连接到第二个容器cct2
# docker attach cct2
测试连接:curl http://172.17.0.2

重启容器
docker restart cct1
发现IP地址已改变,说明容器的ip地址是不可靠的连接,提供另一种机制来实现容器之间的互联,在容器启动时添加--link选项

--link
    # docker run --link=[CONTAINER_NAME]:[ALIAS] [IMAGE] [COMMAND]
    其中ALIAS是CONTAINER_NAME的别名

目前官方已不推荐使用--link参数挂载容器与其他容器互联,使用docker network来实现容器之间的互联,在使用时用docker network --help查看


启动第三个容器
# docker run -it --name cct3 --link=cct1:webtest summer258/cct(此时webtest是cct1的别名)
/# ping webtest
/# env      查看容器的环境变量,发现增加了很多关于webtest的变量
/# vim /etc/hosts    查看文件发现添加了webtest容器的地址映射

重启docker服务
    # systemctl restart docker  (centos)
    # sudo service docker restart
    # docker restart cct1 cct2 cct3
    # docker attach cct3
    /# ping webtest
    /# vim /etc/hosts    查看文件发现webtest地址映射中的ip地址发生了变化
    即重启docker服务,--link参数挂载方式并不影响docker容器之间的互联

拒绝所有容器间互联

Docker守护进程的启动选项
    DOCKER_OPTS= " --icc=false"

# ubuntu
$ sudo vim /etc/default/docker
    DOCKER_OPTS = "--icc=false"
# centos
$ sudo vim /etc/docker/daemon.json
    {
        …
        “icc”:false,
        …
    }


# systemctl restart docker  (centos)
# sudo service docker restart
# ps -ef | grep docker
# sudo docker restart cct1 cct2 cct3
# sudo docker attach cct3
/# curl webtest
/# ping webtest   发现ping不通,容器连接被阻断

允许特定容器间的连接

步骤一:
Docker守护进程的启动选项
    --icc=false --iptables=true
步骤二:
docker容器启动时使用--link参数挂载

# sudo iptables -F         iptables设置清空(清空后,可以实现允许特定容器间的连接,不清空好像有问题,docker的bug,不知道现在有没有)
# sudo iptables -L -n      显示iptables内容

Docker容器与外部网络的连接

ip_forward

--ip-forward=true(默认是true)
    决定系统是否会转发流量

# sudo sysctl net.ipv4.conf.all.forwarding   当返回结果是1,则系统会转发流量

iptables

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

  • 表table
  • 链chain
  • 规则rule:ACCEPT,REJECT,DROP
filter表中包含的链:
    INPUT
    FORWARD
    OUTPUT
    DOCKER

# sudo iptables -t filter -L -n  查看filter表
# sudo iptables -L -n  查看filter表(iptables默认查询的是filter表)

端口映射访问

# docker run -it -p 80 --name cct5 myimages_one
/# nginx
/# Ctrl+Q+P
# docker port cct5
# curl 127.0.0.1:49153
# ifconfig             宿主机的ip为10.128.3.162

换另一台能ping通10.128.3.162的linux机器
# curl 10.128.3.162:49153        能显示网页html代码

查看iptables可以看到DOCKER链中多了一条0.0.0.0(宿主机)到容器cct5的规则,代表可以转发包

限制IP访问容器

操作iptables可以实现限制IP访问容器,只要增加相应的规则即可
可实现特定ip对特定容器的限制性访问

$ sudo iptables -I DOCKER -s 10.128.3.162 -d 172.17.0.7 -p TCP --dport 80 -j DROP
-s源地址,-d目的地址,-p协议,-dport目的端口,-j操作

Docker入门学习笔记(五)

  1. Docker容器的数据管理

14. Docker容器的数据管理

Docker容器的数据卷

什么是数据卷?(Data Volume)

  • 数据卷是经过特殊设计的目录,可以绕过联合文件系统(UFS),为一个或多个容器提供访问
  • 数据卷设计的目的,在于数据的永久化,它完全独立于容器的生存周期,因此,Docker不会在容器删除时删除其挂载的数据卷,也不会存在类似的垃圾收集机制,对容器引用的数据卷进行处理。

数据卷(Data Volume)的特点

  • 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会拷贝到新初始化的数据卷中。
  • 数据卷可以在容器之间共享和重用。
  • 可以对数据卷里的内容直接进行修改(即时性的)
  • 数据卷的变化不会影响镜像的更新
  • 卷会一直存在,即使挂载数据卷的容器已经被删除

为容器添加数据卷

可以实现宿主机和容器之间的数据共享

  # sudo docker run -it -v ~/container_data:/data ubuntu /bin/bash
  :前面是宿主机的文件夹路径,如果没有,则自动会创建这个文件夹,:后面是容器中添加的文件夹位置
  /# ls

为数据卷添加访问权限

  # sudo docker run -it -v ~/datavolume:/data:ro ubuntu /bin/bash
  ro:只读
  wr: 读写权限

可以查看容器Volume目录信息和数据卷的读写权限

  # sudo docker inspect 容器名/id
  可以查看容器Volume目录信息和数据卷的读写权限

使用Dockerfile构建包含数据卷的镜像

  Dockerfile指令:VOLUME["/datavolume",["/otherdatavolume"]]
  可以同时添加多个数据卷
  不能像上面-v选项一样可以指明宿主机的文件路径,这里容器中/datavolume文件夹对应的宿主机的文件夹路径是由系统默认创建的,可以通过sudo docker inspect 容器名/id查看

Docker的数据卷容器

什么是数据卷容器

命名的容器挂载数据卷,其他容器通过挂载这个容器实现数据共享,挂载数据卷的容器,就叫做数据卷容器。
所有挂载数据卷容器的容器和数据卷容器都可以互相实现数据共享。

好处:可以不用暴露数据卷容器的信息,sudo docker inspect 容器名/id 返回的是数据卷容器在宿主机上挂载的路径,在多租户的使用环境很安全。
数据卷容器的作用仅仅是将数据卷的配置传递给挂载这个数据卷容器的容器中。

挂载数据卷容器的方法

  # docker run --volumes-from 数据卷容器名或id
  例子:
  # docker run -it --name dvt2 --volumes-from dvt1 ubuntu /bin/bash
  
  将数据卷容器删除,并不影响已经挂载数据卷容器的容器对数据卷的使用,这是因为数据卷的特点的第5点:
  卷会一直存在,即使挂载数据卷的容器已经被删除
  
  # docker rm -v dvt1  即使-v选项删除数据卷容器,只要这个数据卷被其他容器使用,数据卷就不会被删除
  

Docker数据卷的备份和还原

数据备份方法

  # sudo docker run --volumes-from [container name] -v $(pwd):/backup[:wr] ubuntu tar cvf /backup/backup.tar [container data volume]
  解析:创建并运行一个新的docker容器,通过2种方式挂载数据卷,第一种是数据卷容器,
  第2种是-v选项指明宿主机和容器的文件路径,$(pwd)代表的是宿主机的文件路径,如:~/backup
  wr代表数据卷的访问权限是读写,执行tar命令,第一个参数/backup/backup.tar是压缩后文件存放的位置和名字,
  第二个参数[container data volume]代表将要压缩的文件目录,可以是数据卷容器的数据卷路径
  可以通过宿主机的路径访问到压缩后的数据文件:ls $(pwd)

数据还原方法

  $ sudo docker run --volumes-from [container name] -v $(pwd):/backup[:wr] ubuntu tar xvf /backup/backup.tar [container data volume]

Docker入门学习笔记(六)

  1. Docker容器的跨主机连接

15. Docker容器的跨主机连接

使用网桥实现跨主机连接

原理:
网络拓扑

环境准备

  Mac OS X 
  两台Ubuntu 14.04 虚拟机
  安装网桥管理工具:
      apt-get install bridge-utils
  IP地址:Host1:10.211.55.3
          Host2:10.211.55.5

等价于将2个宿主机连接在同一个交换机上,Mac OS X等同于交换机,宿主机和容器都使用同一个网段中的ip地址,只要ip地址不重复。
如果是不同网段,ping不通,因为不同网段需要查找路由表来确定不同网段的网络地址。

虚拟机网络配置

为了永久保存配置
宿主机的物理网卡eth0绑定在br0网桥上了

  修改/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 eth0

Docker设置

  修改/etc/default/docker文件
  -b 指定使用自定义网桥
      -b=br0          (此时重启计算机后,ifconfig将不再有docker0网卡)
  --fixed-cidr限制IP地址分配范围
      IP地址划分:
      Host1:10.211.55.64/26
          地址范围:10.211.55.65~10.211.55.126
      Host2: 10.211.55.128/26
          地址范围:10.211.55.129~10.211.55.190

此时虚拟机中的docker容器可以访问外网了,比如:ping www.baidu.com可以ping通,也可以访问其他外网的容器

优点

配置简单,不依赖第三方软件

缺点

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

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

Open vSwitch是什么?

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

原理:

什么是GRE隧道?

GRE:通用路由协议封装

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

环境准备

  Mac OS X + Virtualbox
  两台Ubuntu14.04虚拟机
  双网卡,Host-Only&NAT
  安装Open vSwitch:
      apt-get install openvswitch-switch
  安装网桥管理工具:
      apt-get install bridge-utils
  IP地址:Host1:192.168.59.103
          Host2:192.168.59.104

操作

建立ovs网桥
添加gre连接
配置docker容器虚拟网桥
为虚拟网桥添加ovs接口
添加不同Docker容器网段路由

  主机:192.168.59.103
  查看ovs状态
  $ sudo ovs-vsctl show
  建立ovs网桥
  $ sudo ovs-vsctl add-br obr0
  添加gre接口
  $ sudo ovs-vsctl add-port obr0 gre0
  $ sudo ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.59.104
  $ sudo ovs-vsctl show

  建立本机docker容器需要使用的虚拟网桥
  新建网桥
  $ sudo brctl addbr br0
  设置网络地址
  $ sudo ifconfig br0 192.168.1.1 netmask 255.255.255.0
  为br0网桥添加ovs网桥的连接
  $ sudo brctl addif br0 obr0
  查看当前网桥的状态
  $ sudo brctl show

  配置docker,用新建的网桥代替docker0
  $ sudo vim /etc/default/docker
      DOCKER_OPTS="obr0 "  / DOCKER_OPTS="-b=br0  "   (不知道是哪一个,可能有误)
  $ sudo service docker restart

  新建一个docker容器
  $ docker run -it ubuntu /bin/bash
  /# ifconfig
      inet addr:192.168.1.2
  /# ping 192.168.59.104    (另一台远程linux宿主机ip地址)




  切换主机:192.168.59.104
  $ ifconfig
      br0网桥 addr:192.168.2.1(这是docker容器所在的网段:192.168.2.0)
  启动一个docker容器
  $ sudo docker run -it ubuntu /bin/bash
  /# ifconfig
      inet addr:192.168.2.4
  /# ping 192.168.59.104




  切回主机:192.168.59.103
  /# ping 192.168.2.4
      ping不通,因为不同网段需要查找路由表来确定不同网段的网络地址
      
  查看路由表信息
  $ route
  添加路由表项
  $ sudo ip route add 192.168.2.0/24 via 192.168.59.104 dev eth0

  $ sudo docker run -it ubuntu /bin/bash
  /# ping 192.168.2.4
        可以ping通了

使用weave实现跨主机容器连接(推荐)

weave是什么?

语义:编织
建立一个虚拟的网络,用于将运行在不同主机的Docker容器连接起来
https://www.weave.works/
https://github.com/weaveworks/weave#readme

环境准备

  Mac OS X + Virtualbox
  两台Ubuntu14.04虚拟机
  双网卡,Host-Only&NAT
  IP地址:Host1:192.168.59.103
          Host2: 192.168.59.104

操作

安装weave
启动weave: $ weave launch 连接不同主机
通过weave启动容器



  主机:192.168.59.103
  $ sudo wget -O /usr/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave
  $ sudo chmod a+x /usr/bin/weave
  $ weave launch
  $ sudo docker ps -l
  
  

  切换主机:192.168.59.104
  重复安装操作
  $ sudo wget -O /usr/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave
  $ sudo chmod a+x /usr/bin/weave
  
  启动weave,加上第一个主机的ip地址
  $ weave launch 192.168.59.103
  weave的命令类似于docker的命令,启动一个容器,分配一个ip地址,这里是192.168.1.2/24,
  然后将这条weave命令执行后的返回值赋给c2,这里的返回值是启动容器的容器id
  $ c2=$(weave run 192.168.1.2/24 -it ubuntu /bin/bash)
  $ echo $c2
  利用docker attach进入到这个容器
  $ docker attach $c2   (也可以用weave --name 给这个容器赋个名字,然后操作名字:docker attach weave_name)
  /# ifconfig
  多了一个网络设备ethwe,inet addr:192.168.1.2

  切换Host1:192.168.59.103
  $ weave run 192.168.1.10/24 -it --name wc1 ubuntu /bin/bash
  相同网段的IP地址
  $ sudo docker aatach wc1
  /# ifconfig
  增加wthwe,inet addr:192.168.1.10
  /# ping 192.168.1.2
  能够ping通
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!