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'