Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - support for KubernetesInDocker (kind) clusters #69

Merged
merged 35 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
dc4884b
support for collecting from CRDs using default deployment yaml
davidkydd Apr 22, 2021
bc21285
Merge branch 'master' into dakydd/master
davidkydd Apr 22, 2021
b516b5c
Merge branch 'master' of https://github.com/Azure/aks-periscope
davidkydd May 6, 2021
f2683a6
revert additional resource permissions
davidkydd May 6, 2021
9a8e367
expose a feature flag for collectors and diagnosers
davidkydd May 6, 2021
5d344b9
typo
davidkydd May 6, 2021
5104ef7
fix targeting configmap rather than config itself
davidkydd May 6, 2021
178b618
- treat exporters the same as collectors + diagnosers
davidkydd May 7, 2021
ecfe3ff
minor tidy
davidkydd May 7, 2021
864297a
create dev deployment yaml in its own subdir and revert changes to to…
davidkydd May 7, 2021
790744a
go fmt
davidkydd May 8, 2021
2b66c39
rename for clarity
davidkydd May 8, 2021
308e350
Helm chart for azure-k8s-periscope
safeermohammed Apr 28, 2021
d569772
add new configmaps to chart
davidkydd May 10, 2021
4e69de1
WIP - support for KubernetesInDocker (kind) clusters
davidkydd Jun 20, 2021
a377636
simplify err => boolean
davidkydd Jun 20, 2021
228cf6b
reset line endings to crlf
davidkydd Jun 20, 2021
a905fe9
Merge branch 'collectorDiagnoserConfig' into kindClusterSupport
davidkydd Jun 23, 2021
7c5c80d
Fix additional merge issues
davidkydd Jun 23, 2021
9b9a582
overload collectors-config to support both ENABLED_COLLECTORS and COL…
davidkydd Jun 23, 2021
915b745
Remove helm
davidkydd Jun 23, 2021
7032976
Remove dev periscope yaml
davidkydd Jun 23, 2021
5a1df46
Handle kubeadm (perhaps poorly) and aks-engine fqdn -> containerName …
davidkydd Jun 23, 2021
92a767c
additional test cases
davidkydd Jun 23, 2021
12bbfd3
new containerlogs collector for containerd clusters - still needs to …
davidkydd Jun 25, 2021
0a5aa64
register containerD collector
davidkydd Jun 25, 2021
2bb4a37
reverse the kind vs. non-kind check to be AKS vs. non-AKS
davidkydd Jun 25, 2021
0c61fed
register the containerlogscontainerd collector for the kind deploymen…
davidkydd Jun 25, 2021
fc7bc03
remove unused config
davidkydd Jun 25, 2021
248d8fd
register new collector in initialization, fix typo + collector name
davidkydd Jun 25, 2021
c32622a
zip_and_export flag added to exporter config, false for KIND, default…
davidkydd Jun 25, 2021
c575b09
containerD collector needs to copy files from host to container prior…
davidkydd Jun 25, 2021
99fb06c
fixes for when running on AKS - image: dakyddacr.azurecr.io/periscope…
davidkydd Jun 26, 2021
c68790f
Merge branch 'master' into kindClusterSupport
davidkydd Jun 28, 2021
3fd2587
fix golint errors
davidkydd Jun 28, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 188 additions & 61 deletions cmd/aks-periscope/aks-periscope.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"log"
"os"
"strconv"
"strings"
"sync"

Expand All @@ -11,19 +12,17 @@ import (
"github.com/Azure/aks-periscope/pkg/exporter"
"github.com/Azure/aks-periscope/pkg/interfaces"
"github.com/Azure/aks-periscope/pkg/utils"

"github.com/hashicorp/go-multierror"
)

func main() {
zipAndExportMode := true
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is always true - remove it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced with ZIP_AND_EXPORT bool in exporters-config

exporter := &exporter.AzureBlobExporter{}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced with selectExporters method


err := utils.CreateCRD()
if err != nil {
log.Fatalf("Failed to create CRD: %v", err)
}

collectorList := strings.Fields(os.Getenv("COLLECTOR_LIST"))

Comment on lines -25 to -26
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved into selectCollectors

// Copies self-signed cert information to container if application is running on Azure Stack Cloud.
// We need the cert in order to communicate with the storage account.
if utils.IsAzureStackCloud() {
Expand All @@ -32,40 +31,183 @@ func main() {
}
}

collectors, diagnosers, exporters := initializeComponents()

collectorGrp := new(sync.WaitGroup)
runCollectors(collectors, collectorGrp)
collectorGrp.Wait()

diagnoserGrp := new(sync.WaitGroup)
runDiagnosers(diagnosers, diagnoserGrp)
diagnoserGrp.Wait()

zipAndExportString, found := os.LookupEnv("ZIP_AND_EXPORT")
zipAndExport, parseErr := strconv.ParseBool(zipAndExportString)
if !found || parseErr != nil {
zipAndExport = true
}

if zipAndExport {
log.Print("Zip result files")
zippedOutputs, err := zipOutputDirectory()
if err != nil {
log.Printf("Failed to zip result files: %+v", err)
}

log.Print("Run exporters for result files")
err = runExporters(exporters, zippedOutputs)
if err != nil {
log.Printf("Failed to export result files: %+v", err)
}
}

// TODO: Hack: for now AKS-Periscope is running as a deamonset so it shall not stop (or the pod will be restarted)
// Revert from https://github.com/Azure/aks-periscope/blob/b98d66a238e942158ef2628a9315b58937ff9c8f/cmd/aks-periscope/aks-periscope.go#L70
select {}
}

// initializeComponents initializes and returns collectors, diagnosers and exporters
func initializeComponents() ([]interfaces.Collector, []interfaces.Diagnoser, []interfaces.Exporter) {
//TODO it would be nice if we only instantiated those collector/diagnoser/exporters that were actually selected for execution

//exporters
azureBlobExporter := exporter.NewAzureBlobExporter()
selectedExporters := selectExporters(
map[string]interfaces.Exporter{
azureBlobExporter.GetName(): azureBlobExporter,
})

//collectors
containerLogsCollector := collector.NewContainerLogsCollector(selectedExporters)
containerLogsCollectorContainerD := collector.NewContainerLogsCollectorContainerD(selectedExporters)
systemLogsCollector := collector.NewSystemLogsCollector(selectedExporters)
networkOutboundCollector := collector.NewNetworkOutboundCollector(5, selectedExporters)
ipTablesCollector := collector.NewIPTablesCollector(selectedExporters)
dnsCollector := collector.NewDNSCollector(selectedExporters)
nodeLogsCollector := collector.NewNodeLogsCollector(selectedExporters)
kubeObjectsCollector := collector.NewKubeObjectsCollector(selectedExporters)
kubeletCmdCollector := collector.NewKubeletCmdCollector(selectedExporters)
systemPerfCollector := collector.NewSystemPerfCollector(selectedExporters)
helmCollector := collector.NewHelmCollector(selectedExporters)
osmCollector := collector.NewOsmCollector(selectedExporters)

selectedCollectors := selectCollectors(
map[string]interfaces.Collector{
containerLogsCollector.GetName(): containerLogsCollector,
containerLogsCollectorContainerD.GetName(): containerLogsCollectorContainerD,
systemLogsCollector.GetName(): systemLogsCollector,
networkOutboundCollector.GetName(): networkOutboundCollector,
ipTablesCollector.GetName(): ipTablesCollector,
nodeLogsCollector.GetName(): nodeLogsCollector,
dnsCollector.GetName(): dnsCollector,
kubeObjectsCollector.GetName(): kubeObjectsCollector,
kubeletCmdCollector.GetName(): kubeletCmdCollector,
systemPerfCollector.GetName(): systemPerfCollector,
helmCollector.GetName(): helmCollector,
osmCollector.GetName(): osmCollector,
})

//diagnosers
//NOTE currently the collector instance objects are shared between the collector itself and things which use it as a dependency
networkConfigDiagnoser := diagnoser.NewNetworkConfigDiagnoser(dnsCollector, kubeletCmdCollector, selectedExporters)
networkOutboundDiagnoser := diagnoser.NewNetworkOutboundDiagnoser(networkOutboundCollector, selectedExporters)
selectedDiagnosers := selectDiagnosers(
map[string]interfaces.Diagnoser{
networkConfigDiagnoser.GetName(): networkConfigDiagnoser,
networkOutboundDiagnoser.GetName(): networkOutboundDiagnoser,
})

return selectedCollectors, selectedDiagnosers, selectedExporters
}

// selectCollectors select the collectors to run
func selectCollectors(allCollectorsByName map[string]interfaces.Collector) []interfaces.Collector {
collectors := []interfaces.Collector{}
containerLogsCollector := collector.NewContainerLogsCollector(exporter)
networkOutboundCollector := collector.NewNetworkOutboundCollector(5, exporter)
dnsCollector := collector.NewDNSCollector(exporter)
kubeObjectsCollector := collector.NewKubeObjectsCollector(exporter)
systemLogsCollector := collector.NewSystemLogsCollector(exporter)
ipTablesCollector := collector.NewIPTablesCollector(exporter)
nodeLogsCollector := collector.NewNodeLogsCollector(exporter)
kubeletCmdCollector := collector.NewKubeletCmdCollector(exporter)
systemPerfCollector := collector.NewSystemPerfCollector(exporter)
helmCollector := collector.NewHelmCollector(exporter)
osmCollector := collector.NewOsmCollector(exporter)

collectors = append(collectors, containerLogsCollector)
collectors = append(collectors, dnsCollector)
collectors = append(collectors, kubeObjectsCollector)
collectors = append(collectors, networkOutboundCollector)

if contains(collectorList, "connectedCluster") {
collectors = append(collectors, helmCollector)
//read list of collectors that are enabled
var enabledCollectorNames []string

//TODO try get partners to move from COLLECTOR_LIST to use ENABLED_COLLECTORS instead, for now COLLECTOR_LIST takes precedence if defined
collectorList := strings.Fields(os.Getenv("COLLECTOR_LIST"))
if collectorList != nil {
enabledCollectorNames = selectCollectorsUsingCollectorList(collectorList)
} else {
collectors = append(collectors, systemLogsCollector)
collectors = append(collectors, ipTablesCollector)
collectors = append(collectors, nodeLogsCollector)
collectors = append(collectors, kubeletCmdCollector)
collectors = append(collectors, systemPerfCollector)
enabledCollectorNames = strings.Fields(os.Getenv("ENABLED_COLLECTORS"))
}

for _, collectorName := range enabledCollectorNames {
collectors = append(collectors, allCollectorsByName[collectorName])
}

return collectors
}

//selectCollectorsUsingCollectorList use clusterType
func selectCollectorsUsingCollectorList(collectorList []string) []string {
var enabledCollectorNames []string

//select default collectors
enabledCollectorNames = append(enabledCollectorNames,
"dns", "containerlogs", "kubeobjects", "networkoutbound")

if contains(collectorList, "connectedCluster") {
//select connectedCluster collectors
enabledCollectorNames = append(enabledCollectorNames, "helm")
} else {
//select non-connectedCluster collectors
enabledCollectorNames = append(enabledCollectorNames,
"iptables", "kubeletcmd", "nodelogs", "systemlogs", "systemperf")
}
if contains(collectorList, "OSM") {
collectors = append(collectors, osmCollector)
//select OSM collectors
enabledCollectorNames = append(enabledCollectorNames, "osm")
}

collectorGrp := new(sync.WaitGroup)
return enabledCollectorNames
}

// selectDiagnosers select the diagnosers to run
func selectDiagnosers(allDiagnosersByName map[string]interfaces.Diagnoser) []interfaces.Diagnoser {
diagnosers := []interfaces.Diagnoser{}

//read list of diagnosers that are enabled
enabledDiagnoserString, found := os.LookupEnv("ENABLED_DIAGNOSERS")
if !found {
//if not defined, default to all diagnosers enabled
enabledDiagnoserString = "networkconfig networkoutbound"
}

enabledDiagnoserNames := strings.Fields(enabledDiagnoserString)

for _, diagnoserName := range enabledDiagnoserNames {
diagnosers = append(diagnosers, allDiagnosersByName[diagnoserName])
}

return diagnosers
}

// selectedExporters select the exporters to run
func selectExporters(allExporters map[string]interfaces.Exporter) []interfaces.Exporter {
exporters := []interfaces.Exporter{}

//read list of exporters that are enabled
enabledExportersString, found := os.LookupEnv("ENABLED_EXPORTERS")
if !found {
//if not defined, default to all exporters enabled
enabledExportersString = "azureblob"
}

enabledExporterNames := strings.Fields(enabledExportersString)

for _, exporterName := range enabledExporterNames {
exporters = append(exporters, allExporters[exporterName])
}

return exporters
}

// runCollectors run the collectors
func runCollectors(collectors []interfaces.Collector, collectorGrp *sync.WaitGroup) {
for _, c := range collectors {
collectorGrp.Add(1)
go func(c interfaces.Collector) {
Expand All @@ -85,15 +227,10 @@ func main() {
}
}(c)
}
}

collectorGrp.Wait()

diagnosers := []interfaces.Diagnoser{}
diagnosers = append(diagnosers, diagnoser.NewNetworkConfigDiagnoser(dnsCollector, kubeletCmdCollector, exporter))
diagnosers = append(diagnosers, diagnoser.NewNetworkOutboundDiagnoser(networkOutboundCollector, exporter))

diagnoserGrp := new(sync.WaitGroup)

// runDiagnosers run the diagnosers
func runDiagnosers(diagnosers []interfaces.Diagnoser, diagnoserGrp *sync.WaitGroup) {
for _, d := range diagnosers {
diagnoserGrp.Add(1)
go func(d interfaces.Diagnoser) {
Expand All @@ -113,28 +250,29 @@ func main() {
}
}(d)
}
}

diagnoserGrp.Wait()

if zipAndExportMode {
log.Print("Zip and export result files")
err := zipAndExport(exporter)
if err != nil {
log.Fatalf("Failed to zip and export result files: %v", err)
// runExporters run the exporters
func runExporters(exporters []interfaces.Exporter, filesToExport []string) error {
var result error
for _, e := range exporters {
if err := e.Export(filesToExport); err != nil {
result = multierror.Append(result, err)
}
}
return result
}

// zipAndExport zip the results and export
func zipAndExport(exporter interfaces.Exporter) error {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zipAndExport replaced with two functions: zipOutputDirectory & runExporters

// zipAndExport zip the results
func zipOutputDirectory() (zipFiles []string, error error) {
hostName, err := utils.GetHostName()
if err != nil {
return err
return nil, err
}

creationTimeStamp, err := utils.GetCreationTimeStamp()
if err != nil {
return err
return nil, err
}

sourcePathOnHost := "/var/log/aks-periscope/" + strings.Replace(creationTimeStamp, ":", "-", -1) + "/" + hostName
Expand All @@ -143,21 +281,10 @@ func zipAndExport(exporter interfaces.Exporter) error {

_, err = utils.RunCommandOnHost("zip", "-r", zipFileOnHost, sourcePathOnHost)
if err != nil {
return err
}

err = exporter.Export([]string{zipFileOnContainer})
if err != nil {
return err
return nil, err
}

// TODO: Hack: for now AKS-Periscope is running as a deamonset so it shall not stop (or the pod will be restarted)
// Revert from https://github.com/Azure/aks-periscope/blob/b98d66a238e942158ef2628a9315b58937ff9c8f/cmd/aks-periscope/aks-periscope.go#L70
select {}

// TODO: remove this //nolint comment once the select{} has been removed
//nolint:govet
return nil
return []string{zipFileOnContainer}, nil
}

func contains(flagsList []string, flag string) bool {
Expand Down
Loading