Esempio n. 1
0
def initiate_swarm():
    client.swarm.init()
    print('Swarm initiated...')

    benchmark = client.services.create(
        'nclcloudcomputing/javabenchmarkapp:latest',
        endpoint_spec=EndpointSpec(mode='vip', ports={4000: 8080}),
        mode=ServiceMode(mode='replicated', replicas=2),
        name='benchmarkapp',
    )
    print('Benchmark service initialized with id ' + benchmark.id)

    visualizer = client.services.create(
        'dockersamples/visualizer',
        endpoint_spec=EndpointSpec(mode='vip', ports={5000: 8080}),
        mounts=['/var/run/docker.sock:/var/run/docker.sock'],
        name='visualizer',
    )
    print('Visualizer service initialized with id ' + visualizer.id)

    mongo = client.services.create(
        'mongo',
        endpoint_spec=EndpointSpec(mode='vip', ports={27017: 27017}),
        mounts=['db:/data/db'],
        name='db',
    )
    print('Mongo service initialized with id ' + mongo.id)
Esempio n. 2
0
def run_service(service_name, image_name, command, restart_condition,
                networks, s_and_t, ports, mode='global', replicas=1):
    docker = MANAGER_CLIENR
    from dsp.image.valify import valify
    #if not valify(image_name):
     #   return "找不到应用指定的镜像!"
    # Mount对象的集合
    mounts = []
    image_name = '192.168.123.251/'+image_name
    for s_t in s_and_t:
        type = False
        if s_t.get('read_only', '') == 'yes':
            type = True
        m = Mount(source=s_t.get('source', ''), target=s_t.get('target', ''), read_only=type)
        mounts.append(m)
        print s_t.get('source', '')
    #containSpec = ContainerSpec( image=image_name, mounts=mounts, command=command, tty=True, open_stdin=True)
    containSpec = ContainerSpec( image=image_name, command=command, tty=True, open_stdin=True)

    # 声明TaskTemplate--->task
    # restart_condition --->none, on - failure, or any
    restart_policy = RestartPolicy(condition=restart_condition)
    task = TaskTemplate(container_spec=containSpec, restart_policy=restart_policy)
    # 应用启动模式
    if mode == "global":
        replicas = None
    service_mode = ServiceMode(mode=mode, replicas=replicas)
    # 接入点,包括负载均衡模式设置等
    end_point = EndpointSpec(ports=ports)

    service_id = docker.create_service(task_template=task, name=service_name,
                                       mode=service_mode, networks=networks, endpoint_spec=end_point)
    return service_id
Esempio n. 3
0
 def scale_service(self, service_name, replica_count):
     try:
         service = self._get_service(service_name)
         service.update(
             mode=ServiceMode("replicated", replicas=replica_count))
     except:
         pass
    def test_scale_service_updates_the_service_replicas_to_given_replication_count(
            self):
        service = Mock()
        self.native_docker_client.services.list.return_value = [service]

        self.docker_client.scale_service("web", 3)

        self.native_docker_client.services.list.assert_called_once_with(
            filters=dict(name="web"))
        service.update.assert_called_once_with(
            mode=ServiceMode("replicated", replicas=3))
Esempio n. 5
0
def createService(image, command, cpuRequirments, name, labels, selectedNodeId):
    client = docker.from_env()
    cpuRequirmentsInNanoSeconds = cpuRequirments * 1000000000

    client.services.create(
        image,
        command,
        constraints=["node.role == worker", "node.id == " + selectedNodeId],
        mode=ServiceMode("replicated", 1),
        restart_policy=RestartPolicy(condition='none'),
        resources=Resources(cpu_reservation=cpuRequirmentsInNanoSeconds),
        name=name,
        labels = {"instance_name": labels.get("instance_name")},
        hostname = selectedNodeId
    )
Esempio n. 6
0
    def scale(self, replicas):
        """
        Scale service container.

        Args:
            replicas (int): The number of containers that should be running.

        Returns:
            bool: ``True`` if successful.
        """

        if 'Global' in self.attrs['Spec']['Mode'].keys():
            raise InvalidArgument('Cannot scale a global container')

        service_mode = ServiceMode('replicated', replicas)
        return self.client.api.update_service(self.id, self.version,
                                              mode=service_mode,
                                              fetch_current_spec=True)
