Skip to content

Commit 5a7f7c2

Browse files
committed
kubernetes: trim client-go dependency surface
Replace the full generated clientset and global Kubernetes scheme with a small local REST client layer and minimal scheme registration. This keeps the existing kubeconfig/auth and remote exec behavior while significantly reducing the linked and vendored Kubernetes dependency set. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
1 parent bb48188 commit 5a7f7c2

1,913 files changed

Lines changed: 215 additions & 551638 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

driver/kubernetes/driver.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/docker/buildx/driver"
1313
"github.com/docker/buildx/driver/kubernetes/execconn"
14+
"github.com/docker/buildx/driver/kubernetes/kubeclient"
1415
"github.com/docker/buildx/driver/kubernetes/manifest"
1516
"github.com/docker/buildx/driver/kubernetes/podchooser"
1617
"github.com/docker/buildx/store"
@@ -24,9 +25,6 @@ import (
2425
corev1 "k8s.io/api/core/v1"
2526
apierrors "k8s.io/apimachinery/pkg/api/errors"
2627
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27-
"k8s.io/client-go/kubernetes"
28-
clientappsv1 "k8s.io/client-go/kubernetes/typed/apps/v1"
29-
clientcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
3028
)
3129

3230
const (
@@ -49,10 +47,9 @@ type Driver struct {
4947
minReplicas int
5048
deployment *appsv1.Deployment
5149
configMaps []*corev1.ConfigMap
52-
clientset *kubernetes.Clientset
53-
deploymentClient clientappsv1.DeploymentInterface
54-
podClient clientcorev1.PodInterface
55-
configMapClient clientcorev1.ConfigMapInterface
50+
deploymentClient kubeclient.DeploymentClient
51+
podClient kubeclient.PodClient
52+
configMapClient kubeclient.ConfigMapClient
5653
podChooser podchooser.PodChooser
5754
defaultLoad bool
5855
timeout time.Duration
@@ -201,7 +198,6 @@ func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error {
201198
}
202199

203200
func (d *Driver) Dial(ctx context.Context) (net.Conn, error) {
204-
restClient := d.clientset.CoreV1().RESTClient()
205201
restClientConfig, err := d.clientConfig.ClientConfig()
206202
if err != nil {
207203
return nil, err
@@ -221,7 +217,7 @@ func (d *Driver) Dial(ctx context.Context) (net.Conn, error) {
221217
var conn net.Conn
222218
err = tryWithBackoff(ctx, pod.Name, func() error {
223219
var err error
224-
conn, err = execconn.ExecConn(ctx, restClient, restClientConfig, pod.Namespace, pod.Name, containerName, cmd)
220+
conn, err = execconn.ExecConn(ctx, d.podClient.RESTClient(), restClientConfig, pod.Namespace, pod.Name, containerName, cmd)
225221
return err
226222
})
227223
return conn, err

driver/kubernetes/execconn/execconn.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
"sync"
99
"time"
1010

11+
"github.com/docker/buildx/driver/kubernetes/kubeclient"
1112
"github.com/sirupsen/logrus"
1213
corev1 "k8s.io/api/core/v1"
13-
"k8s.io/client-go/kubernetes/scheme"
1414
"k8s.io/client-go/rest"
1515
"k8s.io/client-go/tools/remotecommand"
1616
)
@@ -29,7 +29,7 @@ func ExecConn(ctx context.Context, restClient rest.Interface, restConfig *rest.C
2929
Stdout: true,
3030
Stderr: true,
3131
TTY: false,
32-
}, scheme.ParameterCodec)
32+
}, kubeclient.ParameterCodec)
3333
exec, err := remotecommand.NewSPDYExecutor(restConfig, "POST", req.URL())
3434
if err != nil {
3535
return nil, err

driver/kubernetes/factory.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import (
1010
"github.com/docker/buildx/driver"
1111
"github.com/docker/buildx/driver/bkimage"
1212
ctxkube "github.com/docker/buildx/driver/kubernetes/context"
13+
"github.com/docker/buildx/driver/kubernetes/kubeclient"
1314
"github.com/docker/buildx/driver/kubernetes/manifest"
1415
"github.com/docker/buildx/driver/kubernetes/podchooser"
1516
dockerclient "github.com/moby/moby/client"
1617
"github.com/pkg/errors"
1718
"github.com/sirupsen/logrus"
1819
corev1 "k8s.io/api/core/v1"
19-
"k8s.io/client-go/kubernetes"
2020
"k8s.io/client-go/rest"
2121
)
2222

@@ -116,16 +116,11 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
116116
if err != nil {
117117
return nil, err
118118
}
119-
clientset, err := kubernetes.NewForConfig(restClientConfig)
120-
if err != nil {
121-
return nil, err
122-
}
123119

124120
d := &Driver{
125121
factory: f,
126122
clientConfig: cc,
127123
InitConfig: cfg,
128-
clientset: clientset,
129124
}
130125

131126
deploymentOpt, loadbalance, namespace, defaultLoad, timeout, err := f.processDriverOpts(deploymentName, namespace, cfg)
@@ -143,9 +138,13 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
143138

144139
d.minReplicas = int(deploymentOpt.Replicas)
145140

146-
d.deploymentClient = clientset.AppsV1().Deployments(namespace)
147-
d.podClient = clientset.CoreV1().Pods(namespace)
148-
d.configMapClient = clientset.CoreV1().ConfigMaps(namespace)
141+
clients, err := kubeclient.New(restClientConfig, namespace)
142+
if err != nil {
143+
return nil, err
144+
}
145+
d.deploymentClient = clients.Deployments
146+
d.podClient = clients.Pods
147+
d.configMapClient = clients.ConfigMaps
149148

150149
switch loadbalance {
151150
case LoadbalanceSticky:
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package kubeclient
2+
3+
import (
4+
"context"
5+
"net/http"
6+
7+
appsv1 "k8s.io/api/apps/v1"
8+
corev1 "k8s.io/api/core/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/runtime/schema"
11+
"k8s.io/client-go/rest"
12+
)
13+
14+
type DeploymentClient interface {
15+
Get(ctx context.Context, name string, opts metav1.GetOptions) (*appsv1.Deployment, error)
16+
Create(ctx context.Context, deployment *appsv1.Deployment, opts metav1.CreateOptions) (*appsv1.Deployment, error)
17+
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
18+
}
19+
20+
type ConfigMapClient interface {
21+
Create(ctx context.Context, configMap *corev1.ConfigMap, opts metav1.CreateOptions) (*corev1.ConfigMap, error)
22+
Update(ctx context.Context, configMap *corev1.ConfigMap, opts metav1.UpdateOptions) (*corev1.ConfigMap, error)
23+
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
24+
}
25+
26+
type PodClient interface {
27+
List(ctx context.Context, opts metav1.ListOptions) (*corev1.PodList, error)
28+
RESTClient() rest.Interface
29+
}
30+
31+
type Clients struct {
32+
Deployments DeploymentClient
33+
ConfigMaps ConfigMapClient
34+
Pods PodClient
35+
}
36+
37+
func New(config *rest.Config, namespace string) (*Clients, error) {
38+
httpClient, err := rest.HTTPClientFor(config)
39+
if err != nil {
40+
return nil, err
41+
}
42+
43+
appsClient, err := newRESTClient(config, httpClient, appsv1.SchemeGroupVersion, "/apis")
44+
if err != nil {
45+
return nil, err
46+
}
47+
48+
coreClient, err := newRESTClient(config, httpClient, corev1.SchemeGroupVersion, "/api")
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
return &Clients{
54+
Deployments: &deploymentClient{client: appsClient, namespace: namespace},
55+
ConfigMaps: &configMapClient{client: coreClient, namespace: namespace},
56+
Pods: &podClient{client: coreClient, namespace: namespace},
57+
}, nil
58+
}
59+
60+
func newRESTClient(config *rest.Config, httpClient *http.Client, gv schema.GroupVersion, apiPath string) (rest.Interface, error) {
61+
cfg := *config
62+
cfg.GroupVersion = &gv
63+
cfg.APIPath = apiPath
64+
cfg.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(Scheme, Codecs).WithoutConversion()
65+
if cfg.UserAgent == "" {
66+
cfg.UserAgent = rest.DefaultKubernetesUserAgent()
67+
}
68+
return rest.RESTClientForConfigAndClient(&cfg, httpClient)
69+
}
70+
71+
type deploymentClient struct {
72+
client rest.Interface
73+
namespace string
74+
}
75+
76+
func (c *deploymentClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*appsv1.Deployment, error) {
77+
result := &appsv1.Deployment{}
78+
err := c.client.Get().
79+
UseProtobufAsDefault().
80+
Namespace(c.namespace).
81+
Resource("deployments").
82+
Name(name).
83+
VersionedParams(&opts, ParameterCodec).
84+
Do(ctx).
85+
Into(result)
86+
return result, err
87+
}
88+
89+
func (c *deploymentClient) Create(ctx context.Context, deployment *appsv1.Deployment, opts metav1.CreateOptions) (*appsv1.Deployment, error) {
90+
result := &appsv1.Deployment{}
91+
err := c.client.Post().
92+
UseProtobufAsDefault().
93+
Namespace(c.namespace).
94+
Resource("deployments").
95+
VersionedParams(&opts, ParameterCodec).
96+
Body(deployment).
97+
Do(ctx).
98+
Into(result)
99+
return result, err
100+
}
101+
102+
func (c *deploymentClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
103+
return c.client.Delete().
104+
UseProtobufAsDefault().
105+
Namespace(c.namespace).
106+
Resource("deployments").
107+
Name(name).
108+
Body(&opts).
109+
Do(ctx).
110+
Error()
111+
}
112+
113+
type configMapClient struct {
114+
client rest.Interface
115+
namespace string
116+
}
117+
118+
func (c *configMapClient) Create(ctx context.Context, configMap *corev1.ConfigMap, opts metav1.CreateOptions) (*corev1.ConfigMap, error) {
119+
result := &corev1.ConfigMap{}
120+
err := c.client.Post().
121+
UseProtobufAsDefault().
122+
Namespace(c.namespace).
123+
Resource("configmaps").
124+
VersionedParams(&opts, ParameterCodec).
125+
Body(configMap).
126+
Do(ctx).
127+
Into(result)
128+
return result, err
129+
}
130+
131+
func (c *configMapClient) Update(ctx context.Context, configMap *corev1.ConfigMap, opts metav1.UpdateOptions) (*corev1.ConfigMap, error) {
132+
result := &corev1.ConfigMap{}
133+
err := c.client.Put().
134+
UseProtobufAsDefault().
135+
Namespace(c.namespace).
136+
Resource("configmaps").
137+
Name(configMap.Name).
138+
VersionedParams(&opts, ParameterCodec).
139+
Body(configMap).
140+
Do(ctx).
141+
Into(result)
142+
return result, err
143+
}
144+
145+
func (c *configMapClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
146+
return c.client.Delete().
147+
UseProtobufAsDefault().
148+
Namespace(c.namespace).
149+
Resource("configmaps").
150+
Name(name).
151+
Body(&opts).
152+
Do(ctx).
153+
Error()
154+
}
155+
156+
type podClient struct {
157+
client rest.Interface
158+
namespace string
159+
}
160+
161+
func (c *podClient) List(ctx context.Context, opts metav1.ListOptions) (*corev1.PodList, error) {
162+
result := &corev1.PodList{}
163+
err := c.client.Get().
164+
UseProtobufAsDefault().
165+
Namespace(c.namespace).
166+
Resource("pods").
167+
VersionedParams(&opts, ParameterCodec).
168+
Do(ctx).
169+
Into(result)
170+
return result, err
171+
}
172+
173+
func (c *podClient) RESTClient() rest.Interface {
174+
return c.client
175+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package kubeclient
2+
3+
import (
4+
appsv1 "k8s.io/api/apps/v1"
5+
corev1 "k8s.io/api/core/v1"
6+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
"k8s.io/apimachinery/pkg/runtime"
8+
"k8s.io/apimachinery/pkg/runtime/schema"
9+
"k8s.io/apimachinery/pkg/runtime/serializer"
10+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
11+
)
12+
13+
var Scheme = runtime.NewScheme()
14+
var Codecs = serializer.NewCodecFactory(Scheme)
15+
var ParameterCodec = runtime.NewParameterCodec(Scheme)
16+
17+
func init() {
18+
metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
19+
utilruntime.Must(corev1.AddToScheme(Scheme))
20+
utilruntime.Must(appsv1.AddToScheme(Scheme))
21+
}

driver/kubernetes/podchooser/podchooser.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import (
66
"sort"
77
"time"
88

9+
"github.com/docker/buildx/driver/kubernetes/kubeclient"
910
"github.com/pkg/errors"
1011
"github.com/serialx/hashring"
1112
"github.com/sirupsen/logrus"
1213
appsv1 "k8s.io/api/apps/v1"
1314
corev1 "k8s.io/api/core/v1"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15-
clientcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
1616
)
1717

1818
type PodChooser interface {
@@ -21,7 +21,7 @@ type PodChooser interface {
2121

2222
type RandomPodChooser struct {
2323
RandSource rand.Source
24-
PodClient clientcorev1.PodInterface
24+
PodClient kubeclient.PodClient
2525
Deployment *appsv1.Deployment
2626
}
2727

@@ -45,7 +45,7 @@ func (pc *RandomPodChooser) ChoosePod(ctx context.Context) (*corev1.Pod, error)
4545

4646
type StickyPodChooser struct {
4747
Key string
48-
PodClient clientcorev1.PodInterface
48+
PodClient kubeclient.PodClient
4949
Deployment *appsv1.Deployment
5050
}
5151

@@ -74,7 +74,7 @@ func (pc *StickyPodChooser) ChoosePod(ctx context.Context) (*corev1.Pod, error)
7474
return podMap[chosen], nil
7575
}
7676

77-
func ListRunningPods(ctx context.Context, client clientcorev1.PodInterface, depl *appsv1.Deployment) ([]*corev1.Pod, error) {
77+
func ListRunningPods(ctx context.Context, client kubeclient.PodClient, depl *appsv1.Deployment) ([]*corev1.Pod, error) {
7878
selector, err := metav1.LabelSelectorAsSelector(depl.Spec.Selector)
7979
if err != nil {
8080
return nil, err

go.mod

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ require (
113113
github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect
114114
github.com/docker/docker-credential-helpers v0.9.5 // indirect
115115
github.com/docker/go-connections v0.6.0 // indirect
116-
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
117116
github.com/felixge/httpsnoop v1.0.4 // indirect
118117
github.com/fvbommel/sortorder v1.1.0 // indirect
119118
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
@@ -147,7 +146,6 @@ require (
147146
github.com/gogo/protobuf v1.3.2 // indirect
148147
github.com/golang/protobuf v1.5.4 // indirect
149148
github.com/google/certificate-transparency-go v1.3.2 // indirect
150-
github.com/google/gnostic-models v0.7.0 // indirect
151149
github.com/google/go-cmp v0.7.0 // indirect
152150
github.com/google/go-containerregistry v0.20.7 // indirect
153151
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
@@ -232,11 +230,9 @@ require (
232230
golang.org/x/time v0.14.0 // indirect
233231
golang.org/x/tools v0.41.0 // indirect
234232
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
235-
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
236233
gopkg.in/inf.v0 v0.9.1 // indirect
237234
gopkg.in/yaml.v3 v3.0.1 // indirect
238235
k8s.io/klog/v2 v2.130.1 // indirect
239-
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
240236
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
241237
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
242238
sigs.k8s.io/randfill v1.0.0 // indirect

0 commit comments

Comments
 (0)