疑问
1、用传统的思维去理解,怎么也无法想清楚为什么实际只有2台物理机,但是却可以建立5个nginx,端口怎么映射呢?
查看2台物理机上用
docker ps
看到有2和3个nginx container运行,用docker exec -it bf15ed0ce233 bash
分别进入这5台container内部修改了index.html,echo '<h1>Hello, Docker nginx 1!</h1>' > index.html
分别改数字为1-5,然后只用1台物理机的IP去多次访问nginx的初始页面,没想到1-5页面都显示过。所以docker内部是带负载均衡的,并且用任意1台物理机的IP去访问,都可以访问到创建的5个任意container。这5个nginx实际指向的物理机端口都是18080,并且自己代理的端口都是80。
一、环境
2台电脑,局域网内组网(非局域网也可以),安装Docker19+,并且打开2377端口、7946和4789这两个端口要tcp和udp全开,否则swarm的节点之间无法通信。
manager管理员 IP:192.168.1.81 系统:centos7
node1集群节点 IP:192.168.1.91 系统:centos7
二、集群操作
1、配置集群
在master81上创建swarm,--advertise-addr参数表示其它swarm中的worker节点使用此ip地址与manager联系。
注意:输入一下指令后,会输出一段信息,其中一行提示其他电脑如何加入集群的指令,token要保存,以后其扩展时需要用到。
docker swarm init --advertise-addr 192.168.1.81
在node节点91上执行上次指令提示的加入节点语句
docker swarm join --token SWMTKN-1-2x7s0bwaz06iie4fres8ew4i26ni3t97l3tzg8lbwb5xypjv3k-f34awf7d1rzk3n5ej5vm4szuo 192.168.1.81:2377
至此集群创建完毕。
2、常用指令
docker node demote
管理节点将为普通节点
docker node inspect
查看节点详情
docker node ls
列出节点
docker node promote
普通节点升为管理节点
docker node ps
查看运行的任务
docker node rm
移除集群
docker node update
改变节点状态
3、部署服务
docker service 命令来管理Swarm集群中的服务。
创建2个nginx服务,如果以前没有下载镜像会有点慢
docker service create --replicas 2 -p 18080:80 --name nginx nginx:latest
如果想扩容的话使用
docker service scale nginx=5
docker service ls
查看swarm集群中运行的服务
docker service ps nginx
查看nginx服务详情
docker service rm nginx
删除nginx
三、实战示例
1、创建基于springboot的webapp
本文基于IDEA创建,其他方式自行搜索。
选择spring initializr点next,然后填写项目包名等信息。
一路next,这里就不链接数据库了,直接
返回一个固定随机数和名字,用2个参数来确定访问的是那个webapp。
HelloController
package com.lucien.swarm.sapp;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
@RestController
@RequestMapping("/")
public class HelloController {
public static int NODE_ID = -1;
public static String NODE_NAME = null;
@GetMapping("{name}")
public String getMsg(@PathVariable("name") String name) {
if(NODE_ID==-1)
NODE_ID = new Random().nextInt(100);
if(NODE_NAME == null)
NODE_NAME = name;
return "Node name:"+NODE_NAME+" Node id :"+NODE_ID;
}
}
application.yml
server:
port: 80
servlet:
context-path: /sapp
编译工程后把jar文件拷贝到81manager的/home/sapp目录下,创建Dockerfile
FROM java:8
ADD sapp-0.0.1-SNAPSHOT.jar /home/webapp/sapp-0.0.1-SNAPSHOT.jar
EXPOSE 80
CMD java -jar /home/webapp/sapp-0.0.1-SNAPSHOT.jar
上docker官网,登录,创建一个名字叫sapp的仓库
登录docker hub,输入账号密码,我的账号是lucienme
docker login
编译
docker build . -t sapp:v1
运行一下,访问192.168.1.81:18080/sapp/test(可跳过)
docker run --name sapp -d -p 18080:80 sapp:v1
修改标签准备上传,斜杠前面是账号名,后面是仓库名,冒号后面是版本号
docker tag sapp:v1 lucienme/sapp:v1
上传
docker push lucienme/sapp:v1
创建sapp-compose.yml
version: "3"
services:
sapp: #服务名,自定义
image: lucienme/sapp:v1 #镜像名,刚才build的image
ports:
- 18080:80 #映射物理机的18080端口
networks:
- sapp_overlay_network #使用网络名称
deploy:
mode: replicated
replicas: 5 #启动5个container
networks:
sapp_overlay_network: #创建网络
# 如果以前有个网络叫sapp_overlay_network,后续的集群想加入这个网络用external
# external: true
启动
docker stack deploy -c sapp-compose.yml sapp
关闭
docker stack down sapp
查看服务运行状况
docker service ls
查看container状况
docker ps
四、结语
1、相比于K8S,swarm相对轻量和简单的多,也容易学习和理解概念。
2、如果swarm自带了负载均衡的话,那nginx如果不是转发特定URL,似乎没必要使用了。
3、如果用swarm集群mysql的话,每个container的IP要如何定义,连接数据库的时候怎么操作?这个放到下次有空的时候再研究。
网友评论