前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >docker_基础_3

docker_基础_3

作者头像
py3study
发布2020-01-08 15:34:21
5990
发布2020-01-08 15:34:21
举报
文章被收录于专栏:python3python3

接上篇

第8-11章

12、基本架构

   早期的docker是基于已经成熟的LXC(linux container)技术实现的.自0.9版本起,docker已经逐渐从LXC转移到新的libcontainer上,并且积极推动开放容器规范runc;    从OS功能上看,目前Docker底层依赖的核心技术主要包括linux操作系统的命名空间(name space), 控制组( cgroup ),联合文件系统( union file system 或 aufs )和linux网络虚拟化支持。

   docker目前采用的是标准的C/S架构,client和service即可以运行在一台机器上,也可以在不同机器上通过socker和RESTful API来进行通信。

12.1、服务端

   Docker Daemon一般在宿主机后台运行,作为服务端接受来自客户的请求,并处理这些请求 ( 创建、运行、分发容器)。    在设计上,docker Daemon 是一个模块化的任务,通过专门的engine模块来分发管理各个来自客户端的任务。    Docker服务器默认监听本地的套接字,只允许本地的root用户或docker用户组成员访问,可以通过-H 选项来修改监听的方式。

代码语言:javascript
复制
Host $ docker daemon -H IP:port   如  docker daemon -H 0.0.0.0:2222

   Docker默认启动配置文件在/etc/default/docker

12.2、客户端

   Docker客户端为用户提供一系列的可执行命令,用户用这些命令与Docker Daemon交互。用户使用的Dokcer可执行命令即为客户端程序,客户端发送命令后,等待服务端返回,一旦收到返回后,客户端立刻执行结束并退出,用户执行新的命令,需要再次调用客户端命令。    如果服务端没有监听在默认的地址,那么连接服务器的时候就需要指定服务端地址,假如服务器监听在1.1.1.1的tcp2345,只有通过-H指定正确的地址才能进行连接

代码语言:javascript
复制
  docker -H tcp://1.1.1.1:2345 version 查看

13、命名空间    命名空间(namespace) 是linux内核的一个强大特性,利用这一特性,每个容器都可以拥有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统环境中一样,命名空间机制保证了容器之间彼此互不影响。

13.1、进程命名空间

   Linux通过命名空间管理进程号,对于同一个进程( 即同一个task_struct),在不同的命名空间中,看到的进程号不相同,每个进程命名空间有一套自己的进程号管理方法,进程命名空间是一个父子关系的结构,子空间中的进程对父空间是可见的,新fork出的进程在父命名空间和子命名空间将分别有一个进程号来对应。

13.2、网络命名空间

   如果有了pid命名空间,那么每个命名空间中的进程就可以相互隔离,但网络端口还是共享本地系统的端口,通过网络命名空间,可以实现网络隔离。    网络空间为进程提供了一个完全独立的网络协议栈的视图,包括网络设备接口,ipv4\ipv6协议栈,ip路由表,防火墙规划,sockets等,这样每个容器的网络都能隔离开来.    使用brctl工具就能看到桥接到宿主机docker0网桥上的虚拟网口

代码语言:javascript
复制
系统如果自带没有需要安装这个软件
yum -y install bridge-utils
docker_基础_3
docker_基础_3

13.3、IPC命名空间

   容器中进程交互还是采用了Linux常见的进程间交互方法(ipc),包括了信号量、消息队列和共享内存等。pid namespace和IPC namespace 可以组合一起使用,同一个IPC命名空间内的进程可以彼此可见,允许进行交互,不同空间的进程则无法交互。

13.4、挂载命名空间

   类似于chroot,将一个进程放到一个特定的目录执行,挂载命名空间允许不同命名空间的进程看到的文件结构不同,这样每个命名空间中的进程所看到的文件目录彼此隔离,可以查看 volume挂载信息。

13.5、UTS命名空间 (名称)

   UTS (unix Time-sharing system)命名空间允许每个容器拥有独立的主机名和域名,从而可以虚拟出一个独立主机名和网络空间的环境,就跟网络上一台独立的主机一样。    默认情况下,Docker容器的主机名就是返回容器ID:

代码语言:javascript
复制
[root@dockers _data]# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                 PORTS                                                           NAMES
046799493e9c        gitlab/gitlab-ce    "/assets/wrapper"        7 hours ago         Up 7 hours (healthy)   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:333->22/tcp   git2

