@@ -19,9 +19,7 @@ package docker
19
19
import (
20
20
"context"
21
21
"fmt"
22
- "net"
23
22
24
- "github.com/pkg/errors"
25
23
ctrl "sigs.k8s.io/controller-runtime"
26
24
"sigs.k8s.io/kind/pkg/apis/config/v1alpha4"
27
25
"sigs.k8s.io/kind/pkg/cluster/constants"
@@ -55,16 +53,9 @@ type nodeCreateOpts struct {
55
53
}
56
54
57
55
// CreateControlPlaneNode will create a new control plane container.
56
+ // NOTE: If port is 0 picking a host port for the control plane is delegated to the container runtime and is not stable across container restarts.
57
+ // This means that connection to a control plane node may take some time to recover if the underlying container is restarted.
58
58
func (m * Manager ) CreateControlPlaneNode (ctx context.Context , name , image , clusterName , listenAddress string , port int32 , mounts []v1alpha4.Mount , portMappings []v1alpha4.PortMapping , labels map [string ]string , ipFamily clusterv1.ClusterIPFamily ) (* types.Node , error ) {
59
- // gets a random host port for the API server
60
- if port == 0 {
61
- p , err := getPort ()
62
- if err != nil {
63
- return nil , errors .Wrap (err , "failed to get port for API server" )
64
- }
65
- port = p
66
- }
67
-
68
59
// add api server port mapping
69
60
portMappingsWithAPIServer := append (portMappings , v1alpha4.PortMapping {
70
61
ListenAddress : listenAddress ,
@@ -106,17 +97,9 @@ func (m *Manager) CreateWorkerNode(ctx context.Context, name, image, clusterName
106
97
}
107
98
108
99
// CreateExternalLoadBalancerNode will create a new container to act as the load balancer for external access.
100
+ // NOTE: If port is 0 picking a host port for the load balancer is delegated to the container runtime and is not stable across container restarts.
101
+ // This can break the Kubeconfig in kind, i.e. the file resulting from `kind get kubeconfig -n $CLUSTER_NAME' if the load balancer container is restarted.
109
102
func (m * Manager ) CreateExternalLoadBalancerNode (ctx context.Context , name , image , clusterName , listenAddress string , port int32 , _ clusterv1.ClusterIPFamily ) (* types.Node , error ) {
110
- // gets a random host port for control-plane load balancer
111
- // gets a random host port for the API server
112
- if port == 0 {
113
- p , err := getPort ()
114
- if err != nil {
115
- return nil , errors .Wrap (err , "failed to get port for API server" )
116
- }
117
- port = p
118
- }
119
-
120
103
// load balancer port mapping
121
104
portMappings := []v1alpha4.PortMapping {{
122
105
ListenAddress : listenAddress ,
@@ -191,19 +174,6 @@ func createNode(ctx context.Context, opts *nodeCreateOpts) (*types.Node, error)
191
174
return types .NewNode (opts .Name , opts .Image , opts .Role ), nil
192
175
}
193
176
194
- // helper used to get a free TCP port for the API server.
195
- func getPort () (int32 , error ) {
196
- listener , err := net .Listen ("tcp" , ":0" ) //nolint:gosec
197
- if err != nil {
198
- return 0 , err
199
- }
200
- port := listener .Addr ().(* net.TCPAddr ).Port
201
- if err := listener .Close (); err != nil {
202
- return 0 , err
203
- }
204
- return int32 (port ), nil
205
- }
206
-
207
177
func generateMountInfo (mounts []v1alpha4.Mount ) []container.Mount {
208
178
mountInfo := []container.Mount {}
209
179
for _ , mount := range mounts {
0 commit comments