2017-11-06 20:50:41 +00:00
package cluster
import (
2018-01-09 22:10:56 +00:00
"context"
2017-11-21 23:49:30 +00:00
"fmt"
2018-01-16 18:29:09 +00:00
"net"
2019-04-13 14:43:34 +00:00
"strconv"
2018-01-16 18:29:09 +00:00
"strings"
2020-11-09 12:11:43 +00:00
"time"
2017-11-21 23:49:30 +00:00
2020-06-26 07:35:32 +00:00
cidr "github.com/apparentlymart/go-cidr/cidr"
2018-01-16 18:29:09 +00:00
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
"github.com/rancher/rke/docker"
"github.com/rancher/rke/hosts"
2018-01-09 22:10:56 +00:00
"github.com/rancher/rke/log"
2017-11-21 23:49:30 +00:00
"github.com/rancher/rke/pki"
2017-12-16 03:37:45 +00:00
"github.com/rancher/rke/templates"
2020-07-11 16:24:19 +00:00
v3 "github.com/rancher/rke/types"
2018-10-17 22:26:54 +00:00
"github.com/rancher/rke/util"
2018-01-16 18:29:09 +00:00
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
2020-03-26 21:39:24 +00:00
appsv1 "k8s.io/api/apps/v1"
2017-11-06 20:50:41 +00:00
)
const (
2017-11-30 14:49:00 +00:00
NetworkPluginResourceName = "rke-network-plugin"
2017-12-05 01:29:29 +00:00
2018-01-18 20:41:04 +00:00
PortCheckContainer = "rke-port-checker"
EtcdPortListenContainer = "rke-etcd-port-listener"
CPPortListenContainer = "rke-cp-port-listener"
WorkerPortListenContainer = "rke-worker-port-listener"
2018-01-16 18:29:09 +00:00
2019-04-13 14:43:34 +00:00
KubeAPIPort = "6443"
EtcdPort1 = "2379"
EtcdPort2 = "2380"
ScedulerPort = "10251"
ControllerPort = "10252"
KubeletPort = "10250"
KubeProxyPort = "10256"
FlannelVxLanPort = 8472
FlannelVxLanNetworkIdentify = 1
2018-01-16 18:29:09 +00:00
2018-02-13 00:47:56 +00:00
ProtocolTCP = "TCP"
ProtocolUDP = "UDP"
2018-11-28 00:23:15 +00:00
NoNetworkPlugin = "none"
2017-12-05 01:29:29 +00:00
FlannelNetworkPlugin = "flannel"
2017-12-12 16:14:18 +00:00
FlannelIface = "flannel_iface"
2018-05-30 08:30:12 +00:00
FlannelBackendType = "flannel_backend_type"
2019-04-13 14:43:34 +00:00
// FlannelBackendPort must be 4789 if using VxLan mode in the cluster with Windows nodes
FlannelBackendPort = "flannel_backend_port"
// FlannelBackendVxLanNetworkIdentify should be greater than or equal to 4096 if using VxLan mode in the cluster with Windows nodes
2021-02-04 21:05:35 +00:00
FlannelBackendVxLanNetworkIdentify = "flannel_backend_vni"
KubeFlannelPriorityClassNameKeyName = "kube_flannel_priority_class_name"
2017-12-05 01:29:29 +00:00
2021-02-04 21:05:35 +00:00
CalicoNetworkPlugin = "calico"
CalicoNodeLabel = "calico-node"
CalicoControllerLabel = "calico-kube-controllers"
CalicoCloudProvider = "calico_cloud_provider"
CalicoFlexVolPluginDirectory = "calico_flex_volume_plugin_dir"
CalicoNodePriorityClassNameKeyName = "calico_node_priority_class_name"
CalicoKubeControllersPriorityClassNameKeyName = "calico_kube_controllers_priority_class_name"
2017-12-05 01:29:29 +00:00
2018-05-30 08:30:12 +00:00
CanalNetworkPlugin = "canal"
CanalIface = "canal_iface"
CanalFlannelBackendType = "canal_flannel_backend_type"
2019-04-13 14:43:34 +00:00
// CanalFlannelBackendPort must be 4789 if using Flannel VxLan mode in the cluster with Windows nodes
CanalFlannelBackendPort = "canal_flannel_backend_port"
// CanalFlannelBackendVxLanNetworkIdentify should be greater than or equal to 4096 if using Flannel VxLan mode in the cluster with Windows nodes
CanalFlannelBackendVxLanNetworkIdentify = "canal_flannel_backend_vni"
2020-02-21 18:52:18 +00:00
CanalFlexVolPluginDirectory = "canal_flex_volume_plugin_dir"
2021-02-04 21:05:35 +00:00
CanalPriorityClassNameKeyName = "canal_priority_class_name"
2017-12-06 03:53:51 +00:00
2021-02-04 21:05:35 +00:00
WeaveNetworkPlugin = "weave"
WeaveNetworkAppName = "weave-net"
WeaveNetPriorityClassNameKeyName = "weave_net_priority_class_name"
2020-06-26 07:35:32 +00:00
AciNetworkPlugin = "aci"
AciOVSMemoryLimit = "aci_ovs_memory_limit"
AciImagePullPolicy = "aci_image_pull_policy"
AciPBRTrackingNonSnat = "aci_pbr_tracking_non_snat"
AciInstallIstio = "aci_install_istio"
AciIstioProfile = "aci_istio_profile"
AciDropLogEnable = "aci_drop_log_enable"
AciControllerLogLevel = "aci_controller_log_level"
AciHostAgentLogLevel = "aci_host_agent_log_level"
AciOpflexAgentLogLevel = "aci_opflex_agent_log_level"
AciApicRefreshTime = "aci_apic_refresh_time"
AciServiceMonitorInterval = "aci_server_monitor_interval"
AciSystemIdentifier = "aci_system_identifier"
AciToken = "aci_token"
AciApicUserName = "aci_apic_user_name"
AciApicUserKey = "aci_apic_user_key"
AciApicUserCrt = "aci_apic_user_crt"
AciVmmDomain = "aci_vmm_domain"
AciVmmController = "aci_vmm_controller"
AciEncapType = "aci_encap_type"
AciAEP = "aci_aep"
AciVRFName = "aci_vrf_name"
AciVRFTenant = "aci_vrf_tenant"
AciL3Out = "aci_l3out"
AciDynamicExternalSubnet = "aci_dynamic_external_subnet"
AciStaticExternalSubnet = "aci_static_external_subnet"
AciServiceGraphSubnet = "aci_service_graph_subnet"
AciKubeAPIVlan = "aci_kubeapi_vlan"
AciServiceVlan = "aci_service_vlan"
AciInfraVlan = "aci_infra_vlan"
AciImagePullSecret = "aci_image_pull_secret"
AciTenant = "aci_tenant"
AciNodeSubnet = "aci_node_subnet"
AciMcastRangeStart = "aci_mcast_range_start"
AciMcastRangeEnd = "aci_mcast_range_end"
AciUseAciCniPriorityClass = "aci_use_aci_cni_priority_class"
AciNoPriorityClass = "aci_no_priority_class"
AciMaxNodesSvcGraph = "aci_max_nodes_svc_graph"
AciSnatContractScope = "aci_snat_contract_scope"
AciPodSubnetChunkSize = "aci_pod_subnet_chunk_size"
AciEnableEndpointSlice = "aci_enable_endpoint_slice"
AciSnatNamespace = "aci_snat_namespace"
AciEpRegistry = "aci_ep_registry"
AciOpflexMode = "aci_opflex_mode"
AciSnatPortRangeStart = "aci_snat_port_range_start"
AciSnatPortRangeEnd = "aci_snat_port_range_end"
AciSnatPortsPerNode = "aci_snat_ports_per_node"
AciOpflexClientSSL = "aci_opflex_client_ssl"
AciUsePrivilegedContainer = "aci_use_privileged_container"
AciUseHostNetnsVolume = "aci_use_host_netns_volume"
AciUseOpflexServerVolume = "aci_use_opflex_server_volume"
AciKafkaClientCrt = "aci_kafka_client_crt"
AciKafkaClientKey = "aci_kafka_client_key"
AciSubnetDomainName = "aci_subnet_domain_name"
AciCApic = "aci_capic"
AciUseAciAnywhereCRD = "aci_use_aci_anywhere_crd"
AciOverlayVRFName = "aci_overlay_vrf_name"
AciGbpPodSubnet = "aci_gbp_pod_subnet"
AciRunGbpContainer = "aci_run_gbp_container"
AciRunOpflexServerContainer = "aci_run_opflex_server_container"
AciOpflexServerPort = "aci_opflex_server_port"
2017-12-16 03:37:45 +00:00
// List of map keys to be used with network templates
// EtcdEndpoints is the server address for Etcd, used by calico
EtcdEndpoints = "EtcdEndpoints"
// APIRoot is the kubernetes API address
APIRoot = "APIRoot"
// kubernetes client certificates and kubeconfig paths
2018-02-14 20:58:35 +00:00
EtcdClientCert = "EtcdClientCert"
EtcdClientKey = "EtcdClientKey"
EtcdClientCA = "EtcdClientCA"
EtcdClientCertPath = "EtcdClientCertPath"
EtcdClientKeyPath = "EtcdClientKeyPath"
EtcdClientCAPath = "EtcdClientCAPath"
2018-01-16 23:10:14 +00:00
ClientCertPath = "ClientCertPath"
ClientKeyPath = "ClientKeyPath"
ClientCAPath = "ClientCAPath"
KubeCfg = "KubeCfg"
2017-12-16 03:37:45 +00:00
ClusterCIDR = "ClusterCIDR"
// Images key names
2018-05-17 00:27:47 +00:00
Image = "Image"
CNIImage = "CNIImage"
NodeImage = "NodeImage"
ControllersImage = "ControllersImage"
CanalFlannelImg = "CanalFlannelImg"
2019-08-23 16:43:56 +00:00
FlexVolImg = "FlexVolImg"
2018-05-17 00:27:47 +00:00
WeaveLoopbackImage = "WeaveLoopbackImage"
2017-12-16 03:37:45 +00:00
Calicoctl = "Calicoctl"
2021-02-04 21:05:35 +00:00
FlannelInterface = "FlannelInterface"
FlannelBackend = "FlannelBackend"
KubeFlannelPriorityClassName = "KubeFlannelPriorityClassName"
CalicoNodePriorityClassName = "CalicoNodePriorityClassName"
CalicoKubeControllersPriorityClassName = "CalicoKubeControllersPriorityClassName"
CanalInterface = "CanalInterface"
CanalPriorityClassName = "CanalPriorityClassName"
FlexVolPluginDir = "FlexVolPluginDir"
WeavePassword = "WeavePassword"
WeaveNetPriorityClassName = "WeaveNetPriorityClassName"
MTU = "MTU"
RBACConfig = "RBACConfig"
ClusterVersion = "ClusterVersion"
SystemIdentifier = "SystemIdentifier"
ApicHosts = "ApicHosts"
Token = "Token"
ApicUserName = "ApicUserName"
ApicUserKey = "ApicUserKey"
ApicUserCrt = "ApicUserCrt"
ApicRefreshTime = "ApicRefreshTime"
VmmDomain = "VmmDomain"
VmmController = "VmmController"
EncapType = "EncapType"
McastRangeStart = "McastRangeStart"
McastRangeEnd = "McastRangeEnd"
AEP = "AEP"
VRFName = "VRFName"
VRFTenant = "VRFTenant"
L3Out = "L3Out"
L3OutExternalNetworks = "L3OutExternalNetworks"
DynamicExternalSubnet = "DynamicExternalSubnet"
StaticExternalSubnet = "StaticExternalSubnet"
ServiceGraphSubnet = "ServiceGraphSubnet"
KubeAPIVlan = "KubeAPIVlan"
ServiceVlan = "ServiceVlan"
InfraVlan = "InfraVlan"
ImagePullPolicy = "ImagePullPolicy"
ImagePullSecret = "ImagePullSecret"
Tenant = "Tenant"
ServiceMonitorInterval = "ServiceMonitorInterval"
PBRTrackingNonSnat = "PBRTrackingNonSnat"
InstallIstio = "InstallIstio"
IstioProfile = "IstioProfile"
DropLogEnable = "DropLogEnable"
ControllerLogLevel = "ControllerLogLevel"
HostAgentLogLevel = "HostAgentLogLevel"
OpflexAgentLogLevel = "OpflexAgentLogLevel"
AciCniDeployContainer = "AciCniDeployContainer"
AciHostContainer = "AciHostContainer"
AciOpflexContainer = "AciOpflexContainer"
AciMcastContainer = "AciMcastContainer"
AciOpenvSwitchContainer = "AciOpenvSwitchContainer"
AciControllerContainer = "AciControllerContainer"
AciGbpServerContainer = "AciGbpServerContainer"
AciOpflexServerContainer = "AciOpflexServerContainer"
StaticServiceIPStart = "StaticServiceIPStart"
StaticServiceIPEnd = "StaticServiceIPEnd"
PodGateway = "PodGateway"
PodIPStart = "PodIPStart"
PodIPEnd = "PodIPEnd"
NodeServiceIPStart = "NodeServiceIPStart"
NodeServiceIPEnd = "NodeServiceIPEnd"
ServiceIPStart = "ServiceIPStart"
ServiceIPEnd = "ServiceIPEnd"
UseAciCniPriorityClass = "UseAciCniPriorityClass"
NoPriorityClass = "NoPriorityClass"
MaxNodesSvcGraph = "MaxNodesSvcGraph"
SnatContractScope = "SnatContractScope"
PodSubnetChunkSize = "PodSubnetChunkSize"
EnableEndpointSlice = "EnableEndpointSlice"
SnatNamespace = "SnatNamespace"
EpRegistry = "EpRegistry"
OpflexMode = "OpflexMode"
SnatPortRangeStart = "SnatPortRangeStart"
SnatPortRangeEnd = "SnatPortRangeEnd"
SnatPortsPerNode = "SnatPortsPerNode"
OpflexClientSSL = "OpflexClientSSL"
UsePrivilegedContainer = "UsePrivilegedContainer"
UseHostNetnsVolume = "UseHostNetnsVolume"
UseOpflexServerVolume = "UseOpflexServerVolume"
KafkaBrokers = "KafkaBrokers"
KafkaClientCrt = "KafkaClientCrt"
KafkaClientKey = "KafkaClientKey"
SubnetDomainName = "SubnetDomainName"
CApic = "CApic"
UseAciAnywhereCRD = "UseAciAnywhereCRD"
OverlayVRFName = "OverlayVRFName"
GbpPodSubnet = "GbpPodSubnet"
RunGbpContainer = "RunGbpContainer"
RunOpflexServerContainer = "RunOpflexServerContainer"
OpflexServerPort = "OpflexServerPort"
OVSMemoryLimit = "OVSMemoryLimit"
NodeSubnet = "NodeSubnet"
NodeSelector = "NodeSelector"
UpdateStrategy = "UpdateStrategy"
Tolerations = "Tolerations"
2017-11-06 20:50:41 +00:00
)
2018-02-13 00:47:56 +00:00
var EtcdPortList = [ ] string {
EtcdPort1 ,
EtcdPort2 ,
}
var ControlPlanePortList = [ ] string {
KubeAPIPort ,
}
var WorkerPortList = [ ] string {
KubeletPort ,
}
2018-06-07 20:47:37 +00:00
var EtcdClientPortList = [ ] string {
EtcdPort1 ,
}
2019-08-08 17:10:44 +00:00
var CalicoNetworkLabels = [ ] string { CalicoNodeLabel , CalicoControllerLabel }
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) deployNetworkPlugin ( ctx context . Context , data map [ string ] interface { } ) error {
2018-01-09 22:10:56 +00:00
log . Infof ( ctx , "[network] Setting up network plugin: %s" , c . Network . Plugin )
2017-11-21 23:49:30 +00:00
switch c . Network . Plugin {
2017-11-28 17:45:24 +00:00
case FlannelNetworkPlugin :
2019-06-17 20:52:15 +00:00
return c . doFlannelDeploy ( ctx , data )
2017-11-28 17:45:24 +00:00
case CalicoNetworkPlugin :
2019-06-17 20:52:15 +00:00
return c . doCalicoDeploy ( ctx , data )
2017-11-28 17:45:24 +00:00
case CanalNetworkPlugin :
2019-06-17 20:52:15 +00:00
return c . doCanalDeploy ( ctx , data )
2017-11-30 11:35:31 +00:00
case WeaveNetworkPlugin :
2019-06-17 20:52:15 +00:00
return c . doWeaveDeploy ( ctx , data )
2020-06-26 07:35:32 +00:00
case AciNetworkPlugin :
return c . doAciDeploy ( ctx , data )
2018-11-28 00:23:15 +00:00
case NoNetworkPlugin :
log . Infof ( ctx , "[network] Not deploying a cluster network, expecting custom CNI" )
return nil
2017-11-21 23:49:30 +00:00
default :
return fmt . Errorf ( "[network] Unsupported network plugin: %s" , c . Network . Plugin )
}
}
2017-11-08 17:45:51 +00:00
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) doFlannelDeploy ( ctx context . Context , data map [ string ] interface { } ) error {
2019-04-13 14:43:34 +00:00
vni , err := atoiWithDefault ( c . Network . Options [ FlannelBackendVxLanNetworkIdentify ] , FlannelVxLanNetworkIdentify )
if err != nil {
return err
}
port , err := atoiWithDefault ( c . Network . Options [ FlannelBackendPort ] , FlannelVxLanPort )
if err != nil {
return err
}
2018-05-30 08:30:12 +00:00
flannelConfig := map [ string ] interface { } {
2017-12-16 03:37:45 +00:00
ClusterCIDR : c . ClusterCIDR ,
2018-02-05 15:50:39 +00:00
Image : c . SystemImages . Flannel ,
CNIImage : c . SystemImages . FlannelCNI ,
2017-12-16 03:37:45 +00:00
FlannelInterface : c . Network . Options [ FlannelIface ] ,
2018-05-30 08:30:12 +00:00
FlannelBackend : map [ string ] interface { } {
"Type" : c . Network . Options [ FlannelBackendType ] ,
2019-04-13 14:43:34 +00:00
"VNI" : vni ,
"Port" : port ,
2018-05-30 08:30:12 +00:00
} ,
2018-10-05 00:41:18 +00:00
RBACConfig : c . Authorization . Mode ,
2019-02-26 23:14:01 +00:00
ClusterVersion : util . GetTagMajorVersion ( c . Version ) ,
2019-08-29 18:00:26 +00:00
NodeSelector : c . Network . NodeSelector ,
2020-03-26 21:39:24 +00:00
UpdateStrategy : & appsv1 . DaemonSetUpdateStrategy {
Type : c . Network . UpdateStrategy . Strategy ,
RollingUpdate : c . Network . UpdateStrategy . RollingUpdate ,
} ,
2021-02-04 21:05:35 +00:00
KubeFlannelPriorityClassName : c . Network . Options [ KubeFlannelPriorityClassNameKeyName ] ,
2017-12-16 03:37:45 +00:00
}
2019-06-17 20:52:15 +00:00
pluginYaml , err := c . getNetworkPluginManifest ( flannelConfig , data )
2017-12-16 03:37:45 +00:00
if err != nil {
return err
2017-12-12 16:14:18 +00:00
}
2018-05-07 21:51:09 +00:00
return c . doAddonDeploy ( ctx , pluginYaml , NetworkPluginResourceName , true )
2017-11-21 23:49:30 +00:00
}
2017-11-18 12:51:28 +00:00
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) doCalicoDeploy ( ctx context . Context , data map [ string ] interface { } ) error {
2018-01-16 23:10:14 +00:00
clientConfig := pki . GetConfigPath ( pki . KubeNodeCertName )
2019-08-23 16:43:56 +00:00
2018-05-30 08:30:12 +00:00
calicoConfig := map [ string ] interface { } {
2019-07-11 20:59:03 +00:00
KubeCfg : clientConfig ,
ClusterCIDR : c . ClusterCIDR ,
CNIImage : c . SystemImages . CalicoCNI ,
NodeImage : c . SystemImages . CalicoNode ,
Calicoctl : c . SystemImages . CalicoCtl ,
ControllersImage : c . SystemImages . CalicoControllers ,
CloudProvider : c . Network . Options [ CalicoCloudProvider ] ,
2019-08-23 16:43:56 +00:00
FlexVolImg : c . SystemImages . CalicoFlexVol ,
2019-07-11 20:59:03 +00:00
RBACConfig : c . Authorization . Mode ,
2019-08-29 18:00:26 +00:00
NodeSelector : c . Network . NodeSelector ,
2019-12-06 16:59:15 +00:00
MTU : c . Network . MTU ,
2020-03-26 21:39:24 +00:00
UpdateStrategy : & appsv1 . DaemonSetUpdateStrategy {
Type : c . Network . UpdateStrategy . Strategy ,
RollingUpdate : c . Network . UpdateStrategy . RollingUpdate ,
} ,
2021-02-04 21:05:35 +00:00
Tolerations : c . Network . Tolerations ,
FlexVolPluginDir : c . Network . Options [ CalicoFlexVolPluginDirectory ] ,
CalicoNodePriorityClassName : c . Network . Options [ CalicoNodePriorityClassNameKeyName ] ,
CalicoKubeControllersPriorityClassName : c . Network . Options [ CalicoKubeControllersPriorityClassNameKeyName ] ,
2017-12-16 03:37:45 +00:00
}
2019-06-17 20:52:15 +00:00
pluginYaml , err := c . getNetworkPluginManifest ( calicoConfig , data )
2017-12-16 03:37:45 +00:00
if err != nil {
return err
2017-12-05 01:29:29 +00:00
}
2018-05-07 21:51:09 +00:00
return c . doAddonDeploy ( ctx , pluginYaml , NetworkPluginResourceName , true )
2017-11-21 23:49:30 +00:00
}
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) doCanalDeploy ( ctx context . Context , data map [ string ] interface { } ) error {
2019-04-13 14:43:34 +00:00
flannelVni , err := atoiWithDefault ( c . Network . Options [ CanalFlannelBackendVxLanNetworkIdentify ] , FlannelVxLanNetworkIdentify )
if err != nil {
return err
}
flannelPort , err := atoiWithDefault ( c . Network . Options [ CanalFlannelBackendPort ] , FlannelVxLanPort )
if err != nil {
return err
}
2018-01-16 23:10:14 +00:00
clientConfig := pki . GetConfigPath ( pki . KubeNodeCertName )
2018-05-30 08:30:12 +00:00
canalConfig := map [ string ] interface { } {
2020-09-05 00:49:39 +00:00
ClientCertPath : pki . GetCertPath ( pki . KubeNodeCertName ) ,
APIRoot : "https://127.0.0.1:6443" ,
ClientKeyPath : pki . GetKeyPath ( pki . KubeNodeCertName ) ,
ClientCAPath : pki . GetCertPath ( pki . CACertName ) ,
KubeCfg : clientConfig ,
ClusterCIDR : c . ClusterCIDR ,
NodeImage : c . SystemImages . CanalNode ,
CNIImage : c . SystemImages . CanalCNI ,
ControllersImage : c . SystemImages . CanalControllers ,
CanalFlannelImg : c . SystemImages . CanalFlannel ,
RBACConfig : c . Authorization . Mode ,
CanalInterface : c . Network . Options [ CanalIface ] ,
FlexVolImg : c . SystemImages . CanalFlexVol ,
2018-05-30 08:30:12 +00:00
FlannelBackend : map [ string ] interface { } {
"Type" : c . Network . Options [ CanalFlannelBackendType ] ,
2019-04-13 14:43:34 +00:00
"VNI" : flannelVni ,
"Port" : flannelPort ,
2018-05-30 08:30:12 +00:00
} ,
2020-03-26 21:39:24 +00:00
NodeSelector : c . Network . NodeSelector ,
MTU : c . Network . MTU ,
UpdateStrategy : & appsv1 . DaemonSetUpdateStrategy {
Type : c . Network . UpdateStrategy . Strategy ,
RollingUpdate : c . Network . UpdateStrategy . RollingUpdate ,
} ,
2021-02-04 21:05:35 +00:00
Tolerations : c . Network . Tolerations ,
FlexVolPluginDir : c . Network . Options [ CanalFlexVolPluginDirectory ] ,
CanalPriorityClassName : c . Network . Options [ CanalPriorityClassNameKeyName ] ,
CalicoKubeControllersPriorityClassName : c . Network . Options [ CalicoKubeControllersPriorityClassNameKeyName ] ,
2017-12-16 03:37:45 +00:00
}
2019-06-17 20:52:15 +00:00
pluginYaml , err := c . getNetworkPluginManifest ( canalConfig , data )
2017-12-16 03:37:45 +00:00
if err != nil {
return err
2017-12-05 01:29:29 +00:00
}
2018-05-07 21:51:09 +00:00
return c . doAddonDeploy ( ctx , pluginYaml , NetworkPluginResourceName , true )
2017-11-06 20:50:41 +00:00
}
2017-12-05 01:29:29 +00:00
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) doWeaveDeploy ( ctx context . Context , data map [ string ] interface { } ) error {
2018-05-30 08:30:12 +00:00
weaveConfig := map [ string ] interface { } {
2018-05-17 00:27:47 +00:00
ClusterCIDR : c . ClusterCIDR ,
2019-03-05 18:50:19 +00:00
WeavePassword : c . Network . Options [ WeavePassword ] ,
2018-05-17 00:27:47 +00:00
Image : c . SystemImages . WeaveNode ,
CNIImage : c . SystemImages . WeaveCNI ,
WeaveLoopbackImage : c . SystemImages . Alpine ,
RBACConfig : c . Authorization . Mode ,
2019-08-29 18:00:26 +00:00
NodeSelector : c . Network . NodeSelector ,
2019-12-06 16:59:15 +00:00
MTU : c . Network . MTU ,
2020-03-26 21:39:24 +00:00
UpdateStrategy : & appsv1 . DaemonSetUpdateStrategy {
Type : c . Network . UpdateStrategy . Strategy ,
RollingUpdate : c . Network . UpdateStrategy . RollingUpdate ,
} ,
2021-02-04 21:05:35 +00:00
WeaveNetPriorityClassName : c . Network . Options [ WeaveNetPriorityClassNameKeyName ] ,
2017-12-16 03:37:45 +00:00
}
2019-06-17 20:52:15 +00:00
pluginYaml , err := c . getNetworkPluginManifest ( weaveConfig , data )
2017-12-16 03:37:45 +00:00
if err != nil {
return err
2017-12-14 21:56:19 +00:00
}
2018-05-07 21:51:09 +00:00
return c . doAddonDeploy ( ctx , pluginYaml , NetworkPluginResourceName , true )
2017-11-30 11:35:31 +00:00
}
2020-06-26 07:35:32 +00:00
func ( c * Cluster ) doAciDeploy ( ctx context . Context , data map [ string ] interface { } ) error {
_ , clusterCIDR , err := net . ParseCIDR ( c . ClusterCIDR )
if err != nil {
return err
}
podIPStart , podIPEnd := cidr . AddressRange ( clusterCIDR )
_ , staticExternalSubnet , err := net . ParseCIDR ( c . Network . Options [ AciStaticExternalSubnet ] )
staticServiceIPStart , staticServiceIPEnd := cidr . AddressRange ( staticExternalSubnet )
_ , svcGraphSubnet , err := net . ParseCIDR ( c . Network . Options [ AciServiceGraphSubnet ] )
if err != nil {
return err
}
nodeServiceIPStart , nodeServiceIPEnd := cidr . AddressRange ( svcGraphSubnet )
_ , dynamicExternalSubnet , err := net . ParseCIDR ( c . Network . Options [ AciDynamicExternalSubnet ] )
if err != nil {
return err
}
serviceIPStart , serviceIPEnd := cidr . AddressRange ( dynamicExternalSubnet )
if c . Network . Options [ AciTenant ] == "" {
c . Network . Options [ AciTenant ] = c . Network . Options [ AciSystemIdentifier ]
}
AciConfig := map [ string ] interface { } {
SystemIdentifier : c . Network . Options [ AciSystemIdentifier ] ,
ApicHosts : c . Network . AciNetworkProvider . ApicHosts ,
Token : c . Network . Options [ AciToken ] ,
ApicUserName : c . Network . Options [ AciApicUserName ] ,
ApicUserKey : c . Network . Options [ AciApicUserKey ] ,
ApicUserCrt : c . Network . Options [ AciApicUserCrt ] ,
ApicRefreshTime : c . Network . Options [ AciApicRefreshTime ] ,
VmmDomain : c . Network . Options [ AciVmmDomain ] ,
VmmController : c . Network . Options [ AciVmmController ] ,
EncapType : c . Network . Options [ AciEncapType ] ,
McastRangeStart : c . Network . Options [ AciMcastRangeStart ] ,
McastRangeEnd : c . Network . Options [ AciMcastRangeEnd ] ,
NodeSubnet : c . Network . Options [ AciNodeSubnet ] ,
AEP : c . Network . Options [ AciAEP ] ,
VRFName : c . Network . Options [ AciVRFName ] ,
VRFTenant : c . Network . Options [ AciVRFTenant ] ,
L3Out : c . Network . Options [ AciL3Out ] ,
L3OutExternalNetworks : c . Network . AciNetworkProvider . L3OutExternalNetworks ,
DynamicExternalSubnet : c . Network . Options [ AciDynamicExternalSubnet ] ,
StaticExternalSubnet : c . Network . Options [ AciStaticExternalSubnet ] ,
ServiceGraphSubnet : c . Network . Options [ AciServiceGraphSubnet ] ,
KubeAPIVlan : c . Network . Options [ AciKubeAPIVlan ] ,
ServiceVlan : c . Network . Options [ AciServiceVlan ] ,
InfraVlan : c . Network . Options [ AciInfraVlan ] ,
ImagePullPolicy : c . Network . Options [ AciImagePullPolicy ] ,
ImagePullSecret : c . Network . Options [ AciImagePullSecret ] ,
Tenant : c . Network . Options [ AciTenant ] ,
ServiceMonitorInterval : c . Network . Options [ AciServiceMonitorInterval ] ,
PBRTrackingNonSnat : c . Network . Options [ AciPBRTrackingNonSnat ] ,
InstallIstio : c . Network . Options [ AciInstallIstio ] ,
IstioProfile : c . Network . Options [ AciIstioProfile ] ,
DropLogEnable : c . Network . Options [ AciDropLogEnable ] ,
ControllerLogLevel : c . Network . Options [ AciControllerLogLevel ] ,
HostAgentLogLevel : c . Network . Options [ AciHostAgentLogLevel ] ,
OpflexAgentLogLevel : c . Network . Options [ AciOpflexAgentLogLevel ] ,
OVSMemoryLimit : c . Network . Options [ AciOVSMemoryLimit ] ,
ClusterCIDR : c . ClusterCIDR ,
StaticServiceIPStart : cidr . Inc ( cidr . Inc ( staticServiceIPStart ) ) ,
StaticServiceIPEnd : cidr . Dec ( staticServiceIPEnd ) ,
PodGateway : cidr . Inc ( podIPStart ) ,
PodIPStart : cidr . Inc ( cidr . Inc ( podIPStart ) ) ,
PodIPEnd : cidr . Dec ( podIPEnd ) ,
NodeServiceIPStart : cidr . Inc ( cidr . Inc ( nodeServiceIPStart ) ) ,
NodeServiceIPEnd : cidr . Dec ( nodeServiceIPEnd ) ,
ServiceIPStart : cidr . Inc ( cidr . Inc ( serviceIPStart ) ) ,
ServiceIPEnd : cidr . Dec ( serviceIPEnd ) ,
UseAciCniPriorityClass : c . Network . Options [ AciUseAciCniPriorityClass ] ,
NoPriorityClass : c . Network . Options [ AciNoPriorityClass ] ,
MaxNodesSvcGraph : c . Network . Options [ AciMaxNodesSvcGraph ] ,
SnatContractScope : c . Network . Options [ AciSnatContractScope ] ,
PodSubnetChunkSize : c . Network . Options [ AciPodSubnetChunkSize ] ,
EnableEndpointSlice : c . Network . Options [ AciEnableEndpointSlice ] ,
SnatNamespace : c . Network . Options [ AciSnatNamespace ] ,
EpRegistry : c . Network . Options [ AciEpRegistry ] ,
OpflexMode : c . Network . Options [ AciOpflexMode ] ,
SnatPortRangeStart : c . Network . Options [ AciSnatPortRangeStart ] ,
SnatPortRangeEnd : c . Network . Options [ AciSnatPortRangeEnd ] ,
SnatPortsPerNode : c . Network . Options [ AciSnatPortsPerNode ] ,
OpflexClientSSL : c . Network . Options [ AciOpflexClientSSL ] ,
UsePrivilegedContainer : c . Network . Options [ AciUsePrivilegedContainer ] ,
UseHostNetnsVolume : c . Network . Options [ AciUseHostNetnsVolume ] ,
UseOpflexServerVolume : c . Network . Options [ AciUseOpflexServerVolume ] ,
KafkaBrokers : c . Network . AciNetworkProvider . KafkaBrokers ,
KafkaClientCrt : c . Network . Options [ AciKafkaClientCrt ] ,
KafkaClientKey : c . Network . Options [ AciKafkaClientKey ] ,
SubnetDomainName : c . Network . Options [ AciSubnetDomainName ] ,
CApic : c . Network . Options [ AciCApic ] ,
UseAciAnywhereCRD : c . Network . Options [ AciUseAciAnywhereCRD ] ,
OverlayVRFName : c . Network . Options [ AciOverlayVRFName ] ,
GbpPodSubnet : c . Network . Options [ AciGbpPodSubnet ] ,
RunGbpContainer : c . Network . Options [ AciRunGbpContainer ] ,
RunOpflexServerContainer : c . Network . Options [ AciRunOpflexServerContainer ] ,
OpflexServerPort : c . Network . Options [ AciOpflexServerPort ] ,
AciCniDeployContainer : c . SystemImages . AciCniDeployContainer ,
AciHostContainer : c . SystemImages . AciHostContainer ,
AciOpflexContainer : c . SystemImages . AciOpflexContainer ,
AciMcastContainer : c . SystemImages . AciMcastContainer ,
AciOpenvSwitchContainer : c . SystemImages . AciOpenvSwitchContainer ,
AciControllerContainer : c . SystemImages . AciControllerContainer ,
AciGbpServerContainer : c . SystemImages . AciGbpServerContainer ,
AciOpflexServerContainer : c . SystemImages . AciOpflexServerContainer ,
MTU : c . Network . MTU ,
}
pluginYaml , err := c . getNetworkPluginManifest ( AciConfig , data )
if err != nil {
return err
}
return c . doAddonDeploy ( ctx , pluginYaml , NetworkPluginResourceName , true )
}
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) getNetworkPluginManifest ( pluginConfig , data map [ string ] interface { } ) ( string , error ) {
2017-12-16 03:37:45 +00:00
switch c . Network . Plugin {
2020-06-26 07:35:32 +00:00
case CanalNetworkPlugin , FlannelNetworkPlugin , CalicoNetworkPlugin , WeaveNetworkPlugin , AciNetworkPlugin :
2019-08-13 20:34:49 +00:00
tmplt , err := templates . GetVersionedTemplates ( c . Network . Plugin , data , c . Version )
if err != nil {
return "" , err
}
return templates . CompileTemplateFromMap ( tmplt , pluginConfig )
2017-12-16 03:37:45 +00:00
default :
return "" , fmt . Errorf ( "[network] Unsupported network plugin: %s" , c . Network . Plugin )
}
}
2018-01-16 18:29:09 +00:00
2018-01-18 20:41:04 +00:00
func ( c * Cluster ) CheckClusterPorts ( ctx context . Context , currentCluster * Cluster ) error {
if currentCluster != nil {
newEtcdHost := hosts . GetToAddHosts ( currentCluster . EtcdHosts , c . EtcdHosts )
2019-09-25 01:28:13 +00:00
newControlPlaneHosts := hosts . GetToAddHosts ( currentCluster . ControlPlaneHosts , c . ControlPlaneHosts )
2018-01-18 20:41:04 +00:00
newWorkerHosts := hosts . GetToAddHosts ( currentCluster . WorkerHosts , c . WorkerHosts )
if len ( newEtcdHost ) == 0 &&
len ( newWorkerHosts ) == 0 &&
2019-09-25 01:28:13 +00:00
len ( newControlPlaneHosts ) == 0 {
2018-01-18 20:41:04 +00:00
log . Infof ( ctx , "[network] No hosts added existing cluster, skipping port check" )
return nil
}
}
if err := c . deployTCPPortListeners ( ctx , currentCluster ) ; err != nil {
2018-01-16 18:29:09 +00:00
return err
}
if err := c . runServicePortChecks ( ctx ) ; err != nil {
return err
}
2018-05-08 22:30:50 +00:00
// Skip kubeapi check if we are using custom k8s dialer or bastion/jump host
if c . K8sWrapTransport == nil && len ( c . BastionHost . Address ) == 0 {
2018-03-04 12:14:22 +00:00
if err := c . checkKubeAPIPort ( ctx ) ; err != nil {
return err
}
2018-05-08 22:30:50 +00:00
} else {
log . Infof ( ctx , "[network] Skipping kubeapi port check" )
2018-01-16 18:29:09 +00:00
}
2018-03-04 12:14:22 +00:00
2018-01-16 18:29:09 +00:00
return c . removeTCPPortListeners ( ctx )
}
func ( c * Cluster ) checkKubeAPIPort ( ctx context . Context ) error {
log . Infof ( ctx , "[network] Checking KubeAPI port Control Plane hosts" )
for _ , host := range c . ControlPlaneHosts {
2019-05-24 00:17:25 +00:00
logrus . Debugf ( "[network] Checking KubeAPI port [%s] on host: %s" , KubeAPIPort , host . Address )
2018-01-16 18:29:09 +00:00
address := fmt . Sprintf ( "%s:%s" , host . Address , KubeAPIPort )
2019-05-24 00:17:25 +00:00
conn , err := net . Dial ( "tcp" , address )
if err != nil {
return fmt . Errorf ( "[network] Can't access KubeAPI port [%s] on Control Plane host: %s" , KubeAPIPort , host . Address )
2018-01-16 18:29:09 +00:00
}
2019-05-24 00:17:25 +00:00
conn . Close ( )
2018-01-16 18:29:09 +00:00
}
return nil
}
2018-01-18 20:41:04 +00:00
func ( c * Cluster ) deployTCPPortListeners ( ctx context . Context , currentCluster * Cluster ) error {
2018-01-16 18:29:09 +00:00
log . Infof ( ctx , "[network] Deploying port listener containers" )
2018-01-18 20:41:04 +00:00
// deploy ectd listeners
2018-09-20 16:55:20 +00:00
if err := c . deployListenerOnPlane ( ctx , EtcdPortList , c . EtcdHosts , EtcdPortListenContainer ) ; err != nil {
2018-01-18 20:41:04 +00:00
return err
}
// deploy controlplane listeners
2018-09-20 16:55:20 +00:00
if err := c . deployListenerOnPlane ( ctx , ControlPlanePortList , c . ControlPlaneHosts , CPPortListenContainer ) ; err != nil {
2018-01-18 20:41:04 +00:00
return err
}
// deploy worker listeners
2018-09-20 16:55:20 +00:00
if err := c . deployListenerOnPlane ( ctx , WorkerPortList , c . WorkerHosts , WorkerPortListenContainer ) ; err != nil {
2018-01-18 20:41:04 +00:00
return err
}
log . Infof ( ctx , "[network] Port listener containers deployed successfully" )
return nil
}
2018-10-17 22:26:54 +00:00
func ( c * Cluster ) deployListenerOnPlane ( ctx context . Context , portList [ ] string , hostPlane [ ] * hosts . Host , containerName string ) error {
2018-01-19 22:43:19 +00:00
var errgrp errgroup . Group
2018-10-17 22:26:54 +00:00
hostsQueue := util . GetObjectQueue ( hostPlane )
for w := 0 ; w < WorkerThreads ; w ++ {
2018-01-19 22:43:19 +00:00
errgrp . Go ( func ( ) error {
2018-10-17 22:26:54 +00:00
var errList [ ] error
for host := range hostsQueue {
err := c . deployListener ( ctx , host . ( * hosts . Host ) , portList , containerName )
if err != nil {
errList = append ( errList , err )
}
}
return util . ErrList ( errList )
2018-01-19 22:43:19 +00:00
} )
2018-01-16 18:29:09 +00:00
}
2018-01-19 22:43:19 +00:00
return errgrp . Wait ( )
}
2018-10-17 22:26:54 +00:00
2018-01-19 22:43:19 +00:00
func ( c * Cluster ) deployListener ( ctx context . Context , host * hosts . Host , portList [ ] string , containerName string ) error {
2018-01-16 18:29:09 +00:00
imageCfg := & container . Config {
2018-01-30 12:32:50 +00:00
Image : c . SystemImages . Alpine ,
2018-01-16 18:29:09 +00:00
Cmd : [ ] string {
2019-05-24 00:17:25 +00:00
"nc" ,
"-kl" ,
"-p" ,
"1337" ,
"-e" ,
"echo" ,
2018-01-16 18:29:09 +00:00
} ,
ExposedPorts : nat . PortSet {
"1337/tcp" : { } ,
} ,
}
hostCfg := & container . HostConfig {
PortBindings : nat . PortMap {
2018-01-19 22:43:19 +00:00
"1337/tcp" : getPortBindings ( "0.0.0.0" , portList ) ,
2018-01-16 18:29:09 +00:00
} ,
}
2018-01-19 22:43:19 +00:00
logrus . Debugf ( "[network] Starting deployListener [%s] on host [%s]" , containerName , host . Address )
2018-01-31 17:50:55 +00:00
if err := docker . DoRunContainer ( ctx , host . DClient , imageCfg , hostCfg , containerName , host . Address , "network" , c . PrivateRegistriesMap ) ; err != nil {
2018-01-19 22:43:19 +00:00
if strings . Contains ( err . Error ( ) , "bind: address already in use" ) {
logrus . Debugf ( "[network] Service is already up on host [%s]" , host . Address )
return nil
}
return err
2018-01-16 18:29:09 +00:00
}
2018-01-19 22:43:19 +00:00
return nil
2018-01-16 18:29:09 +00:00
}
2018-01-18 20:41:04 +00:00
2018-01-16 18:29:09 +00:00
func ( c * Cluster ) removeTCPPortListeners ( ctx context . Context ) error {
log . Infof ( ctx , "[network] Removing port listener containers" )
2018-01-18 20:41:04 +00:00
if err := removeListenerFromPlane ( ctx , c . EtcdHosts , EtcdPortListenContainer ) ; err != nil {
return err
2018-01-16 18:29:09 +00:00
}
2018-01-18 20:41:04 +00:00
if err := removeListenerFromPlane ( ctx , c . ControlPlaneHosts , CPPortListenContainer ) ; err != nil {
return err
}
if err := removeListenerFromPlane ( ctx , c . WorkerHosts , WorkerPortListenContainer ) ; err != nil {
2018-01-16 18:29:09 +00:00
return err
}
log . Infof ( ctx , "[network] Port listener containers removed successfully" )
return nil
}
2018-01-18 20:41:04 +00:00
func removeListenerFromPlane ( ctx context . Context , hostPlane [ ] * hosts . Host , containerName string ) error {
var errgrp errgroup . Group
2018-10-17 22:26:54 +00:00
hostsQueue := util . GetObjectQueue ( hostPlane )
for w := 0 ; w < WorkerThreads ; w ++ {
2018-01-18 20:41:04 +00:00
errgrp . Go ( func ( ) error {
2018-10-17 22:26:54 +00:00
var errList [ ] error
for host := range hostsQueue {
runHost := host . ( * hosts . Host )
err := docker . DoRemoveContainer ( ctx , runHost . DClient , containerName , runHost . Address )
if err != nil {
errList = append ( errList , err )
}
}
return util . ErrList ( errList )
2018-01-18 20:41:04 +00:00
} )
}
return errgrp . Wait ( )
}
2018-10-17 22:26:54 +00:00
2018-01-16 18:29:09 +00:00
func ( c * Cluster ) runServicePortChecks ( ctx context . Context ) error {
var errgrp errgroup . Group
// check etcd <-> etcd
// one etcd host is a pass
if len ( c . EtcdHosts ) > 1 {
log . Infof ( ctx , "[network] Running etcd <-> etcd port checks" )
2018-10-17 22:26:54 +00:00
hostsQueue := util . GetObjectQueue ( c . EtcdHosts )
for w := 0 ; w < WorkerThreads ; w ++ {
2018-01-16 18:29:09 +00:00
errgrp . Go ( func ( ) error {
2018-10-17 22:26:54 +00:00
var errList [ ] error
for host := range hostsQueue {
2019-01-28 18:57:25 +00:00
err := checkPlaneTCPPortsFromHost ( ctx , host . ( * hosts . Host ) , EtcdPortList , c . EtcdHosts , c . SystemImages . Alpine , c . PrivateRegistriesMap )
2018-10-17 22:26:54 +00:00
if err != nil {
errList = append ( errList , err )
}
}
return util . ErrList ( errList )
2018-01-16 18:29:09 +00:00
} )
}
if err := errgrp . Wait ( ) ; err != nil {
return err
}
}
2018-06-07 20:47:37 +00:00
// check control -> etcd connectivity
2018-03-20 12:56:49 +00:00
log . Infof ( ctx , "[network] Running control plane -> etcd port checks" )
2018-10-17 22:26:54 +00:00
hostsQueue := util . GetObjectQueue ( c . ControlPlaneHosts )
for w := 0 ; w < WorkerThreads ; w ++ {
2018-01-16 18:29:09 +00:00
errgrp . Go ( func ( ) error {
2018-10-17 22:26:54 +00:00
var errList [ ] error
for host := range hostsQueue {
2019-01-28 18:57:25 +00:00
err := checkPlaneTCPPortsFromHost ( ctx , host . ( * hosts . Host ) , EtcdClientPortList , c . EtcdHosts , c . SystemImages . Alpine , c . PrivateRegistriesMap )
2018-10-17 22:26:54 +00:00
if err != nil {
errList = append ( errList , err )
}
}
return util . ErrList ( errList )
2018-01-16 18:29:09 +00:00
} )
}
if err := errgrp . Wait ( ) ; err != nil {
return err
}
// check controle plane -> Workers
2018-03-20 12:56:49 +00:00
log . Infof ( ctx , "[network] Running control plane -> worker port checks" )
2018-10-17 22:26:54 +00:00
hostsQueue = util . GetObjectQueue ( c . ControlPlaneHosts )
for w := 0 ; w < WorkerThreads ; w ++ {
2018-01-16 18:29:09 +00:00
errgrp . Go ( func ( ) error {
2018-10-17 22:26:54 +00:00
var errList [ ] error
for host := range hostsQueue {
2019-01-28 18:57:25 +00:00
err := checkPlaneTCPPortsFromHost ( ctx , host . ( * hosts . Host ) , WorkerPortList , c . WorkerHosts , c . SystemImages . Alpine , c . PrivateRegistriesMap )
2018-10-17 22:26:54 +00:00
if err != nil {
errList = append ( errList , err )
}
}
return util . ErrList ( errList )
2018-01-16 18:29:09 +00:00
} )
}
if err := errgrp . Wait ( ) ; err != nil {
return err
}
// check workers -> control plane
log . Infof ( ctx , "[network] Running workers -> control plane port checks" )
2018-10-17 22:26:54 +00:00
hostsQueue = util . GetObjectQueue ( c . WorkerHosts )
for w := 0 ; w < WorkerThreads ; w ++ {
2018-01-16 18:29:09 +00:00
errgrp . Go ( func ( ) error {
2018-10-17 22:26:54 +00:00
var errList [ ] error
for host := range hostsQueue {
2019-01-28 18:57:25 +00:00
err := checkPlaneTCPPortsFromHost ( ctx , host . ( * hosts . Host ) , ControlPlanePortList , c . ControlPlaneHosts , c . SystemImages . Alpine , c . PrivateRegistriesMap )
2018-10-17 22:26:54 +00:00
if err != nil {
errList = append ( errList , err )
}
}
return util . ErrList ( errList )
2018-01-16 18:29:09 +00:00
} )
}
return errgrp . Wait ( )
}
2019-01-28 18:57:25 +00:00
func checkPlaneTCPPortsFromHost ( ctx context . Context , host * hosts . Host , portList [ ] string , planeHosts [ ] * hosts . Host , image string , prsMap map [ string ] v3 . PrivateRegistry ) error {
2018-04-19 14:03:14 +00:00
var hosts [ ] string
2020-11-09 12:11:43 +00:00
var portCheckLogs string
2018-01-16 18:29:09 +00:00
for _ , host := range planeHosts {
2018-01-18 20:41:04 +00:00
hosts = append ( hosts , host . InternalAddress )
2018-01-16 18:29:09 +00:00
}
imageCfg := & container . Config {
Image : image ,
Env : [ ] string {
fmt . Sprintf ( "HOSTS=%s" , strings . Join ( hosts , " " ) ) ,
fmt . Sprintf ( "PORTS=%s" , strings . Join ( portList , " " ) ) ,
} ,
2019-01-28 18:57:25 +00:00
Cmd : [ ] string {
"sh" ,
"-c" ,
"for host in $HOSTS; do for port in $PORTS ; do echo \"Checking host ${host} on port ${port}\" >&1 & nc -w 5 -z $host $port > /dev/null || echo \"${host}:${port}\" >&2 & done; wait; done" ,
} ,
2018-01-16 18:29:09 +00:00
}
2018-01-30 17:12:45 +00:00
hostCfg := & container . HostConfig {
NetworkMode : "host" ,
2018-04-19 14:03:14 +00:00
LogConfig : container . LogConfig {
Type : "json-file" ,
} ,
2018-01-30 17:12:45 +00:00
}
2020-11-09 12:11:43 +00:00
for retries := 0 ; retries < 3 ; retries ++ {
logrus . Infof ( "[network] Checking if host [%s] can connect to host(s) [%s] on port(s) [%s], try #%d" , host . Address , strings . Join ( hosts , " " ) , strings . Join ( portList , " " ) , retries + 1 )
if err := docker . DoRemoveContainer ( ctx , host . DClient , PortCheckContainer , host . Address ) ; err != nil {
return err
}
if err := docker . DoRunContainer ( ctx , host . DClient , imageCfg , hostCfg , PortCheckContainer , host . Address , "network" , prsMap ) ; err != nil {
return err
}
2018-04-19 14:03:14 +00:00
2020-11-09 12:11:43 +00:00
containerLog , _ , logsErr := docker . GetContainerLogsStdoutStderr ( ctx , host . DClient , PortCheckContainer , "all" , true )
if logsErr != nil {
log . Warnf ( ctx , "[network] Failed to get network port check logs: %v" , logsErr )
}
logrus . Debugf ( "[network] containerLog [%s] on host: %s" , containerLog , host . Address )
2018-04-19 14:03:14 +00:00
2020-11-09 12:11:43 +00:00
if err := docker . RemoveContainer ( ctx , host . DClient , host . Address , PortCheckContainer ) ; err != nil {
return err
}
logrus . Debugf ( "[network] Length of containerLog is [%d] on host: %s" , len ( containerLog ) , host . Address )
if len ( containerLog ) == 0 {
return nil
}
portCheckLogs = strings . Join ( strings . Split ( strings . TrimSpace ( containerLog ) , "\n" ) , ", " )
time . Sleep ( 5 * time . Second )
2018-01-16 18:29:09 +00:00
}
2020-11-09 12:11:43 +00:00
return fmt . Errorf ( "[network] Host [%s] is not able to connect to the following ports: [%s]. Please check network policies and firewall rules" , host . Address , portCheckLogs )
2018-01-16 18:29:09 +00:00
}
2018-01-19 22:43:19 +00:00
func getPortBindings ( hostAddress string , portList [ ] string ) [ ] nat . PortBinding {
portBindingList := [ ] nat . PortBinding { }
for _ , portNumber := range portList {
rawPort := fmt . Sprintf ( "%s:%s:1337/tcp" , hostAddress , portNumber )
portMapping , _ := nat . ParsePortSpec ( rawPort )
portBindingList = append ( portBindingList , portMapping [ 0 ] . Binding )
}
return portBindingList
}
2019-04-13 14:43:34 +00:00
func atoiWithDefault ( val string , defaultVal int ) ( int , error ) {
if val == "" {
return defaultVal , nil
}
ret , err := strconv . Atoi ( val )
if err != nil {
return 0 , err
}
return ret , nil
}