docker inspect -f '{{.Config.Hostname}}' git2
046799493e9c

13.6、用户命名空间

   每个容器可以有不同的用户和组ID,也就是说可以在容器内使用特定的用户执行程序,而非本地系统上存在的用户

14、控制组(cgroup)    控制组主要用来对共享资源进行隔离、限制、审计等,只有能控制分配到容器的资源,才能避免多个容器同时运行时对宿主机系统的资源竞争。

具体来看控制组提供:

  • 资源限制:可以将组设置为不超过设定内存的限制,比如:内存子系统可以为进程组设定一个内存使用上限,一旦进程组使用的内存达到限额再申请内存,就会发出 out of memory的警告, 也可以是CPU,硬盘等。
  • 优先级: 通过优先级让一些组优先得到更多的资源。
  • 资源审记:用来统计系统实际上把多少资源用到适合的目的上,可以使用cpuacct子系统记录某个进程组使用的CPU时间。
  • 隔离:为组隔离命名空间,这样一个组不会看到另一个组的进程、网络连接和文件系统。
  • 控制:挂起,恢复和重新启动等操作

安装完docker之后,用户可以在/sys/fs/cgroup/memory/docker/目录下看到对Docker组应用的各种限制值,包括, 目录是容器的各项限制

docker_基础_3
docker_基础_3

容器的限制值

docker_基础_3
docker_基础_3
docker_基础_3
docker_基础_3

注意:也可以在启动容器的时候为每个容器指定资源的限制,例如使用 -c | --cpu-shares=[0]参数来调整cpu的权重,使用-m| --monry[=MEMORY]参数来调整容器使用内存的大小。

15、联合文件系统

   联合文件系统(unionFS) 是一种轻量级的高性能分层文件系统,它支持将文件系统中的修改信息作为一次提交,并层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,应用看到的是挂载的最终结果。

15.1、Docker存储

   Docker目前通过插件化方式支持多种文件系统后端。如图所示。aufs支持为每一个成员目录设定只读,读写,或写出的权限,同时AUFS里有一个类似分层的概念,对只读权限的分支可以在逻辑上进行增量地修改。Docker镜像自身就是由多个文件层组成,每一层有唯一的编号(层ID).

docker_基础_3
docker_基础_3

15.2、多种文件系统比较

   Docker目前支持的联合文件系统种类包括AUFS、OverlayFS、Btrfs、vfs、zfs和Device Mapper等。

  • AUFS: 最早支持的文件系统,对Debian/Ubuntu支持好,虽然没有合并到 linux内核中,但成熟度很高;
  • OverlayFS:类似于AUFS,性能会更好一些,已经合并到内核,未来会取代AUFS,但成熟度有待提高;
  • Device mapper:红帽公司和Docker团队一起开发用于支持RHEL的文件系统,内核支持,性能略慢,成熟度高;
  • btrfs:参考zfs等特性设计的文件系统,由linux社区开发,试图未来取代Device Mapper,成熟度有待提高;
  • vfs:基于普通文件系统(ext、nfs等)的中间层抽象,性能差,比较占用空间,成熟度也一般;
  • zfs:最初设计为solaris 10上的写时文件系统,拥有不少好的特性,但对linux支持还不够成熟。 总结:AUFS和Device mapper的应用最为广泛,支持也相对成熟,推荐生产环境考虑,长期来看,OverlaryFS将可能具有更好的特性。

