Skip to content

Commit 8bce430

Browse files
authored
Merge pull request #167 from AkihiroSuda/kube
new driver: kubernetes
2 parents f5c2673 + c6f8de9 commit 8bce430

File tree

659 files changed

+258714
-368
lines changed

Some content is hidden

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

659 files changed

+258714
-368
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ _buildx is Tech Preview_
1111
- Multi-node builds for cross-platform images
1212
- Compose build support
1313
- WIP: High-level build constructs (`bake`)
14-
- TODO: In-container driver support
14+
- In-container driver support (both Docker and Kubernetes)
1515

1616
# Table of Contents
1717

@@ -394,12 +394,18 @@ Passes additional driver-specific options. Details for each driver:
394394
395395
- `docker` - No driver options
396396
- `docker-container`
397-
- `image` - Sets the container image to be used for running buildkit.
398-
- `network` - Sets the network mode for running the buildkit container.
397+
- `image=IMAGE` - Sets the container image to be used for running buildkit.
398+
- `network=NETMODE` - Sets the network mode for running the buildkit container.
399399
- Example:
400400
```
401401
--driver docker-container --driver-opt image=moby/buildkit:master,network=host
402402
```
403+
- `kubernetes`
404+
- `image=IMAGE` - Sets the container image to be used for running buildkit.
405+
- `namespace=NS` - Sets the Kubernetes namespace. Defaults to the current namespace.
406+
- `replicas=N` - Sets the number of `Pod` replicas. Defaults to 1.
407+
- `rootless=(true|false)` - Run the container as a non-root user without `securityContext.privileged`. [Using Ubuntu host kernel is recommended](https://github.com/moby/buildkit/blob/master/docs/rootless.md). Defaults to false.
408+
- `loadbalance=(sticky|random)` - Load-balancing strategy. If set to "sticky", the pod is chosen using the hash of the context path. Defaults to "sticky"
403409
404410
#### `--leave`
405411

cmd/buildx/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@ import (
1212
cliflags "github.com/docker/cli/cli/flags"
1313
"github.com/spf13/cobra"
1414

15+
// FIXME: "k8s.io/client-go/plugin/pkg/client/auth/azure" is excluded because of compilation error
16+
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
17+
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
18+
_ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
19+
1520
_ "github.com/docker/buildx/driver/docker"
1621
_ "github.com/docker/buildx/driver/docker-container"
22+
_ "github.com/docker/buildx/driver/kubernetes"
1723
)
1824

1925
var experimental string

commands/bake.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) error {
5656
return err
5757
}
5858

59-
return buildTargets(ctx, dockerCli, bo, in.progress)
59+
contextPathHash, _ := os.Getwd()
60+
61+
return buildTargets(ctx, dockerCli, bo, in.progress, contextPathHash)
6062
}
6163