Esempio n. 7
0
    def deploy(self,
               img: ImageSpec,
               env_vars,
               mounts,
               cargos,
               ports,
               cmd: list,
               name: str,
               tasks: int = 1,
               allow_probe=False):

        [self.load_vol(v, name) for v in cargos]
        self.assert_network()
        depl = self.find_depl(name)

        kwargs = self.cleaner(
            dict(name=name,
                 endpoint_spec=dict(Ports=self.swarm_ports(ports)),
                 networks=[DockerConst.NETWORK],
                 mode=ServiceMode('replicated', replicas=tasks),
                 task_template=TaskTemplate(
                     force_update=5,
                     resources=self.swarm_resources(),
                     container_spec=ContainerSpec(
                         command=cmd,
                         image=img.target,
                         env=env_vars,
                         mounts=mounts + [v.mount for v in cargos],
                         healthcheck=self.swarm_healthcheck(allow_probe)))))

        if depl is None:
            self.LOG.debug(
                "Creating container service '{}' with kwargs:".format(name))
            self.LOG.debug(kwargs)
            return self.docker_api.create_service(**kwargs)
        else:
            kwargs.update(service=depl['ID'], version=depl['Version']['Index'])
            self.LOG.debug(
                "Updating container service '{}' with kwargs:".format(name))
            self.LOG.debug(kwargs)
            return self.docker_api.update_service(**kwargs)
Esempio n. 8
0
    def create_jmeter_service(self, script_file, replicas):
        """
        Creates jmeter service and runs it.
        This function first check if pre-requisite containers are running before starting the required number of
        jmeter with args.

        * influxdb is running
        * elasticsearch is running
        * kibana is running
        * logstash is running

        :param script_file: name of the script
        :param replicas: number of replicas
        :return: returns the (Service)
        """
        # TODO influxdb is running
        # TODO elasticsearch is running
        # TODO kibana is running
        # TODO logstash is running

        try:
            jmeter = self.client.services.create(
                image='jmeter:' + JMETER_TAG,
                name='jmeter',
                command='jmeter.sh -n -t ./scripts/' + script_file +
                ' -j ./results/jmeter.log',
                mounts=[
                    SCRIPT_LOCATION + ':/opt/apache-jmeter-3.3/bin/scripts',
                    RESULT_LOCATION + ':/opt/apache-jmeter-3.3/bin/results'
                ],
                networks=['juggernaut'],
                labels={'app': 'juggernaut'},
                workdir='/opt/apache-jmeter-3.3/bin/',
                mode=ServiceMode(mode='replicated', replicas=replicas),
                update_config=UpdateConfig(parallelism=1, delay=60))
        except APIError as e:
            print(e)
        else:
            return jmeter
Esempio n. 9
0
 def test_invalid_mode(self):
     with pytest.raises(InvalidArgument):
         ServiceMode('foobar')
Esempio n. 10
0
 def test_replicated_replicas_0(self):
     mode = ServiceMode('replicated', 0)
     assert mode == {'replicated': {'Replicas': 0}}
     assert mode.mode == 'replicated'
     assert mode.replicas == 0
Esempio n. 11
0
 def test_replicated_replicas(self):
     mode = ServiceMode('replicated', 21)
     assert mode == {'replicated': {'Replicas': 21}}
     assert mode.mode == 'replicated'
     assert mode.replicas == 21
Esempio n. 12
0
 def test_global_replicas_error(self):
     with pytest.raises(InvalidArgument):
         ServiceMode('global', 21)
Esempio n. 13
0
 def test_global_simple(self):
     mode = ServiceMode('global')
     assert mode == {'global': {}}
     assert mode.mode == 'global'
     assert mode.replicas is None
Esempio n. 14
0
 def test_replicated_simple(self):
     mode = ServiceMode('replicated')
     assert mode == {'replicated': {}}
     assert mode.mode == 'replicated'
     assert mode.replicas is None
Esempio n. 15
0
def gen_director_service_params(  # pylint: disable=unused-argument
        client: DockerClient, site_id: int,
        site_data: Dict[str, Any]) -> Dict[str, Any]:
    extra_env = {
        "PORT": "80",
        "HOST": "0.0.0.0",
    }

    params = gen_director_shared_params(client, site_id, site_data)

    env = params.pop("env", [])
    env.extend("{}={}".format(name, val) for name, val in extra_env.items())

    # We do the run.sh path detection in the shell so that it can adapt to the path changing without
    # updating the Docker service
    # The killing of the child process is based off of
    # https://unix.stackexchange.com/a/146770/306760
    shell_command = """date +'DIRECTOR: Starting server at %Y-%m-%d %H:%M:%S %Z'
# See docs/UMASK.md before touching this
umask "$1"
for path in /site/run.sh /site/private/run.sh /site/public/run.sh; do
    if [ -x "$path" ]; then
        term() {
            date +'DIRECTOR: Stopping server at %Y-%m-%d %H:%M:%S %Z'
            kill "$child"
        }
        trap term TERM

        "$path" &
        child="$!"

        while ! wait; do true; done
        exec date +'DIRECTOR: Stopped server at %Y-%m-%d %H:%M:%S %Z'
    fi
done
echo 'DIRECTOR: No run.sh file found -- if it exists, make sure it is set as executable'
exec sleep 2147483647"""

    params.update({
        "name":
        get_director_service_name(site_id),
        "read_only":
        True,
        # See docs/UMASK.md before touching this
        "command":
        ["sh", "-c", shell_command, "sh",
         oct(settings.SITE_UMASK)[2:]],
        "workdir":
        "/site/public",
        "networks": ["director-sites"],
        "resources":
        Resources(
            # 0.1 CPUs, 100M or so of memory
            cpu_limit=convert_cpu_limit(site_data["resource_limits"]["cpus"]),
            mem_limit=convert_memory_limit(
                site_data["resource_limits"]["mem_limit"]),
        ),
        "env":
        env,
        "log_driver":
        "json-file",
        "log_driver_options": {
            # Keep minimal logs
            "max-size": "500k",
            "max-file": "1",
        },
        "hosts":
        params.pop("extra_hosts"),
        "stop_grace_period":
        3,
        "endpoint_spec":
        EndpointSpec(mode="vip", ports={}),
        "mode":
        ServiceMode(mode="replicated",
                    replicas=1 if site_data["is_being_served"] else 0),
        "restart_policy":
        RestartPolicy(condition="any", delay=5, max_attempts=5, window=0),
        "update_config":
        UpdateConfig(
            parallelism=1,
            order="stop-first",
            failure_action="rollback",
            max_failure_ratio=0,
            # delay and monitor are in nanoseconds (1e9 seconds)
            delay=int(5 * (10**9)),
            monitor=int(5 * (10**9)),
        ),
    })

    return params
