docker 集群

Docker 容器 

移除所有的容器和镜像(大扫除)
    用一行命令大扫除:

        docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) ; docker rmi $(docker images -q -a) 
        注:shell 中的 $() 和 `` 类似,会先执行这里面的内容,上面的脚本会出现如下 docker kill "pids" ; docker kill 在 docker 中用于停止容器,docker rm 删除容器, docker rmi 删除镜像
        当没有运行的容器或者是根本没有容器的时候,这只会提示一个警告信息。当你想尝试的时候,这就是个非常好的单行命令。如果你仅仅想删除所有的容器,你可以运行如下命令:

        docker kill $(docker ps -q) ; docker rm $(docker ps -a -q)

        
    退出时删除容器
    
        如果你仅仅想在一个容器中快速的运行一个命令,然后退出,并且不用担心容器状态,把 --rm 参数加入 run 命令后面,这将结束很多你保存了的容器,并且清理它们。

        示例:docker run --rm -i -t busybox /bin/bash    
        
        
        
        
Docker Machine 

    统一 docker 虚拟机 环境 按照工具
    
    在 docker1.12 后 按照docker 自带
    
    创建一个machine
        docker-machine create --driver virtualbox worker  (virtualbox)
        docker-machine create --driver hyperv  manager        (hyperv)

  注意:
   docker machine 使用的系统是  Tiny Core Linux
   该系统号称世界最小的 LINUX 系统。并且该系统运行在内存中。 docker 对其镜像了拓展 预装了docker 环境。
         
    查看machine列表
        docker-machine ls
        
    查看 machine 的环境变量的配置信息
        docker-machine env my-machine
        
    连接到machine的shell    
        eval "$(docker-machine env my-machine)"
        
    shh  链接
        docker-machine ssh my-machine
        
    关于 env 链接问题

        在win10 中  
         docker-machine    env my-machine | Invoke-Expression
        
        查看docker-machine ls
        
        NAME       ACTIVE     DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
        my-machine   *        virtualbox   Running   tcp://192.168.99.100:2376           v1.12.3
        my-machine   -        virtualbox   Running   tcp://192.168.99.100:2376           v1.12.3
        
        
        ACTIVE = *  显示当前链接的 是  my-machine 的 docker  
        
        后续
        
            可以直接如本地docker 环境一样使用 
            
            docker images
            
docker-compose
{
    批量按照 镜像
    
    
    安装docker-compose
    
    # curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    # chmod +x /usr/local/bin/docker-compose
    # docker-compose -v
    
    # cat docker-compose.yml
        version: "2"

        services:
          rng:
            build: rng
            ports:
            - "8001:80"

          hasher:
            build: hasher
            ports:
            - "8002:80"

          webui:
            build: webui
            ports:
            - "8000:80"
            volumes:
            - "./webui/files/:/files/"

          redis:
            image: redis

          worker:
            build: worker
    docker币应用一共有4个服务. 分别对应4个目录rng, hasher, webui, worker:
        详情可进入对应目录查看Dockerfile.

        rng是一个web service 生成随机的bytes数据.
        hasher是一个计算POST 数据hash值的web service.
        worker作为工作节点 后台调用rng 生成随机bytes数据, 然后将数据post到hasher服务计算hash值, 如果hashe值开头为0.则产生一个docker币.并将docker币保存到redis数据库中.
        webui一个web接口来监控整个系统.读取redis数据库中的docker币数量
        
    运行docker应用
        docker-compose up  // 在docker-compose.yml 文件夹中
        
    应用运行情况
        docker-compose ps
        
    增加节点
        docker-compose scale worker=10
        
        docker-compose ps
        
        
                        Name                       Command               State          Ports         
        -------------------------------------------------------------------------------------
        dockercoins_hasher_1    ruby hasher.rb                   Up      0.0.0.0:8002->80/tcp
        dockercoins_redis_1     docker-entrypoint.sh redis ...   Up      6379/tcp             
        dockercoins_rng_1       python rng.py                    Up      0.0.0.0:8001->80/tcp
        dockercoins_webui_1     node webui.js                    Up      0.0.0.0:8000->80/tcp
        dockercoins_worker_1    python worker.py                 Up                           
        dockercoins_worker_10   python worker.py                 Up                           
        dockercoins_worker_2    python worker.py                 Up                           
        dockercoins_worker_3    python worker.py                 Up                           
        dockercoins_worker_4    python worker.py                 Up                           
        dockercoins_worker_5    python worker.py                 Up                           
        dockercoins_worker_6    python worker.py                 Up                           
        dockercoins_worker_7    python worker.py                 Up                           
        dockercoins_worker_8    python worker.py                 Up                           
        dockercoins_worker_9    python worker.py                 Up

        
    ps: docker-compose 并未详细学习
}
    
