Beispiel #1
0
def node_start(node_image, runtime, log_dir, ip, ip6, as_num, detach,
               libnetwork_image, no_pull):
    """
    Create the calico-node container and establish Calico networking on this
    host.

    :param ip:  The IPv4 address of the host.
    :param node_image:  The calico-node image to use.
    :param ip6:  The IPv6 address of the host (or None if not configured)
    :param as_num:  The BGP AS Number to use for this node.  If not specified
    the global default value will be used.
    :param detach: True to run in Docker's "detached" mode, False to run
    attached.
    :param libnetwork_image: The name of the Calico libnetwork driver image to
    use.  None, if not using libnetwork.
    :param no_pull: Boolean, True to prevent function from pulling the Calico
    node Docker images.
    :return:  None.
    """
    # The command has to be run as root to access iptables and services
    enforce_root()

    # Normally, Felix will load the modules it needs, but when running inside a
    # container it might not be able to do so. Ensure the required modules are
    # loaded each time the node starts.
    # We only make a best effort attempt because the command may fail if the
    # modules are built in.
    # We'll warn during the check_system() if the modules are unavailable.
    if not running_in_container():
        try:
            call(["modprobe", "-a"] + REQUIRED_MODULES)
        except OSError:
            pass

        _setup_ip_forwarding()
        _set_nf_conntrack_max()

        # Print warnings for any known system issues before continuing
        if runtime == 'docker' and not running_in_container():
            using_docker = True
        else:
            using_docker = False

        (_, docker_ok, etcd_ok) = \
            check_system(quit_if_error=False, libnetwork=libnetwork_image,
                         check_docker=using_docker,
                         check_modules=not running_in_container())

        if not etcd_ok or (using_docker and not docker_ok):
            sys.exit(1)

    # Ensure log directory exists
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    # The format of the authority and endpoints strings have already been
    # validated.
    etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT)
    etcd_endpoints = os.getenv(ETCD_ENDPOINTS_ENV)

    # Get etcd SSL environment variables if they exist
    etcd_scheme = os.getenv(ETCD_SCHEME_ENV, ETCD_SCHEME_DEFAULT)
    etcd_key_file = os.getenv(ETCD_KEY_FILE_ENV)
    etcd_cert_file = os.getenv(ETCD_CERT_FILE_ENV)
    etcd_ca_cert_file = os.getenv(ETCD_CA_CERT_FILE_ENV)

    etcd_volumes = []
    etcd_binds = {}
    etcd_envs = [
        "ETCD_AUTHORITY=%s" % etcd_authority,
        "ETCD_SCHEME=%s" % etcd_scheme
    ]

    if etcd_endpoints:
        etcd_envs.append("ETCD_ENDPOINTS=%s" % etcd_endpoints)

    if etcd_ca_cert_file and etcd_key_file and etcd_cert_file:
        etcd_volumes.append(ETCD_CA_CERT_NODE_FILE)
        etcd_binds[etcd_ca_cert_file] = {
            "bind": ETCD_CA_CERT_NODE_FILE,
            "ro": True
        }
        etcd_envs.append("ETCD_CA_CERT_FILE=%s" % ETCD_CA_CERT_NODE_FILE)

        etcd_volumes.append(ETCD_KEY_NODE_FILE)
        etcd_binds[etcd_key_file] = {"bind": ETCD_KEY_NODE_FILE, "ro": True}
        etcd_envs.append("ETCD_KEY_FILE=%s" % ETCD_KEY_NODE_FILE)

        etcd_volumes.append(ETCD_CERT_NODE_FILE)
        etcd_binds[etcd_cert_file] = {"bind": ETCD_CERT_NODE_FILE, "ro": True}
        etcd_envs.append("ETCD_CERT_FILE=%s" % ETCD_CERT_NODE_FILE)

    if runtime == 'docker':
        _start_node_container_docker(ip, ip6, as_num, log_dir, node_image,
                                     detach, etcd_envs, etcd_volumes,
                                     etcd_binds, no_pull)
        if libnetwork_image:
            _start_libnetwork_container(libnetwork_image, etcd_envs,
                                        etcd_volumes, etcd_binds, no_pull)
    if runtime == 'rkt':
        _start_node_container_rkt(ip, ip6, as_num, node_image, etcd_envs,
                                  etcd_volumes, etcd_binds)