16、网络模式

   Docker的本地网络实现其实就是利用了linux上的网络命名空间和虚拟网络设备(特别是veth pair)。 在使用docker run 命令启动容器的时候 可以指定--net参数来指定容器的配置 网络配置可选值 bridge、none、containrer、host和用户定义的网络

  1. --net=bridge:默认值,在docker网桥docker0上为容器创建新的网络栈;
  2. --net=none:让Docker将新容器放到隔离的网络栈中,但是不进行网络配置,之后用户可以自行进行配置 。
  3. --net=container:NAME_OR_ID: 让Docker将新建容器的进程放到一个已存在容器的网络栈中,\ 新容器进程有自己 的文件系统、进程列表和资源限制,但是会和已存在的容器共享IP地址和端口等网络资源 ,两者进程 可以直接通过LO环回接口通信。
  4. --net=host:告诉Docker不要将容器网络放到隔离的命名空间中,即不要容器化容器内的网络,此时容器使用本地主机的网络,它拥有完全的本地主机接口访问权限。\ 容器进程可以和主机其它root进程一样打开低范围内的端口,可以访问本地网络服务,比如D-bus,如果进一步使用 --privileged=true参数,容器甚至会被允许直接配置主机的网络栈。
  5. --net=user_defined_network:用户自行用network命令创建一个网络,通过这种方式将容器连接到指定的已创建网络上去。 使用 docker network create networkname 可以创建一个新的网络 docker network ls 查看 docker network rm networkname 删除网络 17、配置私有仓库 17.1、安装Docker Registry   目前docker registry最新工具为2.0系列版本,这一版本与一些类库、工具一起被打包为负责容器内容分发的工具集:docker Distribution,目前其核心功能组件仍为负责镜像仓库的管理。

17.1.1、基于容器的运行方式

代码语言:javascript
复制
docker run -dit -p 5000:5000 --restart=always --name registry registry
使用docker inspect查看详细配置 
          "Cmd": [     配置文件目录
                "/etc/docker/registry/config.yml"
            ],
            "ArgsEscaped": true,
            "Image": "registry",
            "Volumes": {    保存仓库的位置
                "/var/lib/registry": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "/entrypoint.sh"
            ],

[root@dockers ~]# docker exec -it df5757d25854 cat /etc/docker/registry/config.yml
version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

配置 文件目录及保存仓库位置应当持久化至本地
[root@dockers registry]# docker volume create registry

文件挂载使用-v比较方便,目录可以使用--mount
[root@dockers registry]# docker run -dit --name registry2 -v /root/registry/config.yml:/etc/docker/registry/config.yml --mount source=registry,target=/var/lib/registry registry
b6569571613eb1de01dc43a4c18c948784d7721cbbfb6a38e5067e5c47c8cb75
[root@dockers registry]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                  PORTS                                                           NAMES
b6569571613e        registry            "/entrypoint.sh /etc…"   5 seconds ago       Up 2 seconds            5000/tcp                                                        registry2

17.1.2、本地安装运行

代码语言:javascript
复制
先安装golang跟git环境,此次安装是在另外一台机器上
yum -y install golang git

docker×××地址 docker distibution分发工具包
https://github.com/docker/distribution

git clone源码
git clone https://github.com/docker/distribution.git

迅雷或其它方式下载
https://codeload.github.com/docker/distribution/zip/master

创建配置文件目录
mkdir /etc/docker/registry -pv

当前目录解压distribution-master.zip
cd distribution-master

复制配置文件
cp cmd/registry/config-dev.yml /etc/docker/registry/config.yml

仓库目录
mkdir /var/lib/registry

注意: 一定要定义GOPATH环境变量 比如
# vim /etc/profile.d/go.sh
    export GOPATH=/go
    export PATH=$GOPATH:$PATH

# source /etc/profile.d/go.sh

安装
[root@do2 distribution-master]# make --prefix=/go clean binaries

安装的时候报错信息
cannot find package "github.com/docker/distribution/registry/auth/htpasswd" in any of:
    /usr/lib/golang/src/github.com/docker/distribution/registry/auth/htpasswd (from $GOROOT)

解决办法 
[root@do2 ~]# mv distribution-master /go/src/github.com/docker/
[root@do2 ~]# cd !$
cd /go/src/github.com/docker/
[root@do2 docker]# mv distribution-master/ distribution

[root@do2 distribution]# pwd
/go/src/github.com/docker/distribution

然后再编译
[root@do2 distribution]# make prefix=/go clean binaries
+ clean
fatal: Not a git repository (or any of the parent directories): .git
+ /go/src/github.com/docker/distribution/bin/registry
fatal: Not a git repository (or any of the parent directories): .git
+ /go/src/github.com/docker/distribution/bin/digest
fatal: Not a git repository (or any of the parent directories): .git
+ /go/src/github.com/docker/distribution/bin/registry-api-descriptor-template
+ binaries

编译成功启动
[root@do2 distribution]# ./bin/registry serve /etc/docker/registry/config.yml 
INFO[0000] debug server listening :5001 

