Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new driver: kubernetes #167

Merged
merged 2 commits into from
Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ _buildx is Tech Preview_
- Multi-node builds for cross-platform images
- Compose build support
- WIP: High-level build constructs (`bake`)
- TODO: In-container driver support
- In-container driver support (both Docker and Kubernetes)

# Table of Contents

Expand Down Expand Up @@ -394,12 +394,18 @@ Passes additional driver-specific options. Details for each driver:

- `docker` - No driver options
- `docker-container`
- `image` - Sets the container image to be used for running buildkit.
- `network` - Sets the network mode for running the buildkit container.
- `image=IMAGE` - Sets the container image to be used for running buildkit.
- `network=NETMODE` - Sets the network mode for running the buildkit container.
- Example:
```
--driver docker-container --driver-opt image=moby/buildkit:master,network=host
```
- `kubernetes`
- `image=IMAGE` - Sets the container image to be used for running buildkit.
- `namespace=NS` - Sets the Kubernetes namespace. Defaults to the current namespace.
- `replicas=N` - Sets the number of `Pod` replicas. Defaults to 1.
- `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.
- `loadbalance=(sticky|random)` - Load-balancing strategy. If set to "sticky", the pod is chosen using the hash of the context path. Defaults to "sticky"

#### `--leave`

Expand Down
6 changes: 6 additions & 0 deletions cmd/buildx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ import (
cliflags "github.com/docker/cli/cli/flags"
"github.com/spf13/cobra"

// FIXME: "k8s.io/client-go/plugin/pkg/client/auth/azure" is excluded because of compilation error
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
_ "k8s.io/client-go/plugin/pkg/client/auth/openstack"

_ "github.com/docker/buildx/driver/docker"
_ "github.com/docker/buildx/driver/docker-container"
_ "github.com/docker/buildx/driver/kubernetes"
)

var experimental string
Expand Down
4 changes: 3 additions & 1 deletion commands/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) error {
return err
}

return buildTargets(ctx, dockerCli, bo, in.progress)
contextPathHash, _ := os.Getwd()

return buildTargets(ctx, dockerCli, bo, in.progress, contextPathHash)
}

func defaultFiles() ([]string, error) {
Expand Down
13 changes: 10 additions & 3 deletions commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"context"
"os"
"path/filepath"
"strings"

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

return buildTargets(ctx, dockerCli, map[string]build.Options{"default": opts}, in.progress)
// key string used for kubernetes "sticky" mode
contextPathHash, err := filepath.Abs(in.contextPath)
if err != nil {
contextPathHash = in.contextPath
}

return buildTargets(ctx, dockerCli, map[string]build.Options{"default": opts}, in.progress, contextPathHash)
}

func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode string) error {
dis, err := getDefaultDrivers(ctx, dockerCli)
func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode, contextPathHash string) error {
dis, err := getDefaultDrivers(ctx, dockerCli, contextPathHash)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions commands/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func rmCmd(dockerCli command.Cli) *cobra.Command {
}

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

func stopCurrent(ctx context.Context, dockerCli command.Cli, rm bool) error {
dis, err := getDefaultDrivers(ctx, dockerCli)
dis, err := getDefaultDrivers(ctx, dockerCli, "")
if err != nil {
return err
}
Expand Down
50 changes: 43 additions & 7 deletions commands/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import (
"github.com/docker/buildx/util/platformutil"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/kubernetes"
dopts "github.com/docker/cli/opts"
dockerclient "github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
)

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

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

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

d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi, n.Flags, n.ConfigFile, n.DriverOpts)
contextStore := dockerCli.ContextStore()
kcc, err := kubernetes.ConfigFromContext(n.Endpoint, contextStore)
if err != nil {
// err is returned if n.Endpoint is non-context name like "unix:///var/run/docker.sock".
// try again with name="default".
// FIXME: n should retain real context name.
kcc, err = kubernetes.ConfigFromContext("default", contextStore)
if err != nil {
logrus.Error(err)
}
}
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi, kcc, n.Flags, n.ConfigFile, n.DriverOpts, contextPathHash)
if err != nil {
di.Err = err
return nil
Expand Down Expand Up @@ -235,7 +248,7 @@ func clientForEndpoint(dockerCli command.Cli, name string) (dockerclient.APIClie
}

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

if ng != nil {
return driversForNodeGroup(ctx, dockerCli, ng)
return driversForNodeGroup(ctx, dockerCli, ng, contextPathHash)
}

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

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

return eg.Wait()
if eg.Wait(); err != nil {
return err
}
for _, di := range ngi.drivers {
// dynamic nodes are used in Kubernetes driver.
// Kubernetes pods are dynamically mapped to BuildKit Nodes.
if di.info != nil && len(di.info.DynamicNodes) > 0 {
var drivers []dinfo
for i := 0; i < len(di.info.DynamicNodes); i++ {
// all []dinfo share *build.DriverInfo and *driver.Info
diClone := di
if pl := di.info.DynamicNodes[i].Platforms; len(pl) > 0 {
diClone.platforms = pl
}
drivers = append(drivers, di)
}
// not append (remove the static nodes in the store)
ngi.ng.Nodes = di.info.DynamicNodes
ngi.ng.Dynamic = true
ngi.drivers = drivers
return nil
}
}
return nil
}

func dockerAPI(dockerCli command.Cli) *api {
Expand Down
6 changes: 6 additions & 0 deletions driver/bkimage/bkimage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package bkimage

const (
DefaultImage = "moby/buildkit:buildx-stable-1" // TODO: make this verified
DefaultRootlessImage = "moby/buildkit:v0.6.2-rootless"
)
5 changes: 2 additions & 3 deletions driver/docker-container/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/docker/buildx/driver"
"github.com/docker/buildx/driver/bkimage"
"github.com/docker/buildx/util/progress"
"github.com/docker/docker/api/types"
dockertypes "github.com/docker/docker/api/types"
Expand All @@ -22,8 +23,6 @@ import (
"github.com/pkg/errors"
)

var defaultBuildkitImage = "moby/buildkit:buildx-stable-1" // TODO: make this verified

type Driver struct {
driver.InitConfig
factory driver.Factory
Expand Down Expand Up @@ -54,7 +53,7 @@ func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
}

func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
imageName := defaultBuildkitImage
imageName := bkimage.DefaultImage
if d.image != "" {
imageName = d.image
}
Expand Down
3 changes: 3 additions & 0 deletions driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package driver
import (
"context"

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

type Info struct {
Status Status
// DynamicNodes must be empty if the actual nodes are statically listed in the store
DynamicNodes []store.Node
}

type Driver interface {
Expand Down
Loading