Beispiel #2
0
def node_start(node_image, runtime, log_dir, ip, ip6, as_num, detach,
               libnetwork_image):
    """
    Create the calico-node container and establish Calico networking on this
    host.

    :param ip:  The IPv4 address of the host.
    :param node_image:  The calico-node image to use.
    :param ip6:  The IPv6 address of the host (or None if not configured)
    :param as_num:  The BGP AS Number to use for this node.  If not specified
    the global default value will be used.
    :param detach: True to run in Docker's "detached" mode, False to run
    attached.
    :param libnetwork_image: The name of the Calico libnetwork driver image to
    use.  None, if not using libnetwork.
    :return:  None.
    """
    # Normally, Felix will load the modules it needs, but when running inside a
    # container it might not be able to do so. Ensure the required modules are
    # loaded each time the node starts.
    # We only make a best effort attempt because the command may fail if the
    # modules are built in.
    # We'll warn during the check_system() if the modules are unavailable.
    if not running_in_container():
        try:
            call(["modprobe", "-a"] + REQUIRED_MODULES)
        except OSError:
            pass

        # We will always want to setup IP forwarding
        _setup_ip_forwarding()

        # Print warnings for any known system issues before continuing
        if runtime == 'docker' and not running_in_container():
            using_docker = True
        else:
            using_docker = False

        (_, _, etcd_ok) = \
            check_system(quit_if_error=False, libnetwork=libnetwork_image,
                         check_docker=using_docker,
                         check_modules=not running_in_container())

        if not etcd_ok:
            sys.exit(1)

    # Ensure log directory exists
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    # Get IP address of host, if none was specified
    if not ip:
        ips = get_host_ips(exclude=[
            "^docker.*", "^cbr.*", "virbr.*", "lxcbr.*", "veth.*", "cali.*",
            "tunl.*"
        ])
        try:
            ip = ips.pop()
        except IndexError:
            print "Couldn't autodetect a management IP address. Please provide" \
                  " an IP by rerunning the command with the --ip=<IP_ADDRESS> flag."
            sys.exit(1)
        else:
            print "No IP provided. Using detected IP: %s" % ip

    # Verify that IPs are not already in use by another host.
    error_if_bgp_ip_conflict(ip, ip6)

    # Verify that the chosen IP exists on the current host
    warn_if_unknown_ip(ip, ip6)

    # Warn if this hostname conflicts with an existing host
    warn_if_hostname_conflict(ip)

    # Set up etcd
    ipv4_pools = client.get_ip_pools(4)
    ipv6_pools = client.get_ip_pools(6)

    # Create default pools if required
    if not ipv4_pools:
        client.add_ip_pool(4, DEFAULT_IPV4_POOL)
    if not ipv6_pools:
        client.add_ip_pool(6, DEFAULT_IPV6_POOL)

    client.ensure_global_config()
    client.create_host(hostname, ip, ip6, as_num)

    # If IPIP is enabled, the host requires an IP address for its tunnel
    # device, which is in an IPIP pool.  Without this, a host can't originate
    # traffic to a pool address because the response traffic would not be
    # routed via the tunnel (likely being dropped by RPF checks in the fabric).
    ipv4_pools = client.get_ip_pools(4)
    ipip_pools = [p for p in ipv4_pools if p.ipip]
    if ipip_pools:
        # IPIP is enabled, make sure the host has an address for its tunnel.
        _ensure_host_tunnel_addr(ipv4_pools, ipip_pools)
    else:
        # No IPIP pools, clean up any old address.
        _remove_host_tunnel_addr()

    # The format of the authority string has already been validated.
    etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT)

    # Get etcd SSL environment variables if they exist
    etcd_scheme = os.getenv(ETCD_SCHEME_ENV, ETCD_SCHEME_DEFAULT)
    etcd_key_file = os.getenv(ETCD_KEY_FILE_ENV, None)
    etcd_cert_file = os.getenv(ETCD_CERT_FILE_ENV, None)
    etcd_ca_cert_file = os.getenv(ETCD_CA_CERT_FILE_ENV, None)

    etcd_volumes = []
    etcd_binds = {}
    etcd_envs = [
        "ETCD_AUTHORITY=%s" % etcd_authority,
        "ETCD_SCHEME=%s" % etcd_scheme
    ]
    felix_envs = [
        "FELIX_ETCDADDR=%s" % etcd_authority,
        "FELIX_ETCDSCHEME=%s" % etcd_scheme
    ]

    if etcd_ca_cert_file and etcd_key_file and etcd_cert_file:
        etcd_volumes.append(ETCD_CA_CERT_NODE_FILE)
        etcd_binds[etcd_ca_cert_file] = {
            "bind": ETCD_CA_CERT_NODE_FILE,
            "ro": True
        }
        etcd_envs.append("ETCD_CA_CERT_FILE=%s" % ETCD_CA_CERT_NODE_FILE)
        felix_envs.append("FELIX_ETCDCAFILE=%s" % ETCD_CA_CERT_NODE_FILE)

        etcd_volumes.append(ETCD_KEY_NODE_FILE)
        etcd_binds[etcd_key_file] = {"bind": ETCD_KEY_NODE_FILE, "ro": True}
        etcd_envs.append("ETCD_KEY_FILE=%s" % ETCD_KEY_NODE_FILE)
        felix_envs.append("FELIX_ETCDKEYFILE=%s" % ETCD_KEY_NODE_FILE)

        etcd_volumes.append(ETCD_CERT_NODE_FILE)
        etcd_binds[etcd_cert_file] = {"bind": ETCD_CERT_NODE_FILE, "ro": True}
        etcd_envs.append("ETCD_CERT_FILE=%s" % ETCD_CERT_NODE_FILE)
        felix_envs.append("FELIX_ETCDCERTFILE=%s" % ETCD_CERT_NODE_FILE)

    if runtime == 'docker':
        _start_node_container_docker(ip, ip6, log_dir, node_image, detach,
                                     etcd_envs, felix_envs, etcd_volumes,
                                     etcd_binds)
        if libnetwork_image:
            _start_libnetwork_container(libnetwork_image, etcd_envs,
                                        etcd_volumes, etcd_binds)
    if runtime == 'rkt':
        _start_node_container_rkt(ip, ip6, node_image, etcd_envs, felix_envs,
                                  etcd_volumes, etcd_binds)
