Merge pull request #47906 from akerouanton/libnet-add-otel-spans-v3

api, daemon, libnet: Create OTel spans at various places
This commit is contained in:
Albin Kerouanton
2024-06-14 17:03:56 +02:00
committed by GitHub
77 changed files with 914 additions and 542 deletions

View File

@@ -32,6 +32,9 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/runconfig"
"github.com/docker/go-connections/nat"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
func ipAddresses(ips []net.IP) []string {
@@ -309,7 +312,7 @@ func (daemon *Daemon) updateNetwork(cfg *config.Config, container *container.Con
return fmt.Errorf("Update network failed: %v", err)
}
if err := sb.Refresh(sbOptions...); err != nil {
if err := sb.Refresh(context.TODO(), sbOptions...); err != nil {
return fmt.Errorf("Update network failed: Failure in refresh sandbox %s: %v", sid, err)
}
@@ -476,7 +479,7 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai
}
}
func (daemon *Daemon) allocateNetwork(cfg *config.Config, container *container.Container) (retErr error) {
func (daemon *Daemon) allocateNetwork(ctx context.Context, cfg *config.Config, container *container.Container) (retErr error) {
if daemon.netController == nil {
return nil
}
@@ -484,8 +487,8 @@ func (daemon *Daemon) allocateNetwork(cfg *config.Config, container *container.C
start := time.Now()
// Cleanup any stale sandbox left over due to ungraceful daemon shutdown
if err := daemon.netController.SandboxDestroy(container.ID); err != nil {
log.G(context.TODO()).WithError(err).Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
if err := daemon.netController.SandboxDestroy(ctx, container.ID); err != nil {
log.G(ctx).WithError(err).Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
}
if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
@@ -505,7 +508,7 @@ func (daemon *Daemon) allocateNetwork(cfg *config.Config, container *container.C
defaultNetName := runconfig.DefaultDaemonNetworkMode().NetworkName()
if nConf, ok := container.NetworkSettings.Networks[defaultNetName]; ok {
cleanOperationalData(nConf)
if err := daemon.connectToNetwork(cfg, container, defaultNetName, nConf, updateSettings); err != nil {
if err := daemon.connectToNetwork(ctx, cfg, container, defaultNetName, nConf, updateSettings); err != nil {
return err
}
}
@@ -522,7 +525,7 @@ func (daemon *Daemon) allocateNetwork(cfg *config.Config, container *container.C
for netName, epConf := range networks {
cleanOperationalData(epConf)
if err := daemon.connectToNetwork(cfg, container, netName, epConf, updateSettings); err != nil {
if err := daemon.connectToNetwork(ctx, cfg, container, netName, epConf, updateSettings); err != nil {
return err
}
}
@@ -539,14 +542,14 @@ func (daemon *Daemon) allocateNetwork(cfg *config.Config, container *container.C
if err != nil {
return err
}
sb, err := daemon.netController.NewSandbox(container.ID, sbOptions...)
sb, err := daemon.netController.NewSandbox(ctx, container.ID, sbOptions...)
if err != nil {
return err
}
setNetworkSandbox(container, sb)
defer func() {
if retErr != nil {
sb.Delete()
sb.Delete(context.WithoutCancel(ctx))
}
}()
}
@@ -695,8 +698,16 @@ func buildEndpointDNSNames(ctr *container.Container, aliases []string) []string
return sliceutil.Dedup(dnsNames)
}
func (daemon *Daemon) connectToNetwork(cfg *config.Config, container *container.Container, idOrName string, endpointConfig *network.EndpointSettings, updateSettings bool) (retErr error) {
func (daemon *Daemon) connectToNetwork(ctx context.Context, cfg *config.Config, container *container.Container, idOrName string, endpointConfig *network.EndpointSettings, updateSettings bool) (retErr error) {
containerName := strings.TrimPrefix(container.Name, "/")
ctx, span := otel.Tracer("").Start(ctx, "daemon.connectToNetwork", trace.WithAttributes(
attribute.String("container.ID", container.ID),
attribute.String("container.name", containerName),
attribute.String("network.idOrName", idOrName)))
defer span.End()
start := time.Now()
if container.HostConfig.NetworkMode.IsContainer() {
return runconfig.ErrConflictSharedNetwork
}
@@ -749,15 +760,14 @@ func (daemon *Daemon) connectToNetwork(cfg *config.Config, container *container.
return err
}
endpointName := strings.TrimPrefix(container.Name, "/")
ep, err := n.CreateEndpoint(endpointName, createOptions...)
ep, err := n.CreateEndpoint(ctx, containerName, createOptions...)
if err != nil {
return err
}
defer func() {
if retErr != nil {
if err := ep.Delete(false); err != nil {
log.G(context.TODO()).Warnf("Could not rollback container connection to network %s", idOrName)
if err := ep.Delete(context.WithoutCancel(ctx), false); err != nil {
log.G(ctx).Warnf("Could not rollback container connection to network %s", idOrName)
}
}
}()
@@ -774,7 +784,7 @@ func (daemon *Daemon) connectToNetwork(cfg *config.Config, container *container.
if err != nil {
return err
}
sb, err = daemon.netController.NewSandbox(container.ID, sbOptions...)
sb, err = daemon.netController.NewSandbox(ctx, container.ID, sbOptions...)
if err != nil {
return err
}
@@ -787,7 +797,7 @@ func (daemon *Daemon) connectToNetwork(cfg *config.Config, container *container.
return err
}
if err := ep.Join(sb, joinOptions...); err != nil {
if err := ep.Join(ctx, sb, joinOptions...); err != nil {
return err
}
@@ -851,10 +861,10 @@ func (daemon *Daemon) ForceEndpointDelete(name string, networkName string) error
if err != nil {
return err
}
return ep.Delete(true)
return ep.Delete(context.TODO(), true)
}
func (daemon *Daemon) disconnectFromNetwork(container *container.Container, n *libnetwork.Network, force bool) error {
func (daemon *Daemon) disconnectFromNetwork(ctx context.Context, container *container.Container, n *libnetwork.Network, force bool) error {
var (
ep *libnetwork.Endpoint
sbox *libnetwork.Sandbox
@@ -881,18 +891,18 @@ func (daemon *Daemon) disconnectFromNetwork(container *container.Container, n *l
if err != nil {
return err
}
return ep.Delete(force)
return ep.Delete(ctx, force)
}
return fmt.Errorf("container %s is not connected to network %s", container.ID, n.Name())
}
if err := ep.Leave(sbox); err != nil {
if err := ep.Leave(ctx, sbox); err != nil {
return fmt.Errorf("container %s failed to leave network %s: %v", container.ID, n.Name(), err)
}
container.NetworkSettings.Ports = getPortMapInfo(sbox)
if err := ep.Delete(false); err != nil {
if err := ep.Delete(ctx, false); err != nil {
return fmt.Errorf("endpoint delete failed for container %s on network %s: %v", container.ID, n.Name(), err)
}
@@ -936,7 +946,7 @@ func (daemon *Daemon) normalizeNetMode(container *container.Container) error {
return nil
}
func (daemon *Daemon) initializeNetworking(cfg *config.Config, container *container.Container) error {
func (daemon *Daemon) initializeNetworking(ctx context.Context, cfg *config.Config, container *container.Container) error {
if container.HostConfig.NetworkMode.IsContainer() {
// we need to get the hosts files from the container to join
nc, err := daemon.getNetworkedContainer(container.ID, container.HostConfig.NetworkMode.ConnectedContainer())
@@ -962,7 +972,7 @@ func (daemon *Daemon) initializeNetworking(cfg *config.Config, container *contai
container.Config.Hostname = hn
}
if err := daemon.allocateNetwork(cfg, container); err != nil {
if err := daemon.allocateNetwork(ctx, cfg, container); err != nil {
return err
}
@@ -986,7 +996,9 @@ func (daemon *Daemon) getNetworkedContainer(containerID, connectedContainerID st
return nc, nil
}
func (daemon *Daemon) releaseNetwork(container *container.Container) {
func (daemon *Daemon) releaseNetwork(ctx context.Context, container *container.Container) {
ctx = context.WithoutCancel(ctx)
start := time.Now()
// If live-restore is enabled, the daemon cleans up dead containers when it starts up. In that case, the
// netController hasn't been initialized yet and so we can't proceed.
@@ -1023,12 +1035,12 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) {
sb, err := daemon.netController.SandboxByID(sid)
if err != nil {
log.G(context.TODO()).Warnf("error locating sandbox id %s: %v", sid, err)
log.G(ctx).Warnf("error locating sandbox id %s: %v", sid, err)
return
}
if err := sb.Delete(); err != nil {
log.G(context.TODO()).Errorf("Error deleting sandbox id %s for container %s: %v", sid, container.ID, err)
if err := sb.Delete(ctx); err != nil {
log.G(ctx).Errorf("Error deleting sandbox id %s for container %s: %v", sid, container.ID, err)
}
for _, nw := range networks {
@@ -1042,7 +1054,7 @@ func errRemovalContainer(containerID string) error {
}
// ConnectToNetwork connects a container to a network
func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
func (daemon *Daemon) ConnectToNetwork(ctx context.Context, container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
if endpointConfig == nil {
endpointConfig = &networktypes.EndpointSettings{}
}
@@ -1068,16 +1080,16 @@ func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName
epc := &network.EndpointSettings{
EndpointSettings: endpointConfig,
}
if err := daemon.connectToNetwork(&daemon.config().Config, container, idOrName, epc, true); err != nil {
if err := daemon.connectToNetwork(ctx, &daemon.config().Config, container, idOrName, epc, true); err != nil {
return err
}
}
return container.CheckpointTo(daemon.containersReplica)
return container.CheckpointTo(ctx, daemon.containersReplica)
}
// DisconnectFromNetwork disconnects container from network n.
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
func (daemon *Daemon) DisconnectFromNetwork(ctx context.Context, container *container.Container, networkName string, force bool) error {
n, err := daemon.FindNetwork(networkName)
container.Lock()
defer container.Unlock()
@@ -1100,14 +1112,14 @@ func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, netw
return runconfig.ErrConflictHostNetwork
}
if err := daemon.disconnectFromNetwork(container, n, false); err != nil {
if err := daemon.disconnectFromNetwork(ctx, container, n, false); err != nil {
return err
}
} else {
return err
}
if err := container.CheckpointTo(daemon.containersReplica); err != nil {
if err := container.CheckpointTo(ctx, daemon.containersReplica); err != nil {
return err
}