diff --git a/deploy/addons/ambassador/ambassador-operator-crds.yaml b/deploy/addons/ambassador/ambassador-operator-crds.yaml new file mode 100644 index 0000000000000000000000000000000000000000..287b706639f3a697d531fb273c67f728e79ddfe2 --- /dev/null +++ b/deploy/addons/ambassador/ambassador-operator-crds.yaml @@ -0,0 +1,186 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ambassadorinstallations.getambassador.io +spec: + additionalPrinterColumns: + - JSONPath: .spec.version + name: VERSION + type: string + - JSONPath: .spec.updateWindow + name: UPDATE-WINDOW + type: integer + - JSONPath: .status.lastCheckTime + description: Last time checked + name: LAST-CHECK + type: string + - JSONPath: .status.conditions[?(@.type=='Deployed')].status + description: Indicates if deployment has completed + name: DEPLOYED + type: string + - JSONPath: .status.conditions[?(@.type=='Deployed')].reason + description: Reason for deployment completed + name: REASON + priority: 1 + type: string + - JSONPath: .status.conditions[?(@.type=='Deployed')].message + description: Message for deployment completed + name: MESSAGE + priority: 1 + type: string + - JSONPath: .status.deployedRelease.appVersion + description: Deployed version of Ambassador + name: DEPLOYED-VERSION + type: string + - JSONPath: .status.deployedRelease.flavor + description: Deployed flavor of Ambassador (OSS or AES) + name: DEPLOYED-FLAVOR + type: string + group: getambassador.io + names: + kind: AmbassadorInstallation + listKind: AmbassadorInstallationList + plural: ambassadorinstallations + singular: ambassadorinstallation + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + description: AmbassadorInstallation is the Schema for the ambassadorinstallations + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AmbassadorInstallationSpec defines the desired state of AmbassadorInstallation + properties: + baseImage: + description: An (optional) image to use instead of the image specified + in the Helm chart. + type: string + helmRepo: + description: An (optional) Helm repository. + type: string + installOSS: + description: 'Installs [Ambassador OSS](https://www.getambassador.io/docs/latest/topics/install/install-ambassador-oss/) + instead of [AES](https://www.getambassador.io/docs/latest/topics/install/). + Default is false which means it installs AES by default. TODO: 1. + AES/AOSS is not installed and the user installs using `installOSS: + true`, then we straightaway install AOSS. 2. AOSS is installed via + operator and the user sets `installOSS: false`, then we perform the + migration as detailed here - https://www.getambassador.io/docs/latest/topics/install/upgrade-to-edge-stack/ + 3. AES is installed and the user sets `installOSS: true`, then we + point users to the docs which gives them pointers on how to do + that themselves.' + type: boolean + logLevel: + description: 'An (optional) log level: debug, info...' + enum: + - info + - debug + - warn + - warning + - error + - critical + - fatal + type: string + updateWindow: + description: "`updateWindow` is an optional item that will control when + the updates can take place. This is used to force system updates to + happen late at night if that’s what the sysadmins want. \n * There + can be any number of `updateWindow` entries (separated by commas). + \ * `Never` turns off automatic updates even if there are other entries + in the comma-separated list. `Never` is used by sysadmins to disable + all updates during blackout periods by doing a `kubectl apply` + or using our Edge Policy Console to set this. * Each `updateWindow` + is in crontab format (see https://crontab.guru/) Some examples of + `updateWindows` are: - `* 0-6 * * * SUN`: every Sunday, from _0am_ + to _6am_ - `* 5 1 * * *`: every first day of the month, at _5am_ + * The Operator cannot guarantee minute time granularity, so specifying + \ a minute in the crontab expression can lead to some updates happening + \ sooner/later than expected." + type: string + version: + description: "We are using SemVer for the version number and it can + be specified with any level of precision and can optionally end in + `*`. These are interpreted as: \n * `1.0` = exactly version 1.0 * + `1.1` = exactly version 1.1 * `1.1.*` = version 1.1 and any bug fix + versions `1.1.1`, `1.1.2`, `1.1.3`, etc. * `2.*` = version 2.0 and + any incremental and bug fix versions `2.0`, `2.0.1`, `2.0.2`, `2.1`, + `2.2`, `2.2.1`, etc. * `*` = all versions. * `3.0-ea` = version `3.0-ea1` + and any subsequent EA releases on `3.0`. Also selects the final + 3.0 once the final GA version is released. * `4.*-ea` = version `4.0-ea1` + and any subsequent EA release on `4.0`. Also selects the final GA + `4.0`. Also selects any incremental and bug fix versions `4.*` and + `4.*.*`. Also selects the most recent `4.*` EA release i.e., if + `4.0.5` is the last GA version and there is a `4.1-EA3`, then this + \ selects `4.1-EA3` over the `4.0.5` GA. \n You can find the reference + docs about the SemVer syntax accepted [here](https://github.com/Masterminds/semver#basic-comparisons)." + type: string + type: object + status: + description: AmbassadorInstallationStatus defines the observed state of + AmbassadorInstallation + properties: + conditions: + description: List of conditions the installation has experienced. + items: + description: AmbInsCondition defines an Ambassador installation condition, + as well as the last time there was a transition to this condition.. + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + deployedRelease: + description: the currently deployed Helm chart + nullable: true + properties: + appVersion: + type: string + flavor: + type: string + manifest: + type: string + name: + type: string + version: + type: string + type: object + lastCheckTime: + description: Last time a successful update check was performed. + format: date-time + nullable: true + type: string + required: + - conditions + type: object + type: object + version: v2 + versions: + - name: v2 + served: true + storage: true diff --git a/deploy/addons/ambassador/ambassador-operator.yaml b/deploy/addons/ambassador/ambassador-operator.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a6a6babe89e048505016774f3f2a783fc2d3cd69 --- /dev/null +++ b/deploy/addons/ambassador/ambassador-operator.yaml @@ -0,0 +1,190 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: ambassador + labels: + addonmanager.kubernetes.io/mode: Reconcile +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: ambassador-operator + namespace: ambassador +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ambassador-operator + namespace: ambassador +rules: + - apiGroups: + - "" + resources: + - pods + - services + - services/finalizers + - endpoints + - persistentvolumeclaims + - events + - configmaps + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + resources: + - deployments + - daemonsets + - replicasets + - statefulsets + - customresourcedefinitions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - apps + resourceNames: + - ambassador-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - apiGroups: + - apps + resources: + - replicasets + - deployments + verbs: + - get + - apiGroups: + - getambassador.io + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: ambassador-operator-cluster + namespace: ambassador +rules: + - apiGroups: ['*'] + resources: ['*'] + verbs: ['*'] + - nonResourceURLs: ['*'] + verbs: ['*'] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ambassador-operator + namespace: ambassador +subjects: + - kind: ServiceAccount + name: ambassador-operator +roleRef: + kind: Role + name: ambassador-operator + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ambassador-operator-cluster + namespace: ambassador +subjects: + - kind: ServiceAccount + name: ambassador-operator + namespace: ambassador +roleRef: + kind: ClusterRole + name: ambassador-operator-cluster + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: static-helm-values + namespace: ambassador +data: + values.yaml: |+ + deploymentTool: amb-oper-manifest +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ambassador-operator + namespace: ambassador + labels: + getambassador.io/installer: operator +spec: + replicas: 1 + selector: + matchLabels: + name: ambassador-operator + template: + metadata: + labels: + name: ambassador-operator + getambassador.io/installer: operator + spec: + serviceAccountName: ambassador-operator + containers: + - name: ambassador-operator + # Replace this with the built image name + image: quay.io/datawire/ambassador-operator:v1.2.3 + command: + - ambassador-operator + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "ambassador-operator" + volumeMounts: + - name: static-helm-values + mountPath: /tmp/helm + volumes: + - name: static-helm-values + configMap: + name: static-helm-values diff --git a/deploy/addons/ambassador/ambassadorinstallation.yaml b/deploy/addons/ambassador/ambassadorinstallation.yaml new file mode 100644 index 0000000000000000000000000000000000000000..befbf897f20ebdea7650927874dbd298911136ae --- /dev/null +++ b/deploy/addons/ambassador/ambassadorinstallation.yaml @@ -0,0 +1,9 @@ +apiVersion: getambassador.io/v2 +kind: AmbassadorInstallation +metadata: + name: ambassador + namespace: ambassador +spec: + installOSS: true + helmValues: + deploymentTool: amb-oper-minikube diff --git a/pkg/addons/config.go b/pkg/addons/config.go index d1cf93e4fbfc8a2dd59e0fdaa468a441757ac50d..0b3f7e57ef70d9aa7a4f64a6241ebf816d9cf6c0 100644 --- a/pkg/addons/config.go +++ b/pkg/addons/config.go @@ -138,4 +138,9 @@ var Addons = []*Addon{ set: SetBool, callbacks: []setFn{enableOrDisableAddon}, }, + { + name: "ambassador", + set: SetBool, + callbacks: []setFn{enableOrDisableAddon}, + }, } diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 3ddaca16ee10e17701a4ee94e5b062187660be57..c4be70ae270842aa511654a006a27125fc1da3fb 100644 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -383,6 +383,26 @@ var Addons = map[string]*Addon{ "0640", true), }, false, "metallb"), + "ambassador": NewAddon([]*BinAsset{ + MustBinAsset( + "deploy/addons/ambassador/ambassador-operator-crds.yaml", + vmpath.GuestAddonsDir, + "ambassador-operator-crds.yaml", + "0640", + false), + MustBinAsset( + "deploy/addons/ambassador/ambassador-operator.yaml", + vmpath.GuestAddonsDir, + "ambassador-operator.yaml", + "0640", + false), + MustBinAsset( + "deploy/addons/ambassador/ambassadorinstallation.yaml", + vmpath.GuestAddonsDir, + "ambassadorinstallation.yaml.yaml", + "0640", + false), + }, false, "ambassador"), } // GenerateTemplateData generates template data for template assets diff --git a/site/content/en/docs/tutorials/ambassador_ingress_controller.md b/site/content/en/docs/tutorials/ambassador_ingress_controller.md new file mode 100644 index 0000000000000000000000000000000000000000..faf56fafee5e84b6ee94be0b9e14bbad3f74f415 --- /dev/null +++ b/site/content/en/docs/tutorials/ambassador_ingress_controller.md @@ -0,0 +1,131 @@ +--- +title: "Using Ambassador Ingress Controller" +linkTitle: "Using Ambassador Ingress Controller" +weight: 1 +date: 2020-05-14 +description: > + Using Ambassador Ingress Controller with Minikube +--- + +## Overview + +[Ambassador](https://getambassador.io/) allows access to Kubernetes services running inside Minikube. Ambassador can be +configured via both, [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) resources and +[Mapping](https://www.getambassador.io/docs/latest/topics/using/intro-mappings/) resources. + +## Prerequisites + +- Minikube version higher than v1.10.1 +- kubectl + +## Configuring Ambassador + +### Installing Ambassador + +Ambassador is available as a Minikube +[addon]((https://github.com/kubernetes/minikube/tree/master/deploy/addons/ambassdor)). Install it by running - + +```shell script +minikube addons enable ambassador +``` + +This will install Ambassador in the namespace `ambassador`. + +### Accessing Ambassador via `minikube tunnel` + +The service `ambassador` is of type `LoadBalancer`. To access this service, run a +[Minikube tunnel](https://minikube.sigs.k8s.io/docs/handbook/accessing/#using-minikube-tunnel) in a separate terminal. + +```shell script +minikube tunnel +``` + +You can now access Ambassador at the external IP allotted to the `ambassador` service. +Get the external IP with the following command: +```shell script +kubectl get service ambassador -n ambassador +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +ambassador LoadBalancer 10.104.86.124 10.104.86.124 80:31287/TCP,443:31934/TCP 77m +``` + +### Configuring via Ingress resource + +In this tutorial, we'll configure Ambassador via an Ingress resource. To configure via `IngressClass` resource, read +this [post](https://blog.getambassador.io/new-kubernetes-1-18-extends-ingress-c34abdc2f064). + +First, let's create a Kubernetes deployment and service which we will talk to via Ambassador. + +```shell script +kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4 +kubectl expose deployment hello-minikube --port=8080 +``` + +This service `hello-minikube` is of type `ClusterIP` and is not accessible from outside the cluster. + +Now, create an Ingress resource which exposes this service at the path `/hello/` + +**Note:** The Ingress resource must have the annotation `kubernetes.io/ingress.class: ambassador` for Ambassador to +pick it up. + +`hello-ingress.yaml` +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: ambassador + name: test-ingress +spec: + rules: + - http: + paths: + - path: /hello/ + backend: + serviceName: hello-minikube + servicePort: 8080 +``` +Run the command: `kubectl apply -f hello-ingress.yaml` + +That's it! You can now access your service via Ambassador: +```shell script +curl http:// +``` + +**Note:** For more advanced Ingress configurations with Ambassador, like TLS termination and name-based virtual hosting, +see Ambassador's [documentation](https://www.getambassador.io/docs/latest/topics/running/ingress-controller/). + +### Configuring via Mapping resource + +While Ambassador understands the Ingress spec, the Ingress spec does not leverage all of Ambassador's features. The +[Mapping](https://www.getambassador.io/docs/latest/topics/using/intro-mappings/) resource is Ambassador's core resource +that maps a target backend service to a given host or prefix. + +Let's create another Kubernetes deployment and service that we will expose via Ambassador - +```shell script +kubectl create deployment mapping-minikube --image=k8s.gcr.io/echoserver:1.4 +kubectl expose deployment mapping-minikube --port=8080 +``` + +This service `mapping-minikube` is of type `ClusterIP` and is not accessible from outside the cluster. + +Now, let's create a mapping that exposes this service via Ambassador at the path `/hello-mapping/` + +`hello-mapping.yaml` +```yaml +apiVersion: getambassador.io/v2 +kind: Mapping +metadata: + name: mapping-minikube +spec: + prefix: /hello-mapping/ + service: mapping-minikube.default:8080 +``` +Run the command: `kubectl apply -f hello-mapping.yaml` + +That's it! You can now access your service via Ambassador: +```shell script +curl http:// +``` + +**Note:** Read more about mappings in Ambassador's +[documentation](https://www.getambassador.io/docs/latest/topics/using/mappings/). \ No newline at end of file