Docker!!!---- Docker Compose容器编排

Docker---- Compose编排

一: Docker网络通信

1.1: Docker单主机容器通信的四种方式

  • 1)host模式

    由于容器和宿主机共享同一个网络命名空间,换言之,容器的IP地址即为宿主机的IP地址。所以容器可以和宿主机一样,使用宿主机的任意网卡,实现和外界的通信。其网络模型可以参照下图:

    mark

    采用host模式的容器,可以直接使用宿主机的IP地址与外界进行通信,若宿主机具有公有IP,那么容器也拥有这个公有IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行NAT转换,而且由于容器通信时,不再需要通过linuxbridge等方式转发或数据包的拆封,性能上有很大优势。当然,这种模式有优势,也就有劣势,主要包括以下几个方面:
    1)最明显的就是容器不再拥有隔离、独立的网络栈。容器会与宿主机竞争网络栈的使用,并且容器的崩溃就可能导致宿主机崩溃,在生产环境中,这种问题可能是不被允许的。
    2)容器内部将不再拥有所有的端口资源,因为一些端口已经被宿主机服务、bridge模式的容器端口绑定等其他服务占用掉了。

  • 2)bridge模式

    bridge模式是docker默认的,也是开发者最常使用的网络模式。在这种模式下,docker为容器创建独立的网络栈,保证容器内的进程使用独立的网络环境,实现容器之间、容器与宿主机之间的网络栈隔离。同时,通过宿主机上的docker0网桥,容器可以与宿主机乃至外界进行网络通信。其网络模型可以参考下图:

    mark

  • 从上面的网络模型可以看出,容器从原理上是可以与宿主机乃至外界的其他机器通信的。同一宿主机上,容器之间都是连接掉docker0这个网桥上的,它可以作为虚拟交换机使容器可以相互通信。然而,由于宿主机的IP地址与容器veth pair的 IP地址均不在同一个网段,故仅仅依靠veth pair和namespace的技术,还不足以使宿主机以外的网络主动发现容器的存在。为了使外界可以方位容器中的进程,docker采用了端口绑定的方式,也就是通过iptables的NAT,将宿主机上的端口端口流量转发到容器内的端口上。举一个简单的例子,使用下面的命令创建容器,并将宿主机的3306端口绑定到容器的3306端口:

    docker run -tid --name db -p 3306:3306 MySQL

    在宿主机上,可以通过iptables -t nat -L -n,查到一条DNAT规则

    DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.5:3306

    上面的172.17.0.5即为bridge模式下,创建的容器IP。

    很明显,bridge模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,对宿主机端口的管理会是一个比较大的问题。同时,由于容器与外界通信是基于三层上iptables NAT,性能和效率上的损耗是可以预见的。

  • 3)none模式

    在这种模式下,容器有独立的网络栈,但不包含任何网络配置,只具有lo这个loopback网卡用于进程通信。也就是说,none模式为容器做了最少的网络设置,但是俗话说得好“少即是多”,在没有网络配置的情况下,通过第三方工具或者手工的方式,开发这任意定制容器的网络,提供了最高的灵活性。

  • 4) container模式

    container 是docker中一种较为特别的网络的模式。在这个模式下的容器,会使用其他容器的网络命名空间,其网络隔离性会处于bridge桥接模式与host模式之间。当容器共享其他容器的网络命名空间,则在这两个容器之间不存在网络隔离,而她们又与宿主机以及除此之外其他的容器存在网络隔离。其网络模型可以参考下图:

    mark

    在这种模式下的容器可以通过localhost来同一网络命名空间下的其他容器,传输效率较高。而且这种模式还节约了一定数量的网络资源,但它并没有改变容器与外界通信的方式。在一些特殊的场景中非常有用,例如,kubernetes的pod,kubernetes为pod创建一个基础设施容器,同一pod下的其他容器都以其他容器模式共享这个基础设施容器的网络命名空间,相互之间以localhost访问,构成一个统一的整体。