6264
func defaultFiles() ([]string, error) {

commands/build.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package commands
33
import (
44
"context"
55
"os"
6+
"path/filepath"
67
"strings"
78

89
"github.com/docker/buildx/build"
@@ -175,11 +176,17 @@ func runBuild(dockerCli command.Cli, in buildOptions) error {
175176
}
176177
opts.Allow = allow
177178

178-
return buildTargets(ctx, dockerCli, map[string]build.Options{"default": opts}, in.progress)
179+
// key string used for kubernetes "sticky" mode
180+
contextPathHash, err := filepath.Abs(in.contextPath)
181+
if err != nil {
182+
contextPathHash = in.contextPath
183+
}
184+
185+
return buildTargets(ctx, dockerCli, map[string]build.Options{"default": opts}, in.progress, contextPathHash)
179186
}
180187

181-
func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode string) error {
182-
dis, err := getDefaultDrivers(ctx, dockerCli)
188+
func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode, contextPathHash string) error {
189+
dis, err := getDefaultDrivers(ctx, dockerCli, contextPathHash)
183190
if err != nil {
184191
return err
185192
}

commands/rm.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func rmCmd(dockerCli command.Cli) *cobra.Command {
6565
}
6666

6767
func stop(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, rm bool) error {
68-
dis, err := driversForNodeGroup(ctx, dockerCli, ng)
68+
dis, err := driversForNodeGroup(ctx, dockerCli, ng, "")
6969
if err != nil {
7070
return err
7171
}
@@ -88,7 +88,7 @@ func stop(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, rm bo
8888
}
8989

9090
func stopCurrent(ctx context.Context, dockerCli command.Cli, rm bool) error {
91-
dis, err := getDefaultDrivers(ctx, dockerCli)
91+
dis, err := getDefaultDrivers(ctx, dockerCli, "")
9292
if err != nil {
9393
return err
9494
}

commands/util.go

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import (
1111
"github.com/docker/buildx/util/platformutil"
1212
"github.com/docker/cli/cli/command"
1313
"github.com/docker/cli/cli/context/docker"
14+
"github.com/docker/cli/cli/context/kubernetes"
1415
dopts "github.com/docker/cli/opts"
1516
dockerclient "github.com/docker/docker/client"
1617
"github.com/pkg/errors"
18+
"github.com/sirupsen/logrus"
1719
"golang.org/x/sync/errgroup"
1820
)
1921

@@ -133,7 +135,7 @@ func getNodeGroup(txn *store.Txn, dockerCli command.Cli, name string) (*store.No
133135
}
134136

135137
// driversForNodeGroup returns drivers for a nodegroup instance
136-
func driversForNodeGroup(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup) ([]build.DriverInfo, error) {
138+
func driversForNodeGroup(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, contextPathHash string) ([]build.DriverInfo, error) {
137139
eg, _ := errgroup.WithContext(ctx)
138140

139141
dis := make([]build.DriverInfo, len(ng.Nodes))
@@ -174,7 +176,18 @@ func driversForNodeGroup(ctx context.Context, dockerCli command.Cli, ng *store.N
174176
// TODO: replace the following line with dockerclient.WithAPIVersionNegotiation option in clientForEndpoint
175177
dockerapi.NegotiateAPIVersion(ctx)
176178

177-
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi, n.Flags, n.ConfigFile, n.DriverOpts)
179+
contextStore := dockerCli.ContextStore()
180+
kcc, err := kubernetes.ConfigFromContext(n.Endpoint, contextStore)
181+
if err != nil {
182+
// err is returned if n.Endpoint is non-context name like "unix:///var/run/docker.sock".
183+
// try again with name="default".
184+
// FIXME: n should retain real context name.
185+
kcc, err = kubernetes.ConfigFromContext("default", contextStore)
186+
if err != nil {
187+
logrus.Error(err)
188+
}
189+
}
190+
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi, kcc, n.Flags, n.ConfigFile, n.DriverOpts, contextPathHash)
178191
if err != nil {
179192
di.Err = err
180193
return nil
@@ -235,7 +248,7 @@ func clientForEndpoint(dockerCli command.Cli, name string) (dockerclient.APIClie
235248
}
236249

237250
// getDefaultDrivers returns drivers based on current cli config
238-
func getDefaultDrivers(ctx context.Context, dockerCli command.Cli) ([]build.DriverInfo, error) {
251+
func getDefaultDrivers(ctx context.Context, dockerCli command.Cli, contextPathHash string) ([]build.DriverInfo, error) {
239252
txn, release, err := getStore(dockerCli)
240253
if err != nil {
241254
return nil, err
@@ -248,10 +261,10 @@ func getDefaultDrivers(ctx context.Context, dockerCli command.Cli) ([]build.Driv
248261
}
249262

250263
if ng != nil {
251-
return driversForNodeGroup(ctx, dockerCli, ng)
264+
return driversForNodeGroup(ctx, dockerCli, ng, contextPathHash)
252265
}
253266

254-
d, err := driver.GetDriver(ctx, "buildx_buildkit_default", nil, dockerCli.Client(), nil, "", nil)
267+
d, err := driver.GetDriver(ctx, "buildx_buildkit_default", nil, dockerCli.Client(), nil, nil, "", nil, contextPathHash)
255268
if err != nil {
256269
return nil, err
257270
}
@@ -294,7 +307,7 @@ func loadInfoData(ctx context.Context, d *dinfo) error {
294307
func loadNodeGroupData(ctx context.Context, dockerCli command.Cli, ngi *nginfo) error {
295308
eg, _ := errgroup.WithContext(ctx)
296309

297-
dis, err := driversForNodeGroup(ctx, dockerCli, ngi.ng)
310+
dis, err := driversForNodeGroup(ctx, dockerCli, ngi.ng, "")
298311
if err != nil {
299312
return err
300313
}
@@ -312,7 +325,30 @@ func loadNodeGroupData(ctx context.Context, dockerCli command.Cli, ngi *nginfo)
312325
}(&ngi.drivers[i])
313326
}
314327

315-
return eg.Wait()
328+
if eg.Wait(); err != nil {
329+
return err
330+
}
331+
for _, di := range ngi.drivers {
332+
// dynamic nodes are used in Kubernetes driver.
333+
// Kubernetes pods are dynamically mapped to BuildKit Nodes.
334+
if di.info != nil && len(di.info.DynamicNodes) > 0 {
335+
var drivers []dinfo
336+
for i := 0; i < len(di.info.DynamicNodes); i++ {
337+
// all []dinfo share *build.DriverInfo and *driver.Info
338+
diClone := di
339+
if pl := di.info.DynamicNodes[i].Platforms; len(pl) > 0 {
340+
diClone.platforms = pl
341+
}
342+
drivers = append(drivers, di)
343+
}
344+
// not append (remove the static nodes in the store)
345+
ngi.ng.Nodes = di.info.DynamicNodes
346+
ngi.ng.Dynamic = true
347+
ngi.drivers = drivers
348+
return nil
349+
}
350+
}
351+
return nil
316352
}
317353

318354
func dockerAPI(dockerCli command.Cli) *api {

driver/bkimage/bkimage.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package bkimage
2+
3+
const (
4+
DefaultImage = "moby/buildkit:buildx-stable-1" // TODO: make this verified
5+
DefaultRootlessImage = "moby/buildkit:v0.6.2-rootless"
6+
)

driver/docker-container/driver.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/docker/buildx/driver"
14+
"github.com/docker/buildx/driver/bkimage"
1415
"github.com/docker/buildx/util/progress"
1516
"github.com/docker/docker/api/types"
1617
dockertypes "github.com/docker/docker/api/types"
@@ -22,8 +23,6 @@ import (
2223
"github.com/pkg/errors"
2324
)
2425

25-
var defaultBuildkitImage = "moby/buildkit:buildx-stable-1" // TODO: make this verified
26-
2726
type Driver struct {
2827
driver.InitConfig
2928
factory driver.Factory
@@ -54,7 +53,7 @@ func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
5453
}
5554

5655
func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
57-
imageName := defaultBuildkitImage
56+
imageName := bkimage.DefaultImage
5857
if d.image != "" {
5958
imageName = d.image
6059
}

driver/driver.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package driver
33
import (
44
"context"
55

6+
"github.com/docker/buildx/store"
67
"github.com/docker/buildx/util/progress"
78
"github.com/moby/buildkit/client"
89
"github.com/pkg/errors"
@@ -39,6 +40,8 @@ func (s Status) String() string {
3940

4041
type Info struct {
4142
Status Status
43+
// DynamicNodes must be empty if the actual nodes are statically listed in the store
44+
DynamicNodes []store.Node
4245
}
4346

4447
type Driver interface {

0 commit comments

Comments
 (0)