Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
Distributed Computing and Network Fusion System
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
3
Issues
3
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
WirelessInformationCollaborate
Distributed Computing and Network Fusion System
Commits
1f84edba
Commit
1f84edba
authored
Nov 07, 2019
by
wutu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
定义网络拓扑的数据结构(采用二维数组进行描述),实现了基本的网络创建接口。未进行测试!
parent
1adf8cee
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
406 additions
and
5 deletions
+406
-5
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/controller/IndexController.java
...ava/top/ninwoo/edgecenter/controller/IndexController.java
+26
-0
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/entity/ClusterConfig.java
...main/java/top/ninwoo/edgecenter/entity/ClusterConfig.java
+1
-0
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/entity/NetworkTopology.java
...in/java/top/ninwoo/edgecenter/entity/NetworkTopology.java
+24
-0
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/service/IpService.java
...rc/main/java/top/ninwoo/edgecenter/service/IpService.java
+17
-0
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/service/TopologyService.java
...n/java/top/ninwoo/edgecenter/service/TopologyService.java
+18
-0
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/service/impl/IpServiceImpl.java
...ava/top/ninwoo/edgecenter/service/impl/IpServiceImpl.java
+34
-0
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/service/impl/TopologyServiceImpl.java
...p/ninwoo/edgecenter/service/impl/TopologyServiceImpl.java
+150
-0
bishe-utils/src/main/java/top/ninwoo/utils/service/OVSService.java
...ls/src/main/java/top/ninwoo/utils/service/OVSService.java
+4
-0
bishe-utils/src/main/java/top/ninwoo/utils/service/impl/OVSServiceImpl.java
...in/java/top/ninwoo/utils/service/impl/OVSServiceImpl.java
+45
-1
bishe-utils/src/main/java/top/ninwoo/utils/util/OvsUtils.java
...e-utils/src/main/java/top/ninwoo/utils/util/OvsUtils.java
+9
-1
bishe-utils/src/main/java/top/ninwoo/utils/util/impl/IptablesUtilsImpl.java
...in/java/top/ninwoo/utils/util/impl/IptablesUtilsImpl.java
+1
-1
bishe-utils/src/main/java/top/ninwoo/utils/util/impl/OvsUtilsImpl.java
...rc/main/java/top/ninwoo/utils/util/impl/OvsUtilsImpl.java
+77
-2
No files found.
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/controller/IndexController.java
View file @
1f84edba
...
...
@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.web.bind.annotation.*
;
import
top.ninwoo.edgecenter.entity.ClusterConfig
;
import
top.ninwoo.edgecenter.entity.ContainerInfo
;
import
top.ninwoo.edgecenter.entity.NetworkTopology
;
import
top.ninwoo.edgecenter.service.ClusterService
;
import
top.ninwoo.utils.entity.DockerContainer
;
import
top.ninwoo.utils.entity.NetworkInfo
;
...
...
@@ -152,4 +153,29 @@ public class IndexController {
edgeInfo
.
put
(
"mem"
,
clusterService
.
mem
());
return
edgeInfo
;
}
@RequestMapping
(
value
=
"/createTopo"
,
method
=
RequestMethod
.
POST
)
public
NetworkTopology
createTopo
(
long
topologyId
,
String
[]
appNames
,
String
topology
)
{
// 二维数组作为一个字符串传递进来,需要进行一个解析
NetworkTopology
topo
=
new
NetworkTopology
();
topo
.
setAppNames
(
appNames
);
topo
.
setTopologyId
(
111
);
topo
.
setTopology
(
parseString
(
topology
));
return
topo
;
}
private
int
[][]
parseString
(
String
topology
)
{
String
[]
lines
=
topology
.
split
(
";"
);
int
x
=
lines
.
length
;
int
y
=
lines
[
0
].
split
(
","
).
length
;
int
[][]
topo
=
new
int
[
x
][
y
];
for
(
int
i
=
0
;
i
<
x
;
i
++)
{
String
[]
integers
=
lines
[
i
].
split
(
","
);
for
(
int
j
=
0
;
j
<
y
;
j
++)
{
topo
[
i
][
j
]
=
Integer
.
parseInt
(
integers
[
j
]);
}
}
return
topo
;
}
}
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/entity/ClusterConfig.java
View file @
1f84edba
...
...
@@ -18,4 +18,5 @@ public class ClusterConfig {
private
Date
createTime
;
private
String
owner
;
private
List
<
ContainerDescription
>
dockers
;
private
NetworkTopology
topology
;
}
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/entity/NetworkTopology.java
0 → 100644
View file @
1f84edba
package
top.ninwoo.edgecenter.entity
;
import
lombok.Data
;
/**
* @Author joliu
* @Description 描述网络拓扑, 这个数据结构最终要存储到数据库中
* @Date Create in 下午9:30 2019/11/6
*/
@Data
public
class
NetworkTopology
{
private
long
topologyId
;
private
String
[]
appNames
;
private
int
[][]
topology
;
/* public NetworkTopology(long topologyId, String[] appNames) {
this.topologyId = topologyId;
this.appNames = appNames;
if(appNames == null || appNames.length < 1) {
throw new RuntimeException("容器的数组不能为空");
}
topology = new int[appNames.length][appNames.length];
}*/
}
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/service/IpService.java
0 → 100644
View file @
1f84edba
package
top.ninwoo.edgecenter.service
;
/**
* @Author joliu
* @Description 用于分配ip的服务接口
* @Date Create in 下午4:36 2019/11/7
*/
public
interface
IpService
{
/**
* 分配IP
* @param networkSegment IP的网段
* @param containerId 容器ID
* @return Ipv4的地址
*/
String
assignIpString
(
String
networkSegment
,
String
containerId
);
}
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/service/TopologyService.java
0 → 100644
View file @
1f84edba
package
top.ninwoo.edgecenter.service
;
import
top.ninwoo.edgecenter.entity.ClusterConfig
;
/**
* @Author joliu
* @Description Topo服务
* @Date Create in 上午10:55 2019/11/7
*/
public
interface
TopologyService
{
/**
* 初始化网络拓扑
* 将集群中的网络拓扑构建
* @param clusterConfig
*/
void
initTopo
(
ClusterConfig
clusterConfig
);
}
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/service/impl/IpServiceImpl.java
0 → 100644
View file @
1f84edba
package
top.ninwoo.edgecenter.service.impl
;
import
org.springframework.stereotype.Service
;
import
top.ninwoo.edgecenter.service.IpService
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.atomic.AtomicInteger
;
/**
* @Author joliu
* @Description
* @Date Create in 下午8:20 2019/11/7
*/
@Service
public
class
IpServiceImpl
implements
IpService
{
ConcurrentHashMap
<
String
,
AtomicInteger
>
countMap
=
new
ConcurrentHashMap
<>();
ConcurrentHashMap
<
String
,
String
>
ipMap
=
new
ConcurrentHashMap
<>();
// TODO: 这个应该结合数据库,由云端提供服务,暂时提供一个测试版本
@Override
public
String
assignIpString
(
String
networkSegment
,
String
containerId
)
{
// networkSegment 10.100.1.0/24
// 在分配IP前还需要校验下这个网段是否是空闲的网段
AtomicInteger
atomicInteger
;
if
(!
countMap
.
containsKey
(
networkSegment
))
{
countMap
.
put
(
networkSegment
,
new
AtomicInteger
(
2
));
}
atomicInteger
=
countMap
.
get
(
networkSegment
);
String
ip
=
networkSegment
.
substring
(
0
,
networkSegment
.
length
()
-
4
)
+
atomicInteger
.
getAndIncrement
()
+
networkSegment
.
substring
(
networkSegment
.
length
()-
3
);
ipMap
.
put
(
containerId
,
ip
);
return
ip
;
}
}
bishe-edge-center/src/main/java/top/ninwoo/edgecenter/service/impl/TopologyServiceImpl.java
0 → 100644
View file @
1f84edba
package
top.ninwoo.edgecenter.service.impl
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
top.ninwoo.edgecenter.entity.ClusterConfig
;
import
top.ninwoo.edgecenter.entity.NetworkTopology
;
import
top.ninwoo.edgecenter.service.ClusterService
;
import
top.ninwoo.edgecenter.service.IpService
;
import
top.ninwoo.edgecenter.service.TopologyService
;
import
top.ninwoo.utils.service.OVSService
;
import
top.ninwoo.utils.service.OvsDockerService
;
import
java.util.Set
;
/**
* @Author joliu
* @Description 这里描述的物理连接的拓扑关系
* @Date Create in 上午11:16 2019/11/7
*/
public
class
TopologyServiceImpl
implements
TopologyService
{
private
final
static
Logger
LOG
=
LoggerFactory
.
getLogger
(
TopologyServiceImpl
.
class
);
@Autowired
OVSService
ovsService
;
@Autowired
OvsDockerService
ovsDockerService
;
// 这个服务接口的具体功能应该下沉
@Autowired
ClusterService
clusterService
;
@Autowired
IpService
ipService
;
@Override
public
void
initTopo
(
ClusterConfig
clusterConfig
)
{
// 获取topology
NetworkTopology
topology
=
clusterConfig
.
getTopology
();
if
(
topology
==
null
)
{
LOG
.
warn
(
"集群["
+
clusterConfig
.
getId
()
+
"]未设置网络"
);
return
;
}
// 校验信息
String
[]
cNames
=
topology
.
getAppNames
();
int
[][]
topo
=
topology
.
getTopology
();
if
(
cNames
==
null
||
cNames
.
length
<=
1
)
{
return
;
}
// 这里声明:cNames中以br:开头的名称为ovs虚拟交换机
for
(
int
i
=
1
;
i
<
cNames
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
i
;
j
++)
{
// 判断每一个节点的连接状态
if
(
topo
[
i
][
j
]
==
1
)
{
// 如果存在连接,则创建连接
addLink
(
clusterConfig
.
getId
(),
cNames
[
i
],
cNames
[
j
]);
}
}
}
}
public
void
addLink
(
long
clusterId
,
String
appName1
,
String
appName2
)
{
int
flag
=
0
;
// 校验 参数是否合法
// step1: 判断appNames中是否存在ovs虚拟交换机
if
(
appName1
.
startsWith
(
"br:"
))
{
// flag计数器加1
flag
++;
// 创建对应的虚拟交换机
// 在创建前需要检查,是否已经创建过对应的交换机
if
(!
ovsService
.
isBridge
(
appName1
))
{
LOG
.
info
(
"Create Ovs Bridge!"
);
ovsService
.
addBridge
(
appName1
.
substring
(
3
));
}
LOG
.
info
(
"Ovs Bridge["
+
appName1
+
"] is normal!"
);
}
if
(
appName2
.
startsWith
(
"br:"
))
{
flag
++;
// 创建对应的虚拟交换机
if
(!
ovsService
.
isBridge
(
appName2
))
{
LOG
.
info
(
"Create Ovs Bridge!"
);
ovsService
.
addBridge
(
appName2
.
substring
(
3
));
}
LOG
.
info
(
"Ovs Bridge["
+
appName2
+
"] is normal!"
);
}
// 如果两个都是虚拟交换机,则需要创建交换机连接
if
(
flag
==
2
)
{
// 校验是否是远端的交换机
// 远端交换机输入样例:br:remote:testBr:192.168.31.111
String
remoteIp1
=
""
;
if
(
appName1
.
contains
(
"remote"
))
{
remoteIp1
=
appName1
.
split
(
":"
)[
3
];
}
String
remoteIp2
=
""
;
if
(
appName2
.
contains
(
"remote"
))
{
remoteIp2
=
appName2
.
split
(
":"
)[
3
];
}
// 两个都是本地交换机
if
(
""
.
equals
(
remoteIp1
)
&&
""
.
equals
(
remoteIp2
))
{
// 创建两个虚拟交换机
ovsService
.
addBridge
(
appName1
);
ovsService
.
addBridge
(
appName2
);
// 创建两个交换机之间的连接
ovsService
.
linkOvs
(
appName1
,
appName2
);
}
// 如果两个都是远程交换机
else
if
(!
""
.
equals
(
remoteIp1
)
&&
!
""
.
equals
(
remoteIp2
))
{
// do nothing
}
// 如果其中之一是本地交换机,找到本地交换机,设置远端ip
else
{
if
(
""
.
equals
(
remoteIp1
))
{
// appName2是远程的
ovsService
.
setVxlan
(
appName1
,
remoteIp2
);
}
else
if
(
""
.
equals
(
remoteIp2
))
{
// appName1是远程的
ovsService
.
setVxlan
(
appName2
,
remoteIp1
);
}
}
}
// 如果其中一个是虚拟交换机,则创建虚拟交换机到容器的连接
else
if
(
flag
==
1
)
{
String
ovsName
=
appName1
.
startsWith
(
"br:"
)
?
appName1
.
substring
(
3
)
:
appName2
.
substring
(
3
);
String
containerName
=
appName1
.
startsWith
(
"br:"
)
?
appName2
:
appName2
;
// 使用ovsDocker接口创建连接
// 获取全部的APP容器id
Set
<
String
>
cids
=
clusterService
.
getContainerIdsByClusterId
(
clusterId
,
containerName
);
cids
.
forEach
(
cid
->
{
// ip分配服务
// TODO: 网段应该是和网络拓扑绑定到一起,需要重新进行设计
String
ip
=
ipService
.
assignIpString
(
"10.10.1.0/24"
,
cid
);
// ovsDockerService.addPort(ovsName, "eth1", containerName, "ip");
ovsDockerService
.
addPort
(
ovsName
,
"eth1"
,
cid
,
ip
);
});
}
// TODO: 如果两个都是容器,这里可以配置逻辑连接
else
{
throw
new
RuntimeException
(
"Physical topology does not support c2c link."
);
}
}
}
bishe-utils/src/main/java/top/ninwoo/utils/service/OVSService.java
View file @
1f84edba
...
...
@@ -12,4 +12,8 @@ public interface OVSService {
boolean
delBridge
(
String
bridgeName
);
void
addBridge
(
String
bridgeName
);
boolean
linkOvs
(
String
br1
,
String
br2
);
boolean
setVxlan
(
String
bridgeName
,
String
remoteIp
);
}
bishe-utils/src/main/java/top/ninwoo/utils/service/impl/OVSServiceImpl.java
View file @
1f84edba
package
top.ninwoo.utils.service.impl
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.scheduling.annotation.Scheduled
;
...
...
@@ -25,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
*/
@Service
public
class
OVSServiceImpl
implements
OVSService
,
InitializingBean
{
private
final
static
Logger
LOG
=
LoggerFactory
.
getLogger
(
OVSServiceImpl
.
class
);
@Autowired
private
OvsUtils
ovsUtils
;
...
...
@@ -115,7 +118,7 @@ public class OVSServiceImpl implements OVSService, InitializingBean {
ovsUtils
.
addBridge
(
bridgeName
);
}
public
void
addPortToBridge
(
String
bridgeName
,
int
port
)
{
public
void
addPortToBridge
(
String
bridgeName
,
String
port
)
{
if
(!
isInstall
)
{
throw
new
RuntimeException
(
"Ovs未安装!"
);
}
...
...
@@ -143,4 +146,45 @@ public class OVSServiceImpl implements OVSService, InitializingBean {
ovsUtils
.
addBridge
(
bridgeName
);
}
/**
* 连接两个虚拟交换机
* @param br1
* @param br2
* @return
*/
@Override
public
boolean
linkOvs
(
String
br1
,
String
br2
)
{
// 判断两个Ovs网桥是否存在
if
(!
ovsBridges
.
containsKey
(
br1
)
||
!
ovsBridges
.
containsKey
(
br2
))
{
LOG
.
error
(
"ovs bridge["
+
br1
,
", "
+
br2
+
"]不存在"
);
return
false
;
}
// 先创建虚拟网卡对
String
[]
vethPair
=
ovsUtils
.
createVethPair
(
br1
,
br2
);
// 将虚拟网卡对的两端分别接入到ovs上
boolean
b
=
ovsUtils
.
addBridgePort
(
br1
,
vethPair
[
0
]);
boolean
b1
=
ovsUtils
.
addBridgePort
(
br2
,
vethPair
[
1
]);
// 启动端口
boolean
b2
=
ovsUtils
.
enableLinuxPort
(
vethPair
);
return
b
&&
b1
&&
b2
;
}
/**
* 设置VxLan
* @param bridgeName
* @param remoteIp
* @return
*/
@Override
public
boolean
setVxlan
(
String
bridgeName
,
String
remoteIp
)
{
// TODO: 最好再校验一下RemoteIp是否合法
if
(!
isBridge
(
bridgeName
))
{
LOG
.
warn
(
"bridge["
+
bridgeName
+
"] 不存在"
);
return
false
;
}
return
ovsUtils
.
setVxlan
(
bridgeName
,
remoteIp
);
}
}
bishe-utils/src/main/java/top/ninwoo/utils/util/OvsUtils.java
View file @
1f84edba
...
...
@@ -57,7 +57,7 @@ public interface OvsUtils {
* @param bridgeName
* @param port
*/
boolean
addBridgePort
(
String
bridgeName
,
int
port
);
boolean
addBridgePort
(
String
bridgeName
,
String
port
);
/**
* 删除指定的端口
...
...
@@ -65,4 +65,12 @@ public interface OvsUtils {
* @param port
*/
boolean
delBridgePort
(
String
bridgeName
,
int
port
);
String
[]
createVethPair
(
String
br1
,
String
br2
);
boolean
enableLinuxPort
(
String
port
);
boolean
enableLinuxPort
(
String
[]
ports
);
boolean
setVxlan
(
String
bridgeName
,
String
remoteIp
);
}
bishe-utils/src/main/java/top/ninwoo/utils/util/impl/IptablesUtilsImpl.java
View file @
1f84edba
...
...
@@ -231,5 +231,5 @@ public class IptablesUtilsImpl implements IptablesUtils {
//return dockerUtils.execInDocker(containerId, cmd.split(" "));
}
// 差一个转发的实现
//
TODO:
差一个转发的实现
}
bishe-utils/src/main/java/top/ninwoo/utils/util/impl/OvsUtilsImpl.java
View file @
1f84edba
...
...
@@ -168,8 +168,14 @@ public class OvsUtilsImpl implements OvsUtils {
* @return
*/
@Override
public
boolean
addBridgePort
(
String
bridgeName
,
int
port
)
{
// TODO: 待实现
public
boolean
addBridgePort
(
String
bridgeName
,
String
port
)
{
String
cmd
=
"echo 'Vudo3423' | sudo -S ovs-vsctl add-port "
+
bridgeName
+
" "
+
port
;
String
res
=
linuxCtlUtils
.
runCmd
(
cmd
);
if
(!
""
.
equals
(
res
))
{
LOG
.
warn
(
"AddBridgePort:"
+
"["
+
bridgeName
+
","
+
port
+
"]"
+
res
);
return
false
;
}
return
true
;
}
...
...
@@ -183,4 +189,73 @@ public class OvsUtilsImpl implements OvsUtils {
}
return
true
;
}
/**
* 创建一对虚拟网卡,输入的两个网桥名字作为创建网桥的辅助工具
* @param br1
* @param br2
* @return
*/
@Override
public
String
[]
createVethPair
(
String
br1
,
String
br2
)
{
String
veth1
=
br1
+
"_"
+
br2
;
String
veth2
=
br2
+
"_"
+
br1
;
String
cmd
=
"echo 'Vudo3423' | sudo -S ip link add "
+
veth1
+
" type veth peer name "
+
veth2
;
String
res
=
linuxCtlUtils
.
runCmd
(
cmd
);
if
(!
""
.
equals
(
res
))
{
LOG
.
warn
(
"createVethPair:["
+
br1
+
","
+
br2
+
"]:"
+
res
);
}
return
new
String
[]{
veth1
,
veth2
};
}
/**
* 启动虚拟网卡
* @param port
* @return
*/
@Override
public
boolean
enableLinuxPort
(
String
port
)
{
String
cmd
=
"echo 'Vudo3423' | sudo -S ifconfig "
+
port
+
" up"
;
String
res
=
linuxCtlUtils
.
runCmd
(
cmd
);
if
(!
""
.
equals
(
res
))
{
LOG
.
warn
(
"EnbaleLinuxPort:"
+
"["
+
port
+
"]:"
+
port
);
return
false
;
}
return
true
;
}
/**
* 启动网卡
* @param ports
* @return
*/
@Override
public
boolean
enableLinuxPort
(
String
[]
ports
)
{
boolean
result
=
true
;
for
(
String
port
:
ports
)
{
if
(!
enableLinuxPort
(
port
))
{
result
=
false
;
}
}
return
result
;
}
/**
* 设置vxlan
* @param bridgeName
* @param remoteIp
* @return
*/
@Override
public
boolean
setVxlan
(
String
bridgeName
,
String
remoteIp
)
{
String
cmd
=
"echo 'Vudo3423' | sudo -S ovs-vsctl add-port "
+
bridgeName
+
" vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip="
+
remoteIp
;
String
res
=
linuxCtlUtils
.
runCmd
(
cmd
);
if
(!
""
.
equals
(
res
))
{
LOG
.
warn
(
"setVxlan:"
+
"["
+
bridgeName
+
"]:"
+
res
);
return
false
;
}
return
true
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment