Commit 2a792feb authored by wutu's avatar wutu

实现嵌入Docker的服务接口,并完成基础的测试。

parent ffdfc09b
......@@ -10,6 +10,6 @@ mybatis:
configuration:
map-underscore-to-camel-case: true
mapper-locations: classpath:mapping/*.xml
debug: true
debug: false
server:
port: 8081
\ No newline at end of file
package top.ninwoo.edgecenter;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.service.OVSService;
import top.ninwoo.utils.service.OvsDockerService;
/**
* 测试嵌入式Docker的服务接口
* @Author joliu
* @Description
* @Date Create in 下午8:41 2019/10/28
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class InDockerTests {
@Autowired
DockerService dockerService;
@Autowired
OVSService ovsService;
@Autowired
OvsDockerService ovsDockerService;
DockerContainer dockerContainer1 = null;
DockerContainer dockerContainer2 = null;
private final String bridgeName = "testbr";
/**
* 构建两个docker
*/
@Before
public void init() {
// 创建两个Docker
dockerContainer1 = new DockerContainer();
dockerContainer1.setName("RouterTestIn1");
dockerContainer1.setImage("joliu/networktest");
dockerContainer1.setCommand("sh");
dockerContainer1 = dockerService.runDocker(dockerContainer1);
dockerContainer2 = new DockerContainer();
dockerContainer2.setName("RouterTestIn2");
dockerContainer2.setImage("joliu/networktest");
dockerContainer2.setCommand("sh");
dockerContainer2 = dockerService.runDocker(dockerContainer2);
// 创建一个ovs网桥
if(ovsService.isBridge(bridgeName)) {
ovsService.delBridge(bridgeName);
}
ovsService.addBridge(bridgeName);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 绑定两个Docker的网卡到ovs网桥上
ovsDockerService.addPort(bridgeName, "eth1", dockerContainer1.getId(), "10.1.100.2/24");
ovsDockerService.addPort(bridgeName, "eth1", dockerContainer2.getId(), "10.1.100.3/24");
}
@Test
public void testInDocker() {
String result = "";
// 网络联通测试
result = dockerService.execInDocker(dockerContainer1.getId(), new String[]{"ping", "10.1.100.3", "-c", "2"});
System.out.println(result);
// 使用Iptables进行端口限制
result = dockerService.execInDocker(dockerContainer1.getId(), new String[]{"iptables", "-I", "INPUT", "-s", "10.1.100.3", "-j", "DROP"});
System.out.println(result);
// 测试网络
result = dockerService.execInDocker(dockerContainer1.getId(), new String[]{"ping", "10.1.100.3", "-c", "2"});
System.out.println(result);
}
@After
public void close() {
// 清除Docker
Assert.assertTrue(dockerService.deleteDockerById("RouterTestIn1"));
Assert.assertTrue(dockerService.deleteDockerById("RouterTestIn2"));
Assert.assertTrue(ovsService.delBridge("testbr"));
}
}
......@@ -27,9 +27,12 @@ public class OvsBridge {
if(obj instanceof OvsBridge) {
OvsBridge bridge = (OvsBridge) obj;
if(bridge.bridgeId.equals(this.bridgeId)) {
if(this.ports == null && bridge.ports == null) {
if (this.ports == null && bridge.ports == null) {
return true;
} else if(this.ports.size() == bridge.ports.size()) {
} else if (this.ports == null || bridge.ports == null) {
return false;
}
else if(this.ports.size() == bridge.ports.size()) {
for (int i = 0; i < this.ports.size(); i++) {
if(!this.ports.get(i).equals(bridge.ports.get(i))) {
return false;
......
......@@ -83,4 +83,8 @@ public interface DockerService {
* 初始化当前的容器信息
*/
void init();
boolean hasRunningContainer(String containerId);
String execInDocker(String containerId, String... args);
}
......@@ -6,4 +6,10 @@ import java.util.List;
public interface OVSService {
List<OvsBridge> getOvsBridges();
boolean isBridge(String bridgeName);
boolean delBridge(String bridgeName);
void addBridge(String bridgeName);
}
......@@ -175,4 +175,39 @@ public class DockerServiceImpl implements DockerService, InitializingBean {
public void afterPropertiesSet() throws Exception {
init();
}
/**
* 是否存在该运行的容器
* @param containerId
* @return
*/
@Override
public boolean hasRunningContainer(String containerId) {
return runingContainers.containsKey(containerId);
}
@Override
public String execInDocker(String containerId, String... args) {
// 可以对命令进行一个判断
if(!runingContainers.containsKey(containerId)) {
if (allContainers.containsKey(containerId)) {
// start container!
if(!dockerUtils.startContainer(containerId)) {
throw new RuntimeException("容器启动失败");
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!runingContainers.containsKey(containerId)) {
throw new RuntimeException("容器不存在");
}
} else {
throw new RuntimeException("容器不存在");
}
}
String result = dockerUtils.execInDocker(containerId, args);
return result;
}
}
......@@ -18,6 +18,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* TODO: ovs的功能还需要再总结
* @description 拟采用带状态的实现方案,采用单独线程进行异步更新,无论外部请求多少
* 始终限制在一个用户去查询
* @author joliu
......@@ -103,4 +104,43 @@ public class OVSServiceImpl implements OVSService, InitializingBean {
public List<OvsBridge> getOvsBridges() {
return new ArrayList<>(ovsBridges.values());
}
/**
* 创建网桥
*/
public void createBridge(String bridgeName) {
if(!isInstall) {
throw new RuntimeException("Ovs未安装!");
}
ovsUtils.addBridge(bridgeName);
}
public void addPortToBridge(String bridgeName, int port) {
if(!isInstall) {
throw new RuntimeException("Ovs未安装!");
}
if(ovsBridges.containsKey(bridgeName)) {
throw new RuntimeException("bridge:" + bridgeName + "不存在!");
}
ovsUtils.addBridgePort(bridgeName, port);
}
@Override
public boolean isBridge(String bridgeName) {
return ovsBridges.containsKey(bridgeName);
}
@Override
public boolean delBridge(String bridgeName) {
// TODO: 要优化下返回值
ovsUtils.delBridge(bridgeName);
return true;
}
@Override
public void addBridge(String bridgeName) {
// TODO: 优化下返回值
ovsUtils.addBridge(bridgeName);
}
}
......@@ -2,21 +2,33 @@ package top.ninwoo.utils.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.service.OVSService;
import top.ninwoo.utils.service.OvsDockerService;
import top.ninwoo.utils.util.LinuxCtlUtils;
import top.ninwoo.utils.util.OvsDockerUtils;
@Service
public class OvsDockerServiceImpl implements OvsDockerService {
@Autowired
LinuxCtlUtils linuxCtlUtils;
OvsDockerUtils ovsDockerUtils;
@Autowired
OVSService ovsService;
@Autowired
DockerService dockerService;
@Override
public String addPort(String bridgeName, String devName,String containerId, String ip) {
String cmd = "ovs-docker add-port " + bridgeName + " " + devName + " " + containerId + " --ipaddress=" + ip;
String res = linuxCtlUtils.runCmd(cmd);
if(res.contains("Error")) {
throw new RuntimeException(res);
public String addPort(String bridgeName, String devName, String containerId, String ip) {
// 做一些校验
if(!ovsService.isBridge(bridgeName)) {
throw new RuntimeException("网桥[" + bridgeName + "]不存在!");
}
if(!dockerService.hasRunningContainer(containerId)) {
throw new RuntimeException("容器[" + containerId + "]不存在");
}
return res;
return ovsDockerUtils.addPort(bridgeName, devName, containerId, ip);
}
}
......@@ -36,4 +36,6 @@ public interface DockerUtils {
boolean deleteDockerById(String id);
String execInDocker(String containerId, String... args);
boolean startContainer(String containerId);
}
......@@ -51,4 +51,18 @@ public interface OvsUtils {
* @param name
*/
void delBridge(String name);
/**
* TODO 待实现
* @param bridgeName
* @param port
*/
boolean addBridgePort(String bridgeName, int port);
/**
* 删除指定的端口
* @param bridgeName
* @param port
*/
boolean delBridgePort(String bridgeName, int port);
}
......@@ -95,11 +95,11 @@ public class DockerUtilsImpl implements DockerUtils {
public DockerContainer runDocker(DockerContainer container) {
// TODO: 这里启动Docker容器,需要再研究port如何起作用
// TODO: 这里还需要处理name等属性为空的情况
String cmd = "docker run -itd --name " + container.getName() + " " + container.getImage() + " " + container.getCommand();
String cmd = "docker run -itd --name " + container.getName() + " --privileged " + container.getImage() + " " + container.getCommand();
String result = linuxCtlUtils.runCmd(cmd);
if(result.contains("Error")) {
throw new RuntimeException("Run Docker failed!:" + cmd);
throw new RuntimeException("Run Docker failed!:[" + cmd + "]:" + result);
}
// TODO:需要从Docker中查询处完整的信息
container.setId(result);
......@@ -169,4 +169,22 @@ public class DockerUtilsImpl implements DockerUtils {
}
return result;
}
/**
* 启动容器
* @param containerId
* @return true不一定是启动成功,启动成功还需要通过容器列表来判断
*/
@Override
public boolean startContainer(String containerId) {
try {
dockerClient.startContainer(containerId);
return true;
} catch (DockerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
}
}
......@@ -3,19 +3,21 @@ package top.ninwoo.utils.util.impl;
import org.springframework.beans.factory.annotation.Autowired;
import top.ninwoo.utils.util.LinuxCtlUtils;
import top.ninwoo.utils.util.OvsDockerUtils;
import top.ninwoo.utils.util.Utils;
/**
* @Author joliu
* @Description
* @Date Create in 下午9:29 2019/10/20
*/
@Utils
public class OvsDockerUtilsImpl implements OvsDockerUtils {
@Autowired
LinuxCtlUtils linuxCtlUtils;
@Override
public String addPort(String bridgeName, String devName,String containerId, String ip) {
String cmd = "ovs-docker add-port " + bridgeName + " " + devName + " " + containerId + " --ipaddress=" + ip;
String cmd = "echo 'Vudo3423' | sudo -S ovs-docker add-port " + bridgeName + " " + devName + " " + containerId + " --ipaddress=" + ip;
String res = linuxCtlUtils.runCmd(cmd);
if(res.contains("Error")) {
throw new RuntimeException(res);
......
package top.ninwoo.utils.util.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import top.ninwoo.utils.entity.BridgePort;
import top.ninwoo.utils.entity.Ovs;
......@@ -18,6 +20,8 @@ import java.util.List;
*/
@Utils
public class OvsUtilsImpl implements OvsUtils {
private final Logger LOG = LoggerFactory.getLogger(OvsUtilsImpl.class);
@Autowired
LinuxCtlUtils linuxCtlUtils;
......@@ -156,4 +160,27 @@ public class OvsUtilsImpl implements OvsUtils {
throw new RuntimeException("bridge not found!");
}
}
/**
* 添加一个新的端口
* @param bridgeName
* @param port
* @return
*/
@Override
public boolean addBridgePort(String bridgeName, int port) {
// TODO: 待实现
return true;
}
@Override
public boolean delBridgePort(String bridgeName, int port) {
String cmd = "echo 'Vudo3423' | sudo -S ovs-vsctl del-port " + bridgeName + " " + port;
String res = linuxCtlUtils.runCmd(cmd);
if(!"".equals(res)) {
LOG.warn(bridgeName + ":" + port + "[" + res + "]");
return false;
}
return true;
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment