github.com/looshlee/beatles@v0.0.0-20220727174639-742810ab631c/daemon/health.go (about) 1 // Copyright 2016-2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "context" 19 "fmt" 20 "path/filepath" 21 "time" 22 23 health "github.com/cilium/cilium/cilium-health/launch" 24 "github.com/cilium/cilium/pkg/cleanup" 25 "github.com/cilium/cilium/pkg/controller" 26 "github.com/cilium/cilium/pkg/endpoint" 27 "github.com/cilium/cilium/pkg/endpointmanager" 28 "github.com/cilium/cilium/pkg/k8s" 29 "github.com/cilium/cilium/pkg/logging/logfields" 30 "github.com/cilium/cilium/pkg/option" 31 "github.com/cilium/cilium/pkg/pidfile" 32 ) 33 34 func (d *Daemon) initHealth() { 35 if option.Config.IsFlannelMasterDeviceSet() { 36 // Do not run health endpoint in policy enforcement mode as we can't 37 // allocate an IP address for this endpoint and the datapath is not 38 // controlled by Cilium. 39 return 40 } 41 42 // Launch cilium-health in the same process (and namespace) as cilium. 43 log.Info("Launching Cilium health daemon") 44 if ch, err := health.Launch(); err != nil { 45 log.WithError(err).Fatal("Failed to launch cilium-health") 46 } else { 47 d.ciliumHealth = ch 48 } 49 50 // If endpoint health checking is disabled, the virtual endpoint does not need to be launched 51 if !option.Config.EnableEndpointHealthChecking { 52 return 53 } 54 55 // Launch the cilium-health-responder as an endpoint, managed by cilium. 56 log.Info("Launching Cilium health endpoint") 57 if k8s.IsEnabled() { 58 // When Cilium starts up in k8s mode, it is guaranteed to be 59 // running inside a new PID namespace which means that existing 60 // PIDfiles are referring to PIDs that may be reused. Clean up. 61 pidfilePath := filepath.Join(option.Config.StateDir, health.PidfilePath) 62 if err := pidfile.Remove(pidfilePath); err != nil { 63 log.WithField(logfields.PIDFile, pidfilePath). 64 WithError(err). 65 Warning("Failed to remove pidfile") 66 } 67 } 68 69 // Wait for the API, then launch the controller 70 var client *health.Client 71 72 controller.NewManager().UpdateController("cilium-health-ep", 73 controller.ControllerParams{ 74 DoFunc: func(ctx context.Context) error { 75 var err error 76 77 if client != nil { 78 err = client.PingEndpoint() 79 } 80 // On the first initialization, or on 81 // error, restart the health EP. 82 if client == nil || err != nil { 83 var launchErr error 84 d.cleanupHealthEndpoint() 85 client, launchErr = health.LaunchAsEndpoint(ctx, d, &d.nodeDiscovery.LocalNode, d.mtuConfig) 86 if launchErr != nil { 87 if err != nil { 88 return fmt.Errorf("failed to restart endpoint (check failed: %q): %s", err, launchErr) 89 } 90 return launchErr 91 } 92 } 93 return err 94 }, 95 StopFunc: func(ctx context.Context) error { 96 log.Info("Stopping health endpoint") 97 err := client.PingEndpoint() 98 d.cleanupHealthEndpoint() 99 return err 100 }, 101 RunInterval: 60 * time.Second, 102 }, 103 ) 104 105 // Make sure to clean up the endpoint namespace when cilium-agent terminates 106 cleanup.DeferTerminationCleanupFunction(cleanUPWg, cleanUPSig, func() { 107 health.KillEndpoint() 108 health.CleanupEndpoint() 109 }) 110 } 111 112 func (d *Daemon) cleanupHealthEndpoint() { 113 localNode := d.nodeDiscovery.LocalNode 114 115 // Delete the process 116 health.KillEndpoint() 117 118 // Clean up agent resources 119 var ep *endpoint.Endpoint 120 if localNode.IPv4HealthIP != nil { 121 ep = endpointmanager.LookupIPv4(localNode.IPv4HealthIP.String()) 122 } 123 if ep == nil && localNode.IPv6HealthIP != nil { 124 ep = endpointmanager.LookupIPv6(localNode.IPv6HealthIP.String()) 125 } 126 if ep == nil { 127 log.Debug("Didn't find existing cilium-health endpoint to delete") 128 } else { 129 log.Debug("Removing existing cilium-health endpoint") 130 errs := d.deleteEndpointQuiet(ep, endpoint.DeleteConfig{ 131 NoIPRelease: true, 132 }) 133 for _, err := range errs { 134 log.WithError(err).Debug("Error occurred while deleting cilium-health endpoint") 135 } 136 } 137 health.CleanupEndpoint() 138 }