def test_average_schedule(test_db):
    # 4个16核, 不限制共享数
    group, pod = _create_data(10, -1, 4)

    assert len(average_schedule(group, pod, ncontainer=100, ncore=2)) == 0
    assert len(average_schedule(group, pod, ncontainer=130, ncore=0, nshare=5)) == 0

    r = average_schedule(group, pod, ncontainer=10, ncore=1)
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 10
    for (host, count), cores in r.iteritems():
        assert count in (2, 3)
        if count == 2:
            assert len(cores['full']) == 2
            assert len(cores['part']) == 0
        if count == 3:
            assert len(cores['full']) == 3
            assert len(cores['part']) == 0

    r = average_schedule(group, pod, ncontainer=9, ncore=2)
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 9
    for (host, count), cores in r.iteritems():
        assert count in (2, 3)
        if count == 2:
            assert len(cores['full']) == 4
            assert len(cores['part']) == 0
        if count == 3:
            assert len(cores['full']) == 6
            assert len(cores['part']) == 0

    r = average_schedule(group, pod, ncontainer=40, ncore=1, nshare=5)
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 40
    for (host, count), cores in r.iteritems():
        assert count == 10 
        assert len(cores['full']) == 10
        assert len(cores['part']) == 10
        assert len(set(cores['part'])) == 5

    r = average_schedule(group, pod, ncontainer=22, ncore=2, nshare=3)
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 22
    for (host, count), cores in r.iteritems():
        assert count in (5, 6)
        if count == 5:
            assert len(cores['full']) == 10
            assert len(cores['part']) == 5
            assert len(set(cores['part'])) == 2
        if count == 6:
            assert len(cores['full']) == 12
            assert len(cores['part']) == 6
            assert len(set(cores['part'])) == 2
Exemple #2
0
def test_average_schedule(test_db):
    # 4个16核, 不限制共享数
    pod = _create_data(10, -1, 4)

    assert len(average_schedule(pod, ncontainer=100, ncore=2)) == 0
    assert len(average_schedule(pod, ncontainer=130, ncore=0, nshare=5)) == 0

    r = average_schedule(pod, ncontainer=10, ncore=1)
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 10
    for (host, count), cores in r.iteritems():
        assert count in (2, 3)
        if count == 2:
            assert len(cores['full']) == 2
            assert len(cores['part']) == 0
        if count == 3:
            assert len(cores['full']) == 3
            assert len(cores['part']) == 0

    r = average_schedule(pod, ncontainer=9, ncore=2)
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 9
    for (host, count), cores in r.iteritems():
        assert count in (2, 3)
        if count == 2:
            assert len(cores['full']) == 4
            assert len(cores['part']) == 0
        if count == 3:
            assert len(cores['full']) == 6
            assert len(cores['part']) == 0

    r = average_schedule(pod, ncontainer=40, ncore=1, nshare=5)
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 40
    for (host, count), cores in r.iteritems():
        assert count == 10
        assert len(cores['full']) == 10
        assert len(cores['part']) == 10
        assert len(set(cores['part'])) == 5

    r = average_schedule(pod, ncontainer=22, ncore=2, nshare=3)
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 22
    for (host, count), cores in r.iteritems():
        assert count in (5, 6)
        if count == 5:
            assert len(cores['full']) == 10
            assert len(cores['part']) == 5
            assert len(set(cores['part'])) == 2
        if count == 6:
            assert len(cores['full']) == 12
            assert len(cores['part']) == 6
            assert len(set(cores['part'])) == 2
Exemple #3
0
def migrate_container(container_id, need_to_remove=True):
    container = Container.get_by_container_id(container_id)
    if not container:
        _log.error('container %s is not found, ignore migration', container_id)
        return

    ncore, nshare = container.host.pod.get_core_allocation(container.ncore)
    host_cores = average_schedule(container.host.pod, 1, ncore, nshare, None)
    if not host_cores:
        _log.error('not enough cores to migrate')
        return

    cids = [container.id]
    spec_ips = cidrs = container.get_ips()
    (host, container_count), cores = next(host_cores.iteritems())

    props = {
        'ncontainer': 1,
        'entrypoint': container.entrypoint,
        'env': container.env,
        'full_cores': [c.label for c in cores.get('full', [])],
        'part_cores': [c.label for c in cores.get('part', [])],
        'ports': None,
        'args': None,
        'nshare': nshare,
        'networks': cidrs,
        'image': None,
        'route': '',
        'callback_url': container.callback_url,
        'container_ids': cids,
    }
    task = Task.create(consts.TASK_MIGRATE, container.version, host, props)
    if not task:
        _log.error('create migrate task error')
        return

    _log.info('start migration...')
    if need_to_remove:
        remove_containers.apply(args=(task.id, cids, False),
                                task_id='task:%s' % task.id)
    create_containers.apply(args=(task.id, 1, nshare, cores, cidrs, spec_ips),
                            task_id='task:%s' % task.id)
    _log.info('migration done')
Exemple #4
0
def migrate_container(container_id, need_to_remove=True):
    container = Container.get_by_container_id(container_id)
    if not container:
        _log.error('container %s is not found, ignore migration', container_id)
        return

    ncore, nshare= container.host.pod.get_core_allocation(container.ncore)
    host_cores = average_schedule(container.host.pod, 1, ncore, nshare, None)
    if not host_cores:
        _log.error('not enough cores to migrate')
        return

    cids = [container.id]
    spec_ips = cidrs = container.get_ips()
    (host, container_count), cores = next(host_cores.iteritems())

    props = {
        'ncontainer': 1,
        'entrypoint': container.entrypoint,
        'env': container.env,
        'full_cores': [c.label for c in cores.get('full', [])],
        'part_cores': [c.label for c in cores.get('part', [])],
        'ports': None,
        'args': None,
        'nshare': nshare,
        'networks': cidrs,
        'image': None,
        'route': '',
        'callback_url': container.callback_url,
        'container_ids': cids,
    }
    task = Task.create(consts.TASK_MIGRATE, container.version, host, props)
    if not task:
        _log.error('create migrate task error')
        return

    _log.info('start migration...')
    if need_to_remove:
        remove_containers.apply(args=(task.id, cids, False), task_id='task:%s' % task.id)
    create_containers.apply(args=(task.id, 1, nshare, cores, cidrs, spec_ips), task_id='task:%s' % task.id)
    _log.info('migration done')
Exemple #5
0
def create_private(group_name, pod_name, appname):
    """ncore: 需要的核心数, 可以是小数, 例如1.5个"""
    data = request.get_json()

    vstr = data['version']

    group, pod, application, version = validate_instance(group_name,
            pod_name, appname, vstr)

    # TODO check if group has this pod

    core_require = int(float(data['ncore']) * pod.core_share) # 是说一个容器要几个核...
    ncore = core_require / pod.core_share
    nshare = core_require % pod.core_share

    ncontainer = int(data['ncontainer'])
    networks = Network.get_multi(data.get('networks', []))
    spec_ips = data.get('spec_ips', [])
    appconfig = version.appconfig

    strategy = data.get('strategy', 'average')

    # 指定的host, 如果没有则按照编排分配host
    hostname = data.get('hostname', '')
    host = hostname and Host.get_by_name(hostname) or None
    if host and not (host.group_id == group.id and host.pod_id == pod.id):
        current_app.logger.error('Host must belong to pod/group (hostname=%s, pod=%s, group=%s)',
                host, pod_name, group_name)
        raise EruAbortException(consts.HTTP_BAD_REQUEST, 'Host must belong to this pod and group')

    if not data['entrypoint'] in appconfig.entrypoints:
        current_app.logger.error('Entrypoint not in app.yaml (entry=%s, name=%s, version=%s)',
                data['entrypoint'], appname, version.short_sha)
        raise EruAbortException(consts.HTTP_BAD_REQUEST, 'Entrypoint %s not in app.yaml' % data['entrypoint'])

    ts, keys = [], []
    with rds.lock('%s:%s' % (group_name, pod_name)):
        if strategy == 'average':
            host_cores = average_schedule(group, pod, ncontainer, ncore, nshare, spec_host=host)
        elif strategy == 'centralized':
            host_cores = centralized_schedule(group, pod, ncontainer, ncore, nshare, spec_host=host)
        else:
            raise EruAbortException(consts.HTTP_BAD_REQUEST, 'strategy %s not supported' % strategy)

        if not host_cores:
            current_app.logger.error('Not enough cores (name=%s, version=%s, ncore=%s)',
                    appname, version.short_sha, data['ncore'])
            raise EruAbortException(consts.HTTP_BAD_REQUEST, 'Not enough core resources')

        for (host, container_count), cores in host_cores.iteritems():
            t = _create_task(
                version,
                host,
                container_count,
                cores,
                nshare,
                networks,
                spec_ips,
                data['entrypoint'],
                data['env'],
                image=data.get('image', ''),
            )
            if not t:
                continue

            host.occupy_cores(cores, nshare)
            ts.append(t.id)
            keys.append(t.result_key)

    return {'r': 0, 'msg': 'ok', 'tasks': ts, 'watch_keys': keys}