Docker Swarm

    集群管理工具
    
    Docker  1.12 集成了Swarm集群工具

    docker swarm 开启swarm模式; 加入Swarm集群; 配置集群参数
    docker node 查询集群节点信息; 提升/移除一个管理节点; 管理swarm节点主机
    docker service 创建管理 service

    初始化swram集群
        docker swarm init --advertise-addr 192.168.99.101
    
        --advertise-addr参数, 后面跟你swarm集群的通讯地址
    

    
    docker swarm mode信息:
        在swram docker环境中 
        docker info
            Swarm: active
        
    加入swarm集群的命令和密钥
        docker swarm join-token worker  (工人)
        docker swarm join-token manager    (管理员)
    
    加入swarm集群
        在需要加入集群的docker环境中  
            运行 docker swarm join-token worker      (工人) 显示的语句
            运行 docker swarm join-token manager    (管理员)显示的语句
    
    查集群节点列表
        docker node ls
    
    
    Swarm集群上运行service
        原来使用docker run的命令, 把前面替换成docker service create
            docker service create --name ping-google alpine ping 8.8.8.8
    
    查询 swarm service列表    
            docker service ls
        ID            NAME         REPLICAS  IMAGE   COMMAND
        9cyy6xrk2n0w  ping-google  1/1       alpine  ping 8.8.8.8
    
        ps : 注意 REPLICAS  1/1  前面的1 是已经启动的 容器   后面的1 是总共需要几个容器
        
    查看服务到底跑在哪个节点服务器上:    
        
        docker service ps <serviceID> 
        
        docker service ps ping-google
        ID                         NAME               IMAGE   NODE    DESIRED STATE  CURRENT STATE           ERROR
        alxkyacovh4ltiklpccjhf2u5  ping-google.1      alpine  node03  Running        Running 5 minutes ago   
        15e8v9q83wu3skrz63ieacbkr   \_ ping-google.1  alpine  node01  Shutdown       Rejected 5 minutes ago  "No such image: alpine:latest"
    
    Scale扩展服务
        Scale服务到10个副本容器
            docker service scale <serivce ID>=<replicas No>
            
            ps :docker service scale ping-google=10
            
            ID            NAME         REPLICAS  IMAGE   COMMAND
            9cyy6xrk2n0w  ping-google  1/10      alpine  ping 8.8.8.8
                
            注意REPLICAS现在显示1/10表示这个service一共有10个副本,现在成功运行了1个. 集群正在启动其他的副本.
            
        修改服务的属性 扩展服务
            
            查看服务属性
                docker service inspect 服务名称
                    "Mode": {
                        "Replicated": {
                            "Replicas": 1
                        }
                    },
                    
            更新服务属性    
                docker service update rng --replicas 5
                
    global模式
        
        global模式的service, 就是在swarm集群的每个节点创建一个容器副本
        让一个service分布在集群的每个节点上
        
        
        // 指定网络  并且 使用 global模式
        docker service create --network dockercoins --name debug --mode global 服务名称
        
        

    
        
    暴露一个服务端口
        swarm集群的service端口暴露还有如下特性:

            公共的端口会暴露在每一个swarm集群中的节点服务器上.
            请求进如公共端口后会负载均衡到所有的sevice实例上.
        
        发布端口的参数跟单机环境一样是-p, 就是把docker run -p替换成docker service create -p.    
            docker service create --name search --publish 9200:9200 --replicas 7 elasticsearch
            
            replicas 是设置创建 7个 容器
    
    
    
    swarm集群负载均衡service有两种方式VIP和DNSRR:

            VIP模式每个service会得到一个 virtual IP地址作为服务请求的入口. 基于virtual IP进行负载均衡.
            
            DNSRR模式service利用DNS解析来进行负载均衡, 这种模式在旧的Docker Engine下, 经常行为诡异…所以不推荐.
            
            查看service的负载均衡模式
            
                docker service inspect rng
                
                        "EndpointSpec": {
                        "Mode": "vip"
                        }
                },
                "Endpoint": {
                    "Spec": {
                        "Mode": "vip"
                    },
                    "VirtualIPs": [
                        {
                            "NetworkID": "396fwpd5ja6azh93dshalmxro",
                            "Addr": "10.0.0.6/24"
                        }
                        
                        
        容器之间是不联通的  可以通过 主机IP 还联通 、 实用自定义网络 联通
        
        
        注意!!
            如果是通过 服务名称访问  服务名称不要有 特殊字符  如 @ _  等
                
    
    删除服务
        
        docker service rm <service ID or Name>
    
    
    容器服务更新
    
        程序代码进行修改后  构建新版的号的镜像 上次到 镜像仓库   
        
        更新服务是同版本好来更新的
        
            docker service update 命令
            
                --update-parallelism指定每次update的容器数量, 
                --update-delay 每次更新之后的等待时间.
                --image后面跟服务镜像名称
                
            // 原先的版本号是 0.1  更新版本 为 0.01    
            docker service update 服务名称 --update-parallelism 2 --update-delay 5s --image localhost:5000/dockercoins_worker:v0.01

            以一次更新2个容器副本的    频率更新到v0.01版本.
        
    
    容器服务回滚
    
        和 容器服务更新 一样  只要 指定版本号就可以了
        
    
    
    
    
    
    跨主机问题  
        
        经过测试  可以 阿里云主机 与本地Docker Machine 创建的虚拟机 互联! 
    
   注意!!
   
    要打开 端口!



      Port 7946 TCP/UDP for container network discovery.



Port 4789 UDP for the container ingress network.
关于 获取请求 ip 地址的问题

   在 swarm  overlay 模式下   获取的IP 是服务器IP地址 不是 用户请求IP 地址。
 
  解决办法
    目前为止   docker service create --publish mode=host,target=9221,published=9221  
    制定为 mode=host   直接将请求到容日 不进行转发。
  据说 17.07 版本后 会解决。
镜像仓库registry
        
        创建registry服务, 发布5000端口
            docker service create --name registry --publish 5000:5000 registry:2
        ps:
            启动了一个registry副本容器, 根据docker swarm集群的端口发布服务特性
            swarm集群所有节点都会自动发布本机的5000对应到registry
            所以不管你在哪个节点上执行curl localhost:5000/v2/_catalog
            都是可以访问到registry服务的.所以你不用关心这个registry跑在那个节点上
            
            
    推送镜像

        需要先tag这个镜像的名字成<registry>/<image name>:<tag>:
            docker tag alpine localhost:5000/test
        推送image        
            docker push <image name>   
            
    overlay网络
    
        docker 1.12以前, swarm集群需要一个额外的key-value存储(consul, etcd etc). 来同步网络配置
        保证所有容器在同一个网段中.在docker 1.12已经内置了这个存储, 集成了overlay networks的支持
            
            
        创建一个名为dockercoins的overlay network
            docker network create命令
                docker network create --driver overlay dockercoins
                
        指定网络
            直接使用--network <network name>参数, 在指定网络上创建service
            
            docker service create --network dockercoins --name redis redis
            
            
            
            
            
            
            
    指定service约束

    
        节点属性        匹配                    示例
        node.id            节点 ID                    node.id == 2ivku8v2gvtg4
        node.hostname    节点 hostname            node.hostname != node02
        node.role        节点 role: manager        node.role == manager
        node.labels        用户自定义 node labels    node.labels.security == high
        engine.labels    Docker Engine labels    engine.labels.operatingsystem == ubuntu 14.04    
            
    举例  约束 服务 在固定的  服务器节点
        
        由于swarm自动调度定义执行在某个节点上的 重启服务以后 服务可能会被启动再随机的节点  
        
        docker service create --name registry --publish 5000:5000 \
        --constraint 'node.hostname==node01' registry


    
            
    挂载本地文件夹


        docker service create --name registry --publish 5000:5000 \
        --mount source=registry-vol,type=volume,target=/var/lib/registry \
        -e SEARCH_BACKEND=sqlalchemy \
        --constraint 'node.hostname==node01' registry
        
        
        docker service create --mount type=bind,target=/container_data/,source=/host_data/

        例 - 本地目录:     target = 容器里面的路径, source = 本地硬盘路径
        docker service create --name nginx --mount type=bind,target=/usr/share/nginx/html/,source=/opt/web/ --replicas 2 --publish 80:80/tcp nginx



        docker service create --mount type=volume,source=<VOLUME-NAME>,target=<CONTAINER-PATH>,volume-driver=<DRIVER>,

        例 - 挂载volume卷:  source  =  volume 名称 ,  traget = 容器里面的路径
        docker service create --name nginx --mount type=volume,source=myvolume,target=/usr/share/nginx/html,volume-driver=local --replicas 2 --publish 80:80/tcp nginx
        
            
        约束服务在node01 服务器节点  
        暴露 绑定IP 5000
        
            source=registry-vol 中registry-vol为卷名字  target 是地址
            target = 容器里面的路径, source = 本地硬盘路径
            
        使用docker volume ls命令查看
            
            docker volume ls
        
            
            docker volume inspect registry-vol
            可以看到本机卷挂载到节点的目录.
            
    为启动的服务 挂载本地文件夹
            
            update
            
            docker service update registry \
               --mount-add type=volume,source=registry-vol,target=/var/lib/registry
    
    
    
    
    
    关于 cloud 
    
        直接使用  服务名称 
        
        
            指定  cloud 服务名称  与 docker 服务名称相同
        
            defaultZone: http://discovery:8761/eureka/
            
                应为 通过docker已经自动负载了
                
                
     本文 很多部分都是 摘自 https://guai.im/   很详细的介绍和搭建了 Docker 集群     感兴趣的 可以看看


重要提示  关于 spring cloud docker 化的问题   

  由于容器隔离问题  会出现  spring cloud 服务无法访问的问题。  

  问题原因  
     
    docker 容器中 会有多个网卡  理论上  spring cloud 会获取 第一个网卡   也就是 在 docker 同一网络中 可以访问通的 IP 
    但是 很多情况下  获取到的缺不是  可以访问通的IP 

  解决方法
    
    spring cloud 设置 网卡过滤
spring:
  cloud:
    inetutils:
      ignoredInterfaces:
        - eth1
        - eth2
        - eth3
        - lo

    关于网卡名称到的是什么 可以运行

        docker service create --network cloud  --replicas 1 --name centos registry.cn-hangzhou.aliyuncs.com/atliwen/centos6.8-ssh ifconfig

     查看 日志  docker service logs centos  看到

docker 集群 网络 是由管理端 服务器 做中转的    只要可以访问到 管理端服务器  就可以加入该集群   容器就可以互通


CentOS 7 修改主机名称   

  hostnamectl set-hostname <hostname>

  hostnamectl set-hostname <主机名> 


CentOS 7 安装 Docker

  Prerequisites




  Docker CE is supported on CentOS 7.3 64-bit.




    1. Set up the repository




      Set up the Docker CE repository on CentOS:




sudo yum install -y yum-utils




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




          sudo yum makecache fast

    2. Get Docker CE




      Install the latest version of Docker CE on CentOS:




sudo yum -y install docker-ce

      Start Docker:




sudo systemctl start docker

    3. Test your Docker CE installation




      Test your installation:




sudo docker run hello-world

    开机自启动

 

       sudo chkconfig docker on

    开放firewall防火墙端口

        firewall-cmd --zone=public --add-port=2377/tcp --permanent && \
        firewall-cmd --zone=public --add-port=7946/tcp --permanent && \
        firewall-cmd --zone=public --add-port=7946/udp --permanent && \
        firewall-cmd --zone=public --add-port=4789/tcp --permanent && \
        firewall-cmd --zone=public --add-port=4789/udp --permanent && \
        firewall-cmd --reload

    查看端口开放情况

        firewall-cmd --list-ports

    直接关闭防火墙

        systemctl stop firewalld.service #停止firewall

        systemctl disable firewalld.service #禁止firewall开机启动

卸载docker 

  sudo yum -y remove docker*
  rm -rf /var/lib/docker


设置静态IP

    BOOTPROTO="static" #dhcp改为static
    ONBOOT="yes" #开机启用本配置
    IPADDR=192.168.18.129 #静态IP
    GATEWAY=192.168.18.2 #默认网关
    NETMASK=255.255.255.0 #子网掩码
    DNS1=192.168.18.2 #DNS 配置

poweroff  立刻关机 
shutdown -h now 立刻关机(root用户使用)
重启命令 reboot 
     shutdown -r now 
立刻重启 shutdown -r 10

systemctl is-enabled iptables.service
systemctl is-enabled servicename.service #查询服务是否开机启动
systemctl enable *.service #开机运行服务
systemctl disable *.service #取消开机运行
systemctl start *.service #启动服务
systemctl stop *.service #停止服务
systemctl restart *.service #重启服务
systemctl reload *.service #重新加载服务配置文件
systemctl status *.service #查询服务运行状态
systemctl --failed #显示启动失败的服务

注:*代表某个服务的名字,如http的服务名为httpd

 

构建 DOcker 镜像

  构建镜像

      mvn clean package docker:build

  构建镜像并且推送到镜像表

 

      mvn clean package docker:build -DpushImage

 

 

 集群节点添加标识

     docker node update  djts-4 --label-add servertype=zuul

    集群节点删除标识 

    docker node update  djts-4 --label-rm   servertype

 

  集群服务编排 指定节点标签

    --constraint 'node.labels.servertype==zuul'