# 检查服务是否成功开启
curl -i 127.0.0.1:5000
HTTP/1.1 200 OK
Cache-Control: no-cache
Date: Tue, 10 Apr 2018 22:08:36 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

## docker 服务器上操作
[root@dockers registry]# docker push 192.168.9.223:5000/v2/sshd:v2
The push refers to repository [192.168.9.223:5000/v2/sshd]
An image does not exist locally with the tag: 192.168.9.223:5000/v2/sshd
[root@dockers registry]# docker push 192.168.9.223:5000/sshd:v2
The push refers to repository [192.168.9.223:5000/sshd]
Get https://192.168.9.223:5000/v2/: http: server gave HTTP response to HTTPS client

增加这个地址
[root@dockers registry]# vim /etc/docker/daemon.json 
{ 
  "insecure-registries":[
      "192.168.9.223:5000"
  ]
}

# 上传成功
# docker push 192.168.9.223:5000/sshd:v3
    The push refers to repository [192.168.9.223:5000/sshd]
    9b7093b64bd7: Layer already exists 
    68d4a84c343f: Layer already exists 
    71a8af6570d5: Layer already exists 
    b03095563b79: Layer already exists 
    v3: digest: sha256:46d7064f74b2fd47be7014f02e81d9e96bdafb1a07bc31dccc5d912e8f26c400 size: 1154

# 下载
# docker pull 192.168.9.223:5000/sshd:v3
    v3: Pulling from sshd
    Digest: sha256:46d7064f74b2fd47be7014f02e81d9e96bdafb1a07bc31dccc5d912e8f26c400
    Status: Downloaded newer image for 192.168.9.223:5000/sshd:v3

[root@dockers ~]# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
192.168.9.223:5000/sshd   v3                  fdfec675a68c        5 days ago          218MB

[root@dockers ~]# docker tag 192.168.9.223:5000/sshd:v3 sshd:v4
[root@dockers ~]# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
192.168.9.223:5000/sshd   v3                  fdfec675a68c        5 days ago          218MB
sshd                      v4                  fdfec675a68c        5 days ago          218MB

最后删除上面192.168*的镜像就行

TLS + SSL 等compose的时候再弄

18、安全防护与配置

在评估Docker的安全性时,主要考虑下面几个方面:

  1. linux内核的命名空间机制提供的容器隔离安全;
  2. Linux控制组机制对容器资源的控制能力安全;
  3. linux内核的能力机制所带来的操作权限安全;
  4. Docker程序本身的搞***性;
  5. 其它安全增强机制( apparmor, SELinux等) 对容器安全性的影响;
  6. 通过第三方工具(如Docker Bench工具)对Docker环境的安全性进行评估

19、高级网络功能

19.1、通过参数指定网络

代码语言:javascript
复制
其中有些命令选项只有在 Docker 服务启动的时候才能配置,而且不能马上生效。
    -b BRIDGE 或 --bridge=BRIDGE 指定容器挂载的网桥
    --bip=CIDR 定制 docker0 的掩码
    -H SOCKET... 或 --host=SOCKET... Docker 服务端接收命令的通道
    --icc=true|false 是否支持容器之间进行通信
    --ip-forward=true|false 请看下文容器之间的通信
    --iptables=true|false 是否允许 Docker 添加 iptables 规则
    --mtu=BYTES 容器网络中的 MTU

下面2个命令选项既可以在启动服务时指定,也可以在启动容器时指定。在 Docker 服务启动的时候指定则会成为默认值,后面执行 docker run 时可以覆盖设置的默认值。
    --dns=IP_ADDRESS... 使用指定的DNS服务器
    --dns-search=DOMAIN... 指定DNS搜索域

最后这些选项只有在 docker run 执行时使用,因为它是针对容器的特性内容。
    -h HOSTNAME 或 --hostname=HOSTNAME 配置容器主机名
    --link=CONTAINER_NAME:ALIAS 添加到另一个容器的连接
    --net=bridge|none|container:NAME_or_ID|host 配置容器的桥接模式
    -p SPEC 或 --publish=SPEC 映射容器端口到宿主主机
    -P or --publish-all=true|false 映射容器所有端口到宿主主机

19.2、容器访问外部网络

  容器默认是可以访问到宿主机本地的,但如果容器想通过宿主机访问到外部网络,需要宿主机进行转发。 在宿主机Linux系统上,检查转发是否开启;