1.2: Docker跨主机容器通信

  • 早期大家的跨主机通信方案主要有以下几种:
    1)容器使用host模式:容器直接使用宿主机的网络,这样天生就可以支持跨主机通信。虽然可以解决跨主机通信问题,但这种方式应用场景很有限,容易出现端口冲突,也无法做到隔离网络环境,一个容器崩溃很可能引起整个宿主机的崩溃。

    2)端口绑定:通过绑定容器端口到宿主机端口,跨主机通信时,使用主机IP+端口的方式访问容器中的服务。显而易见,这种方式仅能支持网络栈的四层及以上的应用,并且容器与宿主机紧耦合,很难灵活的处理,可扩展性不佳。

    3)docker外定制容器网络:在容器通过docker创建完成后,然后再通过修改容器的网络命名空间来定义容器网络。典型的就是很久以前的pipework,容器以none模式创建,pipework通过进入容器的网络命名空间为容器重新配置网络,这样容器网络可以是静态IP、vxlan网络等各种方式,非常灵活,容器启动的一段时间内会没有IP,明显无法在大规模场景下使用,只能在实验室中测试使用。

    4)第三方SDN定义容器网络:使用Open vSwitch或Flannel等第三方SDN工具,为容器构建可以跨主机通信的网络环境。这些方案一般要求各个主机上的docker0网桥的cidr不同,以避免出现IP冲突的问题,限制了容器在宿主机上的可获取IP范围。并且在容器需要对集群外提供服务时,需要比较复杂的配置,对部署实施人员的网络技能要求比较高。

    上面这些方案有各种各样的缺陷,同时也因为跨主机通信的迫切需求,docker 1.9版本时,官方提出了基于vxlan的overlay网络实现,原生支持容器的跨主机通信。同时,还支持通过libnetwork的plugin机制扩展各种第三方实现,从而以不同的方式实现跨主机通信。就目前社区比较流行的方案来说,跨主机通信的基本实现方案有以下几种:

    1)基于隧道的overlay网络:按隧道类型来说,不同的公司或者组织有不同的实现方案。docker原生的overlay网络就是基于vxlan隧道实现的。ovn则需要通过geneve或者stt隧道来实现的。flannel最新版本也开始默认基于vxlan实现overlay网络。

    2)基于包封装的overlay网络:基于UDP封装等数据包包装方式,在docker集群上实现跨主机网络。典型实现方案有Weave、Flannel的早期版本.

    3)基于三层实现SDN网络**:基于三层协议和路由,直接在三层上实现跨主机网络,并且通过iptables实现网络的安全隔离。典型的方案为 **Calico。同时对不支持三层路由的环境,Calico还提供了基于IPIP封装的跨主机网络实现