Exemple #6
0
def test_scheduler(test_db):
    # 10000个16核, 不限制共享数
    pod = _create_data(10, -1, 10000)

    def test_max_container_count(ncore, nshare, expected):
        start = time.time()
        assert get_max_container_count(pod, ncore, nshare) == expected
        delta = time.time() - start
        _log.debug('test_max_container_count with ncore={}, nshare={}, expected={} takes {}'.format(ncore, nshare, expected, delta))


    test_max_container_count_cases = (
        (1, 0, 160000),
        (2, 0, 80000),
        (3, 0, 50000),
        (4, 0, 40000),
        (5, 0, 30000),
        (1, 5, 100000),
        (2, 5, 60000),
        (3, 5, 40000),
        (1, 1, 140000),
        (2, 1, 70000),
    )

    for case in test_max_container_count_cases:
        test_max_container_count(*case)

    start = time.time()
    assert len(average_schedule(pod, ncontainer=100, ncore=2)) == 100
    print time.time() - start

    start = time.time()
    assert len(average_schedule(pod, ncontainer=130, ncore=0, nshare=5)) == 130
    print time.time() - start

    start = time.time()
    r = average_schedule(pod, ncontainer=10, ncore=1)
    print time.time() - start
    assert len(r) == 10
    assert sum(i[1] for i in r.keys()) == 10
    for (host, count), cores in r.iteritems():
        assert len(cores['full']) == 1
        assert len(cores['part']) == 0

    start = time.time()
    r = average_schedule(pod, ncontainer=10000, ncore=2)
    print time.time() - start
    assert len(r) == 10000
    assert sum(i[1] for i in r.keys()) == 10000
    for (host, count), cores in r.iteritems():
        assert count == 1
        assert len(cores['full']) == 2
        assert len(cores['part']) == 0

    start = time.time()
    r = average_schedule(pod, ncontainer=10000, ncore=1, nshare=5)
    print time.time() - start
    assert len(r) == 10000
    assert sum(i[1] for i in r.keys()) == 10000
    for (host, count), cores in r.iteritems():
        assert count == 1
        assert len(cores['full']) == 1
        assert len(cores['part']) == 1

    start = time.time()
    r = average_schedule(pod, ncontainer=10000, ncore=2, nshare=3)
    print time.time() - start
    assert len(r) == 10000
    assert sum(i[1] for i in r.keys()) == 10000
    for (host, count), cores in r.iteritems():
        assert count == 1
        assert len(cores['full']) == 2
        assert len(cores['part']) == 1

    start = time.time()
    assert len(centralized_schedule(pod, ncontainer=100, ncore=2)) == 13
    print time.time() - start
    start = time.time()
    assert len(centralized_schedule(pod, ncontainer=130, ncore=0, nshare=5)) == 5
    print time.time() - start

    start = time.time()
    r = centralized_schedule(pod, ncontainer=10000, ncore=1)
    print time.time() - start
    assert len(r) == 625
    assert sum(i[1] for i in r.keys()) == 10000
    for (host, count), cores in r.iteritems():
        assert count == 16
        assert len(cores['full']) == 16
        assert len(cores['part']) == 0

    start = time.time()
    r = centralized_schedule(pod, ncontainer=100, ncore=2)
    print time.time() - start
    assert len(r) == 13
    assert sum(i[1] for i in r.keys()) == 100
    for (host, count), cores in r.iteritems():
        assert count in (4, 8)
        if count == 4:
            assert len(cores['full']) == 8
            assert len(cores['part']) == 0
        if count == 8:
            assert len(cores['full']) == 16
            assert len(cores['part']) == 0

    start = time.time()
    r = centralized_schedule(pod, ncontainer=30, ncore=1, nshare=5)
    print time.time() - start
    assert len(r) == 3
    assert sum(i[1] for i in r.keys()) == 30
    for (host, count), cores in r.iteritems():
        assert count == 10
        assert len(cores['full']) == 10
        assert len(cores['part']) == 10
        assert len(set(cores['part'])) == 5

    start = time.time()
    r = centralized_schedule(pod, ncontainer=20, ncore=2, nshare=3)
    print time.time() - start
    assert len(r) == 4
    assert sum(i[1] for i in r.keys()) == 20
    for (host, count), cores in r.iteritems():
        assert count in (2, 6)
        if count == 2:
            assert len(cores['full']) == 4
            assert len(cores['part']) == 2
            assert len(set(cores['part'])) == 1
        if count == 6:
            assert len(cores['full']) == 12
            assert len(cores['part']) == 6
            assert len(set(cores['part'])) == 2