代码语言:javascript
复制
为1时表示开启,为0表示没有开启
[root@dockers ~]# echo "1" >  /proc/sys/net/ipv4/ip_forward
[root@dockers ~]# syscl -w net.ipv4.ip_forward=1    

更简单的可以在运行容器时直接 --ip-forword=true。docker服务就会自动打开宿主机的转发服务

19.3、容器之间的访问 容器之间的访问需要两方面的支持 1、网络拓扑是否连接,默认情况下容器都会连接到docker0网桥上,这意味着默认情况下拓扑是互通的。 2、本地系统的防火墙iptables是否允许通过,这取决于防火墙的默认规则是允许还是禁止。

代码语言:javascript
复制
 一. 访问所有端口

  当启动docker服务的时候,默认会添加一条"允许"策略到iptables的FORWARD链上,通过配置 --icc=true|false (默认为true)允许可以控制默认的策略,   同时如果启动docker服务时手动指定 --iptables=false 参数则不会修改宿主机上的iptables规则 二. 访问指定端口   通过icc=false禁止容器相互访问后,仍可通过 --link=CONTAINER_NAME:ALIAS选项来允许访问指定容器的开放端口。    也可以同时使用icc=false,iptables=true参数来配置容器间禁止访问,并允许docker自动修改系统中的iptables规则. 其实也可以直接使用--link=container:alias就直接互相连接了。

19.4、自定义网桥   先创建一个docker0的网桥,使用veth pair创建一对虚拟网卡,一端放到新创建的容器中,并重命名eth0,另一端放到宿主机上,以veth+随机7个字符串命名,并将这个网络设备加入到docker0网桥中,网桥自动为容器分配一个IP,并设置docker0的IP为容器默认网关。

代码语言:javascript
复制
1、停止容器 关掉默认网桥
Host# systemctl  stop docker
Host# ip link set dev docker0 down
Host# brctl delbr docker0

2、新建网桥
Host# brctl addbr bridge0
Host# ip addr add 172.15.1.1/24 dev bridge0
Host# ip link set dev bridge0 up

# 如果本地网卡,这样获取的就是局域网地址 比如ens160,注意如果是这样的话一定要使用脚本的方式,否则连接会断开,这里bridge0 地址也应该是ens160的地址

Host# ip addr add 172.15.1.1/24 dev bridge0 
Host# ip link delete dev ens160
Host# brctl addif bridge0 ens160
Host# ip link set dev bridge0 up

查看网桥
Host#  ip addr show bridge0
658: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
    link/ether b2:03:32:49:8d:98 brd ff:ff:ff:ff:ff:ff
    inet 172.15.1.1/24 scope global bridge0
       valid_lft forever preferred_lft forever
    inet6 fe80::b003:32ff:fe49:8d98/64 scope link 
       valid_lft forever preferred_lft forever

3、启动时使用bridge0网桥
Host#  cat /etc/docker/daemon.json
{
  "insecure-registries":["192.168.9.223:5000"],
  # 添加这行,如果还有多行直接 , 换下一条添加
  "bridge": "bridge0",
  "registry-mirrors": [
     "https://registry.docker-cn.com"
  ]
}

以上配置,方式一 与方式二都需要

代码语言:javascript
复制
# 方式一: 运行一个自动获取地址的容器
[root@dockers ~]# docker run -dit centos 
81e9afed70b68a74d4c1e28919a3e0f3df8afdc5d06c74b74fc54ec9b879180f