def start():
    print("/start\n", flush=True)
    # Get a dictionary of services currently running on the swarm
    existing_services = {
        service.name: service.id
        for service in client.services.list()
    }

    # Store reuse flag for this client's workflow
    lot_id = request.json['parking_lot_id']
    lot_map[lot_id] = {}
    lot_map[lot_id]['reuse'] = request.json['reuse']
    # Can store additional client-related data in this dict

    start_time = time.perf_counter()
    # Start requested services (if necessary) and scale them
    for service in request.json['services']:
        service_name = service['name']
        replicas = service['replicas']
        image_name = SERVICE_PARAMS[service_name]['image']
        service_mode = ServiceMode('replicated', replicas)

        if service_name == 'cassandra':
            if SEED_NAME not in existing_services:
                # Create seed node
                print(SEED_NAME + " creating", flush=True)

                service = client.services.create(
                    image_name,
                    name=SEED_NAME,
                    env=['CASSANDRA_BROADCAST_ADDRESS=' + SEED_NAME],
                    networks=['parking-lot-net'])

                print(SEED_NAME + " created", flush=True)

                # Create the rest of the nodes and let them point to the seed node
                for i in range(1, replicas):
                    j = (i % 3) + 1

                    DB_name = 'cassandra-' + str(j)
                    DB_env = 'CASSANDRA_BROADCAST_ADDRESS=' + DB_name

                    print(DB_name + " creating", flush=True)

                    service = client.services.create(
                        image_name,
                        name=DB_name,
                        env=[DB_env, 'CASSANDRA_SEEDS=' + SEED_NAME],
                        networks=['parking-lot-net'])

                    print(DB_name + " created", flush=True)
        else:
            if not request.json[
                    'reuse']:  # Append lot ID if reuse is not desired
                service_name = service_name + str(
                    request.json['parking_lot_id'])

            print(service_name + " " + image_name + " creating", flush=True)
            if service_name in existing_services:
                service = client.services.get(existing_services[service_name])
            else:
                service = client.services.create(image_name,
                                                 name=service_name,
                                                 networks=['parking-lot-net'],
                                                 mode=service_mode)

            print(service_name + " " + image_name + " created", flush=True)
    end_time = time.perf_counter()
    print('Services deployment finished in ' + str(end_time - start_time) +
          ' sec',
          flush=True)

    # Confirm that all services are ready before returning success method to client
    MAX_ATTEMPTS = 30
    attempt = 0

    while attempt < MAX_ATTEMPTS:
        ready = True

        try:
            for service in request.json['services']:
                service_name = service['name']
                if service_name != 'cassandra':
                    port = SERVICE_PARAMS[service_name]['port']

                    if not request.json[
                            'reuse']:  # Append lot id if non-reuse case
                        service_name = service_name + str(
                            request.json['parking_lot_id'])

                    print("attempting to check " + service_name, flush=True)
                    url = 'http://' + service_name + ':' + port + '/is-alive'
                    if not requests.get(url).json()['alive']:
                        ready = False
                        print(service_name + " connection failed", flush=True)
            if ready:
                available_time = time.perf_counter()
                print('Services are available in ' +
                      str(available_time - start_time) + ' sec',
                      flush=True)
                return jsonify(success=True)
        except:
            print(
                'Failed to establish connection to a service. Trying again...')

        attempt += 1
        sleep(SLEEP_TIME)

    return jsonify(success=False, message='Max retries exceeded')