1.3: 创建固定地址的容器

  • 1.先创建网桥
    2.再基于网桥分配容器固定ip
    [root@docker02 ~]# docker network create --subnet=172.10.0.0/24 li-network
    "创建172.10.0.0的网段的网桥,网桥命名为li-network"
    62f3ea8d2634189389e70e8ef70ff6717a91f373f98060ee3ad186c4d6244bce
    [root@docker02 ~]# ifconfig			"62f3ea8d2634为网桥的容器Id"
    br-62f3ea8d2634: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            inet 172.10.0.1  netmask 255.255.255.0  broadcast 172.10.0.255
            ether 02:42:cb:97:64:9d  txqueuelen 0  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    [root@docker02 ~]# docker run -itd --name test --net li-network --ip 172.10.0.10 centos:7 /bin/bash		"基于li-network 网桥创建容器并分配固定地址"
    [root@docker02 ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                    PORTS               NAMES
    f94496351d49        centos:7            "/bin/bash"              About a minute ago   Up About a minute                             test
    01011d30d57c        registry            "/entrypoint.sh /etc…"   31 hours ago         Exited (2) 31 hours ago                       crazy_johnson
    [root@docker02 ~]# docker exec -it f94496351d49 /bin/bash
    [root@f94496351d49 /]# yum install -y net-tools
    [root@f94496351d49 /]# ifconfig			"查看分配的固定板地址"
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.10.0.10  netmask 255.255.255.0  broadcast 172.10.0.255
    [root@docker02 ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    49e2f1a32354        bridge              bridge              local
    79bebd37be8c        host                host                local
    62f3ea8d2634        li-network          bridge              local
    41655f841a1c        none                null                local
    宿主机网桥"br-62f3ea8d2634"对应这里的li-network
    

二:Docker Compose容器编排详解

2.1:Docker Compose基本概念

  • Docker Compose 的前身是Fig,它是一个定义及运行多个容器的工具

    使用Docker Compose不再需要使用shell脚本来启动容器

    通过Docker Compose可以使用YML文件来配置应用程序所需要的的所有服务

    Docker Compose非常适合组合使用多个容器进行开发的场景

  • YAML是一种标记语言很直观的数据序列化格式,非常适合用来表达或者编辑数据结构、各种配置文件、文件大纲等,例如:许多电子邮件标题格式和YAML非常接近

    文件格式以及编写注意事项

    • 1、不支持制表符tab键缩进,需要使用空格缩进,使用缩进表示层级关系
    • 2、通常开头缩进2个空格,缩进的空格数不重要,只要相同层级的元素左对齐即可
    • 3、字符后缩进一个空格,如冒号、逗号、横杆
    • 4、用#号注释
    • 5、如果包含特殊字符用单引号引起来
    • 6、布尔值必须用引号括起来

2.2:使用Docker Compose详解:使用步骤、环境准备、格式详解

  • compose使用的三个步骤

    1、使用Dockerfile定义应用程序的环境

    2、使用docker-compose.yml定义构成应用程序的服务,这样它们可以在隔离环境中一起运行

    3、最后执行docker-compose up命令来启动并运行整个应用程序

  • [root@docker ~]# curl -L https://github.com/docker/compose/releases/download/1.21.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose	'//在Linux上我们可以从GitHub上下载它的二进制包来使用,此命令是下载Docker Compose的当前稳定版本'
    [root@docker ~]# chmod +x /usr/local/bin/docker-compose
    [root@docker ~]# docker-compose -v
    docker-compose version 1.21.1, build 5a3f1a3
    
  • Docker Compose文件结构举例:docker-compose.yml

    1、compose版本号、服务标识符必须顶格写

    2、属性名与属性值以:(冒号加空格)分隔开

    3、层级使用两个空格表示

    4、服务属性使用-(空格空格-空格)表示

    version: '2'	'//compose版本号'
    services:	'//服务标识符'
      web:	'//子服务名'
        image: dockercloud/hello-world	'//服务依赖镜像属性'
        ports:	'//服务端口属性'
          - 8080
        networks:	'//网络服务属性'
          - front-tier
          - back-tier
      redis:
        image: redis
        links:	'//容器间的连接设置'
          - web
        networks:
          - back-tier
      lb:
        image: dockercloud/haproxy
        ports:
          - 80:80
        links:
          - web
        networks:
          - front-tier
          - back-tier
        volumes:	'//挂载一个目录或者一个已存在的数据卷容器'
          - /var/run/docker.sock:/var/run/docker.sock 
    networks:
      front-tier:
        driver: bridge
      back-tier:
        driver: bridge
    
    

2.3:Docker Compose配置常用字段

  • 常用字段在上述的yml文件格式中有过一些解释,下面是详细解释

    字段描述
    build dockerfile context指定Dockerfile文件名构建镜像上下文路径
    image指定镜像
    command执行命令,覆盖默认命令
    container name指定容器名称,由于容器名称是唯一的,如果指定 自定义名称,则无法scale
    deploy指定部署和运行服务相关配置,只能在swarm模式适用
    environment添加环境变量
    networks加入网络
    ports暴露容器端口,与-p相同,但端口不能低于60
    volumes挂载宿主机路径或命令卷
    restart重启策略,默认no,always,no-failure,unless-stoped
    hostname容器主机名

2.4:Docker Compose常用命令

  • 基本的命令格式:docker-compose [选项] [命令] [参数]

  • docker-compose选项

    –verbose:输出更多调试信息

    –version:打印版本并退出

    -f、–file FILE:使用特定的compose末班文件,默认为docker-compose.yml

    -p、–project-name NAME:指定项目名称,默认使用目录名称

    字段解释
    build重新构建服务
    ps列出容器
    up创建和启动容器
    exec在容器里面执行命令
    scale指定一个服务容器启动数量
    top显示容器进程
    logs查看容器输出
    down删除容器、网络、数据卷和镜像
    stop/start/restart停止/启动/重启服务

三: 使用Docker-Compose创建nginx

  • compose 部署并创建nginx编排
1、部署Docker-Compose环境
[root@docker02 ~]# yum install -y docker-ce
[root@docker02 ~]# curl -L https://github.com/docker/compose/releases/download/1.21.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose	'//在Linux上我们可以从GitHub上下载它的二进制包来使用,此命令是下载Docker Compose的当前稳定版本'
[root@docker02 ~]# chmod +x /usr/local/bin/docker-compose
[root@docker02 ~]# docker-compose -v
docker-compose version 1.21.1, build 5a3f1a3
#或者上传文件
[root@docker02 ~]# cp -p docker-compose /usr/local/bin
//就是一个工具,直接添加到/usr/local/bin/ 当成工具来用

2、使用Dockerfile定义应用程序的环境
mkdir -r /root/compose_nginx/nginx
cd /root/compose_nginx/nginx
[root@docker02 nginx]# cat Dockerfile 
FROM centos:7
MAINTAINER this is kgc-nginx image <li>
RUN yum -y update
RUN yum install pcre pcre-devel zlib-devel gcc gcc-c++ make -y
RUN useradd -s /sbin/nologin nginx -M
ADD nginx-1.12.0.tar.gz /usr/local/src
WORKDIR /usr/local/src/nginx-1.12.0
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
RUN ln -s /usr/local/nginx-1.12.0/sbin/ /usr/local/bin/
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
[root@docker02 nginx]# cat run.sh 
#!/bin/bash
/usr/local/nginx/sbin/nginx
[root@docker02 nginx]# ls
Dockerfile  nginx-1.12.0.tar.gz  run.sh

3、使用docker-compose.yml定义构成应用程序的服务
[root@docker02 compose_nginx]# vim docker-compose.yml
version: '3'
services:
  nginx:
    hostname: nginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
     - 1216:80
     - 1217:443
    networks:
     - li
    volumes:
     - ./wwwroot:/usr/local/nginx/html
networks:
  li:
 
[root@docker02 compose_nginx]# tree
.
├── docker-compose.yml
└── nginx
    ├── Dockerfile
    ├── nginx-1.12.0.tar.gz
    └── run.sh
4、执行docker-compose up命令来启动并运行整个应用程序
[root@docker02 compose_nginx]# docker-compose -f docker-compose.yml up -d	"用编排文件创建容器,并启动"
[root@docker02 compose_nginx]# tree
.
├── docker-compose.yml
├── nginx
   ├── Dockerfile
   ├── nginx-1.12.0.tar.gz
   └── run.sh
└── wwwroot
"自动创建了wwwroot"
[root@docker02 wwwroot]# docker ps -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                    PORTS                                         NAMES
82ec65e396ff        compose_nginx_nginx   "/run.sh"                13 minutes ago      Up 13 minutes             0.0.0.0:1216->80/tcp, 0.0.0.0:1217->443/tcp   compose_nginx_nginx_1
f94496351d49        centos:7              "/bin/bash"              50 minutes ago      Up 50 minutes                                                           test
[root@docker02 wwwroot]# vim index.html
<h1>this is test web</h1>
[root@docker02 ~]# curl http://192.168.100.190:1216
<h1>this is test web</h1>

mark

四: 使用Docker-Compose创建nginx和tomcat

  • compose 部署并创建nginx & tomcat编排
cat > docker-compose.yml<<EOF
version: '3'
services:
  nginx:
    hostname: nginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
     - 1216:80
     - 1217:443
    networks:
     - li
    volumes:
     - ./wwwroot:/usr/local/nginx/html
  tomcat:
    hostname: tomcat
    build:
      context: ./tomcat
      dockerfile: Dockerfile
    ports:
     - 1200:8080
    networks:
     - li
    volumes:
     - ./tomcat/webapps:/usr/local/tomcat/webapps/ROOT
     - ./tomcat/logs:/usr/local/tomcat/logs
networks:
  li:
  li:
EOF

[root@docker02 webapps]# ls
index.html  index.jsp

[root@docker02 tomcat]# ls
apache-tomcat-9.0.16.tar.gz  Dockerfile  jdk-8u201-linux-x64.rpm  logs  webapps
[root@docker02 tomcat]# cat Dockerfile 
FROM centos:7
MAINTAINER this is tomcat <li>
ADD jdk-8u201-linux-x64.rpm /usr/local
WORKDIR /usr/local
RUN rpm -ivh jdk-8u201-linux-x64.rpm
ENV JAVA_HOME /usr/java/jdk1.8.0_201-amd64
ENV CLASSPATH /lib/tools.jar:/lib/dt.jar
ENV PATH /bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
ADD apache-tomcat-9.0.16.tar.gz /usr/local
WORKDIR /usr/local
RUN mv apache-tomcat-9.0.16 /usr/local/tomcat
EXPOSE 8080
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]

[root@docker02 nginx]# ls
Dockerfile  nginx-1.12.0.tar.gz  run.sh
[root@docker02 nginx]# cat run.sh 
#!/bin/bash
/usr/local/nginx/sbin/nginx
[root@docker02 nginx]# cat Dockerfile 
FROM centos:7
MAINTAINER this is kgc-nginx image <li>
RUN yum -y update
RUN yum install pcre pcre-devel zlib-devel gcc gcc-c++ make -y
RUN useradd -s /sbin/nologin nginx -M
ADD nginx-1.12.0.tar.gz /usr/local/src
WORKDIR /usr/local/src/nginx-1.12.0
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
RUN ln -s /usr/local/nginx-1.12.0/sbin/ /usr/local/bin/
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]

[root@docker02 compose_nginx]# ls
docker-compose.yml  nginx  tomcat  wwwroot

[root@docker02 compose_nginx]# docker-compose -f docker-compose.yml up -d

mark

mark

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值