From 2a6b811207f2fa4055b115322a0f5d66c5830eb5 Mon Sep 17 00:00:00 2001 From: lichuqiang Date: Fri, 30 Nov 2018 12:56:23 +0800 Subject: [PATCH] Allow config ingress gateway (#2434) * update ingress reconciler to watch the configmap * remove knative-ingressgateway usage * add docs to tell how to set up gateway * indent columns * sync pkg --- Gopkg.lock | 4 +- Gopkg.toml | 4 +- config/202-gateway.yaml | 260 ++---------------- docs/setting-up-custom-ingress-gateway.md | 254 +++++++++++++++++ docs/setting-up-ingress-static-ip.md | 23 +- .../v1alpha1/clusteringress/clusteringress.go | 23 +- .../clusteringress/clusteringress_test.go | 185 ++++++++++++- .../clusteringress/resources/names/names.go | 5 - .../v1alpha1/route/resources/service_test.go | 4 +- pkg/reconciler/v1alpha1/route/table_test.go | 2 +- test/README.md | 2 +- test/cluster.sh | 4 +- test/e2e/helloworld_shell_test.go | 2 +- test/performance/performance.go | 2 +- .../apis/duck/v1alpha1/addressable_types.go | 1 - .../apis/duck/v1alpha1/generational_types.go | 1 - .../duck/v1alpha1/legacy_targetable_types.go | 1 - .../duck/v1alpha1/retired_targetable_types.go | 1 - .../authentication/v1alpha1/policy_types.go | 42 +-- .../pkg/apis/istio/common/v1alpha1/string.go | 18 +- .../istio/v1alpha3/destinationrule_types.go | 66 ++--- .../istio/v1alpha3/virtualservice_types.go | 2 +- .../knative/pkg/controller/controller.go | 7 +- .../pkg/metrics/metricskey/constants.go | 14 +- .../knative/pkg/test/spoof/spoof.go | 21 +- .../knative/pkg/test/zipkin/util.go | 6 +- 26 files changed, 598 insertions(+), 356 deletions(-) create mode 100644 docs/setting-up-custom-ingress-gateway.md diff --git a/Gopkg.lock b/Gopkg.lock index c12f4d33c42b..833e0f6ec671 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -396,7 +396,7 @@ revision = "f0d7bb60956f88d4743f5fea66b5607b96d262c9" [[projects]] - digest = "1:e0f8a12fc45f4fa1087f78d08b15e340ba0fdc43db1e9b92d6229b390b7f3936" + digest = "1:d4cee2d9908d4a05064a1680916455c95cba498394c1f6c3aa4f22742f6edc59" name = "github.com/knative/pkg" packages = [ "apis", @@ -440,7 +440,7 @@ "webhook", ] pruneopts = "NUT" - revision = "acfd173abd8d2063ddceedb3487599f97ac93db8" + revision = "9a644df00f19da719379ca936c1949f56d8c3eb5" [[projects]] branch = "master" diff --git a/Gopkg.toml b/Gopkg.toml index 8934f30ec719..c1ceb3313eb9 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -23,8 +23,8 @@ required = [ [[override]] name = "github.com/knative/pkg" - # HEAD as of 2018-11-21 - revision = "acfd173abd8d2063ddceedb3487599f97ac93db8" + # HEAD as of 2018-11-28 + revision = "9a644df00f19da719379ca936c1949f56d8c3eb5" [[override]] name = "go.uber.org/zap" diff --git a/config/202-gateway.yaml b/config/202-gateway.yaml index c01b539bc0c1..f84c1be01d69 100644 --- a/config/202-gateway.yaml +++ b/config/202-gateway.yaml @@ -1,18 +1,28 @@ -# We stand up a new Gateway service to receive all external traffic -# for Knative pods. These pods are basically standalone Envoy proxy -# pods to convert all external traffic into cluster traffic. +# Copyright 2018 The Knative Authors # +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -# The reason for standing up these pods are because Istio Gateway -# cannot not share these ingress pods. Istio provide a default, but -# we don't want to use it and causing unwanted sharing with users' -# Gateways if they have some. +# https://www.apache.org/licenses/LICENSE-2.0 # -# The YAML is cloned from Istio's. However, in the future we may want -# to incorporate more of our logic to tailor to our users' specific -# needs. +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# The Gateway resource here is to attach to a gateway service that +# receive all external traffic for Knative pods. We don't maintain +# extra Gateway service and deployment in knative, but use that +# provided in Istio by default. + +# If you want to replace the Gateway service and deployment to that +# of your own, you'll need to update the label selector and ports +# fields accordingly. # This is the shared Gateway for all Knative routes to use. + apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: @@ -20,7 +30,7 @@ metadata: namespace: knative-serving spec: selector: - knative: ingressgateway + istio: ingressgateway servers: - port: number: 80 @@ -36,231 +46,3 @@ spec: - "*" tls: mode: PASSTHROUGH ---- -# TODO(#1969): We should allow the users to use `istio-ingressgateway` by default, -# while having the choice to specify their own Ingress Gateway service -# if that isn't enough for them. That way we can get out of maintaining -# these YAML ourselves. -# -# This is the Service definition for the ingress pods serving -# Knative's shared Gateway. -apiVersion: v1 -kind: Service -metadata: - name: knative-ingressgateway - namespace: istio-system - annotations: - labels: - chart: gateways-1.0.1 - release: RELEASE-NAME - heritage: Tiller - app: knative-ingressgateway - knative: ingressgateway -spec: - type: LoadBalancer - selector: - app: knative-ingressgateway - knative: ingressgateway - ports: - - - name: http2 - nodePort: 32380 - port: 80 - targetPort: 80 - - - name: https - nodePort: 32390 - port: 443 - - - name: tcp - nodePort: 32400 - port: 31400 - - - name: tcp-pilot-grpc-tls - port: 15011 - targetPort: 15011 - - - name: tcp-citadel-grpc-tls - port: 8060 - targetPort: 8060 - - - name: tcp-dns-tls - port: 853 - targetPort: 853 - - - name: http2-prometheus - port: 15030 - targetPort: 15030 - - - name: http2-grafana - port: 15031 - targetPort: 15031 ---- -# This is the corresponding Deployment to backed the aforementioned Service. -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: knative-ingressgateway - namespace: istio-system - labels: - chart: gateways-1.0.1 - release: RELEASE-NAME - heritage: Tiller - app: knative-ingressgateway - knative: ingressgateway -spec: - replicas: 1 - selector: - matchLabels: - app: knative-ingressgateway - knative: ingressgateway - template: - metadata: - labels: - app: knative-ingressgateway - knative: ingressgateway - annotations: - sidecar.istio.io/inject: "false" - scheduler.alpha.kubernetes.io/critical-pod: "" - spec: - serviceAccountName: istio-ingressgateway-service-account - containers: - - name: istio-proxy - image: "docker.io/istio/proxyv2:1.0.2" - imagePullPolicy: IfNotPresent - ports: - - containerPort: 80 - - containerPort: 443 - - containerPort: 31400 - - containerPort: 15011 - - containerPort: 8060 - - containerPort: 853 - - containerPort: 15030 - - containerPort: 15031 - args: - - proxy - - router - - -v - - "2" - - --discoveryRefreshDelay - - '1s' #discoveryRefreshDelay - - --drainDuration - - '45s' #drainDuration - - --parentShutdownDuration - - '1m0s' #parentShutdownDuration - - --connectTimeout - - '10s' #connectTimeout - - --serviceCluster - - knative-ingressgateway - - --zipkinAddress - - zipkin:9411 - - --statsdUdpAddress - - istio-statsd-prom-bridge:9125 - - --proxyAdminPort - - "15000" - - --controlPlaneAuthPolicy - - NONE - - --discoveryAddress - - istio-pilot:8080 - resources: - requests: - cpu: 10m - - env: - - name: POD_NAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: status.podIP - - name: ISTIO_META_POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - volumeMounts: - - name: istio-certs - mountPath: /etc/certs - readOnly: true - - name: ingressgateway-certs - mountPath: "/etc/istio/ingressgateway-certs" - readOnly: true - - name: ingressgateway-ca-certs - mountPath: "/etc/istio/ingressgateway-ca-certs" - readOnly: true - volumes: - - name: istio-certs - secret: - secretName: istio.istio-ingressgateway-service-account - optional: true - - name: ingressgateway-certs - secret: - secretName: "istio-ingressgateway-certs" - optional: true - - name: ingressgateway-ca-certs - secret: - secretName: "istio-ingressgateway-ca-certs" - optional: true - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: beta.kubernetes.io/arch - operator: In - values: - - amd64 - - ppc64le - - s390x - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 2 - preference: - matchExpressions: - - key: beta.kubernetes.io/arch - operator: In - values: - - amd64 - - weight: 2 - preference: - matchExpressions: - - key: beta.kubernetes.io/arch - operator: In - values: - - ppc64le - - weight: 2 - preference: - matchExpressions: - - key: beta.kubernetes.io/arch - operator: In - values: - - s390x ---- -# This is the horizontal pod autoscaler to make sure the ingress Pods -# scale up to meet traffic demand. -# -apiVersion: autoscaling/v2beta1 -kind: HorizontalPodAutoscaler -metadata: - name: knative-ingressgateway - namespace: istio-system -spec: - # TODO(1411): Document/fix this. We are choosing an arbitrary 10 here. - maxReplicas: 10 - minReplicas: 1 - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: knative-ingressgateway - metrics: - - type: Resource - resource: - name: cpu - targetAverageUtilization: 60 diff --git a/docs/setting-up-custom-ingress-gateway.md b/docs/setting-up-custom-ingress-gateway.md new file mode 100644 index 000000000000..8bc21ed07f1c --- /dev/null +++ b/docs/setting-up-custom-ingress-gateway.md @@ -0,0 +1,254 @@ +# Setting Up Custom Ingress Gateway + +Knative uses a shared Gateway to serve all incoming traffic within Knative +service mesh, which is the "knative-shared-gateway" Gateway under +"knative-serving" namespace. By default, we use Istio gateway service `istio-ingressgateway` +under "istio-system" namespace as its underlying service. You can replace the +service with that of your own as follows. + +## Step 1: Create Gateway Service and Deployment Instance + +You'll need to create the gateway service and deployment instance to handle traffic first. +The simplest way should be making a copy of the Gateway service template in [Istio release](https://github.com/istio/istio/releases). + +Here is an example: + +``` +apiVersion: v1 +kind: Service +metadata: + name: custom-ingressgateway + namespace: istio-system + annotations: + labels: + chart: gateways-1.0.1 + release: RELEASE-NAME + heritage: Tiller + app: custom-ingressgateway + custom: ingressgateway +spec: + type: LoadBalancer + selector: + app: custom-ingressgateway + custom: ingressgateway + ports: + - + name: http2 + nodePort: 32380 + port: 80 + targetPort: 80 + - + name: https + nodePort: 32390 + port: 443 + - + name: tcp + nodePort: 32400 + port: 31400 + - + name: tcp-pilot-grpc-tls + port: 15011 + targetPort: 15011 + - + name: tcp-citadel-grpc-tls + port: 8060 + targetPort: 8060 + - + name: tcp-dns-tls + port: 853 + targetPort: 853 + - + name: http2-prometheus + port: 15030 + targetPort: 15030 + - + name: http2-grafana + port: 15031 + targetPort: 15031 +--- +# This is the corresponding Deployment to backed the aforementioned Service. +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: custom-ingressgateway + namespace: istio-system + labels: + chart: gateways-1.0.1 + release: RELEASE-NAME + heritage: Tiller + app: custom-ingressgateway + custom: ingressgateway +spec: + replicas: 1 + selector: + matchLabels: + app: custom-ingressgateway + custom: ingressgateway + template: + metadata: + labels: + app: custom-ingressgateway + custom: ingressgateway + annotations: + sidecar.istio.io/inject: "false" + scheduler.alpha.kubernetes.io/critical-pod: "" + spec: + serviceAccountName: istio-ingressgateway-service-account + containers: + - name: istio-proxy + image: "docker.io/istio/proxyv2:1.0.2" + imagePullPolicy: IfNotPresent + ports: + - containerPort: 80 + - containerPort: 443 + - containerPort: 31400 + - containerPort: 15011 + - containerPort: 8060 + - containerPort: 853 + - containerPort: 15030 + - containerPort: 15031 + args: + - proxy + - router + - -v + - "2" + - --discoveryRefreshDelay + - '1s' #discoveryRefreshDelay + - --drainDuration + - '45s' #drainDuration + - --parentShutdownDuration + - '1m0s' #parentShutdownDuration + - --connectTimeout + - '10s' #connectTimeout + - --serviceCluster + - custom-ingressgateway + - --zipkinAddress + - zipkin:9411 + - --statsdUdpAddress + - istio-statsd-prom-bridge:9125 + - --proxyAdminPort + - "15000" + - --controlPlaneAuthPolicy + - NONE + - --discoveryAddress + - istio-pilot:8080 + resources: + requests: + cpu: 10m + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: ISTIO_META_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: istio-certs + mountPath: /etc/certs + readOnly: true + - name: ingressgateway-certs + mountPath: "/etc/istio/ingressgateway-certs" + readOnly: true + - name: ingressgateway-ca-certs + mountPath: "/etc/istio/ingressgateway-ca-certs" + readOnly: true + volumes: + - name: istio-certs + secret: + secretName: istio.istio-ingressgateway-service-account + optional: true + - name: ingressgateway-certs + secret: + secretName: "istio-ingressgateway-certs" + optional: true + - name: ingressgateway-ca-certs + secret: + secretName: "istio-ingressgateway-ca-certs" + optional: true + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 2 + preference: + matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - amd64 + - weight: 2 + preference: + matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - ppc64le + - weight: 2 + preference: + matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - s390x +``` + + +## Step 2: Update Knative Gateway + +Update gateway instance `knative-shared-gateway` under `knative-serving` namespace: + +```shell +kubectl edit gateway knative-shared-gateway -n knative-serving +``` + +Replace its label selector with the label of your service: + +``` +istio: ingressgateway +``` + +For the service above, it should be updated to + +``` +custom: ingressgateway +``` + +If there is a change in service ports (compared with that of `istio-ingressgateway`), +update the port info in gateway accordingly. + +## Step 3: Update Gateway Configmap + +Update gateway configmap `config-ingressgateway` under `knative-serving` namespace: + +```shell +kubectl edit configmap config-ingressgateway -n knative-serving +``` + +Replace the `ingress-gateway` field with fully qualified url of your service: + +For the service above, it should be updated to + +``` +custom-ingressgateway.istio-system.svc.cluster.local +``` \ No newline at end of file diff --git a/docs/setting-up-ingress-static-ip.md b/docs/setting-up-ingress-static-ip.md index baee0c3e5ac1..4f4077f0f0c5 100644 --- a/docs/setting-up-ingress-static-ip.md +++ b/docs/setting-up-ingress-static-ip.md @@ -3,10 +3,13 @@ Knative uses a shared Gateway to serve all incoming traffic within Knative service mesh, which is the "knative-shared-gateway" Gateway under "knative-serving" namespace. The IP address to access the gateway is the -external IP address of the "knative-ingressgateway" service under the +external IP address of the "istio-ingressgateway" service under the "istio-system" namespace. So in order to set static IP for the Knative shared gateway, you just need to set the external IP address of the -"knative-ingressgateway" service to the static IP you need. +"istio-ingressgateway" service to the static IP you need. +If the gateway service has been replaced to that of other service, you'll +need to replace "istio-ingressgateway" with the service name accordingly. +See [instructions](../setting-up-custom-ingress-gateway.md) for more details. ## Prerequisites @@ -30,28 +33,28 @@ gateway. ## Set Up Static IP for Knative Gateway -### Step 1: Update external IP of "knative-ingressgateway" service +### Step 1: Update external IP of "istio-ingressgateway" service Run following command to reset the external IP for the -"knative-ingressgateway" service to the static IP you reserved. +"istio-ingressgateway" service to the static IP you reserved. ```shell -kubectl patch svc knative-ingressgateway -n istio-system --patch '{"spec": { "loadBalancerIP": "" }}' +kubectl patch svc istio-ingressgateway -n istio-system --patch '{"spec": { "loadBalancerIP": "" }}' ``` -### Step 2: Verify static IP address of knative-ingressgateway service +### Step 2: Verify static IP address of istio-ingressgateway service -You can check the external IP of the "knative-ingressgateway" service with: +You can check the external IP of the "istio-ingressgateway" service with: ```shell -kubectl get svc knative-ingressgateway -n istio-system +kubectl get svc istio-ingressgateway -n istio-system ``` The result should be something like ```console -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -knative-ingressgateway LoadBalancer 10.50.250.120 35.210.48.100 80:32380/TCP,443:32390/TCP,32400:32400/TCP 5h +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +istio-ingressgateway LoadBalancer 10.50.250.120 35.210.48.100 80:31380/TCP,443:31390/TCP,31400:31400/TCP... 5h ``` The external IP will be eventually set to the static IP. This process could diff --git a/pkg/reconciler/v1alpha1/clusteringress/clusteringress.go b/pkg/reconciler/v1alpha1/clusteringress/clusteringress.go index 8bb12c81eb6f..cc54262f1d7d 100644 --- a/pkg/reconciler/v1alpha1/clusteringress/clusteringress.go +++ b/pkg/reconciler/v1alpha1/clusteringress/clusteringress.go @@ -23,6 +23,7 @@ import ( "github.com/knative/pkg/apis/istio/v1alpha3" istioinformers "github.com/knative/pkg/client/informers/externalversions/istio/v1alpha3" istiolisters "github.com/knative/pkg/client/listers/istio/v1alpha3" + "github.com/knative/pkg/configmap" "github.com/knative/pkg/controller" "github.com/knative/pkg/logging" "github.com/knative/serving/pkg/apis/networking" @@ -30,8 +31,8 @@ import ( informers "github.com/knative/serving/pkg/client/informers/externalversions/networking/v1alpha1" listers "github.com/knative/serving/pkg/client/listers/networking/v1alpha1" "github.com/knative/serving/pkg/reconciler" + "github.com/knative/serving/pkg/reconciler/v1alpha1/clusteringress/config" "github.com/knative/serving/pkg/reconciler/v1alpha1/clusteringress/resources" - "github.com/knative/serving/pkg/reconciler/v1alpha1/clusteringress/resources/names" "go.uber.org/zap" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" @@ -47,6 +48,11 @@ const ( controllerAgentName = "clusteringress-controller" ) +type configStore interface { + ToContext(ctx context.Context) context.Context + WatchConfigs(w configmap.Watcher) +} + // Reconciler implements controller.Reconciler for ClusterIngress resources. type Reconciler struct { *reconciler.Base @@ -54,6 +60,7 @@ type Reconciler struct { // listers index properties about resources clusterIngressLister listers.ClusterIngressLister virtualServiceLister istiolisters.VirtualServiceLister + configStore configStore } // Check that our Reconciler implements controller.Reconciler @@ -94,6 +101,12 @@ func NewController( }, }) + c.Logger.Info("Setting up ConfigMap receivers") + resyncIngressesOnIstioConfigChange := configmap.TypeFilter(&config.Istio{})(func(string, interface{}) { + impl.GlobalResync(clusterIngressInformer.Informer()) + }) + c.configStore = config.NewStore(c.Logger.Named("config-store"), resyncIngressesOnIstioConfigChange) + c.configStore.WatchConfigs(opt.ConfigMapWatcher) return impl } @@ -109,6 +122,8 @@ func (c *Reconciler) Reconcile(ctx context.Context, key string) error { } logger := logging.FromContext(ctx) + ctx = c.configStore.ToContext(ctx) + // Get the ClusterIngress resource with this name. original, err := c.clusterIngressLister.Get(name) if apierrs.IsNotFound(err) { @@ -173,12 +188,16 @@ func (c *Reconciler) reconcile(ctx context.Context, ci *v1alpha1.ClusterIngress) // is successfully synced. ci.Status.MarkNetworkConfigured() ci.Status.MarkLoadBalancerReady([]v1alpha1.LoadBalancerIngressStatus{ - {DomainInternal: names.K8sGatewayServiceFullname}, + {DomainInternal: ingressGatewayFromContext(ctx)}, }) logger.Info("ClusterIngress successfully synced") return nil } +func ingressGatewayFromContext(ctx context.Context) string { + return config.FromContext(ctx).Istio.IngressGateway +} + func (c *Reconciler) reconcileVirtualService(ctx context.Context, ci *v1alpha1.ClusterIngress, desired *v1alpha3.VirtualService) error { logger := logging.FromContext(ctx) diff --git a/pkg/reconciler/v1alpha1/clusteringress/clusteringress_test.go b/pkg/reconciler/v1alpha1/clusteringress/clusteringress_test.go index fd1fab0b02ef..ff382e64971b 100644 --- a/pkg/reconciler/v1alpha1/clusteringress/clusteringress_test.go +++ b/pkg/reconciler/v1alpha1/clusteringress/clusteringress_test.go @@ -17,27 +17,43 @@ limitations under the License. package clusteringress import ( + "context" "testing" + "time" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/watch" + kubeinformers "k8s.io/client-go/informers" + fakekubeclientset "k8s.io/client-go/kubernetes/fake" clientgotesting "k8s.io/client-go/testing" duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" "github.com/knative/pkg/apis/istio/v1alpha3" + fakesharedclientset "github.com/knative/pkg/client/clientset/versioned/fake" + sharedinformers "github.com/knative/pkg/client/informers/externalversions" + "github.com/knative/pkg/configmap" "github.com/knative/pkg/controller" "github.com/knative/pkg/kmeta" "github.com/knative/serving/pkg/apis/networking" "github.com/knative/serving/pkg/apis/networking/v1alpha1" "github.com/knative/serving/pkg/apis/serving" + fakeclientset "github.com/knative/serving/pkg/client/clientset/versioned/fake" + informers "github.com/knative/serving/pkg/client/informers/externalversions" "github.com/knative/serving/pkg/reconciler" + "github.com/knative/serving/pkg/reconciler/v1alpha1/clusteringress/config" "github.com/knative/serving/pkg/reconciler/v1alpha1/clusteringress/resources" . "github.com/knative/serving/pkg/reconciler/v1alpha1/testing" "github.com/knative/serving/pkg/system" ) +const ( + originGateway = "origin.ns.svc.cluster.local" + customGateway = "custom.ns.svc.cluster.local" +) + var ( ingressRules = []v1alpha1.ClusterIngressRule{{ Hosts: []string{ @@ -97,7 +113,7 @@ func TestReconcile(t *testing.T) { v1alpha1.IngressStatus{ LoadBalancer: &v1alpha1.LoadBalancerStatus{ Ingress: []v1alpha1.LoadBalancerIngressStatus{ - {DomainInternal: "knative-ingressgateway.istio-system.svc.cluster.local"}, + {DomainInternal: reconciler.GetK8sServiceFullname("istio-ingressgateway", "istio-system")}, }, }, Conditions: duckv1alpha1.Conditions{{ @@ -146,7 +162,7 @@ func TestReconcile(t *testing.T) { v1alpha1.IngressStatus{ LoadBalancer: &v1alpha1.LoadBalancerStatus{ Ingress: []v1alpha1.LoadBalancerIngressStatus{ - {DomainInternal: "knative-ingressgateway.istio-system.svc.cluster.local"}, + {DomainInternal: reconciler.GetK8sServiceFullname("istio-ingressgateway", "istio-system")}, }, }, Conditions: duckv1alpha1.Conditions{{ @@ -177,6 +193,9 @@ func TestReconcile(t *testing.T) { Base: reconciler.NewBase(opt, controllerAgentName), virtualServiceLister: listers.GetVirtualServiceLister(), clusterIngressLister: listers.GetClusterIngressLister(), + configStore: &testConfigStore{ + config: ReconcilerTestConfig(), + }, } })) } @@ -192,6 +211,26 @@ func addAnnotations(ing *v1alpha1.ClusterIngress, annos map[string]string) *v1al return ing } +type testConfigStore struct { + config *config.Config +} + +func (t *testConfigStore) ToContext(ctx context.Context) context.Context { + return config.ToContext(ctx, t.config) +} + +func (t *testConfigStore) WatchConfigs(w configmap.Watcher) {} + +var _ configStore = (*testConfigStore)(nil) + +func ReconcilerTestConfig() *config.Config { + return &config.Config{ + Istio: &config.Istio{ + IngressGateway: reconciler.GetK8sServiceFullname("istio-ingressgateway", "istio-system"), + }, + } +} + func ingressWithStatus(name string, generation int64, status v1alpha1.IngressStatus) *v1alpha1.ClusterIngress { return &v1alpha1.ClusterIngress{ ObjectMeta: metav1.ObjectMeta{ @@ -212,3 +251,145 @@ func ingressWithStatus(name string, generation int64, status v1alpha1.IngressSta func ingress(name string, generation int64) *v1alpha1.ClusterIngress { return ingressWithStatus(name, generation, v1alpha1.IngressStatus{}) } + +func newTestSetup(t *testing.T, configs ...*corev1.ConfigMap) ( + kubeClient *fakekubeclientset.Clientset, + sharedClient *fakesharedclientset.Clientset, + servingClient *fakeclientset.Clientset, + controller *controller.Impl, + rclr *Reconciler, + kubeInformer kubeinformers.SharedInformerFactory, + sharedInformer sharedinformers.SharedInformerFactory, + servingInformer informers.SharedInformerFactory, + configMapWatcher *configmap.ManualWatcher) { + + kubeClient = fakekubeclientset.NewSimpleClientset() + cms := []*corev1.ConfigMap{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: config.IstioConfigName, + Namespace: system.Namespace, + }, + Data: map[string]string{ + config.IngressGatewayKey: originGateway, + }, + }, + } + for _, cm := range configs { + cms = append(cms, cm) + } + + configMapWatcher = &configmap.ManualWatcher{Namespace: system.Namespace} + sharedClient = fakesharedclientset.NewSimpleClientset() + servingClient = fakeclientset.NewSimpleClientset() + + // Create informer factories with fake clients. The second parameter sets the + // resync period to zero, disabling it. + kubeInformer = kubeinformers.NewSharedInformerFactory(kubeClient, 0) + sharedInformer = sharedinformers.NewSharedInformerFactory(sharedClient, 0) + servingInformer = informers.NewSharedInformerFactory(servingClient, 0) + + controller = NewController( + reconciler.Options{ + KubeClientSet: kubeClient, + SharedClientSet: sharedClient, + ServingClientSet: servingClient, + ConfigMapWatcher: configMapWatcher, + Logger: TestLogger(t), + }, + servingInformer.Networking().V1alpha1().ClusterIngresses(), + sharedInformer.Networking().V1alpha3().VirtualServices(), + ) + + rclr = controller.Reconciler.(*Reconciler) + + for _, cfg := range cms { + configMapWatcher.OnChange(cfg) + } + + return +} + +func TestGlobalResyncOnUpdateGatewayConfigMap(t *testing.T) { + _, _, servingClient, controller, _, _, sharedInformer, servingInformer, watcher := newTestSetup(t) + + stopCh := make(chan struct{}) + defer func() { + close(stopCh) + }() + + servingInformer.Start(stopCh) + sharedInformer.Start(stopCh) + if err := watcher.Start(stopCh); err != nil { + t.Fatalf("failed to start cluster ingress manager: %v", err) + } + + go controller.Run(1, stopCh) + + ingress := ingressWithStatus("config-update", 1234, + v1alpha1.IngressStatus{ + LoadBalancer: &v1alpha1.LoadBalancerStatus{ + Ingress: []v1alpha1.LoadBalancerIngressStatus{ + {DomainInternal: originGateway}, + }, + }, + Conditions: duckv1alpha1.Conditions{{ + Type: v1alpha1.ClusterIngressConditionLoadBalancerReady, + Status: corev1.ConditionTrue, + }, { + Type: v1alpha1.ClusterIngressConditionNetworkConfigured, + Status: corev1.ConditionTrue, + }, { + Type: v1alpha1.ClusterIngressConditionReady, + Status: corev1.ConditionTrue, + }}, + }, + ) + ingressClient := servingClient.NetworkingV1alpha1().ClusterIngresses() + ingressWatcher, err := ingressClient.Watch(metav1.ListOptions{}) + if err != nil { + t.Fatalf("Could not create ingress watcher") + } + defer ingressWatcher.Stop() + + // Create a ingress. + ingressClient.Create(ingress) + + // Test changes in gateway config map. ClusterIngress should get updated appropriately. + expectedGateway := customGateway + domainConfig := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.IstioConfigName, + Namespace: system.Namespace, + }, + Data: map[string]string{ + config.IngressGatewayKey: customGateway, + }, + } + watcher.OnChange(&domainConfig) + timer := time.NewTimer(10 * time.Second) + +loop: + for { + select { + case event := <-ingressWatcher.ResultChan(): + if event.Type == watch.Modified { + break loop + } + case <-timer.C: + t.Fatalf("ingressWatcher did not receive a Type==Modified event in 10s") + } + } + + ingress, err = ingressClient.Get(ingress.Name, metav1.GetOptions{}) + if err != nil { + t.Fatalf("Error getting a ingress: %v", err) + } + gateways := ingress.Status.LoadBalancer.Ingress + if len(gateways) != 1 { + t.Errorf("Unexpected gateways: %v", gateways) + } + if gateways[0].DomainInternal != expectedGateway { + t.Errorf("Expected gateway %q but got %q", expectedGateway, gateways[0].DomainInternal) + } +} diff --git a/pkg/reconciler/v1alpha1/clusteringress/resources/names/names.go b/pkg/reconciler/v1alpha1/clusteringress/resources/names/names.go index 016ca8f9ffda..83f298da955c 100644 --- a/pkg/reconciler/v1alpha1/clusteringress/resources/names/names.go +++ b/pkg/reconciler/v1alpha1/clusteringress/resources/names/names.go @@ -27,11 +27,6 @@ var K8sGatewayFullname = reconciler.GetK8sServiceFullname( "knative-shared-gateway", system.Namespace) -// K8sGatewayServiceFullname is the fully-qualified name of in-cluster Knative gateway. -var K8sGatewayServiceFullname = reconciler.GetK8sServiceFullname( - "knative-ingressgateway", - "istio-system") - // VirtualService returns the name of the VirtualService child resource for given ClusterIngress. func VirtualService(i *v1alpha1.ClusterIngress) string { return i.Name diff --git a/pkg/reconciler/v1alpha1/route/resources/service_test.go b/pkg/reconciler/v1alpha1/route/resources/service_test.go index 91add25ee167..0d2bb04d160a 100644 --- a/pkg/reconciler/v1alpha1/route/resources/service_test.go +++ b/pkg/reconciler/v1alpha1/route/resources/service_test.go @@ -104,13 +104,13 @@ func TestNewMakeK8SService(t *testing.T) { ingress: &netv1alpha1.ClusterIngress{ Status: netv1alpha1.IngressStatus{ LoadBalancer: &netv1alpha1.LoadBalancerStatus{ - Ingress: []netv1alpha1.LoadBalancerIngressStatus{{DomainInternal: "knative-ingressgateway.istio-system.svc.cluster.local"}}, + Ingress: []netv1alpha1.LoadBalancerIngressStatus{{DomainInternal: "istio-ingressgateway.istio-system.svc.cluster.local"}}, }, }, }, expectedSpec: corev1.ServiceSpec{ Type: corev1.ServiceTypeExternalName, - ExternalName: "knative-ingressgateway.istio-system.svc.cluster.local", + ExternalName: "istio-ingressgateway.istio-system.svc.cluster.local", }, }, } diff --git a/pkg/reconciler/v1alpha1/route/table_test.go b/pkg/reconciler/v1alpha1/route/table_test.go index 28bdd39ef7a7..076451f56e8e 100644 --- a/pkg/reconciler/v1alpha1/route/table_test.go +++ b/pkg/reconciler/v1alpha1/route/table_test.go @@ -1209,7 +1209,7 @@ func readyIngressStatus() netv1alpha1.IngressStatus { status.InitializeConditions() status.MarkNetworkConfigured() status.MarkLoadBalancerReady([]netv1alpha1.LoadBalancerIngressStatus{ - {DomainInternal: reconciler.GetK8sServiceFullname("knative-ingressgateway", "istio-system")}, + {DomainInternal: reconciler.GetK8sServiceFullname("istio-ingressgateway", "istio-system")}, }) return status diff --git a/test/README.md b/test/README.md index 3c1be03f1f7c..14ab19e8a11d 100644 --- a/test/README.md +++ b/test/README.md @@ -177,7 +177,7 @@ use the domain `example.com`, unless the route has label `app=prod` in which case they will use the domain `prod-domain.com`. Since these domains will not be resolvable to deployments in your test cluster, in order to make a request against the endpoint, the test use the IP assigned to the service -`knative-ingressgateway` in the namespace `istio-system` and spoof the `Host` in +`istio-ingressgateway` in the namespace `istio-system` and spoof the `Host` in the header. If you have configured your cluster to use a resolvable domain, you can use the diff --git a/test/cluster.sh b/test/cluster.sh index cab18c849fcc..578676164c95 100644 --- a/test/cluster.sh +++ b/test/cluster.sh @@ -92,14 +92,14 @@ function install_knative_serving() { # We should revisit this when Istio API exposes a Status that we can rely on. # TODO(tcnghia): remove this when https://github.com/istio/istio/issues/882 is fixed. echo ">> Patching Istio" - kubectl patch hpa -n istio-system knative-ingressgateway --patch '{"spec": {"maxReplicas": 1}}' || return 1 + kubectl patch hpa -n istio-system istio-ingressgateway --patch '{"spec": {"maxReplicas": 1}}' || return 1 echo ">> Creating test resources (test/config/)" ko apply -f test/config/ || return 1 wait_until_pods_running knative-serving || return 1 wait_until_pods_running istio-system || return 1 - wait_until_service_has_external_ip istio-system knative-ingressgateway + wait_until_service_has_external_ip istio-system istio-ingressgateway } # Uninstalls Knative Serving from the current cluster. diff --git a/test/e2e/helloworld_shell_test.go b/test/e2e/helloworld_shell_test.go index 1e60ce2ba493..c1dd875d937d 100644 --- a/test/e2e/helloworld_shell_test.go +++ b/test/e2e/helloworld_shell_test.go @@ -102,7 +102,7 @@ func TestHelloWorldFromShell(t *testing.T) { timeout := ingressTimeout for (serviceIP == "" || serviceHost == "") && timeout >= 0 { serviceHost = noStderrShell("kubectl", "get", "rt", "route-example", "-o", "jsonpath={.status.domain}", "-n", test.ServingNamespace) - serviceIP = noStderrShell("kubectl", "get", "svc", "knative-ingressgateway", "-n", "istio-system", + serviceIP = noStderrShell("kubectl", "get", "svc", "istio-ingressgateway", "-n", "istio-system", "-o", "jsonpath={.status.loadBalancer.ingress[*]['ip']}") time.Sleep(checkInterval) timeout = timeout - checkInterval diff --git a/test/performance/performance.go b/test/performance/performance.go index a7a6d2f4e162..a1c77ba6ee17 100644 --- a/test/performance/performance.go +++ b/test/performance/performance.go @@ -37,7 +37,7 @@ import ( const ( istioNS = "istio-system" monitoringNS = "knative-monitoring" - gateway = "knative-ingressgateway" + gateway = "istio-ingressgateway" ) type PerformanceClient struct { diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/addressable_types.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/addressable_types.go index 0bf1f986dc00..bc7917975c31 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/addressable_types.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/addressable_types.go @@ -37,7 +37,6 @@ type Addressable struct { Hostname string `json:"hostname,omitempty"` } - // Addressable is an Implementable "duck type". var _ duck.Implementable = (*Addressable)(nil) diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/generational_types.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/generational_types.go index c8197f67452d..13ef018038ea 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/generational_types.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/generational_types.go @@ -27,7 +27,6 @@ import ( // Generation is the schema for the generational portion of the payload type Generation int64 - // Generation is an Implementable "duck type". var _ duck.Implementable = (*Generation)(nil) diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/legacy_targetable_types.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/legacy_targetable_types.go index ee50201e83c4..3e13d9eafc9b 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/legacy_targetable_types.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/legacy_targetable_types.go @@ -41,7 +41,6 @@ type LegacyTargetable struct { DomainInternal string `json:"domainInternal,omitempty"` } - // LegacyTargetable is an Implementable "duck type". var _ duck.Implementable = (*LegacyTargetable)(nil) diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/retired_targetable_types.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/retired_targetable_types.go index 695e11c3f653..ab578e523b26 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/retired_targetable_types.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/retired_targetable_types.go @@ -37,7 +37,6 @@ type Targetable struct { DomainInternal string `json:"domainInternal,omitempty"` } - // Targetable is an Implementable "duck type". var _ duck.Implementable = (*Targetable)(nil) diff --git a/vendor/github.com/knative/pkg/apis/istio/authentication/v1alpha1/policy_types.go b/vendor/github.com/knative/pkg/apis/istio/authentication/v1alpha1/policy_types.go index 5e3357b1d7b5..11bea675654b 100644 --- a/vendor/github.com/knative/pkg/apis/istio/authentication/v1alpha1/policy_types.go +++ b/vendor/github.com/knative/pkg/apis/istio/authentication/v1alpha1/policy_types.go @@ -17,8 +17,8 @@ limitations under the License. package v1alpha1 import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/knative/pkg/apis/istio/common/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // +genclient @@ -127,7 +127,7 @@ type PolicySpec struct { // List rules to select destinations that the policy should be applied on. // If empty, policy will be used on all destinations in the same namespace. Targets []TargetSelector `json:"targets,omitempty"` - + // List of authentication methods that can be used for peer authentication. // They will be evaluated in order; the first validate one will be used to // set peer identity (source.user) and other peer attributes. If none of @@ -135,14 +135,14 @@ type PolicySpec struct { // request will be rejected with authentication failed error (401). // Leave the list empty if peer authentication is not required Peers []PeerAuthenticationMethod `json:"peers,omitempty"` - + // Set this flag to true to accept request (for peer authentication perspective), // even when none of the peer authentication methods defined above satisfied. // Typically, this is used to delay the rejection decision to next layer (e.g // authorization). // This flag is ignored if no authentication defined for peer (peers field is empty). PeerIsOptional bool `json:"peerIsOptional,omitempty"` - + // List of authentication methods that can be used for origin authentication. // Similar to peers, these will be evaluated in order; the first validate one // will be used to set origin identity and attributes (i.e request.auth.user, @@ -151,17 +151,17 @@ type PolicySpec struct { // error (401). // Leave the list empty if origin authentication is not required. Origins []OriginAuthenticationMethod `json:"origins,omitempty"` - + // Set this flag to true to accept request (for origin authentication perspective), // even when none of the origin authentication methods defined above satisfied. // Typically, this is used to delay the rejection decision to next layer (e.g // authorization). // This flag is ignored if no authentication defined for origin (origins field is empty). OriginIsOptional bool `json:"originIsOptional,omitempty"` - + // Define whether peer or origin identity should be use for principal. Default // value is USE_PEER. - // If peer (or orgin) identity is not available, either because of peer/origin + // If peer (or origin) identity is not available, either because of peer/origin // authentication is not defined, or failed, principal will be left unset. // In other words, binding rule does not affect the decision to accept or // reject request. @@ -173,7 +173,7 @@ type TargetSelector struct { // REQUIRED. The name must be a short name from the service registry. The // fully qualified domain name will be resolved in a platform specific manner. Name string `json:"name"` - + // Specifies the ports on the destination. Leave empty to match all ports // that are exposed. Ports []PortSelector `json:"ports,omitempty"` @@ -183,12 +183,12 @@ type TargetSelector struct { // matching targets for authenticationn policy. This is copied from // networking API to avoid dependency. type PortSelector struct { - // It is requred to specify exactly one of the fields: + // It is required to specify exactly one of the fields: // Number or Name // Valid port number Number uint32 `json:"number,omitempty"` - + // Port name Name string `json:"name,omitempty"` } @@ -199,11 +199,11 @@ type PortSelector struct { // The type can be progammatically determine by checking the type of the // "params" field. type PeerAuthenticationMethod struct { - // It is requred to specify exactly one of the fields: + // It is required to specify exactly one of the fields: // Mtls or Jwt // Set if mTLS is used. Mtls *MutualTls `json:"mtls,omitempty"` - + // Set if JWT is used. This option is not yet available. Jwt *Jwt `json:"jwt,omitempty"` } @@ -214,7 +214,7 @@ type Mode string const ( // Client cert must be presented, connection is in TLS. ModeStrict Mode = "STRICT" - + // Connection can be either plaintext or TLS, and client cert can be omitted. ModePermissive Mode = "PERMISSIVE" ) @@ -229,7 +229,7 @@ type MutualTls struct { // be left unset. // When the flag is false (default), request must have client certificate. AllowTls bool `json:"allowTls,omitempty"` - + // Defines the mode of mTLS authentication. Mode Mode `json:"mode,omitempty"` } @@ -256,7 +256,7 @@ type Jwt struct { // Example: https://securetoken.google.com // Example: 1234567-compute@developer.gserviceaccount.com Issuer string `json:"issuer,omitempty"` - + // The list of JWT // [audiences](https://tools.ietf.org/html/rfc7519#section-4.1.3). // that are allowed to access. A JWT containing any of these @@ -272,7 +272,7 @@ type Jwt struct { // bookstore_web.apps.googleusercontent.com // ``` Audiences []string `json:"audiences,omitempty"` - + // URL of the provider's public key set to validate signature of the // JWT. See [OpenID // Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). @@ -285,7 +285,7 @@ type Jwt struct { // // Example: https://www.googleapis.com/oauth2/v1/certs JwksUri string `json:"jwksUri,omitempty"` - + // Two fields below define where to extract the JWT from an HTTP request. // // If no explicit location is specified the following default @@ -304,7 +304,7 @@ type Jwt struct { // For example, if `header=x-goog-iap-jwt-assertion`, the header // format will be x-goog-iap-jwt-assertion: . JwtHeaders []string `json:"jwtHeaders,omitempty"` - + // JWT is sent in a query parameter. `query` represents the // query parameter name. // @@ -312,9 +312,9 @@ type Jwt struct { JwtParams []string `json:"jwtParams,omitempty"` // URL paths that should be excluded from the JWT validation. If the request path is matched, - // the JWT validation will be skipped and the request will proceed regardless. - // This is useful to keep a couple of URLs public for external health checks. - // Example: "/health_check", "/status/cpu_usage". + // the JWT validation will be skipped and the request will proceed regardless. + // This is useful to keep a couple of URLs public for external health checks. + // Example: "/health_check", "/status/cpu_usage". ExcludedPaths []v1alpha1.StringMatch `json:"excludedPaths,omitempty"` } diff --git a/vendor/github.com/knative/pkg/apis/istio/common/v1alpha1/string.go b/vendor/github.com/knative/pkg/apis/istio/common/v1alpha1/string.go index ec5c8d392417..52336124d4a6 100644 --- a/vendor/github.com/knative/pkg/apis/istio/common/v1alpha1/string.go +++ b/vendor/github.com/knative/pkg/apis/istio/common/v1alpha1/string.go @@ -19,17 +19,17 @@ package v1alpha1 // Describes how to match a given string in HTTP headers. Match is // case-sensitive. type StringMatch struct { - // Specified exactly one of the fields below. + // Specified exactly one of the fields below. - // exact string match - Exact string `json:"exact,omitempty"` + // exact string match + Exact string `json:"exact,omitempty"` - // prefix-based match - Prefix string `json:"prefix,omitempty"` + // prefix-based match + Prefix string `json:"prefix,omitempty"` - // suffix-based match. - Suffix string `json:"prefix,omitempty"` + // suffix-based match. + Suffix string `json:"prefix,omitempty"` - // ECMAscript style regex-based match - Regex string `json:"regex,omitempty"` + // ECMAscript style regex-based match + Regex string `json:"regex,omitempty"` } diff --git a/vendor/github.com/knative/pkg/apis/istio/v1alpha3/destinationrule_types.go b/vendor/github.com/knative/pkg/apis/istio/v1alpha3/destinationrule_types.go index 181d1f7336df..eff821123daf 100644 --- a/vendor/github.com/knative/pkg/apis/istio/v1alpha3/destinationrule_types.go +++ b/vendor/github.com/knative/pkg/apis/istio/v1alpha3/destinationrule_types.go @@ -117,11 +117,11 @@ type DestinationRuleSpec struct { // // Note that the host field applies to both HTTP and TCP services. Host string `json:"host"` - + // Traffic policies to apply (load balancing policy, connection pool // sizes, outlier detection). TrafficPolicy *TrafficPolicy `json:"trafficPolicy,omitempty"` - + // One or more named sets that represent individual versions of a // service. Traffic policies can be overridden at subset level. Subsets []Subset `json:"subsets,omitempty"` @@ -133,16 +133,16 @@ type TrafficPolicy struct { // Settings controlling the load balancer algorithms. LoadBalancer *LoadBalancerSettings `json:"loadBalancer,omitempty"` - + // Settings controlling the volume of connections to an upstream service ConnectionPool *ConnectionPoolSettings `json:"connectionPool,omitempty"` - + // Settings controlling eviction of unhealthy hosts from the load balancing pool OutlierDetection *OutlierDetection `json:"outlierDetection,omitempty"` - + // TLS related settings for connections to the upstream service. Tls *TLSSettings `json:"tls,omitempty"` - + // Traffic policies specific to individual ports. Note that port level // settings will override the destination-level settings. Traffic // settings specified at the destination-level will not be inherited when @@ -161,13 +161,13 @@ type PortTrafficPolicy struct { // the same protocol the names should be of the form -. Port PortSelector `json:"port"` - + // Settings controlling the load balancer algorithms. LoadBalancer *LoadBalancerSettings `json:"loadBalancer,omitempty"` - + // Settings controlling the volume of connections to an upstream service ConnectionPool *ConnectionPoolSettings `json:"connectionPool,omitempty"` - + // Settings controlling eviction of unhealthy hosts from the load balancing pool OutlierDetection *OutlierDetection `json:"outlierDetection,omitempty"` @@ -207,11 +207,11 @@ type Subset struct { // REQUIRED. Name of the subset. The service name and the subset name can // be used for traffic splitting in a route rule. Name string `json:"port"` - + // REQUIRED. Labels apply a filter over the endpoints of a service in the // service registry. See route rules for examples of usage. Labels map[string]string `json:"labels"` - + // Traffic policies that apply to this subset. Subsets inherit the // traffic policies specified at the DestinationRule level. Settings // specified at the subset level will override the corresponding settings @@ -254,7 +254,7 @@ type Subset struct { // name: user // ttl: 0s type LoadBalancerSettings struct { - // It is requred to specify exactly one of the fields: + // It is required to specify exactly one of the fields: // Simple or ConsistentHash Simple SimpleLB `json:"simple,omitempty"` ConsistentHash *ConsistentHashLB `json:"consistentHash,omitempty"` @@ -266,17 +266,17 @@ type SimpleLB string const ( // Round Robin policy. Default SimpleLBRoundRobin SimpleLB = "ROUND_ROBIN" - + // The least request load balancer uses an O(1) algorithm which selects // two random healthy hosts and picks the host which has fewer active // requests. SimpleLBLeastConn SimpleLB = "LEAST_CONN" - + // The random load balancer selects a random healthy host. The random // load balancer generally performs better than round robin if no health // checking policy is configured. SimpleLBRandom SimpleLB = "RANDOM" - + // This option will forward the connection to the original IP address // requested by the caller without doing any form of load // balancing. This option must be used with care. It is meant for @@ -293,17 +293,17 @@ const ( // service. type ConsistentHashLB struct { - // It is requred to specify exactly one of the fields as hash key: + // It is required to specify exactly one of the fields as hash key: // HttpHeaderName, HttpCookie, or UseSourceIP. // Hash based on a specific HTTP header. HttpHeaderName string `json:"httpHeaderName,omitempty"` - + // Hash based on HTTP cookie. HttpCookie *HTTPCookie `json:"httpCookie,omitempty"` - + // Hash based on the source IP address. UseSourceIp bool `json:"useSourceIp,omitempty"` - + // The minimum number of virtual nodes to use for the hash // ring. Defaults to 1024. Larger ring sizes result in more granular // load distributions. If the number of hosts in the load balancing @@ -359,7 +359,7 @@ type ConnectionPoolSettings struct { type TCPSettings struct { // Maximum number of HTTP1 /TCP connections to a destination host. MaxConnections int32 `json:"maxConnections,omitempty"` - + // TCP connection timeout. ConnectTimeout string `json:"connectTimeout,omitempty"` } @@ -368,14 +368,14 @@ type TCPSettings struct { type HTTPSettings struct { // Maximum number of pending HTTP requests to a destination. Default 1024. Http1MaxPendingRequests int32 `json:"http1MaxPendingRequests,omitempty"` - + // Maximum number of requests to a backend. Default 1024. Http2MaxRequests int32 `json:"http2MaxRequests,omitempty"` - + // Maximum number of requests per connection to a backend. Setting this // parameter to 1 disables keep alive. MaxRequestsPerConnection int32 `json:"maxRequestsPerConnection,omitempty"` - + // Maximum number of retries that can be outstanding to all hosts in a // cluster at a given time. Defaults to 3. MaxRetries int32 `json:"maxRetries,omitempty"` @@ -421,18 +421,18 @@ type OutlierDetection struct { // accessed over an opaque TCP connection, connect timeouts and // connection error/failure events qualify as an error. ConsecutiveErrors int32 `json:"consecutiveErrors,omitempty"` - + // Time interval between ejection sweep analysis. format: // 1h/1m/1s/1ms. MUST BE >=1ms. Default is 10s. Interval string `json:"interval,omitempty"` - + // Minimum ejection duration. A host will remain ejected for a period // equal to the product of minimum ejection duration and the number of // times the host has been ejected. This technique allows the system to // automatically increase the ejection period for unhealthy upstream // servers. format: 1h/1m/1s/1ms. MUST BE >=1ms. Default is 30s. BaseEjectionTime string `json:"baseEjectionTime,omitempty"` - + // Maximum % of hosts in the load balancing pool for the upstream // service that can be ejected. Defaults to 10%. MaxEjectionPercent int32 `json:"maxEjectionPercent,omitempty"` @@ -488,29 +488,29 @@ type TLSSettings struct { // REQUIRED: Indicates whether connections to this port should be secured // using TLS. The value of this field determines how TLS is enforced. Mode TLSmode `json:"mode"` - + // REQUIRED if mode is `MUTUAL`. The path to the file holding the // client-side TLS certificate to use. // Should be empty if mode is `ISTIO_MUTUAL`. ClientCertificate string `json:"clientCertificate,omitempty"` - + // REQUIRED if mode is `MUTUAL`. The path to the file holding the // client's private key. // Should be empty if mode is `ISTIO_MUTUAL`. PrivateKey string `json:"privateKey,omitempty"` - + // OPTIONAL: The path to the file containing certificate authority // certificates to use in verifying a presented server certificate. If // omitted, the proxy will not verify the server's certificate. // Should be empty if mode is `ISTIO_MUTUAL`. CaCertificates string `json:"caCertificates,omitempty"` - + // A list of alternate names to verify the subject identity in the // certificate. If specified, the proxy will verify that the server // certificate's subject alt name matches one of the specified values. // Should be empty if mode is `ISTIO_MUTUAL`. SubjectAltNames []string `json:"subjectAltNames,omitempty"` - + // SNI string to present to the server during TLS handshake. // Should be empty if mode is `ISTIO_MUTUAL`. Sni string `json:"sni,omitempty"` @@ -525,11 +525,11 @@ const ( // Originate a TLS connection to the upstream endpoint. TLSmodeSimple TLSmode = "SIMPLE" - + // Secure connections to the upstream using mutual TLS by presenting // client certificates for authentication. TLSmodeMutual TLSmode = "MUTUAL" - + // Secure connections to the upstream using mutual TLS by presenting // client certificates for authentication. // Compared to Mutual mode, this mode uses certificates generated diff --git a/vendor/github.com/knative/pkg/apis/istio/v1alpha3/virtualservice_types.go b/vendor/github.com/knative/pkg/apis/istio/v1alpha3/virtualservice_types.go index eb65683e1925..547ca7cc3a6d 100644 --- a/vendor/github.com/knative/pkg/apis/istio/v1alpha3/virtualservice_types.go +++ b/vendor/github.com/knative/pkg/apis/istio/v1alpha3/virtualservice_types.go @@ -17,8 +17,8 @@ limitations under the License. package v1alpha3 import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/knative/pkg/apis/istio/common/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // +genclient diff --git a/vendor/github.com/knative/pkg/controller/controller.go b/vendor/github.com/knative/pkg/controller/controller.go index cfccd313b721..686c7fe1c244 100644 --- a/vendor/github.com/knative/pkg/controller/controller.go +++ b/vendor/github.com/knative/pkg/controller/controller.go @@ -151,7 +151,7 @@ func (c *Impl) EnqueueLabelOfNamespaceScopedResource(namespaceLabel, nameLabel s labels := object.GetLabels() controllerKey, ok := labels[nameLabel] if !ok { - c.logger.Infof("Object %s/%s does not have a referring name label %s", + c.logger.Debugf("Object %s/%s does not have a referring name label %s", object.GetNamespace(), object.GetName(), nameLabel) return } @@ -159,7 +159,7 @@ func (c *Impl) EnqueueLabelOfNamespaceScopedResource(namespaceLabel, nameLabel s if namespaceLabel != "" { controllerNamespace, ok := labels[namespaceLabel] if !ok { - c.logger.Infof("Object %s/%s does not have a referring namespace label %s", + c.logger.Debugf("Object %s/%s does not have a referring namespace label %s", object.GetNamespace(), object.GetName(), namespaceLabel) return } @@ -175,7 +175,6 @@ func (c *Impl) EnqueueLabelOfNamespaceScopedResource(namespaceLabel, nameLabel s } } - // EnqueueLabelOfClusterScopedResource returns with an Enqueue func // that takes a resource, identifies its controller resource through // given name label, and passes it to EnqueueKey. @@ -191,7 +190,7 @@ func (c *Impl) EnqueueLabelOfClusterScopedResource(nameLabel string) func(obj in labels := object.GetLabels() controllerKey, ok := labels[nameLabel] if !ok { - c.logger.Infof("Object %s/%s does not have a referring name label %s", + c.logger.Debugf("Object %s/%s does not have a referring name label %s", object.GetNamespace(), object.GetName(), nameLabel) return } diff --git a/vendor/github.com/knative/pkg/metrics/metricskey/constants.go b/vendor/github.com/knative/pkg/metrics/metricskey/constants.go index 57d8338a3876..2e5e0f87679b 100644 --- a/vendor/github.com/knative/pkg/metrics/metricskey/constants.go +++ b/vendor/github.com/knative/pkg/metrics/metricskey/constants.go @@ -46,13 +46,13 @@ const ( var ( // KnativeRevisionLabels stores the set of resource labels for resource type knative_revision KnativeRevisionLabels = map[string]struct{}{ - LabelProject: struct{}{}, - LabelLocation: struct{}{}, - LabelClusterName: struct{}{}, - LabelNamespaceName: struct{}{}, - LabelServiceName: struct{}{}, - LabelConfigurationName: struct{}{}, - LabelRevisionName: struct{}{}, + LabelProject: {}, + LabelLocation: {}, + LabelClusterName: {}, + LabelNamespaceName: {}, + LabelServiceName: {}, + LabelConfigurationName: {}, + LabelRevisionName: {}, } // ResourceTypeToLabelsMap maps resource type to the set of resource labels diff --git a/vendor/github.com/knative/pkg/test/spoof/spoof.go b/vendor/github.com/knative/pkg/test/spoof/spoof.go index 9c94b3c5e705..071617a58f52 100644 --- a/vendor/github.com/knative/pkg/test/spoof/spoof.go +++ b/vendor/github.com/knative/pkg/test/spoof/spoof.go @@ -30,6 +30,7 @@ import ( "github.com/knative/pkg/test/logging" zipkin "github.com/knative/pkg/test/zipkin" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" @@ -43,10 +44,14 @@ const ( requestInterval = 1 * time.Second requestTimeout = 5 * time.Minute // TODO(tcnghia): These probably shouldn't be hard-coded here? - ingressName = "knative-ingressgateway" ingressNamespace = "istio-system" ) +// Temporary work around the upgrade test issue for knative/serving#2434. +// TODO(lichuqiang): remove the backward compatibility for knative-ingressgateway +// once knative/serving#2434 is merged +var ingressNames = []string{"knative-ingressgateway", "istio-ingressgateway"} + // Response is a stripped down subset of http.Response. The is primarily useful // for ResponseCheckers to inspect the response body without consuming it. // Notably, Body is a byte slice instead of an io.ReadCloser. @@ -121,10 +126,18 @@ func New(kubeClientset *kubernetes.Clientset, logger *logging.BaseLogger, domain // GetServiceEndpoint gets the endpoint IP or hostname to use for the service func GetServiceEndpoint(kubeClientset *kubernetes.Clientset) (*string, error) { var endpoint string - ingress, err := kubeClientset.CoreV1().Services(ingressNamespace).Get(ingressName, metav1.GetOptions{}) + var ingress *v1.Service + var err error + for _, ingressName := range ingressNames { + ingress, err = kubeClientset.CoreV1().Services(ingressNamespace).Get(ingressName, metav1.GetOptions{}) + if err == nil { + break + } + } if err != nil { return nil, err } + ingresses := ingress.Status.LoadBalancer.Ingress if len(ingresses) != 1 { return nil, fmt.Errorf("Expected exactly one ingress load balancer, instead had %d: %s", len(ingresses), ingresses) @@ -132,7 +145,7 @@ func GetServiceEndpoint(kubeClientset *kubernetes.Clientset) (*string, error) { ingressToUse := ingresses[0] if ingressToUse.IP == "" { if ingressToUse.Hostname == "" { - return nil, fmt.Errorf("Expected ingress loadbalancer IP or hostname for %s to be set, instead was empty", ingressName) + return nil, fmt.Errorf("Expected ingress loadbalancer IP or hostname for %s to be set, instead was empty", ingress.Name) } endpoint = ingressToUse.Hostname } else { @@ -232,4 +245,4 @@ func (sc *SpoofingClient) LogZipkinTrace(traceID string) error { sc.logger.Infof(prettyJSON.String()) return nil -} \ No newline at end of file +} diff --git a/vendor/github.com/knative/pkg/test/zipkin/util.go b/vendor/github.com/knative/pkg/test/zipkin/util.go index 5d41e5dbc731..a06df7e2a519 100644 --- a/vendor/github.com/knative/pkg/test/zipkin/util.go +++ b/vendor/github.com/knative/pkg/test/zipkin/util.go @@ -27,8 +27,8 @@ import ( "github.com/knative/pkg/test/logging" "go.opencensus.io/trace" - "k8s.io/client-go/kubernetes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" ) const ( @@ -68,7 +68,7 @@ func SetupZipkinTracing(kubeClientset *kubernetes.Clientset) error { return errors.New("No Zipkin Pod found on the cluster. Ensure monitoring is switched on for your Knative Setup") } - portForwardCmd := exec.Command("kubectl", "port-forward", "--namespace=" + ZipkinNamespace, zipkinPods.Items[0].Name, fmt.Sprintf("%d:%d", ZipkinPort, ZipkinPort)) + portForwardCmd := exec.Command("kubectl", "port-forward", "--namespace="+ZipkinNamespace, zipkinPods.Items[0].Name, fmt.Sprintf("%d:%d", ZipkinPort, ZipkinPort)) if err = portForwardCmd.Start(); err != nil { return fmt.Errorf("Error starting kubectl port-forward command : %v", err) @@ -107,4 +107,4 @@ func CheckZipkinPortAvailability() error { } server.Close() return nil -} \ No newline at end of file +}