theinternet.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package render
  2. import (
  3. "net"
  4. "regexp"
  5. "strings"
  6. "camlistore.org/pkg/lru"
  7. "github.com/weaveworks/scope/report"
  8. )
  9. var (
  10. // ServiceNodeIDPrefix is how the ID of all service pseudo nodes begin
  11. ServiceNodeIDPrefix = "service-"
  12. knownServiceMatcher = regexp.MustCompile(`^.+\.(` + strings.Join([]string{
  13. // See http://docs.aws.amazon.com/general/latest/gr/rande.html
  14. // for finer grained details
  15. `amazonaws\.com`,
  16. `googleapis\.com`,
  17. `weave\.works`, // Weave Cloud
  18. `core\.windows\.net`, // Azure Storage - Blob, Tables, Files & Queues
  19. `servicebus\.windows\.net`, // Azure Service Bus
  20. `azure-api\.net`, // Azure API Management
  21. `onmicrosoft\.com`, // Azure Active Directory
  22. `cloudapp\.azure\.com`, // Azure IaaS
  23. `database\.windows\.net`, // Azure SQL DB
  24. `documents\.azure\.com`, // Azure DocumentDB/CosmosDB
  25. }, `|`) + `)$`)
  26. knownServiceExcluder = regexp.MustCompile(`^(` + strings.Join([]string{
  27. // We exclude ec2 machines because they are too generic
  28. // and having separate nodes for them makes visualizations worse
  29. `ec2.*\.amazonaws\.com`,
  30. }, `|`) + `)$`)
  31. // Memoization for isKnownService.
  32. //
  33. // The 10000 comes from the observation that large reports contain
  34. // hundreds of names, and in a multi-tenant context we want to be
  35. // able to render a few dozen reports concurrently. Also, unlike
  36. // memoization in the reducers, which is keyed on reports, this
  37. // cache is effective when rendering multiple reports from the
  38. // same cluster of probes, e.g. from different points in time,
  39. // since names tend to change infrequently.
  40. //
  41. // Since names are generally <50 bytes, this shouldn't weight in
  42. // at more than a few MB of memory.
  43. knownServiceCache = lru.New(10000)
  44. )
  45. func purgeKnownServiceCache() {
  46. knownServiceCache = lru.New(10000)
  47. }
  48. // TODO: Make it user-customizable https://github.com/weaveworks/scope/issues/1876
  49. // NB: this is a hotspot in rendering performance.
  50. func isKnownService(hostname string) bool {
  51. if v, ok := knownServiceCache.Get(hostname); ok {
  52. return v.(bool)
  53. }
  54. known := knownServiceMatcher.MatchString(hostname) && !knownServiceExcluder.MatchString(hostname)
  55. knownServiceCache.Add(hostname, known)
  56. return known
  57. }
  58. // LocalNetworks returns a superset of the networks (think: CIDRs) that are
  59. // "local" from the perspective of each host represented in the report. It's
  60. // used to determine which nodes in the report are "remote", i.e. outside of
  61. // our infrastructure.
  62. func LocalNetworks(r report.Report) report.Networks {
  63. networks := report.MakeNetworks()
  64. for _, topology := range []report.Topology{r.Host, r.Overlay} {
  65. for _, md := range topology.Nodes {
  66. nets, _ := md.Sets.Lookup(report.HostLocalNetworks)
  67. for _, s := range nets {
  68. networks.AddCIDR(s)
  69. }
  70. }
  71. }
  72. if extra := kubeServiceNetwork(r.Service); extra != nil {
  73. networks.Add(extra)
  74. }
  75. return networks
  76. }
  77. // FIXME: Hideous hack to remove persistent-connection edges to
  78. // virtual service IPs attributed to the internet. The global
  79. // service-cluster-ip-range is not exposed by the API server (see
  80. // https://github.com/kubernetes/kubernetes/issues/25533), so instead
  81. // we synthesise it by computing the smallest network that contains
  82. // all service IPs. That network may be smaller than the actual range
  83. // but that is ok, since in the end all we care about is that it
  84. // contains all the service IPs.
  85. //
  86. // The right way of fixing this is performing DNAT mapping on
  87. // persistent connections for which we don't have a robust solution
  88. // (see https://github.com/weaveworks/scope/issues/1491).
  89. func kubeServiceNetwork(services report.Topology) *net.IPNet {
  90. serviceIPs := make([]net.IP, 0, len(services.Nodes))
  91. for _, md := range services.Nodes {
  92. serviceIP, _ := md.Latest.Lookup(report.KubernetesIP)
  93. if ip := net.ParseIP(serviceIP).To4(); ip != nil {
  94. serviceIPs = append(serviceIPs, ip)
  95. }
  96. }
  97. return report.ContainingIPv4Network(serviceIPs)
  98. }