# 查看网络连接
[root@dockers ~]# docker inspect reverent_kapitsa
            "Networks": {
                "bridge": {
                    "Gateway": "172.15.1.1",
                    "IPAddress": "172.15.1.2",
                    "IPPrefixLen": 24,

方式二: 手动建立虚拟机与宿主机的网络连接
# 获取容器的PID
Host# C_PID=$(docker inspect -f '{{.State.Pid}}' 12ba)
Host# echo $C_PID
26467
# 创建虚拟网卡连接目录
Host# mkdir -p /var/run/netns/
Host# ln -sv /proc/$C_PID/ns/net /var/run/netns/$C_PID
"/var/run/netns/26467" -> "/proc/26467/ns/net"

# 这里创建的是双向连接 本地的叫veth$C_PID 容器名 vp$C_PID
Host# ip link add veth$C_PID type veth peer name vp$C_PID

# 添加虚拟网卡到 bridge0中
Host# brctl addif bridge0 veth$C_PID
Host# brctl show
bridge name bridge id       STP enabled interfaces
br-105ebee92a2d     8000.0242793f667e   no      
bridge0     8000.22902f9a823c   no      veth26467
                                        vethf240758

# 启动这个网卡
Host# ip link set veth$C_PID up

# 给进程配置一个network namespace
Host# ip link set vp$C_PID netns $C_PID

# 在容器进程中设置网卡信息
# 将vp$C_PID重名命为eth0
Host# ip netns exec $C_PID ip link set dev vp$C_PID name eth0
Host# ip netns exec $C_PID ip link set eth0 up
Host# ip netns exec $C_PID ip addr add 172.15.1.2/25 dev eth0
Host# ip netns exec $C_PID ip route add default via 172.15.1.1

# 进入容器查看IP地址
[root@12ba56d1dc2b /]# ip addr show
626: eth0@if627: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 82:b2:38:d2:2f:11 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.15.1.2/25 scope global eth0

# 在容器外查看详细信息还是会为空
[root@dockers ~]# docker inspect 12ba
            "Networks": {
                "none": {
                    "Gateway": "",
                    "IPAddress": "",

简单运行的脚本
#!/bin/bash
#

container_name=$(docker run -dit centos)
# 获取容器的PID
C_PID=$(docker inspect -f '{{.State.Pid}}' $container_name)

# 创建虚拟网卡连接目录
dir=/var/run/netns/
if [ ! -d $dir ];then
    mkdir -p /var/run/netns/
fi

ln -sv /proc/$C_PID/ns/net /var/run/netns/$C_PID

# 这里创建的是双向连接 本地的叫veth$C_PID 容器名 vp$C_PID
ip link add veth$C_PID type veth peer name vp$C_PID

# 添加虚拟网卡到 bridge0中
brctl addif bridge0 veth$C_PID

# 启动这个网卡
ip link set veth$C_PID up

# 给进程配置一个network namespace
ip link set vp$C_PID netns $C_PID

# 在容器进程中设置网卡信息
ip netns exec $C_PID ip link set dev vp$C_PID name eth0
ip netns exec $C_PID ip link set eth0 up
ip netns exec $C_PID ip addr add 172.15.1.3/24 dev eth0
ip netns exec $C_PID ip route add default via 172.15.1.1

19.5、pipework

使用pipework配置

代码语言:javascript
复制
设置 网桥信息
Host# brctl addbr bridge0
Host# ip addr add 172.15.1.1/24 dev bridge0 
Host# ip link set dev bridge0 up

# 如果本地网卡,这样获取的就是局域网地址 比如ens160
Host# ip addr add 172.15.1.1/24 dev bridge0 
Host# ip link delete dev ens160
Host# brctl adif bridge0 ens160

pipework下载地址:https://github.com/jpetazzo/pipework
Host# git clone https://github.com/jpetazzo/pipework.git

创建两个容器
Host# docker run -dit --name test1 --net=none centos
Host# docker run -dit --name test2 --net=none centos

Host# ./pipework bridge0 test1 172.15.1.10/24@172.15.1.1
Host# ./pipework bridge0 test2 172.15.1.11/24@172.15.1.1

前面172.15.1.10/24是要给容器设置的地址,后面172.15.1.1 是网关地址

测试
Host#  docker exec -it test1 /bin/bash
[root@f61de5354791 /]# ping 172.15.1.11
PING 172.15.1.11 (172.15.1.11) 56(84) bytes of data.
64 bytes from 172.15.1.11: icmp_seq=1 ttl=64 time=0.090 ms

20、libnetwork 三种基本元素需要了解: 1、Sandbox(沙盒):代表一个容器 ( 准确的说,是其网络命名空间); 2、Endpoint(接入点):代码网络上可以挂载容器的接口,会分配IP地址; 3、Network可以连接多个接入点的一个子网;

cnm容器管理系统,流程:驱动自动注册到网络控制器,网络控制器使用驱动类型来创建网络,然后在创建的网络上创建接口,最后把容器连接到接口上即可。销毁先把容器从接入口上卸载,然后删除接入口和网络。

docker_基础_3
docker_基础_3

目前cnm支持的驱动类型有四种:null、bridge、overlay、remote null:不提供网络服务,容器启动后无网络连接; bridge:docker传统上默认用linux网络和iptables实现的单机网络; Overlay:vxlan隧道实现的跨主机容器网络 remote:扩展类型,预留给其它外部实现的方案,比如sdn方案 如(openstack neutron)

网络和和容器有如下约定: 同一个网络中的容器可以相互通信 分流容器网络流量主要利用多网络的放肆实现,所以所有的Driver都要支持多网络 一个容器可以通过多Endpoint的方式,而属于多个网络 一个Endpoint加入了一个SandBox之后,才能获得网络连通性

Docker 将会支持network相关的命令,这些命令用由libnetwork来实现,命令用法如下

代码语言:javascript
复制
docker network
Usage: docker network [OPTIONS] COMMAND [OPTIONS] [arg...]

    Commands:
        create                   创建
        rm                       删除
        ls                       列出所有
        info                     显示描述信息

    Run 'docker network COMMAND --help' for more information on a command.
      --help=false       打印使用

[root@dockers ~]# 
[root@dockers ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a36bdd783f62        bridge              bridge              local
43b935933822        host                host                local
4ee7cee4fc1c        none                null                local

分别为三种驱动的网络: bridge,host,none

20.1、创建网络 命令格式: docker network create [options] NETWORKNAME

代码语言:javascript
复制
支持参数包括:
  --aux-address value:辅助的IP地址;
    -d, --deiver string:网络驱动模型,如bridge或overlay;
    --gateway value: 网络地址
    --ip-range value:分配IP地址范围
    --ipv6:支持IPV6地址
    --label value:为网络添加元标签信息

20.2、删除网络

删除指定的网络,当网络上并不存在接入点Endpoint时,删除成功。 格式: docker network rm networkname

20.3、接入容器 格式:docker network connect [options] network container

代码语言:javascript
复制
支持参数包括:
    --alias value:为容器添加一个别名,此别名仅在所添加网络上可见
    --ip string:指定IP地址
    --ip6 string:指定ipv6地址
    --link value:添加链接到另一个容器,类似vlan互通
    --link-local-ip value:为容器添加一个链接地址

20.4、卸载查看容器

将一个连接到网络上的容器从网络上移除 格式: docker network disconnect [OPTIONS] network container 支持参数 -f --force强制把容器从网络上移除

查看已存在网络的具体信息 格式:docker network inspect [OPTIONS] NETWORK 支持参数 -f --format string:给定一个golang模板字符串,对输出结果进行格式化

20.5、构建跨主机的容器网络

使用libnetwork中的overlay类型驱动来实现跨主机的容器网络通信。overlay驱动默认使用vxlan协议,在IP地址可以互相访问多个主机上之间搭建隧道,让容器可以互相访问。    在libnetwork网络方案中,要实现跨主机容器网络也需要类似的一个网络信息管理机制,这个机制简单得多,只是一个键值数据库而已,如Consul,etcd,Zookeeper等工具都可以满足需求,如图

以consul为例,启动一个progrium/consul容器,并映射服务到本地的8500端口,用如下命令

代码语言:javascript
复制
docker run -d -p 8500:8500 -h consul1 progrium/consul -server -bootstrap
所在主机作为数据库节点

再启动两台docker主机 n1 和n2 确定两台机器能互相通信

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接上篇
  • 12、基本架构
    • 12.1、服务端
      • 12.2、客户端
        • 13.1、进程命名空间
          • 13.2、网络命名空间
            • 13.3、IPC命名空间
              • 13.4、挂载命名空间
                • 13.5、UTS命名空间 (名称)
                  • 13.6、用户命名空间
                  • 15、联合文件系统
                    • 15.1、Docker存储
                      • 15.2、多种文件系统比较
                        • 17.1.1、基于容器的运行方式
                        • 17.1.2、本地安装运行
                    • 16、网络模式
                    • 18、安全防护与配置
                    • 19、高级网络功能
                      • 19.1、通过参数指定网络
                        • 19.2、容器访问外部网络
                          • 19.5、pipework
                            • 20.2、删除网络
                              • 20.4、卸载查看容器
                                • 20.5、构建跨主机的容器网络
                                相关产品与服务
                                容器服务
                                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档