new driver: kubernetes

Tested with `kind` and GKE.

Note: "nodes" shown in `docker buildx ls` are unrelated to Kubernetes "nodes".
Probably buildx should come up with an alternative term.

Usage:

  $ kind create cluster
  $ export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"

  $ docker buildx create --driver kubernetes --driver-opt replicas=3 --use
  $ docker buildx build -t foo --load .

`--load` loads the image into the local Docker.

Driver opts:

  - `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`. 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"

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda
2019-10-21 15:02:37 +09:00
parent f5c2673878
commit 6b65b0c982
657 changed files with 258673 additions and 370 deletions

View File

@ -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) {

View File

@ -3,6 +3,7 @@ package commands
import (
"context"
"os"
"path/filepath"
"strings"
"github.com/docker/buildx/build"
@ -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
}

View File

@ -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
}
@ -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
}

View File

@ -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"
)
@ -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))
@ -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
@ -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
@ -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
}
@ -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
}