mirror of
https://gitea.com/gitea/runner.git
synced 2026-11-09 08:40:29 +00:00
fix: apply the daemon's mtu to job networks (#1270)
Copy the `mtu` of Docker's default bridge network to job networks, since Docker applies the daemon's `mtu` setting only to the default bridge. Docker's default of 1500 is not copied, so `default-network-opts` in the daemon config keeps applying. Closes https://gitea.com/gitea/runner/issues/232 --------- Co-authored-by: silverwind <[email protected]> Co-authored-by: silverwind <[email protected]> Reviewed-on: https://gitea.com/gitea/runner/pulls/1270 Reviewed-by: silverwind <[email protected]> Co-authored-by: bircni <[email protected]>
This commit is contained in:
1 parent
329115b148
commit
e5aa9add02
4 files changed
+71
-35
No files matched your search
@@ -87,45 +87,54 @@ func NewDockerNetworkCreateExecutor(name string, opts NewDockerNetworkCreateExec
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
return createDockerNetwork(ctx, cli, name, opts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only create the network if it doesn't exist
|
func createDockerNetwork(ctx context.Context, cli client.APIClient, name string, opts NewDockerNetworkCreateExecutorInput) error {
|
||||||
networks, err := cli.NetworkList(ctx, client.NetworkListOptions{})
|
// Only create the network if it doesn't exist
|
||||||
if err != nil {
|
networks, err := cli.NetworkList(ctx, client.NetworkListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var options map[string]string
|
||||||
|
// For Gitea, reduce log noise
|
||||||
|
// common.Logger(ctx).Debugf("%v", networks)
|
||||||
|
for _, n := range networks.Items {
|
||||||
|
if n.Name == name {
|
||||||
|
common.Logger(ctx).Debugf("Network %v exists", name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// the daemon's mtu only reaches its default bridge, Docker's default is left out to keep default-network-opts
|
||||||
|
if mtu := n.Options["com.docker.network.driver.mtu"]; n.Name == network.NetworkBridge && mtu != "" && mtu != "1500" {
|
||||||
|
options = map[string]string{"com.docker.network.driver.mtu": mtu}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range networkCreateAttempts {
|
||||||
|
if i > 0 {
|
||||||
|
common.Logger(ctx).Infof("Waiting for a free docker address pool to create network %s", name)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
case <-time.After(time.Duration(i) * networkCreateRetryDelay):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = cli.NetworkCreate(ctx, name, client.NetworkCreateOptions{
|
||||||
|
Driver: "bridge",
|
||||||
|
Scope: "local",
|
||||||
|
EnableIPv4: opts.EnableIPv4,
|
||||||
|
EnableIPv6: opts.EnableIPv6,
|
||||||
|
Options: options,
|
||||||
|
Labels: runnerLabels(opts.RunnerUUID),
|
||||||
|
}); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !isAddressPoolExhausted(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// For Gitea, reduce log noise
|
|
||||||
// common.Logger(ctx).Debugf("%v", networks)
|
|
||||||
for _, n := range networks.Items {
|
|
||||||
if n.Name == name {
|
|
||||||
common.Logger(ctx).Debugf("Network %v exists", name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range networkCreateAttempts {
|
|
||||||
if i > 0 {
|
|
||||||
common.Logger(ctx).Infof("Waiting for a free docker address pool to create network %s", name)
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
case <-time.After(time.Duration(i) * networkCreateRetryDelay):
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, err = cli.NetworkCreate(ctx, name, client.NetworkCreateOptions{
|
|
||||||
Driver: "bridge",
|
|
||||||
Scope: "local",
|
|
||||||
EnableIPv4: opts.EnableIPv4,
|
|
||||||
EnableIPv6: opts.EnableIPv6,
|
|
||||||
Labels: runnerLabels(opts.RunnerUUID),
|
|
||||||
}); err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if !isAddressPoolExhausted(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("docker has no address pool left for this job's network, lower runner.capacity or widen default-address-pools in the docker daemon config: %w", err)
|
|
||||||
}
|
}
|
||||||
|
return fmt.Errorf("docker has no address pool left for this job's network, lower runner.capacity or widen default-address-pools in the docker daemon config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runnerLabels(runnerUUID string) map[string]string {
|
func runnerLabels(runnerUUID string) map[string]string {
|
||||||
|
|||||||
@@ -57,6 +57,27 @@ func TestIsAddressPoolExhausted(t *testing.T) {
|
|||||||
assert.False(t, isAddressPoolExhausted(cerrdefs.ErrInvalidArgument.WithMessage("invalid subnet 10.0.0.0/8: it overlaps with an existing network")))
|
assert.False(t, isAddressPoolExhausted(cerrdefs.ErrInvalidArgument.WithMessage("invalid subnet 10.0.0.0/8: it overlaps with an existing network")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateDockerNetworkInheritsDaemonMTU(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
for _, tc := range []struct {
|
||||||
|
bridgeOptions, want map[string]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
map[string]string{"com.docker.network.bridge.host_binding_ipv4": "127.0.0.1", "com.docker.network.driver.mtu": "1450"},
|
||||||
|
map[string]string{"com.docker.network.driver.mtu": "1450"},
|
||||||
|
},
|
||||||
|
{map[string]string{"com.docker.network.driver.mtu": "1500"}, nil},
|
||||||
|
} {
|
||||||
|
client := &mockDockerClient{}
|
||||||
|
client.On("NetworkList", ctx, mobyclient.NetworkListOptions{}).
|
||||||
|
Return(mobyclient.NetworkListResult{Items: []network.Summary{{Name: network.NetworkBridge, Options: tc.bridgeOptions}}}, nil)
|
||||||
|
client.On("NetworkCreate", ctx, "job-network", mobyclient.NetworkCreateOptions{Driver: "bridge", Scope: "local", Options: tc.want}).
|
||||||
|
Return(mobyclient.NetworkCreateResult{}, nil)
|
||||||
|
require.NoError(t, createDockerNetwork(ctx, client, "job-network", NewDockerNetworkCreateExecutorInput{}))
|
||||||
|
client.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockDockerClient) NetworkConnect(ctx context.Context, id string, opts mobyclient.NetworkConnectOptions) (mobyclient.NetworkConnectResult, error) {
|
func (m *mockDockerClient) NetworkConnect(ctx context.Context, id string, opts mobyclient.NetworkConnectOptions) (mobyclient.NetworkConnectResult, error) {
|
||||||
return mobyclient.NetworkConnectResult{}, m.Called(ctx, id, opts).Error(0)
|
return mobyclient.NetworkConnectResult{}, m.Called(ctx, id, opts).Error(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,6 +137,11 @@ func (m *mockDockerClient) NetworkList(ctx context.Context, opts mobyclient.Netw
|
|||||||
return args.Get(0).(mobyclient.NetworkListResult), args.Error(1)
|
return args.Get(0).(mobyclient.NetworkListResult), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockDockerClient) NetworkCreate(ctx context.Context, name string, opts mobyclient.NetworkCreateOptions) (mobyclient.NetworkCreateResult, error) {
|
||||||
|
args := m.Called(ctx, name, opts)
|
||||||
|
return args.Get(0).(mobyclient.NetworkCreateResult), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockDockerClient) NetworkInspect(ctx context.Context, id string, opts mobyclient.NetworkInspectOptions) (mobyclient.NetworkInspectResult, error) {
|
func (m *mockDockerClient) NetworkInspect(ctx context.Context, id string, opts mobyclient.NetworkInspectOptions) (mobyclient.NetworkInspectResult, error) {
|
||||||
args := m.Called(ctx, id, opts)
|
args := m.Called(ctx, id, opts)
|
||||||
return args.Get(0).(mobyclient.NetworkInspectResult), args.Error(1)
|
return args.Get(0).(mobyclient.NetworkInspectResult), args.Error(1)
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ container:
|
|||||||
# created by the runner. Omit the entire block to use Docker's defaults. An auto-created
|
# created by the runner. Omit the entire block to use Docker's defaults. An auto-created
|
||||||
# network is labelled com.gitea.runner.uuid=<this runner's uuid>, which is how the idle
|
# network is labelled com.gitea.runner.uuid=<this runner's uuid>, which is how the idle
|
||||||
# cleanup tells its own leftovers apart from those of other runners on the same daemon.
|
# cleanup tells its own leftovers apart from those of other runners on the same daemon.
|
||||||
|
# It also takes the `mtu` set in the Docker daemon config.
|
||||||
#network_create_options:
|
#network_create_options:
|
||||||
# enable_ipv4: true # Omit to use Docker's default (IPv4 enabled). Set false to disable IPv4.
|
# enable_ipv4: true # Omit to use Docker's default (IPv4 enabled). Set false to disable IPv4.
|
||||||
# enable_ipv6: false # Omit to use Docker's default (IPv6 disabled). Enabling it requires dockerd started with --ipv6.
|
# enable_ipv6: false # Omit to use Docker's default (IPv6 disabled). Enabling it requires dockerd started with --ipv6.
|
||||||
|
|||||||
Reference in new issue
Block a user