Beispiel #3
0
def node_start(node_image, runtime, log_dir, ip, ip6, as_num, detach,
               libnetwork_image):
    """
    Create the calico-node container and establish Calico networking on this
    host.

    :param ip:  The IPv4 address of the host.
    :param node_image:  The calico-node image to use.
    :param ip6:  The IPv6 address of the host (or None if not configured)
    :param as_num:  The BGP AS Number to use for this node.  If not specified
    the global default value will be used.
    :param detach: True to run in Docker's "detached" mode, False to run
    attached.
    :param libnetwork_image: The name of the Calico libnetwork driver image to
    use.  None, if not using libnetwork.
    :return:  None.
    """
    # Normally, Felix will load the modules it needs, but when running inside a
    # container it might not be able to do so. Ensure the required modules are
    # loaded each time the node starts.
    # We only make a best effort attempt because the command may fail if the
    # modules are built in.
    # We'll warn during the check_system() if the modules are unavailable.
    if not running_in_container():
        try:
            call(["modprobe", "-a"] + REQUIRED_MODULES)
        except OSError:
            pass

        # We will always want to setup IP forwarding
        _setup_ip_forwarding()

    # Print warnings for any known system issues before continuing
        if runtime == 'docker' and not running_in_container():
            using_docker = True
        else:
            using_docker = False

        (_, _, etcd_ok) = \
            check_system(quit_if_error=False, libnetwork=libnetwork_image,
                         check_docker=using_docker,
                         check_modules=not running_in_container())

        if not etcd_ok:
            sys.exit(1)

    # Ensure log directory exists
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    # Get IP address of host, if none was specified
    if not ip:
        ips = get_host_ips(exclude=["^docker.*", "^cbr.*",
                                    "virbr.*", "lxcbr.*", "veth.*",
                                    "cali.*", "tunl.*"])
        try:
            ip = ips.pop()
        except IndexError:
            print "Couldn't autodetect a management IP address. Please provide" \
                  " an IP by rerunning the command with the --ip=<IP_ADDRESS> flag."
            sys.exit(1)
        else:
            print "No IP provided. Using detected IP: %s" % ip

    # Verify that IPs are not already in use by another host.
    error_if_bgp_ip_conflict(ip, ip6)

    # Verify that the chosen IP exists on the current host
    warn_if_unknown_ip(ip, ip6)

    # Warn if this hostname conflicts with an existing host
    warn_if_hostname_conflict(ip)

    # Set up etcd
    ipv4_pools = client.get_ip_pools(4)
    ipv6_pools = client.get_ip_pools(6)

    # Create default pools if required
    if not ipv4_pools:
        client.add_ip_pool(4, DEFAULT_IPV4_POOL)
    if not ipv6_pools:
        client.add_ip_pool(6, DEFAULT_IPV6_POOL)

    client.ensure_global_config()
    client.create_host(hostname, ip, ip6, as_num)

    # If IPIP is enabled, the host requires an IP address for its tunnel
    # device, which is in an IPIP pool.  Without this, a host can't originate
    # traffic to a pool address because the response traffic would not be
    # routed via the tunnel (likely being dropped by RPF checks in the fabric).
    ipv4_pools = client.get_ip_pools(4)
    ipip_pools = [p for p in ipv4_pools if p.ipip]
    if ipip_pools:
        # IPIP is enabled, make sure the host has an address for its tunnel.
        _ensure_host_tunnel_addr(ipv4_pools, ipip_pools)
    else:
        # No IPIP pools, clean up any old address.
        _remove_host_tunnel_addr()

    # The format of the authority string has already been validated.
    etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT)

    # Get etcd SSL environment variables if they exist
    etcd_scheme = os.getenv(ETCD_SCHEME_ENV, ETCD_SCHEME_DEFAULT)
    etcd_key_file = os.getenv(ETCD_KEY_FILE_ENV, None)
    etcd_cert_file = os.getenv(ETCD_CERT_FILE_ENV, None)
    etcd_ca_cert_file = os.getenv(ETCD_CA_CERT_FILE_ENV, None)

    etcd_volumes = []
    etcd_binds = {}
    etcd_envs = ["ETCD_AUTHORITY=%s" % etcd_authority,
                 "ETCD_SCHEME=%s" % etcd_scheme]
    felix_envs = ["FELIX_ETCDADDR=%s" % etcd_authority,
                  "FELIX_ETCDSCHEME=%s" % etcd_scheme]

    if etcd_ca_cert_file and etcd_key_file and etcd_cert_file:
        etcd_volumes.append(ETCD_CA_CERT_NODE_FILE)
        etcd_binds[etcd_ca_cert_file] = {"bind": ETCD_CA_CERT_NODE_FILE,
                                         "ro": True}
        etcd_envs.append("ETCD_CA_CERT_FILE=%s" % ETCD_CA_CERT_NODE_FILE)
        felix_envs.append("FELIX_ETCDCAFILE=%s" % ETCD_CA_CERT_NODE_FILE)

        etcd_volumes.append(ETCD_KEY_NODE_FILE)
        etcd_binds[etcd_key_file] = {"bind": ETCD_KEY_NODE_FILE,
                                     "ro": True}
        etcd_envs.append("ETCD_KEY_FILE=%s" % ETCD_KEY_NODE_FILE)
        felix_envs.append("FELIX_ETCDKEYFILE=%s" % ETCD_KEY_NODE_FILE)

        etcd_volumes.append(ETCD_CERT_NODE_FILE)
        etcd_binds[etcd_cert_file] = {"bind": ETCD_CERT_NODE_FILE,
                                      "ro": True}
        etcd_envs.append("ETCD_CERT_FILE=%s" % ETCD_CERT_NODE_FILE)
        felix_envs.append("FELIX_ETCDCERTFILE=%s" % ETCD_CERT_NODE_FILE)

    if runtime == 'docker':
        _start_node_container_docker(ip, ip6, log_dir, node_image, detach, etcd_envs,
                                     felix_envs, etcd_volumes, etcd_binds)
        if libnetwork_image:
            _start_libnetwork_container(libnetwork_image, etcd_envs,
                                        etcd_volumes, etcd_binds)
    if runtime == 'rkt':
        _start_node_container_rkt(ip, ip6, node_image, etcd_envs, felix_envs,
                                  etcd_volumes, etcd_binds)
