def _start_node_container(ip, ip6, etcd_authority, log_dir, node_image, detach): """ Start the main Calico node container. :param ip: The IPv4 address of the host. :param ip6: The IPv6 address of the host (or None if not configured) :param etcd_authority: The etcd authority string. :param log_dir: The log directory to use. :param node_image: The calico-node image to use. :param detach: True to run in Docker's "detached" mode, False to run attached. :return: None. """ calico_networking = os.getenv(CALICO_NETWORKING_ENV, CALICO_NETWORKING_DEFAULT) try: docker_client.remove_container("calico-node", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = [ "HOSTNAME=%s" % hostname, "IP=%s" % ip, "IP6=%s" % (ip6 or ""), "ETCD_AUTHORITY=%s" % etcd_authority, # etcd host:port "FELIX_ETCDADDR=%s" % etcd_authority, # etcd host:port "CALICO_NETWORKING=%s" % calico_networking ] binds = { log_dir: { "bind": "/var/log/calico", "ro": False } } host_config = docker.utils.create_host_config( privileged=True, restart_policy={"Name": "Always"}, network_mode="host", binds=binds) _find_or_pull_node_image(node_image) container = docker_client.create_container( node_image, name="calico-node", detach=True, environment=environment, host_config=host_config, volumes=["/var/log/calico"]) cid = container["Id"] docker_client.start(container) print "Calico node is running with id: %s" % cid if not detach: _attach_and_stream(container)
def _start_node_container(ip, ip6, etcd_authority, log_dir, node_image, detach): """ Start the main Calico node container. :param ip: The IPv4 address of the host. :param ip6: The IPv6 address of the host (or None if not configured) :param etcd_authority: The etcd authority string. :param log_dir: The log directory to use. :param node_image: The calico-node image to use. :param detach: True to run in Docker's "detached" mode, False to run attached. :return: None. """ calico_networking = os.getenv(CALICO_NETWORKING_ENV, CALICO_NETWORKING_DEFAULT) # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(node_image) try: docker_client.remove_container("calico-node", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = [ "HOSTNAME=%s" % hostname, "IP=%s" % ip, "IP6=%s" % (ip6 or ""), "ETCD_AUTHORITY=%s" % etcd_authority, # etcd host:port "FELIX_ETCDADDR=%s" % etcd_authority, # etcd host:port "CALICO_NETWORKING=%s" % calico_networking ] binds = {log_dir: {"bind": "/var/log/calico", "ro": False}} host_config = docker.utils.create_host_config( privileged=True, restart_policy={"Name": "always"}, network_mode="host", binds=binds) container = docker_client.create_container(node_image, name="calico-node", detach=True, environment=environment, host_config=host_config, volumes=["/var/log/calico"]) cid = container["Id"] docker_client.start(container) print "Calico node is running with id: %s" % cid if not detach: _attach_and_stream(container)
def _start_libnetwork_container(libnetwork_image, etcd_envs, etcd_volumes, etcd_binds, no_pull): """ Start the libnetwork driver container. :param etcd_envs: Etcd environment variables to pass into the container :param libnetwork_image: The name of the Calico libnetwork driver image to use. None, if not using libnetwork. :param etcd_volumes: List of mount_paths for etcd files to mount on the container :param etcd_binds: Dictionary of host file and mount file pairs for etcd files to mount on the container :param no_pull: Boolean, True to prevent function from pulling the Calico node libnetwork Docker image. :return: None """ if not no_pull: # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(libnetwork_image) try: docker_client.remove_container("calico-libnetwork", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = ["HOSTNAME=%s" % hostname] + etcd_envs binds = { "/run/docker/plugins": { "bind": "/run/docker/plugins", "ro": False } } binds.update(etcd_binds) host_config = docker_client.create_host_config( privileged=True, # Needed since the plugin does "ip link" commands. restart_policy={"Name": "always"}, network_mode="host", binds=binds) volumes = ["/run/docker/plugins"] + etcd_volumes container = docker_client.create_container( libnetwork_image, name="calico-libnetwork", detach=True, environment=environment, host_config=host_config, volumes=volumes) cid = container["Id"] docker_client.start(container) print "Calico libnetwork driver is running with id: %s" % cid
def _start_libnetwork_container(libnetwork_image, etcd_envs, etcd_volumes, etcd_binds, no_pull): """ Start the libnetwork driver container. :param etcd_envs: Etcd environment variables to pass into the container :param libnetwork_image: The name of the Calico libnetwork driver image to use. None, if not using libnetwork. :param etcd_volumes: List of mount_paths for etcd files to mount on the container :param etcd_binds: Dictionary of host file and mount file pairs for etcd files to mount on the container :param no_pull: Boolean, True to prevent function from pulling the Calico node libnetwork Docker image. :return: None """ if not no_pull: # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(libnetwork_image) try: docker_client.remove_container("calico-libnetwork", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = ["HOSTNAME=%s" % hostname] + etcd_envs binds = { "/run/docker/plugins": { "bind": "/run/docker/plugins", "ro": False } } binds.update(etcd_binds) host_config = docker_client.create_host_config( privileged=True, # Needed since the plugin does "ip link" commands. restart_policy={"Name": "always"}, network_mode="host", binds=binds) volumes = ["/run/docker/plugins"] + etcd_volumes container = docker_client.create_container(libnetwork_image, name="calico-libnetwork", detach=True, environment=environment, host_config=host_config, volumes=volumes) cid = container["Id"] docker_client.start(container) print "Calico libnetwork driver is running with id: %s" % cid
def _start_node_container(ip, ip6, log_dir, node_image, detach, etcd_envs, felix_envs, etcd_volumes, etcd_binds): """ Start the main Calico node container. :param ip: The IPv4 address of the host. :param ip6: The IPv6 address of the host (or None if not configured) :param log_dir: The log directory to use. :param node_image: The calico-node image to use. :param detach: True to run in Docker's "detached" mode, False to run attached. :param etcd_envs: Etcd environment variables to pass into the container :param felix_envs: Felix environment variables to pass into the container :param etcd_volumes: List of mount_paths for etcd files to mount on the container :param etcd_binds: Dictionary of host file and mount file pairs for etcd files to mount on the container :return: None. """ calico_networking = os.getenv(CALICO_NETWORKING_ENV, CALICO_NETWORKING_DEFAULT) # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(node_image) try: docker_client.remove_container("calico-node", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = ( ["HOSTNAME=%s" % hostname, "IP=%s" % ip, "IP6=%s" % (ip6 or ""), "CALICO_NETWORKING=%s" % calico_networking] + etcd_envs + felix_envs ) binds = {log_dir: {"bind": "/var/log/calico", "ro": False}} binds.update(etcd_binds) host_config = docker.utils.create_host_config( privileged=True, restart_policy={"Name": "always"}, network_mode="host", binds=binds ) volumes = ["/var/log/calico"] + etcd_volumes container = docker_client.create_container( node_image, name="calico-node", detach=True, environment=environment, host_config=host_config, volumes=volumes ) cid = container["Id"] docker_client.start(container) print "Calico node is running with id: %s" % cid if not detach: _attach_and_stream(container)
def _start_libnetwork_container(etcd_authority, libnetwork_image): """ Start the libnetwork driver container. :param etcd_authority: The etcd authority string. :param log_dir: The log directory to use. :param libnetwork_image: The name of the Calico libnetwork driver image to use. None, if not using libnetwork. :return: None """ # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(libnetwork_image) try: docker_client.remove_container("calico-libnetwork", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = [ "HOSTNAME=%s" % hostname, "ETCD_AUTHORITY=%s" % etcd_authority # etcd host:port ] binds = { "/run/docker/plugins": { "bind": "/run/docker/plugins", "ro": False } } host_config = docker.utils.create_host_config( privileged=True, # Needed since the plugin does "ip link" commands. restart_policy={"Name": "Always"}, network_mode="host", binds=binds) container = docker_client.create_container( libnetwork_image, name="calico-libnetwork", detach=True, environment=environment, host_config=host_config, volumes=["/run/docker/plugins"]) cid = container["Id"] docker_client.start(container) print "Calico libnetwork driver is running with id: %s" % cid
def _start_libnetwork_container(etcd_authority, libnetwork_image): """ Start the libnetwork driver container. :param etcd_authority: The etcd authority string. :param log_dir: The log directory to use. :param libnetwork_image: The name of the Calico libnetwork driver image to use. None, if not using libnetwork. :return: None """ # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(libnetwork_image) try: docker_client.remove_container("calico-libnetwork", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = [ "HOSTNAME=%s" % hostname, "ETCD_AUTHORITY=%s" % etcd_authority # etcd host:port ] binds = { "/run/docker/plugins": { "bind": "/run/docker/plugins", "ro": False } } host_config = docker.utils.create_host_config( privileged=True, # Needed since the plugin does "ip link" commands. restart_policy={"Name": "always"}, network_mode="host", binds=binds) container = docker_client.create_container(libnetwork_image, name="calico-libnetwork", detach=True, environment=environment, host_config=host_config, volumes=["/run/docker/plugins"]) cid = container["Id"] docker_client.start(container) print "Calico libnetwork driver is running with id: %s" % cid
def _start_node_container_docker(ip, ip6, as_num, log_dir, node_image, detach, etcd_envs, etcd_volumes, etcd_binds, no_pull): """ Start the main Calico node container. :param ip: The IPv4 address of the host. :param ip6: The IPv6 address of the host (or None if not configured) :param as_num: The AS number for the host :param log_dir: The log directory to use. :param node_image: The calico-node image to use. :param detach: True to run in Docker's "detached" mode, False to run attached. :param etcd_envs: Etcd environment variables to pass into the container :param etcd_volumes: List of mount_paths for etcd files to mount on the container :param etcd_binds: Dictionary of host file and mount file pairs for etcd files to mount on the container :param no_pull: Boolean, True to prevent function from pulling the Calico node Docker image. :return: None. """ calico_networking = os.getenv(CALICO_NETWORKING_ENV, CALICO_NETWORKING_DEFAULT) no_default_pools = os.getenv(NO_DEFAULT_POOLS_ENV) if not no_pull: # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(node_image) try: docker_client.remove_container("calico-node", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = [ "HOSTNAME=%s" % hostname, "IP=%s" % (ip or ""), "IP6=%s" % (ip6 or ""), "CALICO_NETWORKING=%s" % calico_networking, "AS=%s" % (as_num or ""), "NO_DEFAULT_POOLS=%s" % (no_default_pools or "") ] + etcd_envs binds = { log_dir: { "bind": "/var/log/calico", "ro": False }, "/var/run/calico": { "bind": "/var/run/calico", "ro": False }, "/lib/modules": { "bind": "/lib/modules", "ro": False } } binds.update(etcd_binds) host_config = docker_client.create_host_config( privileged=True, restart_policy={"Name": "always"}, network_mode="host", binds=binds) volumes = ["/var/log/calico", "/var/run/calico", "/lib/modules" ] + etcd_volumes container = docker_client.create_container(node_image, name="calico-node", detach=True, environment=environment, host_config=host_config, volumes=volumes) cid = container["Id"] env_string = "" for an_env in environment: env_string += " -e " + an_env vol_string = "" for a_vol in binds: vol_string += " -v %s:%s" % (a_vol, binds[a_vol]["bind"]) detach_string = " -d" if detach else "" print "Running Docker container with the following command:\n" print "docker run%s --restart=always --net=host --privileged --name=calico-node%s%s %s\n" % \ (detach_string, env_string, vol_string, node_image) docker_client.start(container) print "Calico node is running with id: %s" % cid print "Waiting for successful startup" _attach_and_stream(container, detach)
def node_start(node_image, log_dir, ip, ip6, as_num, detach, kubernetes): """ 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. :return: None. """ # Print warnings for any known system issues before continuing check_system(fix=False, quit_if_error=False) # 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=["docker0"]) 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 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) # Install kubernetes plugin if kubernetes: try: # Attempt to install to the default kubernetes directory install_kubernetes(KUBERNETES_PLUGIN_DIR) except OSError: # Use the backup directory install_kubernetes(KUBERNETES_PLUGIN_DIR_BACKUP) # 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) try: docker_client.remove_container("calico-node", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise # Always try to convert the address(hostname) to an IP. This is a noop if # the address is already an IP address. Note that the format of the authority # string has already been validated. etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT) etcd_authority_address, etcd_authority_port = etcd_authority.split(':') etcd_authority = '%s:%s' % (socket.gethostbyname(etcd_authority_address), etcd_authority_port) environment = [ "HOSTNAME=%s" % hostname, "IP=%s" % ip, "IP6=%s" % (ip6 or ""), "ETCD_AUTHORITY=%s" % etcd_authority, # etcd host:port "FELIX_ETCDADDR=%s" % etcd_authority, # etcd host:port "POLICY_ONLY_CALICO=%s" % os.getenv(POLICY_ONLY_ENV, ""), ] binds = { "/proc": { "bind": "/proc_host", "ro": False }, log_dir: { "bind": "/var/log/calico", "ro": False }, "/run/docker/plugins": { "bind": "/usr/share/docker/plugins", "ro": False } } host_config = docker.utils.create_host_config( privileged=True, restart_policy={"Name": "Always"}, network_mode="host", binds=binds) _find_or_pull_node_image(node_image) container = docker_client.create_container( node_image, name="calico-node", detach=True, environment=environment, host_config=host_config, volumes=["/proc_host", "/var/log/calico", "/usr/share/docker/plugins"]) cid = container["Id"] docker_client.start(container) print "Calico node is running with id: %s" % cid if not detach: _attach_and_stream(container)
def _start_node_container_docker(ip, ip6, log_dir, node_image, detach, etcd_envs, felix_envs, etcd_volumes, etcd_binds): """ Start the main Calico node container. :param ip: The IPv4 address of the host. :param ip6: The IPv6 address of the host (or None if not configured) :param log_dir: The log directory to use. :param node_image: The calico-node image to use. :param detach: True to run in Docker's "detached" mode, False to run attached. :param etcd_envs: Etcd environment variables to pass into the container :param felix_envs: Felix environment variables to pass into the container :param etcd_volumes: List of mount_paths for etcd files to mount on the container :param etcd_binds: Dictionary of host file and mount file pairs for etcd files to mount on the container :return: None. """ calico_networking = os.getenv(CALICO_NETWORKING_ENV, CALICO_NETWORKING_DEFAULT) # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(node_image) try: docker_client.remove_container("calico-node", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = [ "HOSTNAME=%s" % hostname, "IP=%s" % ip, "IP6=%s" % (ip6 or ""), "CALICO_NETWORKING=%s" % calico_networking ] + etcd_envs + felix_envs binds = { log_dir: { "bind": "/var/log/calico", "ro": False }, "/var/run/calico": { "bind": "/var/run/calico", "ro": False } } binds.update(etcd_binds) host_config = docker.utils.create_host_config( privileged=True, restart_policy={"Name": "always"}, network_mode="host", binds=binds) volumes = ["/var/log/calico", "/var/run/calico"] + etcd_volumes container = docker_client.create_container(node_image, name="calico-node", detach=True, environment=environment, host_config=host_config, volumes=volumes) cid = container["Id"] docker_client.start(container) print "Calico node is running with id: %s" % cid if not detach: _attach_and_stream(container)
def node_start(node_image, log_dir, ip, ip6, as_num, detach, kubernetes, libnetwork): """ 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 kubernetes: True to install the kubernetes plugin, False otherwise. :param libnetwork: True to use the calico/node-libnetwork image as the node image, False otherwise. :return: None. """ # Print warnings for any known system issues before continuing check_system(fix=False, quit_if_error=False) # 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.*"]) 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 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) # Install kubernetes plugin if kubernetes: try: # Attempt to install to the default kubernetes directory install_kubernetes(KUBERNETES_PLUGIN_DIR) except OSError: # Use the backup directory install_kubernetes(KUBERNETES_PLUGIN_DIR_BACKUP) # 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) try: docker_client.remove_container("calico-node", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise # Always try to convert the address(hostname) to an IP. This is a noop if # the address is already an IP address. Note that the format of the authority # string has already been validated. etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT) etcd_authority_address, etcd_authority_port = etcd_authority.split(':') etcd_authority = '%s:%s' % (socket.gethostbyname(etcd_authority_address), etcd_authority_port) environment = [ "HOSTNAME=%s" % hostname, "IP=%s" % ip, "IP6=%s" % (ip6 or ""), "ETCD_AUTHORITY=%s" % etcd_authority, # etcd host:port "FELIX_ETCDADDR=%s" % etcd_authority, # etcd host:port "POLICY_ONLY_CALICO=%s" % os.getenv(POLICY_ONLY_ENV, ""), ] binds = { "/proc": { "bind": "/proc_host", "ro": False }, log_dir: { "bind": "/var/log/calico", "ro": False }, "/run/docker/plugins": { "bind": "/usr/share/docker/plugins", "ro": False } } host_config = docker.utils.create_host_config( privileged=True, restart_policy={"Name": "Always"}, network_mode="host", binds=binds) if not node_image: # Use the calico/node-libnetwork image if the libnetwork flag was # passed in. Otherwise, use the default calico/node image. node_image = LIBNETWORK_IMAGE if libnetwork else CALICO_DEFAULT_IMAGE _find_or_pull_node_image(node_image) container = docker_client.create_container( node_image, name="calico-node", detach=True, environment=environment, host_config=host_config, volumes=["/proc_host", "/var/log/calico", "/usr/share/docker/plugins"]) cid = container["Id"] docker_client.start(container) print "Calico node is running with id: %s" % cid if not detach: _attach_and_stream(container)
def _start_node_container_docker(ip, ip6, as_num, log_dir, node_image, detach, etcd_envs, etcd_volumes, etcd_binds, no_pull): """ Start the main Calico node container. :param ip: The IPv4 address of the host. :param ip6: The IPv6 address of the host (or None if not configured) :param as_num: The AS number for the host :param log_dir: The log directory to use. :param node_image: The calico-node image to use. :param detach: True to run in Docker's "detached" mode, False to run attached. :param etcd_envs: Etcd environment variables to pass into the container :param etcd_volumes: List of mount_paths for etcd files to mount on the container :param etcd_binds: Dictionary of host file and mount file pairs for etcd files to mount on the container :param no_pull: Boolean, True to prevent function from pulling the Calico node Docker image. :return: None. """ calico_networking = os.getenv(CALICO_NETWORKING_ENV, CALICO_NETWORKING_DEFAULT) no_default_pools = os.getenv(NO_DEFAULT_POOLS_ENV) if not no_pull: # Make sure the required image is pulled before removing the old one. # This minimizes downtime during upgrade. _find_or_pull_node_image(node_image) try: docker_client.remove_container("calico-node", force=True) except docker.errors.APIError as err: if err.response.status_code != 404: raise environment = [ "HOSTNAME=%s" % hostname, "IP=%s" % (ip or ""), "IP6=%s" % (ip6 or ""), "CALICO_NETWORKING=%s" % calico_networking, "AS=%s" % (as_num or ""), "NO_DEFAULT_POOLS=%s" % (no_default_pools or "") ] + etcd_envs binds = { log_dir: { "bind": "/var/log/calico", "ro": False }, "/var/run/calico": { "bind": "/var/run/calico", "ro": False }, "/lib/modules": { "bind": "/lib/modules", "ro": False } } binds.update(etcd_binds) host_config = docker_client.create_host_config( privileged=True, restart_policy={"Name": "always"}, network_mode="host", binds=binds) volumes = ["/var/log/calico", "/var/run/calico", "/lib/modules"] + etcd_volumes container = docker_client.create_container( node_image, name="calico-node", detach=True, environment=environment, host_config=host_config, volumes=volumes) cid = container["Id"] env_string = "" for an_env in environment: env_string += " -e " + an_env vol_string = "" for a_vol in binds: vol_string += " -v %s:%s" % (a_vol, binds[a_vol]["bind"]) detach_string = " -d" if detach else "" print "Running Docker container with the following command:\n" print "docker run%s --restart=always --net=host --privileged --name=calico-node%s%s %s\n" % \ (detach_string, env_string, vol_string, node_image) docker_client.start(container) print "Calico node is running with id: %s" % cid print "Waiting for successful startup" _attach_and_stream(container, detach)