This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/master by this push: new 62ed749 GKE configuration working 62ed749 is described below commit 62ed749b83d294be79c21a964be99c18956ba206 Author: nferraro <ni.ferr...@gmail.com> AuthorDate: Tue Nov 20 11:43:15 2018 +0100 GKE configuration working --- README.adoc | 8 +++ deploy/builder-pvc.yaml | 2 +- deploy/operator-deployment-kubernetes.yaml | 13 +++++ deploy/operator-deployment-openshift.yaml | 2 + deploy/resources.go | 17 +++++- docs/gke-setup.adoc | 60 +++++++++++++++++++++ pkg/apis/camel/v1alpha1/types.go | 2 + pkg/builder/builder.go | 1 + pkg/builder/kaniko/publisher.go | 83 +++++++++++++++++++++++------- pkg/client/cmd/install.go | 6 ++- pkg/install/operator.go | 4 +- 11 files changed, 174 insertions(+), 24 deletions(-) diff --git a/README.adoc b/README.adoc index dd52f01..8f5d205 100644 --- a/README.adoc +++ b/README.adoc @@ -20,6 +20,14 @@ If you need help on how to create a local development environment based on *Mini [[installation]] === Installation +Make sure you apply specific configuration settings for your cluster before installing Camel K. Customized instructions are needed for +the following cluster types: + +- link:/docs/cluster-setup.adoc[Minishift or Minikube] +- link:/docs/gke-setup.adoc[Google Kubernetes Engine (GKE)] + +Other cluster types (such as OpenShift clusters) should not need prior configuration. + To start using Camel K you need the **"kamel"** binary, that can be used to both configure the cluster and run integrations. Look into the https://github.com/apache/camel-k/releases[release page] for latest version of the `kamel` tool. diff --git a/deploy/builder-pvc.yaml b/deploy/builder-pvc.yaml index 8e6ca4b..a49c345 100644 --- a/deploy/builder-pvc.yaml +++ b/deploy/builder-pvc.yaml @@ -6,7 +6,7 @@ metadata: app: "camel-k" spec: accessModes: - - ReadWriteMany + - ReadWriteOnce resources: requests: storage: 1Gi diff --git a/deploy/operator-deployment-kubernetes.yaml b/deploy/operator-deployment-kubernetes.yaml index 084fb30..2555c4f 100644 --- a/deploy/operator-deployment-kubernetes.yaml +++ b/deploy/operator-deployment-kubernetes.yaml @@ -4,6 +4,7 @@ metadata: name: camel-k-operator labels: app: "camel-k" + camel.apache.org/component: operator spec: replicas: 1 strategy: @@ -15,6 +16,7 @@ spec: metadata: labels: name: camel-k-operator + camel.apache.org/component: operator spec: serviceAccountName: camel-k-operator containers: @@ -36,6 +38,17 @@ spec: volumeMounts: - mountPath: /workspace name: camel-k-builder + initContainers: + - command: + - chmod + - "777" + - /workspace + image: busybox + imagePullPolicy: IfNotPresent + name: build-volume-permission + volumeMounts: + - mountPath: /workspace + name: camel-k-builder volumes: - name: camel-k-builder persistentVolumeClaim: diff --git a/deploy/operator-deployment-openshift.yaml b/deploy/operator-deployment-openshift.yaml index 5b589af..fc15f4a 100644 --- a/deploy/operator-deployment-openshift.yaml +++ b/deploy/operator-deployment-openshift.yaml @@ -4,6 +4,7 @@ metadata: name: camel-k-operator labels: app: "camel-k" + camel.apache.org/component: operator spec: replicas: 1 strategy: @@ -15,6 +16,7 @@ spec: metadata: labels: name: camel-k-operator + camel.apache.org/component: operator spec: serviceAccountName: camel-k-operator containers: diff --git a/deploy/resources.go b/deploy/resources.go index ec14cb0..d67602b 100644 --- a/deploy/resources.go +++ b/deploy/resources.go @@ -34,7 +34,7 @@ metadata: app: "camel-k" spec: accessModes: - - ReadWriteMany + - ReadWriteOnce resources: requests: storage: 1Gi @@ -2212,6 +2212,7 @@ metadata: name: camel-k-operator labels: app: "camel-k" + camel.apache.org/component: operator spec: replicas: 1 strategy: @@ -2223,6 +2224,7 @@ spec: metadata: labels: name: camel-k-operator + camel.apache.org/component: operator spec: serviceAccountName: camel-k-operator containers: @@ -2244,6 +2246,17 @@ spec: volumeMounts: - mountPath: /workspace name: camel-k-builder + initContainers: + - command: + - chmod + - "777" + - /workspace + image: busybox + imagePullPolicy: IfNotPresent + name: build-volume-permission + volumeMounts: + - mountPath: /workspace + name: camel-k-builder volumes: - name: camel-k-builder persistentVolumeClaim: @@ -2258,6 +2271,7 @@ metadata: name: camel-k-operator labels: app: "camel-k" + camel.apache.org/component: operator spec: replicas: 1 strategy: @@ -2269,6 +2283,7 @@ spec: metadata: labels: name: camel-k-operator + camel.apache.org/component: operator spec: serviceAccountName: camel-k-operator containers: diff --git a/docs/gke-setup.adoc b/docs/gke-setup.adoc new file mode 100644 index 0000000..5aa35aa --- /dev/null +++ b/docs/gke-setup.adoc @@ -0,0 +1,60 @@ +[[gke-cluster]] +Configuring a Google Kubernetes Engine (GKE) Cluster +============================== + +This guide assumes you've already create a Kubernetes Engine cluster on https://console.cloud.google.com. + +Make sure you've selected a version of Kubernetes greater than **1.11** when creating the cluster. You can create it in any region. + +In the list of clusters for the current project, GKE provides a connection script that you need to execute on a shell to configure the `kubectl` command. + +NOTE: the script contains a `--project` flag that indicates your **project ID**. You should keep that information for the last step. + +After executing the connection script, if everything is installed correctly, you should be able to execute: + +``` +kubectl get pod +``` + +When the cluster is first installed, you should find that no pods are present in the cluster. You can proceed with the installation then. + +Before installing Camel K on a fresh GKE cluster, you need to perform a extra step to give to your account the required cluster-admin permissions. +This means executing the following command (**replacing "your-addr...@gmail.com" with your account email address**): + +``` +kubectl create clusterrolebinding user-cluster-admin-binding --clusterrole=cluster-admin --user=your-addr...@gmail.com +``` + +The command above is needed to make sure your user is able to delegate some permissions to Camel K service accounts. + +Users of *GKE* are expected to use the `gcr.io` registry to push and pull images. +In order to push images to `gcr.io`, you need to provide a valid key to Camel K. +The best way to obtain a valid key is from the web console: + +- Go to https://console.cloud.google.com +- Make sure the project where you created the Kubernetes cluster is selected in the drop-down list +- To avoid confusion, it's suggested to use the "English" language in preferences of the Google Cloud console +- Select "IAM & admin" from the navigation menu, then "Service accounts" +- Create a new service account specifying the following id: **"camel-k-builder"** +- You'll be asked to select a role. It's important to **select the **"Storage Admin" role** from the "Storage" menu +- Finish creating the service account +- From the action menu of the service account you've created, **create a key** using the JSON format + +A `.json` file with the key will be downloaded to your machine. You need to store that key in a Kubernetes secret. + +It's **important** to rename the file you've just downloaded to `kaniko-secret.json` (make sure you write it correctly). +After the renaming, execute the following command: + +``` +kubectl create secret generic kaniko-secret --from-file=kaniko-secret.json +``` + +You're ready to install Camel K. You should execute the following command to install it correctly: + +``` +kamel install --registry gcr.io --organization <<your-project-id>> --push-secret kaniko-secret +``` + +Use the project id that you've annotated when issuing the first connection string. Note: the project id is **NOT** the cluster id! + +You're now ready to play with Camel K! diff --git a/pkg/apis/camel/v1alpha1/types.go b/pkg/apis/camel/v1alpha1/types.go index f61c555..f8a11c3 100644 --- a/pkg/apis/camel/v1alpha1/types.go +++ b/pkg/apis/camel/v1alpha1/types.go @@ -234,6 +234,8 @@ var allTraitProfiles = []TraitProfile{TraitProfileOpenShift, TraitProfileKuberne type IntegrationPlatformBuildSpec struct { PublishStrategy IntegrationPlatformBuildPublishStrategy `json:"publishStrategy,omitempty"` Registry string `json:"registry,omitempty"` + Organization string `json:"organization,omitempty"` + PushSecret string `json:"pushSecret,omitempty"` } // IntegrationPlatformBuildPublishStrategy enumerates all implemented build strategies diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go index 0877e27..7b2e580 100644 --- a/pkg/builder/builder.go +++ b/pkg/builder/builder.go @@ -130,6 +130,7 @@ func (b *defaultBuilder) submit(request Request) { } builderPath, err := ioutil.TempDir(buildDir, "builder-") if err != nil { + logrus.Warning("Unexpected error while creating a temporary dir ", err) r.Status = StatusError r.Error = err } diff --git a/pkg/builder/kaniko/publisher.go b/pkg/builder/kaniko/publisher.go index 3cc976b..823d13c 100644 --- a/pkg/builder/kaniko/publisher.go +++ b/pkg/builder/kaniko/publisher.go @@ -34,7 +34,11 @@ import ( // Publisher -- func Publisher(ctx *builder.Context) error { - image := ctx.Request.Platform.Build.Registry + "/" + ctx.Namespace + "/camel-k-" + ctx.Request.Identifier.Name + ":" + ctx.Request.Identifier.Qualifier + organization := ctx.Request.Platform.Build.Organization + if organization == "" { + organization = ctx.Namespace + } + image := ctx.Request.Platform.Build.Registry + "/" + organization + "/camel-k-" + ctx.Request.Identifier.Name + ":" + ctx.Request.Identifier.Qualifier baseDir, _ := path.Split(ctx.Archive) contextDir := path.Join(baseDir, "context") if err := tar.Extract(ctx.Archive, contextDir); err != nil { @@ -51,6 +55,49 @@ func Publisher(ctx *builder.Context) error { return err } + volumes := []v1.Volume{ + { + Name: "camel-k-builder", + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ + ClaimName: "camel-k-builder", + }, + }, + }, + } + volumeMounts := []v1.VolumeMount{ + { + Name: "camel-k-builder", + MountPath: "/workspace", + }, + } + envs := []v1.EnvVar{} + baseArgs := []string{ + "--dockerfile=Dockerfile", + "--context=" + contextDir, + "--destination=" + image} + args := append(baseArgs, "--insecure") + + if ctx.Request.Platform.Build.PushSecret != "" { + volumes = append(volumes, v1.Volume{ + Name: "kaniko-secret", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: ctx.Request.Platform.Build.PushSecret, + }, + }, + }) + volumeMounts = append(volumeMounts, v1.VolumeMount{ + Name: "kaniko-secret", + MountPath: "/secret", + }) + envs = append(envs, v1.EnvVar{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", + Value: "/secret/kaniko-secret.json", + }) + args = baseArgs + } + pod := v1.Pod{ TypeMeta: metav1.TypeMeta{ APIVersion: v1.SchemeGroupVersion.String(), @@ -65,28 +112,24 @@ func Publisher(ctx *builder.Context) error { { Name: "kaniko", Image: "gcr.io/kaniko-project/executor@sha256:f29393d9c8d40296e1692417089aa2023494bce9afd632acac7dd0aea763e5bc", - Args: []string{ - "--dockerfile=Dockerfile", - "--context=" + contextDir, - "--destination=" + image, - "--insecure", - }, - VolumeMounts: []v1.VolumeMount{ - { - Name: "camel-k-builder", - MountPath: "/workspace", - }, - }, + Args: args, + Env: envs, + VolumeMounts: volumeMounts, }, }, RestartPolicy: v1.RestartPolicyNever, - Volumes: []v1.Volume{ - { - Name: "camel-k-builder", - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "camel-k-builder", - ReadOnly: true, + Volumes: volumes, + Affinity: &v1.Affinity{ + // Co-locate with builder pod for sharing the volume + PodAffinity: &v1.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "camel.apache.org/component": "operator", + }, + }, + TopologyKey: "kubernetes.io/hostname", }, }, }, diff --git a/pkg/client/cmd/install.go b/pkg/client/cmd/install.go index abe61c5..5437c6e 100644 --- a/pkg/client/cmd/install.go +++ b/pkg/client/cmd/install.go @@ -42,6 +42,8 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) *cobra.Command { cmd.Flags().BoolVar(&options.clusterSetupOnly, "cluster-setup", false, "Execute cluster-wide operations only (may require admin rights)") cmd.Flags().BoolVar(&options.exampleSetup, "example", false, "Install example integration") cmd.Flags().StringVar(&options.registry, "registry", "", "A Docker registry that can be used to publish images") + cmd.Flags().StringVar(&options.organization, "organization", "", "A organization on the Docker registry that can be used to publish images") + cmd.Flags().StringVar(&options.pushSecret, "push-secret", "", "A secret used to push images to the Docker registry") cmd.ParseFlags(os.Args) return &cmd @@ -52,6 +54,8 @@ type installCmdOptions struct { clusterSetupOnly bool exampleSetup bool registry string + organization string + pushSecret string } func (o *installCmdOptions) install(cmd *cobra.Command, args []string) error { @@ -71,7 +75,7 @@ func (o *installCmdOptions) install(cmd *cobra.Command, args []string) error { return err } - err = install.Platform(namespace, o.registry) + err = install.Platform(namespace, o.registry, o.organization, o.pushSecret) if err != nil { return err } diff --git a/pkg/install/operator.go b/pkg/install/operator.go index 8aa7844..5c4fb0a 100644 --- a/pkg/install/operator.go +++ b/pkg/install/operator.go @@ -85,7 +85,7 @@ func installKnative(namespace string) error { } // Platform installs the platform custom resource -func Platform(namespace string, registry string) error { +func Platform(namespace string, registry string, organization string, pushSecret string) error { if err := waitForPlatformCRDAvailable(namespace, 15*time.Second); err != nil { return err } @@ -114,6 +114,8 @@ func Platform(namespace string, registry string) error { registry = *minishiftRegistry } pl.Spec.Build.Registry = registry + pl.Spec.Build.Organization = organization + pl.Spec.Build.PushSecret = pushSecret } var knativeInstalled bool