Beispiel #4
0
def node_start(node_image, runtime, log_dir, ip, ip6, as_num, detach,
               libnetwork_image, no_pull):
    """
    Create the calico-node container and establish Calico networking on this
    host.

    :param ip:  The IPv4 address of the host.
    :param node_image:  The calico-node image to use.
    :param ip6:  The IPv6 address of the host (or None if not configured)
    :param as_num:  The BGP AS Number to use for this node.  If not specified
    the global default value will be used.
    :param detach: True to run in Docker's "detached" mode, False to run
    attached.
    :param libnetwork_image: The name of the Calico libnetwork driver image to
    use.  None, if not using libnetwork.
    :param no_pull: Boolean, True to prevent function from pulling the Calico
    node Docker images.
    :return:  None.
    """
    # The command has to be run as root to access iptables and services
    enforce_root()

    # Normally, Felix will load the modules it needs, but when running inside a
    # container it might not be able to do so. Ensure the required modules are
    # loaded each time the node starts.
    # We only make a best effort attempt because the command may fail if the
    # modules are built in.
    # We'll warn during the check_system() if the modules are unavailable.
    if not running_in_container():
        try:
            call(["modprobe", "-a"] + REQUIRED_MODULES)
        except OSError:
            pass

        _setup_ip_forwarding()
        _set_nf_conntrack_max()

        # Print warnings for any known system issues before continuing
        if runtime == 'docker' and not running_in_container():
            using_docker = True
        else:
            using_docker = False

        (_, docker_ok, etcd_ok) = \
            check_system(quit_if_error=False, libnetwork=libnetwork_image,
                         check_docker=using_docker,
                         check_modules=not running_in_container())

        if not etcd_ok or (using_docker and not docker_ok):
            sys.exit(1)

    # Ensure log directory exists
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    # The format of the authority and endpoints strings have already been
    # validated.
    etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT)
    etcd_endpoints = os.getenv(ETCD_ENDPOINTS_ENV)

    # Get etcd SSL environment variables if they exist
    etcd_scheme = os.getenv(ETCD_SCHEME_ENV, ETCD_SCHEME_DEFAULT)
    etcd_key_file = os.getenv(ETCD_KEY_FILE_ENV)
    etcd_cert_file = os.getenv(ETCD_CERT_FILE_ENV)
    etcd_ca_cert_file = os.getenv(ETCD_CA_CERT_FILE_ENV)

    etcd_volumes = []
    etcd_binds = {}
    etcd_envs = ["ETCD_AUTHORITY=%s" % etcd_authority,
                 "ETCD_SCHEME=%s" % etcd_scheme]

    if etcd_endpoints:
        etcd_envs.append("ETCD_ENDPOINTS=%s" % etcd_endpoints)

    if etcd_ca_cert_file and etcd_key_file and etcd_cert_file:
        etcd_volumes.append(ETCD_CA_CERT_NODE_FILE)
        etcd_binds[etcd_ca_cert_file] = {"bind": ETCD_CA_CERT_NODE_FILE,
                                         "ro": True}
        etcd_envs.append("ETCD_CA_CERT_FILE=%s" % ETCD_CA_CERT_NODE_FILE)

        etcd_volumes.append(ETCD_KEY_NODE_FILE)
        etcd_binds[etcd_key_file] = {"bind": ETCD_KEY_NODE_FILE,
                                     "ro": True}
        etcd_envs.append("ETCD_KEY_FILE=%s" % ETCD_KEY_NODE_FILE)

        etcd_volumes.append(ETCD_CERT_NODE_FILE)
        etcd_binds[etcd_cert_file] = {"bind": ETCD_CERT_NODE_FILE,
                                      "ro": True}
        etcd_envs.append("ETCD_CERT_FILE=%s" % ETCD_CERT_NODE_FILE)

    if runtime == 'docker':
        _start_node_container_docker(ip, ip6, as_num, log_dir, node_image, detach,
                                     etcd_envs, etcd_volumes, etcd_binds, no_pull)
        if libnetwork_image:
            _start_libnetwork_container(libnetwork_image, etcd_envs,
                                        etcd_volumes, etcd_binds, no_pull)
    if runtime == 'rkt':
        _start_node_container_rkt(ip, ip6, as_num, node_image, etcd_envs,
                                  etcd_volumes, etcd_binds)