Repository: knative/serving
Pull request #9855 (2020-10-18 13:32:12)

Add images to ResourceNames
<!-- Please include the 'why' behind your changes if no issue exists -->
## Proposed Changes

* Addressed comment https://github.com/knative/serving/pull/9387#discussion_r500783493
* Refactored testcases for multi container

**Release Note**

<!-- Enter your extended release note in the below block. If the PR requires
additional action from users switching to the new release, include the string
"action required". If no release note is required, write "NONE". -->

```release-note
None
```

/cc @markusthoemmes @julz @dprotaso 

knative-prow-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/9855#" title="Author self-approved">savitaashture</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **tcnghia** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @tcnghia` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fserving).

<details open>
Needs approval from an approver in each of these files:

- **[test/OWNERS](https://github.com/knative/serving/blob/master/test/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["tcnghia"]} -->
codecov[bot]: # [Codecov](https://codecov.io/gh/knative/serving/pull/9855?src=pr&el=h1) Report
> Merging [#9855](https://codecov.io/gh/knative/serving/pull/9855?src=pr&el=desc) into [master](https://codecov.io/gh/knative/serving/commit/92e215b98b323017f639bd0dc5d7ac0f103a498f?el=desc) will **decrease** coverage by `0.03%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/knative/serving/pull/9855/graphs/tree.svg?width=650&height=150&src=pr&token=MPpDfAj4Ui)](https://codecov.io/gh/knative/serving/pull/9855?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #9855      +/-   ##
==========================================
- Coverage   87.76%   87.72%   -0.04%     
==========================================
  Files         180      180              
  Lines        8596     8588       -8     
==========================================
- Hits         7544     7534      -10     
- Misses        803      805       +2     
  Partials      249      249              
```


| [Impacted Files](https://codecov.io/gh/knative/serving/pull/9855?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/autoscaler/scaling/multiscaler.go](https://codecov.io/gh/knative/serving/pull/9855/diff?src=pr&el=tree#diff-cGtnL2F1dG9zY2FsZXIvc2NhbGluZy9tdWx0aXNjYWxlci5nbw==) | `88.03% <0.00%> (-1.71%)` | :arrow_down: |
| [pkg/autoscaler/statforwarder/forwarder.go](https://codecov.io/gh/knative/serving/pull/9855/diff?src=pr&el=tree#diff-cGtnL2F1dG9zY2FsZXIvc3RhdGZvcndhcmRlci9mb3J3YXJkZXIuZ28=) | `81.18% <0.00%> (-1.08%)` | :arrow_down: |
| [pkg/reconciler/route/resources/ingress.go](https://codecov.io/gh/knative/serving/pull/9855/diff?src=pr&el=tree#diff-cGtnL3JlY29uY2lsZXIvcm91dGUvcmVzb3VyY2VzL2luZ3Jlc3MuZ28=) | `96.74% <0.00%> (-0.20%)` | :arrow_down: |
| [pkg/reconciler/configuration/configuration.go](https://codecov.io/gh/knative/serving/pull/9855/diff?src=pr&el=tree#diff-cGtnL3JlY29uY2lsZXIvY29uZmlndXJhdGlvbi9jb25maWd1cmF0aW9uLmdv) | `89.34% <0.00%> (+1.63%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/knative/serving/pull/9855?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/knative/serving/pull/9855?src=pr&el=footer). Last update [92e215b...72192a4](https://codecov.io/gh/knative/serving/pull/9855?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

knative-prow-robot: @savitaashture: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-serving-build-tests | 72192a4b633da989539fddcd25f722e4e96a9981 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/9855/pull-knative-serving-build-tests/1317821044391677955) | `/test pull-knative-serving-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative_serving/9855). [Your PR dashboard](https://gubernator.knative.dev/pr/savitaashture).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @savitaashture: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-serving-build-tests | 72192a4b633da989539fddcd25f722e4e96a9981 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/9855/pull-knative-serving-build-tests/1317821044391677955) | `/test pull-knative-serving-build-tests`
pull-knative-serving-istio-stable-no-mesh | 72192a4b633da989539fddcd25f722e4e96a9981 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/9855/pull-knative-serving-istio-stable-no-mesh/1317821044391677956) | `/test pull-knative-serving-istio-stable-no-mesh`

[Full PR test history](https://gubernator.knative.dev/pr/knative_serving/9855). [Your PR dashboard](https://gubernator.knative.dev/pr/savitaashture).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
savitaashture: > At first look this seems like it makes the common case a bit harder -- which may be worth it, but maybe not. Did you consider keeping the existing Image field for the common case, and adding an additional Images field just for the multi-container case?

@julz i have modified existing Image field `string` to `[]string` because I was not sure which way will be better so i went with modifying existing field
I agree with you that in order to make common case easier like earlier keeping existing `image` filed make sense and adding new field `images` for multi container case.

lets see others thoughts on this and based on that will modify the PR
knative-prow-robot: @savitaashture: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-serving-istio-stable-no-mesh | 4a9feb0821f978dfe6acd22a34efd310632a571c | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/9855/pull-knative-serving-istio-stable-no-mesh/1318081636679553027) | `/test pull-knative-serving-istio-stable-no-mesh`

[Full PR test history](https://gubernator.knative.dev/pr/knative_serving/9855). [Your PR dashboard](https://gubernator.knative.dev/pr/savitaashture).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @savitaashture: PR needs rebase.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
savitaashture: > > At first look this seems like it makes the common case a bit harder -- which may be worth it, but maybe not. Did you consider keeping the existing Image field for the common case, and adding an additional Images field just for the multi-container case?
> 
> @julz i have modified existing Image field `string` to `[]string` because I was not sure which way would be better so i went with modifying existing field
> I agree with you that in order to make common case easier like earlier keeping existing `image` filed make sense and adding new field `images` for multi container case.
> 
> lets see others thoughts on this and based on that will modify the PR

@dprotaso @markusthoemmes 
knative-prow-robot: @savitaashture: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-serving-build-tests | c9160ea3baba2e6fa3c9a06e07f443d10ce00aa9 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/9855/pull-knative-serving-build-tests/1324061594400854016) | `/test pull-knative-serving-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative_serving/9855). [Your PR dashboard](https://gubernator.knative.dev/pr/savitaashture).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->

Patch:
diff --git a/.github/workflows/knative-releasability.yaml b/.github/workflows/knative-releasability.yaml
index e3e928013..f13cc479a 100644
--- a/.github/workflows/knative-releasability.yaml
+++ b/.github/workflows/knative-releasability.yaml
@@ -80,7 +80,7 @@ jobs:
           # The following pushes the stdout of buoy into $CHECK_MESSAGE
           CHECK=0
           echo 'CHECK_MESSAGE<<EOF' >> $GITHUB_ENV
-          buoy check go.mod --release ${RELEASE} --domain knative.dev --verbose >> $GITHUB_ENV || CHECK=$?
+          buoy check go.mod --release ${RELEASE} --domain knative.dev --verbose >> $GITHUB_ENV 2>&1 || CHECK=$?
           echo 'EOF' >> $GITHUB_ENV
 
           # We just captured the return code of the buoy call, test it to see
@@ -104,8 +104,25 @@ jobs:
       - name: Verify
         if: steps.exists.outputs.release-branch == 'false' && env.current == 'true'
         run: |
+          # If we don't run `git status` before the "git diff-index" it seems
+          # to list every file that's been touched by codegen.
+          git status
+          FOUND_DIFF=0
+          for x in $(git diff-index --name-only HEAD --); do
+            if [ "$(basename $x)" = "go.mod" ]; then
+              continue
+            elif [ "$(basename $x)" = "go.sum" ]; then
+              continue
+            elif [ "$(basename $x)" = "modules.txt" ]; then
+              continue
+            fi
+            echo "Found non-module diff: $x"
+            FOUND_DIFF=1
+            break
+          done
+
           # If we see no changes after the upgrade, then we are up to date.
-          if [[ -z "$(git status --porcelain)" ]]; then
+          if [[ "$FOUND_DIFF" -eq "0"  ]]; then
               echo "VERIFY_MESSAGE=${{ github.repository }} up to date." >> $GITHUB_ENV
           else
               echo "VERIFY_MESSAGE=${{ github.repository }} is out of date." >> $GITHUB_ENV
diff --git a/.github/workflows/knative-release-notes.yaml b/.github/workflows/knative-release-notes.yaml
new file mode 100644
index 000000000..b9c30dd99
--- /dev/null
+++ b/.github/workflows/knative-release-notes.yaml
@@ -0,0 +1,96 @@
+# Copyright 2020 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
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+# This file is automagically synced here from github.com/knative-sandbox/.github
+# repo by knobots: https://github.com/knative-sandbox/knobots and will be overwritten.
+
+name: 'Release Notes'
+
+on:
+  workflow_dispatch:
+    inputs:
+      branch:
+        description: 'Branch? (master)'
+        required: true
+        default: 'master'
+      start-sha:
+        description: 'Starting SHA? (last tag on branch)'
+      end-sha:
+        description: 'Ending SHA? (latest HEAD)'
+
+jobs:
+  release-notes:
+    name: Release Notes
+    runs-on: 'ubuntu-latest'
+
+    env:
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+    steps:
+      - name: Set up Go
+        uses: actions/setup-go@v2
+        with:
+          go-version: 1.15.x
+
+      - name: Install Dependencies
+        run: GO111MODULE=on go get k8s.io/release/cmd/release-notes
+
+      - name: Check out code
+        uses: actions/checkout@v2
+        with:
+          # fetch-depth of 0 indicates all history for all branches and tags.
+          fetch-depth: 0
+
+      # Note: Defaults needs to run after we check out the repo.
+      - name: Defaults
+        run: |
+          echo ORG=$(echo '${{ github.repository }}' | awk -F '/' '{print $1}') >> $GITHUB_ENV
+          echo REPO=$(echo '${{ github.repository }}' | awk -F '/' '{print $2}') >> $GITHUB_ENV
+
+          echo "BRANCH=${{ github.event.inputs.branch }}" >> $GITHUB_ENV
+
+          if [[ "${{ github.event.inputs.start-sha }}" != "" ]]; then
+            echo "START_SHA=${{ github.event.inputs.start-sha }}" >> $GITHUB_ENV
+          else
+            # Default Starting SHA (thanks @dprotaso)
+            export semver=$(git describe --match "v[0-9]*" --abbrev=0)
+            echo "Using ${semver} tag for starting sha."
+            echo START_SHA=$(git rev-list -n 1 "${semver}") >> $GITHUB_ENV
+          fi
+
+          if [[ "${{ github.event.inputs.end-sha }}" != "" ]]; then
+            echo "END_SHA=${{ github.event.inputs.end-sha }}" >> $GITHUB_ENV
+          else
+            # Default Ending SHA (thanks @dprotaso)
+            echo "END_SHA=$(git rev-list -n 1 HEAD)" >> $GITHUB_ENV
+          fi
+
+      - name: Generate Notes
+        run: |
+          # See  https://github.com/kubernetes/release/tree/master/cmd/release-notes for options.
+          # Note: we are setting env vars in the Defaults step.
+          release-notes \
+            --required-author "" \
+            --repo-path       "$(pwd)" \
+            --output          release-notes.md
+
+      - name: Display Notes
+        run: |
+          cat release-notes.md
+
+      - name: Archive Release Notes
+        uses: actions/upload-artifact@v2
+        with:
+          name: release-notes.md
+          path: release-notes.md
diff --git a/.github/workflows/knative-style.yaml b/.github/workflows/knative-style.yaml
index a57a71a23..ecf9cf6f0 100644
--- a/.github/workflows/knative-style.yaml
+++ b/.github/workflows/knative-style.yaml
@@ -57,8 +57,14 @@ jobs:
 
       - name: ${{ matrix.tool }} ${{ matrix.options }}
         shell: bash
-        run: |
-          ${{ matrix.tool }} ${{ matrix.options }} -w $(find . -path './vendor' -prune -o -path './third_party' -prune -o -name '*.pb.go' -prune -o -type f -name '*.go' -print)
+        run: >
+          ${{ matrix.tool }} ${{ matrix.options }} -w
+          $(find .
+          -path './vendor' -prune
+          -o -path './third_party' -prune
+          -o -name '*.pb.go' -prune
+          -o -name 'wire_gen.go' -prune
+          -o -type f -name '*.go' -print)
 
       - name: Verify ${{ matrix.tool }}
         shell: bash
@@ -239,7 +245,9 @@ jobs:
               elif echo $ch | grep --quiet -E "fmt\." ; then  # all other fmt. printers.
                 err=$(echo $ch | sed -E 's/(fmt\.)(Print|Fprint)f([^%]+) (%[^sTxq]",)([^,]+)/\1\2\3",\5/')
               fi
-              echo "$file:$line: Please consider avoiding tail format like this:%0A$err"
+              # Trim spaces.
+              ch=$(echo $ch | xargs)
+              echo "$file:$line: Please consider avoiding tail format like this:%0A- $ch%0A+ $err"
           done |
           reviewdog -efm="%f:%l: %m" \
                 -name="Redundant Format" \
diff --git a/config/core/configmaps/leader-election.yaml b/config/core/configmaps/leader-election.yaml
index ec90184ec..156409264 100644
--- a/config/core/configmaps/leader-election.yaml
+++ b/config/core/configmaps/leader-election.yaml
@@ -20,7 +20,7 @@ metadata:
   labels:
     serving.knative.dev/release: devel
   annotations:
-    knative.dev/example-checksum: "a255a6cc"
+    knative.dev/example-checksum: "96896b00"
 data:
   _example: |
     ################################
@@ -49,3 +49,10 @@ data:
     # retryPeriod is how long the leader election client waits between tries of
     # actions; 2 seconds is the value used by core kubernetes controllers.
     retryPeriod: "2s"
+
+    # buckets is the number of buckets used to partition key space of each
+    # Reconciler. If this number is M and the replica number of the controller
+    # is N, the N replicas will compete for the M buckets. The owner of a
+    # bucket will take care of the reconciling for the keys partitioned into
+    # that bucket.
+    buckets: "1"
diff --git a/config/domain-mapping/300-resources/domain-claim.yaml b/config/domain-mapping/300-resources/domain-claim.yaml
new file mode 120000
index 000000000..7c6016c85
--- /dev/null
+++ b/config/domain-mapping/300-resources/domain-claim.yaml
@@ -0,0 +1,1 @@
+../../../vendor/knative.dev/networking/config/domain-claim.yaml
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 390dd8bcc..8907930c9 100644
--- a/go.mod
+++ b/go.mod
@@ -30,15 +30,14 @@ require (
 	google.golang.org/api v0.34.0
 	google.golang.org/grpc v1.33.1
 	k8s.io/api v0.18.8
-	k8s.io/apiextensions-apiserver v0.18.8 // indirect
 	k8s.io/apimachinery v0.18.8
 	k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
 	k8s.io/code-generator v0.18.8
 	k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29
-	knative.dev/caching v0.0.0-20201103013104-4c21374dc777
+	knative.dev/caching v0.0.0-20201104174804-1a305923cfbe
 	knative.dev/hack v0.0.0-20201103151104-3d5abc3a0075
-	knative.dev/networking v0.0.0-20201103013404-f79e1df6f035
-	knative.dev/pkg v0.0.0-20201103150904-7f1970af5b6f
+	knative.dev/networking v0.0.0-20201103163404-b9f80f4537af
+	knative.dev/pkg v0.0.0-20201103163404-5514ab0c1fdf
 )
 
 replace (
diff --git a/go.sum b/go.sum
index d71f34f09..67ad21792 100644
--- a/go.sum
+++ b/go.sum
@@ -1182,20 +1182,18 @@ k8s.io/legacy-cloud-providers v0.18.8/go.mod h1:tgp4xYf6lvjrWnjQwTOPvWQE9IVqSBGP
 k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE=
 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-knative.dev/caching v0.0.0-20201103013104-4c21374dc777 h1:OWBZB0A41gxFBYb9JbUQa6wQsulWD6YD0iDghJapPW8=
-knative.dev/caching v0.0.0-20201103013104-4c21374dc777/go.mod h1:TEN1bO0HOvNwGuRQYs6i9wC+He9TnNyl9wwr0zUpWPQ=
-knative.dev/hack v0.0.0-20201028205534-fe80f1c8af68 h1:ygwpOK8B0PXurq88GHhym2uxKiiMJ+bRFwFeZHqGJNc=
-knative.dev/hack v0.0.0-20201028205534-fe80f1c8af68/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
+knative.dev/caching v0.0.0-20201104174804-1a305923cfbe h1:isrtdMtP9EvJuYn7vIw0yNv8+wpRVwULMuiGlTOduzA=
+knative.dev/caching v0.0.0-20201104174804-1a305923cfbe/go.mod h1:twy5Yz5LtFbmihtbBG0CcgwJzV5d8RUBoGkZFs7uRQs=
 knative.dev/hack v0.0.0-20201102193445-9349aeeb6701 h1:at6mUfi8gHWlBRd/qNM66JvUQ4C964cOpsy9hzac+7c=
 knative.dev/hack v0.0.0-20201102193445-9349aeeb6701/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
 knative.dev/hack v0.0.0-20201103151104-3d5abc3a0075 h1:YAgWplKIy4O5e3F5vUUECmXAAyZ0M5ymo6fCt1jeZhs=
 knative.dev/hack v0.0.0-20201103151104-3d5abc3a0075/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
-knative.dev/networking v0.0.0-20201103013404-f79e1df6f035 h1:gczquGrxGPGdQtewNOY7E0Y6EU+zvqhiKUcUkZaGMb8=
-knative.dev/networking v0.0.0-20201103013404-f79e1df6f035/go.mod h1:7N65kRtkKLuku5B5rjMd2yXbUu5LoEM85WHHL1cfdig=
-knative.dev/pkg v0.0.0-20201102194004-c6a8219d518d h1:JrOfK/tIUnXfMNaNHAkfNswIVQ//OkbO1FMly+nQ9t8=
-knative.dev/pkg v0.0.0-20201102194004-c6a8219d518d/go.mod h1:0/9g74jUIRReXdgCBFs85jHU3Ffyl1Fc9jxrllXYDVM=
+knative.dev/networking v0.0.0-20201103163404-b9f80f4537af h1:xPS3bRfp30XHb69B0F9Pgv4Nc2eTfJHWR0TzVRHf1hU=
+knative.dev/networking v0.0.0-20201103163404-b9f80f4537af/go.mod h1:0OaR4FLbs3Xn6UjeX1zYql9RWO8sLTO/ZMJS4jDbfFE=
 knative.dev/pkg v0.0.0-20201103150904-7f1970af5b6f h1:Ezruo8zcoA6RA8KiP8JH4K7RSjkddjlhvP9CcooWO4Q=
 knative.dev/pkg v0.0.0-20201103150904-7f1970af5b6f/go.mod h1:2hMxAUviPH2nl3BuODx5L6shYCdzA+7SPzQpdkcg9wc=
+knative.dev/pkg v0.0.0-20201103163404-5514ab0c1fdf h1:QwULgRwcv6R3Ya1GZlf/E1atcaGUNw4DKjxSQUfcR6U=
+knative.dev/pkg v0.0.0-20201103163404-5514ab0c1fdf/go.mod h1:cuKOgUvJvnWHIps/apCXX8wZuMlT0dyMZLqRQfsENbQ=
 pgregory.net/rapid v0.3.3 h1:jCjBsY4ln4Atz78QoBWxUEvAHaFyNDQg9+WU62aCn1U=
 pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
diff --git a/pkg/apis/serving/v1/revision_lifecycle.go b/pkg/apis/serving/v1/revision_lifecycle.go
index 85089e9ae..fac3cd359 100644
--- a/pkg/apis/serving/v1/revision_lifecycle.go
+++ b/pkg/apis/serving/v1/revision_lifecycle.go
@@ -123,12 +123,16 @@ func (rs *RevisionStatus) MarkContainerHealthyTrue() {
 
 // MarkContainerHealthyFalse marks ContainerHealthy status on revision as False
 func (rs *RevisionStatus) MarkContainerHealthyFalse(reason, message string) {
-	revisionCondSet.Manage(rs).MarkFalse(RevisionConditionContainerHealthy, reason, message)
+	// We escape here, because errors sometimes contain `%` and that makes the error message
+	// quite poor.
+	revisionCondSet.Manage(rs).MarkFalse(RevisionConditionContainerHealthy, reason, "%s", message)
 }
 
 // MarkContainerHealthyUnknown marks ContainerHealthy status on revision as Unknown
 func (rs *RevisionStatus) MarkContainerHealthyUnknown(reason, message string) {
-	revisionCondSet.Manage(rs).MarkUnknown(RevisionConditionContainerHealthy, reason, message)
+	// We escape here, because errors sometimes contain `%` and that makes the error message
+	// quite poor.
+	revisionCondSet.Manage(rs).MarkUnknown(RevisionConditionContainerHealthy, reason, "%s", message)
 }
 
 // MarkResourcesAvailableTrue marks ResourcesAvailable status on revision as True
diff --git a/pkg/autoscaler/statforwarder/forwarder.go b/pkg/autoscaler/statforwarder/forwarder.go
index 5894fbb75..15f0527d0 100644
--- a/pkg/autoscaler/statforwarder/forwarder.go
+++ b/pkg/autoscaler/statforwarder/forwarder.go
@@ -166,12 +166,13 @@ func (f *Forwarder) filterFunc(namespace string) func(interface{}) bool {
 		}
 
 		// The holder identity is in format of <POD-NAME>_<POD-IP>.
-		ip, err := f.extractIP(*l.Spec.HolderIdentity)
+		holder := *l.Spec.HolderIdentity
+		_, err := f.extractIP(holder)
 		if err != nil {
 			f.logger.Warn("Found invalid Lease holder identify ", *l.Spec.HolderIdentity)
 			return false
 		}
-		if p := f.getProcessor(l.Name); p != nil && p.ip == ip {
+		if p := f.getProcessor(l.Name); p != nil && p.holder == holder {
 			// Already up-to-date.
 			return false
 		}
@@ -195,15 +196,16 @@ func (f *Forwarder) leaseUpdated(obj interface{}) {
 	// Close existing connection if there's one. The target address won't
 	// be the same as the IP has changed.
 	f.shutdown(f.getProcessor(n))
+	holder := *l.Spec.HolderIdentity
 	// The map should have the IP because of the operations in the filter when queueing.
-	ip, ok := f.id2ip[*l.Spec.HolderIdentity]
+	ip, ok := f.id2ip[holder]
 	if !ok {
 		// This shouldn't happen because we store the value into the map in the filter
 		// when queueing. Add a log here in case something unexpected happens.
-		f.logger.Warn("IP not found in cached map for ", *l.Spec.HolderIdentity)
+		f.logger.Warn("IP not found in cached map for ", holder)
 		return
 	}
-	f.setProcessor(n, f.createProcessor(ns, n, ip))
+	f.setProcessor(n, f.createProcessor(ns, n, ip, holder))
 
 	if ip != f.selfIP {
 		// Skip creating/updating Service and Endpoints if not the leader.
@@ -333,17 +335,17 @@ func (f *Forwarder) setProcessor(bkt string, p *bucketProcessor) {
 	f.processors[bkt] = p
 }
 
-func (f *Forwarder) createProcessor(ns, bkt, ip string) *bucketProcessor {
+func (f *Forwarder) createProcessor(ns, bkt, ip, holder string) *bucketProcessor {
 	if ip == f.selfIP {
 		return &bucketProcessor{
 			bkt:    bkt,
 			logger: f.logger.With(zap.String("bucket", bkt)),
-			ip:     ip,
+			holder: holder,
 			accept: f.accept,
 		}
 	}
 
-	return newForwardProcessor(f.logger.With(zap.String("bucket", bkt)), bkt, ip,
+	return newForwardProcessor(f.logger.With(zap.String("bucket", bkt)), bkt, holder,
 		fmt.Sprintf("ws://%s:%d", ip, autoscalerPort),
 		fmt.Sprintf("ws://%s.%s.%s", bkt, ns, svcURLSuffix))
 }
diff --git a/pkg/autoscaler/statforwarder/processor.go b/pkg/autoscaler/statforwarder/processor.go
index 5e32a099f..a2f6402a0 100644
--- a/pkg/autoscaler/statforwarder/processor.go
+++ b/pkg/autoscaler/statforwarder/processor.go
@@ -39,8 +39,8 @@ type bucketProcessor struct {
 	logger *zap.SugaredLogger
 	// The name of the bucket
 	bkt string
-	// ip is the Pod IP extracted from the HolderIdentity.
-	ip       string
+	// holder is the HolderIdentity of a Lease for a bucket.
+	holder   string
 	svcDNS   string
 	connLock sync.RWMutex
 	// conn is the WebSocket connection to the holder pod.
@@ -50,7 +50,7 @@ type bucketProcessor struct {
 	accept statProcessor
 }
 
-func newForwardProcessor(logger *zap.SugaredLogger, bkt, ip, podDNS, svcDNS string) *bucketProcessor {
+func newForwardProcessor(logger *zap.SugaredLogger, bkt, holder, podDNS, svcDNS string) *bucketProcessor {
 	// First try to connect via Pod IP address synchronously. If the connection can
 	// not be established within `establishTimeout`, we assume the pods can not be
 	// accessed by IP address. Then try to connect via Pod IP address synchronously.
@@ -63,7 +63,7 @@ func newForwardProcessor(logger *zap.SugaredLogger, bkt, ip, podDNS, svcDNS stri
 	return &bucketProcessor{
 		logger: logger,
 		bkt:    bkt,
-		ip:     ip,
+		holder: holder,
 		conn:   c,
 		svcDNS: svcDNS,
 	}
@@ -89,7 +89,7 @@ func (p *bucketProcessor) process(sm asmetrics.StatMessage) error {
 		return nil
 	}
 
-	l.Debugf("Forward stat of bucket %s to the holder %s", p.bkt, p.ip)
+	l.Debugf("Forward stat of bucket %s to the holder %s", p.bkt, p.holder)
 	wsms := asmetrics.ToWireStatMessages([]asmetrics.StatMessage{sm})
 	b, err := wsms.Marshal()
 	if err != nil {
diff --git a/pkg/reconciler/autoscaling/kpa/scaler.go b/pkg/reconciler/autoscaling/kpa/scaler.go
index af8aa1118..00954607e 100644
--- a/pkg/reconciler/autoscaling/kpa/scaler.go
+++ b/pkg/reconciler/autoscaling/kpa/scaler.go
@@ -320,7 +320,8 @@ func (ks *scaler) scale(ctx context.Context, pa *pav1alpha1.PodAutoscaler, sks *
 
 	min, max := pa.ScaleBounds(asConfig)
 	initialScale := kparesources.GetInitialScale(asConfig, pa)
-	logger.Debugf("MinScale = %d, MaxScale = %d, InitialScale = %d, DesiredScale = %d Reachable = %v",
+	// Log reachability as quoted string, since default value is "".
+	logger.Debugf("MinScale = %d, MaxScale = %d, InitialScale = %d, DesiredScale = %d Reachable = %q",
 		min, max, initialScale, desiredScale, pa.Spec.Reachability)
 	// If initial scale has been attained, ignore the initialScale altogether.
 	if initialScale > 1 && !pa.Status.IsScaleTargetInitialized() {
diff --git a/pkg/reconciler/domainmapping/reconciler.go b/pkg/reconciler/domainmapping/reconciler.go
index ce8ac2675..4d3523bef 100644
--- a/pkg/reconciler/domainmapping/reconciler.go
+++ b/pkg/reconciler/domainmapping/reconciler.go
@@ -62,10 +62,6 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, dm *v1alpha1.DomainMappi
 		dm.Status.MarkIngressNotConfigured()
 	}
 
-	// TODO(jz) ClusterDomainClaim isn't fully implemented yet, so just mark it
-	// Claimed for now so we have the correct condition flow.
-	dm.Status.MarkDomainClaimed()
-
 	// Mapped URL is the metadata.name of the DomainMapping.
 	url := &apis.URL{Scheme: "http", Host: dm.Name}
 	dm.Status.URL = url
@@ -77,6 +73,12 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, dm *v1alpha1.DomainMappi
 		ingressClass = config.FromContext(ctx).Network.DefaultIngressClass
 	}
 
+	// To prevent Ingress hostname collision, require that we can create, or
+	// already own, a cluster-wide domain claim.
+	if err := r.reconcileDomainClaim(ctx, dm); err != nil {
+		return err
+	}
+
 	// Reconcile the Ingress resource corresponding to the requested Mapping.
 	logger.Debugf("Mapping %s to %s/%s", url, dm.Spec.Ref.Namespace, dm.Spec.Ref.Name)
 	desired := resources.MakeIngress(dm, ingressClass)
@@ -125,3 +127,22 @@ func (r *Reconciler) reconcileIngress(ctx context.Context, dm *v1alpha1.DomainMa
 
 	return ingress, err
 }
+
+func (r *Reconciler) reconcileDomainClaim(ctx context.Context, dm *v1alpha1.DomainMapping) error {
+	dc, err := r.netclient.NetworkingV1alpha1().ClusterDomainClaims().Get(ctx, dm.Name, metav1.GetOptions{})
+	if apierrs.IsNotFound(err) {
+		if dc, err = r.netclient.NetworkingV1alpha1().ClusterDomainClaims().Create(ctx, resources.MakeDomainClaim(dm), metav1.CreateOptions{}); err != nil {
+			return fmt.Errorf("failed to create ClusterDomainClaim: %w", err)
+		}
+	} else if err != nil {
+		return fmt.Errorf("failed to get ClusterDomainClaim: %w", err)
+	}
+
+	if !metav1.IsControlledBy(dc, dm) {
+		dm.Status.MarkDomainClaimNotOwned()
+		return fmt.Errorf("domain mapping: %q does not own matching cluster domain claim", dm.Name)
+	}
+
+	dm.Status.MarkDomainClaimed()
+	return nil
+}
diff --git a/pkg/reconciler/domainmapping/resources/domainclaim.go b/pkg/reconciler/domainmapping/resources/domainclaim.go
new file mode 100644
index 000000000..3fcd82d81
--- /dev/null
+++ b/pkg/reconciler/domainmapping/resources/domainclaim.go
@@ -0,0 +1,35 @@
+/*
+Copyright 2020 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
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+*/
+
+package resources
+
+import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	netv1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
+	"knative.dev/pkg/kmeta"
+	"knative.dev/serving/pkg/apis/serving/v1alpha1"
+)
+
+// MakeDomainClaim creates a ClusterDomainClaim named after and owned by the
+// given DomainMapping.
+func MakeDomainClaim(dm *v1alpha1.DomainMapping) *netv1alpha1.ClusterDomainClaim {
+	return &netv1alpha1.ClusterDomainClaim{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:            dm.Name,
+			OwnerReferences: []metav1.OwnerReference{*kmeta.NewControllerRef(dm)},
+		},
+	}
+}
diff --git a/pkg/reconciler/revision/revision.go b/pkg/reconciler/revision/revision.go
index 90a41b415..aea2a0e88 100644
--- a/pkg/reconciler/revision/revision.go
+++ b/pkg/reconciler/revision/revision.go
@@ -21,7 +21,9 @@ import (
 	"strings"
 	"time"
 
+	"github.com/davecgh/go-spew/spew"
 	"github.com/google/go-containerregistry/pkg/authn/k8schain"
+	"go.uber.org/zap/zapcore"
 
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
@@ -136,6 +138,15 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, rev *v1.Revision) pkgrec
 		return nil
 	}
 
+	// Spew is an expensive operation so guard the computation on the debug level
+	// being enabled.
+	// Some things, like PA reachability, etc are computed based on various labels/annotations
+	// of revision. So it is useful to provide this information for debugging.
+	logger := logging.FromContext(ctx).Desugar()
+	if logger.Core().Enabled(zapcore.DebugLevel) {
+		logger.Debug("Revision meta: " + spew.Sdump(rev.ObjectMeta))
+	}
+
 	for _, phase := range []func(context.Context, *v1.Revision) error{
 		c.reconcileDeployment,
 		c.reconcileImageCache,
@@ -147,10 +158,12 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, rev *v1.Revision) pkgrec
 	}
 	readyAfterReconcile := rev.Status.GetCondition(v1.RevisionConditionReady).IsTrue()
 	if !readyBeforeReconcile && readyAfterReconcile {
-		logging.FromContext(ctx).Info("Revision became ready")
+		logger.Info("Revision became ready")
 		controller.GetEventRecorder(ctx).Event(
 			rev, corev1.EventTypeNormal, "RevisionReady",
 			"Revision becomes ready upon all resources being ready")
+	} else if readyBeforeReconcile && !readyAfterReconcile {
+		logger.Info("Revision stopped being ready")
 	}
 
 	return nil
diff --git a/pkg/reconciler/route/traffic/rollout.go b/pkg/reconciler/route/traffic/rollout.go
index 744464490..d72263fb6 100644
--- a/pkg/reconciler/route/traffic/rollout.go
+++ b/pkg/reconciler/route/traffic/rollout.go
@@ -21,7 +21,9 @@ limitations under the License.
 
 package traffic
 
-import "sort"
+import (
+	"sort"
+)
 
 // Rollout encapsulates the current rollout state of the system.
 // Since the route might reference more than one configuration.
@@ -112,7 +114,8 @@ func (cur *Rollout) Step(prev *Rollout) *Rollout {
 				i++
 			case ccfgs[i].ConfigurationName == pcfgs[j].ConfigurationName:
 				// Config might have 0% traffic assigned, if it is a tag only route (i.e.
-				// receives no traffic via default tag).
+				// receives no traffic via default tag). So just skip it from the rollout
+				// altogether.
 				if ccfgs[i].Percent != 0 {
 					ret = append(ret, *stepConfig(ccfgs[i], pcfgs[j]))
 				}
@@ -120,7 +123,10 @@ func (cur *Rollout) Step(prev *Rollout) *Rollout {
 				j++
 			case ccfgs[i].ConfigurationName < pcfgs[j].ConfigurationName:
 				// A new config, has been added. No action for rollout though.
-				ret = append(ret, *ccfgs[i])
+				// Keep it if it will receive traffic.
+				if ccfgs[i].Percent != 0 {
+					ret = append(ret, *ccfgs[i])
+				}
 				i++
 			default: // cur > prev.
 				// A config has been removed during this update.
@@ -137,6 +143,31 @@ func (cur *Rollout) Step(prev *Rollout) *Rollout {
 	return ro
 }
 
+// adjustPercentage updates the rollout with the new percentage values.
+// If new percentage is larger than the previous, the last revision gets
+// the difference, if it is decreasing then we start removing traffic from
+// the older revisions.
+func adjustPercentage(goal int, cr *ConfigurationRollout) {
+	switch diff := goal - cr.Percent; {
+	case diff > 0:
+		cr.Revisions[len(cr.Revisions)-1].Percent += diff
+	case diff < 0:
+		diff = -diff // To make logic more natural.
+		i := 0
+		for diff > 0 && i < len(cr.Revisions) {
+			if cr.Revisions[i].Percent > diff {
+				cr.Revisions[i].Percent -= diff
+				break
+			}
+			diff -= cr.Revisions[i].Percent
+			i++
+		}
+		cr.Revisions = cr.Revisions[i:]
+	default: // diff = 0
+		// noop
+	}
+}
+
 // stepConfig takes previous and goal configuration shapes and returns a new
 // config rollout, after computing the percetage allocations.
 func stepConfig(goal, prev *ConfigurationRollout) *ConfigurationRollout {
@@ -145,14 +176,21 @@ func stepConfig(goal, prev *ConfigurationRollout) *ConfigurationRollout {
 		ConfigurationName: goal.ConfigurationName,
 		Tag:               goal.Tag,
 		Percent:           goal.Percent,
+		Revisions:         goal.Revisions,
+	}
+
+	if len(prev.Revisions) > 0 {
+		adjustPercentage(goal.Percent, prev)
 	}
 	// goal will always have just one revision in the list – the current desired revision.
-	if goal.Revisions[0].RevisionName == prev.Revisions[pc-1].RevisionName {
+	// If it matches the last revision of the previous rollout state (or there were no revisions)
+	// then no new rollout hast begun for this configuration.
+	if len(prev.Revisions) == 0 || goal.Revisions[0].RevisionName == prev.Revisions[pc-1].RevisionName {
 		// TODO(vagababov): here would go the logic to compute new percentages for the rollout,
 		// i.e step function, so return value will change, depending on that.
-		// TODO(vagababov): percentage might change, so this should trigger recompute of existing
-		// revision rollouts.
-		ret.Revisions = goal.Revisions
+		if len(prev.Revisions) > 0 {
+			ret.Revisions = prev.Revisions
+		}
 		return ret
 	}
 
diff --git a/support/COMMUNITY_CONTACTS.md b/support/COMMUNITY_CONTACTS.md
index b5d969a20..2744e1845 100644
--- a/support/COMMUNITY_CONTACTS.md
+++ b/support/COMMUNITY_CONTACTS.md
@@ -34,9 +34,12 @@ community contact's duty (subject to change) is as followed:
 - Check the
   [knative-users@](https://groups.google.com/forum/#!forum/knative-users)
   mailing list and `@serving-help` on Slack for unanswered questions.
-- Check
+- Check Serving
   [unassigned issues / untriaged issues](https://github.com/knative/serving/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee+no%3Amilestone)
   for unanswered questions.
+- Check Docs
+  [unassigned issues / untriaged issues](https://github.com/knative/docs/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee+no%3Amilestone)
+  for unanswered questions.
 
 ## SLO
 
diff --git a/third_party/net-istio.yaml b/third_party/istio-latest/net-istio.yaml
similarity index 93%
rename from third_party/net-istio.yaml
rename to third_party/istio-latest/net-istio.yaml
index 53a3eddb5..5700608d6 100644
--- a/third_party/net-istio.yaml
+++ b/third_party/istio-latest/net-istio.yaml
@@ -1,3 +1,5 @@
+# Generated when HEAD was 40b59920910828a29cf584c77bd785c8c6cf4a90
+#
 # Copyright 2019 The Knative Authors
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +20,7 @@ metadata:
   # These are the permissions needed by the Istio Ingress implementation.
   name: knative-serving-istio
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     serving.knative.dev/controller: "true"
     networking.knative.dev/ingress-provider: istio
 rules:
@@ -48,7 +50,7 @@ metadata:
   name: knative-ingress-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -85,7 +87,7 @@ metadata:
   name: cluster-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -104,7 +106,7 @@ metadata:
   name: knative-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -123,7 +125,7 @@ metadata:
   name: knative-local-gateway
   namespace: istio-system
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   type: ClusterIP
@@ -143,7 +145,7 @@ metadata:
   name: "webhook"
   namespace: "knative-serving"
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -158,7 +160,7 @@ metadata:
   name: "istio-webhook"
   namespace: "knative-serving"
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -187,7 +189,7 @@ kind: MutatingWebhookConfiguration
 metadata:
   name: webhook.istio.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -223,7 +225,7 @@ kind: ValidatingWebhookConfiguration
 metadata:
   name: config.webhook.istio.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -261,7 +263,7 @@ metadata:
   name: istio-webhook-certs
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 
 ---
@@ -285,7 +287,7 @@ metadata:
   name: config-istio
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 data:
   _example: |
@@ -355,7 +357,7 @@ metadata:
   name: networking-istio
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -371,14 +373,14 @@ spec:
         sidecar.istio.io/inject: "false"
       labels:
         app: networking-istio
-        serving.knative.dev/release: "v20201103-a3c7e145"
+        serving.knative.dev/release: "v20201110-40b59920"
     spec:
       serviceAccountName: controller
       containers:
         - name: networking-istio
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:4e222b4ea22352f09dc7763d68af542d10b48819b86c6f0fcf7b394066e6486b
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:0ef2abf0e613ab19ff927cd2687273dceaadf1f04a6d7c45a33cc0d3e6448146
           resources:
             requests:
               cpu: 30m
@@ -435,7 +437,7 @@ metadata:
   name: istio-webhook
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -449,14 +451,14 @@ spec:
       labels:
         app: istio-webhook
         role: istio-webhook
-        serving.knative.dev/release: "v20201103-a3c7e145"
+        serving.knative.dev/release: "v20201110-40b59920"
     spec:
       serviceAccountName: controller
       containers:
         - name: webhook
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:d64bc26a6dbc837dbe33e69051e656a35ebd851294f3be6b7c6b8ba9a864533c
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:66e4b06f933e56461161af236ced64adb04c2c1bb9e5376a8a86f2ddc4a36859
           resources:
             requests:
               cpu: 20m
@@ -510,7 +512,7 @@ metadata:
   namespace: knative-serving
   labels:
     role: istio-webhook
-    serving.knative.dev/release: "v20201103-a3c7e145"
+    serving.knative.dev/release: "v20201110-40b59920"
     networking.knative.dev/ingress-provider: istio
 spec:
   ports:
diff --git a/vendor/knative.dev/caching/config/image.yaml b/vendor/knative.dev/caching/config/image.yaml
index cc44b4fce..fa1f3d5b2 100644
--- a/vendor/knative.dev/caching/config/image.yaml
+++ b/vendor/knative.dev/caching/config/image.yaml
@@ -44,3 +44,7 @@ spec:
         #
         # see issue: https://github.com/knative/serving/issues/912
         x-kubernetes-preserve-unknown-fields: true
+    additionalPrinterColumns:
+    - name: Image
+      type: string
+      jsonPath: .spec.image
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 457d9c648..b9bc3b554 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -610,7 +610,6 @@ k8s.io/api/storage/v1
 k8s.io/api/storage/v1alpha1
 k8s.io/api/storage/v1beta1
 # k8s.io/apiextensions-apiserver v0.18.8 => k8s.io/apiextensions-apiserver v0.18.8
-## explicit
 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions
 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1
@@ -953,7 +952,7 @@ k8s.io/utils/buffer
 k8s.io/utils/integer
 k8s.io/utils/pointer
 k8s.io/utils/trace
-# knative.dev/caching v0.0.0-20201103013104-4c21374dc777
+# knative.dev/caching v0.0.0-20201104174804-1a305923cfbe
 ## explicit
 knative.dev/caching/config
 knative.dev/caching/pkg/apis/caching
@@ -977,7 +976,7 @@ knative.dev/caching/pkg/client/listers/caching/v1alpha1
 # knative.dev/hack v0.0.0-20201103151104-3d5abc3a0075
 ## explicit
 knative.dev/hack
-# knative.dev/networking v0.0.0-20201103013404-f79e1df6f035
+# knative.dev/networking v0.0.0-20201103163404-b9f80f4537af
 ## explicit
 knative.dev/networking/config
 knative.dev/networking/pkg
@@ -1010,7 +1009,7 @@ knative.dev/networking/test/conformance/ingress
 knative.dev/networking/test/defaultsystem
 knative.dev/networking/test/test_images/grpc-ping/proto
 knative.dev/networking/test/types
-# knative.dev/pkg v0.0.0-20201103150904-7f1970af5b6f
+# knative.dev/pkg v0.0.0-20201103163404-5514ab0c1fdf
 ## explicit
 knative.dev/pkg/apiextensions/storageversion
 knative.dev/pkg/apiextensions/storageversion/cmd/migrate


Test patch:
diff --git a/.github/workflows/kind-e2e.yaml b/.github/workflows/kind-e2e.yaml
index 3e560004d..242a60249 100644
--- a/.github/workflows/kind-e2e.yaml
+++ b/.github/workflows/kind-e2e.yaml
@@ -53,12 +53,6 @@ jobs:
         - test-suite: ./test/conformance/api/v1alpha1
           test-flags: "--enable-alpha"
 
-        exclude:
-          # TODO(#9874): Un-exclude this when Kourier implements the
-          # RewriteHost feature DomainMappings relies on.
-        - test-suite: ./test/conformance/api/v1alpha1
-          k8s-version: v1.18.8
-
     env:
       GOPATH: ${{ github.workspace }}
       GO111MODULE: off
@@ -244,7 +238,7 @@ jobs:
         source test/e2e-networking-library.sh
 
         PATCHED_YAML=$(mktemp)
-        ko resolve -f third_party/net-istio.yaml > $PATCHED_YAML
+        ko resolve -f third_party/istio-latest/net-istio.yaml > $PATCHED_YAML
 
         # TODO: figure out how to use e2e-common.sh directly even if no
         # custom namespace is used here.
diff --git a/pkg/apis/serving/v1/revision_lifecycle_test.go b/pkg/apis/serving/v1/revision_lifecycle_test.go
index 1bb700f40..d6f90e915 100644
--- a/pkg/apis/serving/v1/revision_lifecycle_test.go
+++ b/pkg/apis/serving/v1/revision_lifecycle_test.go
@@ -317,7 +317,7 @@ func TestTypicalFlowWithContainerMissing(t *testing.T) {
 	apistest.CheckConditionOngoing(r, RevisionConditionContainerHealthy, t)
 	apistest.CheckConditionOngoing(r, RevisionConditionReady, t)
 
-	const want = "something about the container being not found"
+	const want = "something about the container being not found %s"
 	r.MarkContainerHealthyFalse(ReasonContainerMissing, want)
 	apistest.CheckConditionOngoing(r, RevisionConditionResourcesAvailable, t)
 	apistest.CheckConditionFailed(r, RevisionConditionContainerHealthy, t)
diff --git a/pkg/autoscaler/statforwarder/forwarder_test.go b/pkg/autoscaler/statforwarder/forwarder_test.go
index 44398dc67..4d7fb930b 100644
--- a/pkg/autoscaler/statforwarder/forwarder_test.go
+++ b/pkg/autoscaler/statforwarder/forwarder_test.go
@@ -439,7 +439,7 @@ func TestProcess(t *testing.T) {
 	if err := wait.PollImmediate(10*time.Millisecond, 10*time.Second, func() (bool, error) {
 		p1 := f.getProcessor(bucket1)
 		p2 := f.getProcessor(bucket2)
-		return p1 != nil && p2 != nil && p1.ip == testIP1 && p2.ip == testIP2, nil
+		return p1 != nil && p2 != nil && p1.holder == testHolder1 && p2.holder == testHolder2, nil
 	}); err != nil {
 		t.Fatalf("Timeout waiting f.processors got updated")
 	}
diff --git a/pkg/leaderelection/config_test.go b/pkg/leaderelection/config_test.go
index 857f0554d..e2491b5fe 100644
--- a/pkg/leaderelection/config_test.go
+++ b/pkg/leaderelection/config_test.go
@@ -31,7 +31,7 @@ import (
 
 func okConfig() *kle.Config {
 	return &kle.Config{
-		Buckets:       1,
+		Buckets:       5,
 		LeaseDuration: 15 * time.Second,
 		RenewDeadline: 10 * time.Second,
 		RetryPeriod:   2 * time.Second,
@@ -40,6 +40,7 @@ func okConfig() *kle.Config {
 
 func okData() map[string]string {
 	return map[string]string{
+		"buckets": "5",
 		// values in this data come from the defaults suggested in the
 		// code:
 		// https://github.com/kubernetes/client-go/blob/kubernetes-1.16.0/tools/leaderelection/leaderelection.go
diff --git a/pkg/reconciler/domainmapping/resources/domainclaim_test.go b/pkg/reconciler/domainmapping/resources/domainclaim_test.go
new file mode 100644
index 000000000..7be177046
--- /dev/null
+++ b/pkg/reconciler/domainmapping/resources/domainclaim_test.go
@@ -0,0 +1,43 @@
+/*
+Copyright 2020 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
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+*/
+
+package resources
+
+import (
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	netv1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
+	"knative.dev/pkg/kmeta"
+	"knative.dev/serving/pkg/apis/serving/v1alpha1"
+)
+
+func TestMakeDomainClaim(t *testing.T) {
+	dm := &v1alpha1.DomainMapping{ObjectMeta: metav1.ObjectMeta{Name: "mapping.com"}}
+	got := MakeDomainClaim(dm)
+
+	want := &netv1alpha1.ClusterDomainClaim{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:            "mapping.com",
+			OwnerReferences: []metav1.OwnerReference{*kmeta.NewControllerRef(dm)},
+		},
+	}
+
+	if !cmp.Equal(want, got) {
+		t.Errorf("Unexpected DomainClaim (-want, +got):\n%s", cmp.Diff(want, got))
+	}
+}
diff --git a/pkg/reconciler/domainmapping/table_test.go b/pkg/reconciler/domainmapping/table_test.go
index cd7efc52e..9e975ae9c 100644
--- a/pkg/reconciler/domainmapping/table_test.go
+++ b/pkg/reconciler/domainmapping/table_test.go
@@ -23,6 +23,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/types"
 	clientgotesting "k8s.io/client-go/testing"
 
 	network "knative.dev/networking/pkg"
@@ -70,6 +71,32 @@ func TestReconcile(t *testing.T) {
 				withInitDomainMappingConditions,
 				withDomainClaimed,
 				withIngressNotConfigured,
+				withDomainClaimed,
+			),
+		}},
+		SkipNamespaceValidation: true, // allow creation of ClusterDomainClaim.
+		WantCreates: []runtime.Object{
+			resources.MakeDomainClaim(domainMapping("default", "first-reconcile.com", withRef("default", "target"))),
+			resources.MakeIngress(domainMapping("default", "first-reconcile.com", withRef("default", "target")), "the-ingress-class"),
+		},
+		WantEvents: []string{
+			Eventf(corev1.EventTypeNormal, "Created", "Created Ingress %q", "first-reconcile.com"),
+		},
+	}, {
+		Name: "first reconcile, pre-owned domain claim",
+		Key:  "default/first-reconcile.com",
+		Objects: []runtime.Object{
+			domainMapping("default", "first-reconcile.com", withRef("default", "target")),
+			resources.MakeDomainClaim(domainMapping("default", "first-reconcile.com", withRef("default", "target"))),
+		},
+		WantStatusUpdates: []clientgotesting.UpdateActionImpl{{
+			Object: domainMapping("default", "first-reconcile.com",
+				withRef("default", "target"),
+				withURL("http", "first-reconcile.com"),
+				withAddress("http", "first-reconcile.com"),
+				withInitDomainMappingConditions,
+				withIngressNotConfigured,
+				withDomainClaimed,
 			),
 		}},
 		WantCreates: []runtime.Object{
@@ -78,6 +105,56 @@ func TestReconcile(t *testing.T) {
 		WantEvents: []string{
 			Eventf(corev1.EventTypeNormal, "Created", "Created Ingress %q", "first-reconcile.com"),
 		},
+	}, {
+		Name: "first reconcile, cant claim domain",
+		Key:  "default/first-reconcile.com",
+		Objects: []runtime.Object{
+			domainMapping("default", "first-reconcile.com", withRef("default", "target")),
+		},
+		SkipNamespaceValidation: true, // allow (attempted) creation of ClusterDomainClaim.
+		WithReactors: []clientgotesting.ReactionFunc{
+			InduceFailure("create", "clusterdomainclaims"),
+		},
+		WantErr: true,
+		WantStatusUpdates: []clientgotesting.UpdateActionImpl{{
+			Object: domainMapping("default", "first-reconcile.com",
+				withRef("default", "target"),
+				withURL("http", "first-reconcile.com"),
+				withAddress("http", "first-reconcile.com"),
+				withInitDomainMappingConditions,
+			),
+		}},
+		WantCreates: []runtime.Object{
+			// this is the clusterdomainclaim create that we induce failure on.
+			resources.MakeDomainClaim(domainMapping("default", "first-reconcile.com", withRef("default", "target"))),
+		},
+		WantEvents: []string{
+			Eventf(corev1.EventTypeWarning, "InternalError", `failed to create ClusterDomainClaim: inducing failure for create clusterdomainclaims`),
+		},
+	}, {
+		Name: "first reconcile, non-owned domainclaim",
+		Key:  "default/first-reconcile.com",
+		Objects: []runtime.Object{
+			domainMapping("default", "first-reconcile.com", withRef("default", "target")),
+			resources.MakeDomainClaim(
+				domainMapping("default", "first-reconcile.com", withRef("default", "target"),
+					withUID("some-other-uid"),
+				),
+			),
+		},
+		WantErr: true,
+		WantStatusUpdates: []clientgotesting.UpdateActionImpl{{
+			Object: domainMapping("default", "first-reconcile.com",
+				withRef("default", "target"),
+				withURL("http", "first-reconcile.com"),
+				withAddress("http", "first-reconcile.com"),
+				withInitDomainMappingConditions,
+				withDomainClaimNotOwned,
+			),
+		}},
+		WantEvents: []string{
+			Eventf(corev1.EventTypeWarning, "InternalError", `domain mapping: "first-reconcile.com" does not own matching cluster domain claim`),
+		},
 	}, {
 		Name: "reconcile with ingressClass annotation",
 		Key:  "default/ingressclass.first-reconcile.com",
@@ -96,12 +173,15 @@ func TestReconcile(t *testing.T) {
 				withInitDomainMappingConditions,
 				withDomainClaimed,
 				withIngressNotConfigured,
+				withDomainClaimed,
 				withAnnotations(map[string]string{
 					networking.IngressClassAnnotationKey: "overridden-ingress-class",
 				}),
 			),
 		}},
+		SkipNamespaceValidation: true, // allow creation of ClusterDomainClaim.
 		WantCreates: []runtime.Object{
+			resources.MakeDomainClaim(domainMapping("default", "ingressclass.first-reconcile.com", withRef("default", "target"))),
 			resources.MakeIngress(domainMapping("default", "ingressclass.first-reconcile.com", withRef("default", "target")),
 				"overridden-ingress-class"),
 		},
@@ -114,6 +194,7 @@ func TestReconcile(t *testing.T) {
 		Objects: []runtime.Object{
 			domainMapping("default", "ingress-exists.org", withRef("default", "changed")),
 			resources.MakeIngress(domainMapping("default", "ingress-exists.org", withRef("default", "target")), "the-ingress-class"),
+			resources.MakeDomainClaim(domainMapping("default", "ingress-exists.org", withRef("default", "target"))),
 		},
 		WantStatusUpdates: []clientgotesting.UpdateActionImpl{{
 			Object: domainMapping("default", "ingress-exists.org",
@@ -123,6 +204,7 @@ func TestReconcile(t *testing.T) {
 				withInitDomainMappingConditions,
 				withDomainClaimed,
 				withIngressNotConfigured,
+				withDomainClaimed,
 			),
 		}},
 		WantUpdates: []clientgotesting.UpdateActionImpl{{
@@ -140,6 +222,7 @@ func TestReconcile(t *testing.T) {
 			ingress(domainMapping("default", "ingress-failed.me", withRef("default", "failed")), "the-ingress-class",
 				WithLoadbalancerFailed("fell over", "hurt myself"),
 			),
+			resources.MakeDomainClaim(domainMapping("default", "ingress-failed.me", withRef("default", "target"))),
 		},
 		WantStatusUpdates: []clientgotesting.UpdateActionImpl{{
 			Object: domainMapping("default", "ingress-failed.me",
@@ -163,6 +246,7 @@ func TestReconcile(t *testing.T) {
 			ingress(domainMapping("default", "ingress-unknown.me", withRef("default", "unknown")), "the-ingress-class",
 				withIngressNotReady,
 			),
+			resources.MakeDomainClaim(domainMapping("default", "ingress-unknown.me", withRef("default", "target"))),
 		},
 		WantStatusUpdates: []clientgotesting.UpdateActionImpl{{
 			Object: domainMapping("default", "ingress-unknown.me",
@@ -186,6 +270,7 @@ func TestReconcile(t *testing.T) {
 			ingress(domainMapping("default", "ingress-ready.me", withRef("default", "ready")), "the-ingress-class",
 				withIngressReady,
 			),
+			resources.MakeDomainClaim(domainMapping("default", "ingress-ready.me", withRef("default", "target"))),
 		},
 		WantStatusUpdates: []clientgotesting.UpdateActionImpl{{
 			Object: domainMapping("default", "ingress-ready.me",
@@ -208,8 +293,11 @@ func TestReconcile(t *testing.T) {
 				withRef("default", "cantcreate"),
 				withURL("http", "cantcreate.this"),
 				withAddress("http", "cantcreate.this"),
+				withInitDomainMappingConditions,
+				withDomainClaimed,
 				withGeneration(1),
 			),
+			resources.MakeDomainClaim(domainMapping("default", "cantcreate.this", withRef("default", "target"))),
 		},
 		WantErr: true,
 		WantCreates: []runtime.Object{
@@ -243,9 +331,12 @@ func TestReconcile(t *testing.T) {
 				withRef("default", "cantupdate"),
 				withURL("http", "cantupdate.this"),
 				withAddress("http", "cantupdate.this"),
+				withInitDomainMappingConditions,
+				withDomainClaimed,
 				withGeneration(1),
 			),
 			ingress(domainMapping("default", "cantupdate.this", withRef("default", "previous-value")), "the-ingress-class"),
+			resources.MakeDomainClaim(domainMapping("default", "cantupdate.this", withRef("default", "target"))),
 		},
 		WantErr: true,
 		WantUpdates: []clientgotesting.UpdateActionImpl{{
@@ -309,6 +400,12 @@ func withAnnotations(ans map[string]string) domainMappingOption {
 	}
 }
 
+func withUID(uid types.UID) domainMappingOption {
+	return func(dm *v1alpha1.DomainMapping) {
+		dm.UID = uid
+	}
+}
+
 func withRef(namespace, name string) domainMappingOption {
 	return func(dm *v1alpha1.DomainMapping) {
 		dm.Spec.Ref.Namespace = namespace
@@ -347,6 +444,10 @@ func withInitDomainMappingConditions(dm *v1alpha1.DomainMapping) {
 	dm.Status.InitializeConditions()
 }
 
+func withDomainClaimNotOwned(dm *v1alpha1.DomainMapping) {
+	dm.Status.MarkDomainClaimNotOwned()
+}
+
 func withDomainClaimed(dm *v1alpha1.DomainMapping) {
 	dm.Status.MarkDomainClaimed()
 }
diff --git a/pkg/reconciler/metric/metric_test.go b/pkg/reconciler/metric/metric_test.go
index 78a0603bc..d17365552 100644
--- a/pkg/reconciler/metric/metric_test.go
+++ b/pkg/reconciler/metric/metric_test.go
@@ -211,14 +211,14 @@ func TestReconcileWithCollector(t *testing.T) {
 
 	scs.AutoscalingV1alpha1().Metrics(m.Namespace).Create(ctx, m, metav1.CreateOptions{})
 
-	if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) {
+	if err := wait.PollImmediate(10*time.Millisecond, 5*time.Second, func() (bool, error) {
 		return collector.createOrUpdateCalls.Load() > 0, nil
 	}); err != nil {
 		t.Fatal("CreateOrUpdate() called 0 times, want non-zero times")
 	}
 
 	scs.AutoscalingV1alpha1().Metrics(m.Namespace).Delete(ctx, m.Name, metav1.DeleteOptions{})
-	if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) {
+	if err := wait.PollImmediate(10*time.Millisecond, 5*time.Second, func() (bool, error) {
 		return collector.deleteCalls.Load() > 0, nil
 	}); err != nil {
 		t.Fatal("Delete() called 0 times, want non-zero times")
diff --git a/pkg/reconciler/revision/resources/pa_test.go b/pkg/reconciler/revision/resources/pa_test.go
index 974ee34b8..88ec41f03 100644
--- a/pkg/reconciler/revision/resources/pa_test.go
+++ b/pkg/reconciler/revision/resources/pa_test.go
@@ -315,7 +315,7 @@ func TestMakePA(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			got := MakePA(test.rev)
 			if !cmp.Equal(got, test.want) {
-				t.Error("MakeK8sService (-want, +got) =", cmp.Diff(test.want, got))
+				t.Error("MakePA (-want, +got) =", cmp.Diff(test.want, got))
 			}
 		})
 	}
diff --git a/pkg/reconciler/route/domains/domains_test.go b/pkg/reconciler/route/domains/domains_test.go
index 9ffc420a5..363fc0dcb 100644
--- a/pkg/reconciler/route/domains/domains_test.go
+++ b/pkg/reconciler/route/domains/domains_test.go
@@ -228,12 +228,12 @@ func TestGetAllDomainsAndTags(t *testing.T) {
 			"myroute.default.example.com":              "",
 		},
 	}, {
-		name:           "bad template in domain",
+		name:           "bad template in domain template",
 		domainTemplate: "{{.NNName}}.{{.Namespace}}.{{.Domain}}",
 		tagTemplate:    "{{.Name}}-{{.Tag}}",
 		wantErr:        true,
 	}, {
-		name:           "bad template in template",
+		name:           "bad template in tag template",
 		domainTemplate: "{{.Name}}.{{.Namespace}}.{{.Domain}}",
 		tagTemplate:    "{{.NNName}}-{{.Tag}}",
 		wantErr:        true,
diff --git a/pkg/reconciler/route/traffic/rollout_test.go b/pkg/reconciler/route/traffic/rollout_test.go
index 6faed9879..dd73569e8 100644
--- a/pkg/reconciler/route/traffic/rollout_test.go
+++ b/pkg/reconciler/route/traffic/rollout_test.go
@@ -27,7 +27,7 @@ import (
 	"github.com/google/go-cmp/cmp"
 )
 
-func TestRoll(t *testing.T) {
+func TestStep(t *testing.T) {
 	tests := []struct {
 		name            string
 		prev, cur, want *Rollout
@@ -36,6 +36,34 @@ func TestRoll(t *testing.T) {
 		cur:  &Rollout{},
 		prev: nil,
 		want: &Rollout{},
+	}, {
+		name: "prev is empty",
+		cur: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           100,
+				Revisions: []RevisionRollout{{
+					RevisionName: "let-it-bleed",
+					Percent:      100,
+				}},
+			}},
+		},
+		prev: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           100,
+			}},
+		},
+		want: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           100,
+				Revisions: []RevisionRollout{{
+					RevisionName: "let-it-bleed",
+					Percent:      100,
+				}},
+			}},
+		},
 	}, {
 		name: "simplest, same",
 		cur: &Rollout{
@@ -68,6 +96,68 @@ func TestRoll(t *testing.T) {
 				}},
 			}},
 		},
+	}, {
+		name: "when new revision becomes 0%",
+		cur: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "charlie",
+				Percent:           0,
+				Revisions: []RevisionRollout{{
+					RevisionName: "aftermath",
+					Percent:      0,
+				}},
+			}},
+		},
+		prev: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "charlie",
+				Percent:           100,
+				Revisions: []RevisionRollout{{
+					RevisionName: "your-satanic-majesties-request",
+					Percent:      100,
+				}},
+			}},
+		},
+		want: &Rollout{},
+	}, {
+		name: "when new config is added but it's 0%",
+		cur: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "charlie",
+				Percent:           0,
+				Revisions: []RevisionRollout{{
+					RevisionName: "aftermath",
+					Percent:      0,
+				}},
+			}, {
+				ConfigurationName: "mick",
+				Percent:           100,
+				Revisions: []RevisionRollout{{
+					RevisionName: "between-the-buttons",
+					Percent:      100,
+				}},
+			}},
+		},
+		prev: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           100,
+				Revisions: []RevisionRollout{{
+					RevisionName: "between-the-buttons",
+					Percent:      100,
+				}},
+			}},
+		},
+		want: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           100,
+				Revisions: []RevisionRollout{{
+					RevisionName: "between-the-buttons",
+					Percent:      100,
+				}},
+			}},
+		},
 	}, {
 		name: "simplest, roll",
 		cur: &Rollout{
@@ -103,6 +193,123 @@ func TestRoll(t *testing.T) {
 				}},
 			}},
 		},
+	}, {
+		name: "roll with percentage change down",
+		cur: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           33,
+				Revisions: []RevisionRollout{{
+					RevisionName: "let-it-bleed",
+					Percent:      33,
+				}},
+			}},
+		},
+		prev: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           42,
+				Revisions: []RevisionRollout{{
+					RevisionName: "goat-head-soup",
+					Percent:      11,
+				}, {
+					RevisionName: "aftermath",
+					Percent:      31,
+				}},
+			}},
+		},
+		want: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           33,
+				Revisions: []RevisionRollout{{
+					RevisionName: "goat-head-soup",
+					Percent:      2,
+				}, {
+					RevisionName: "aftermath",
+					Percent:      30,
+				}, {
+					RevisionName: "let-it-bleed",
+					Percent:      1,
+				}},
+			}},
+		},
+	}, {
+		name: "roll with percentage change up",
+		cur: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           75,
+				Revisions: []RevisionRollout{{
+					RevisionName: "let-it-bleed",
+					Percent:      75,
+				}},
+			}},
+		},
+		prev: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           25,
+				Revisions: []RevisionRollout{{
+					RevisionName: "goat-head-soup",
+					Percent:      11,
+				}, {
+					RevisionName: "aftermath",
+					Percent:      14,
+				}},
+			}},
+		},
+		want: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           75,
+				Revisions: []RevisionRollout{{
+					RevisionName: "goat-head-soup",
+					Percent:      11,
+				}, {
+					RevisionName: "aftermath",
+					Percent:      63,
+				}, {
+					RevisionName: "let-it-bleed",
+					Percent:      1,
+				}},
+			}},
+		},
+	}, {
+		name: "roll, where sum < 100% (one route targets a revision, e.g.)",
+		cur: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "brian",
+				Percent:           70,
+				Revisions: []RevisionRollout{{
+					RevisionName: "let-it-bleed",
+					Percent:      70,
+				}},
+			}},
+		},
+		prev: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "brian",
+				Percent:           70,
+				Revisions: []RevisionRollout{{
+					RevisionName: "exile-on-main-st",
+					Percent:      70,
+				}},
+			}},
+		},
+		want: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "brian",
+				Percent:           70,
+				Revisions: []RevisionRollout{{
+					RevisionName: "exile-on-main-st",
+					Percent:      69,
+				}, {
+					RevisionName: "let-it-bleed",
+					Percent:      1,
+				}},
+			}},
+		},
 	}, {
 		name: "roll with two existing, no deletes",
 		cur: &Rollout{
@@ -182,6 +389,38 @@ func TestRoll(t *testing.T) {
 				}},
 			}},
 		},
+	}, {
+		name: "roll with delete (minimal config target)",
+		cur: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           1,
+				Revisions: []RevisionRollout{{
+					RevisionName: "between-the-buttons",
+					Percent:      1,
+				}},
+			}},
+		},
+		prev: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           1,
+				Revisions: []RevisionRollout{{
+					RevisionName: "bridges-to-babylon",
+					Percent:      1,
+				}},
+			}},
+		},
+		want: &Rollout{
+			Configurations: []ConfigurationRollout{{
+				ConfigurationName: "mick",
+				Percent:           1,
+				Revisions: []RevisionRollout{{
+					RevisionName: "between-the-buttons",
+					Percent:      1,
+				}},
+			}},
+		},
 	}, {
 		name: "new tag, no roll", // just attached a tag to an existing route.
 		cur: &Rollout{
@@ -371,3 +610,130 @@ func TestRoll(t *testing.T) {
 		})
 	}
 }
+
+func TestAdjustPercentage(t *testing.T) {
+	tests := []struct {
+		name string
+		goal int
+		prev *ConfigurationRollout
+		want []RevisionRollout
+	}{{
+		name: "noop, 100%",
+		goal: 100,
+		prev: &ConfigurationRollout{
+			Percent: 100,
+			Revisions: []RevisionRollout{{
+				Percent: 71,
+			}, {
+				Percent: 29,
+			}},
+		},
+		want: []RevisionRollout{{
+			Percent: 71,
+		}, {
+			Percent: 29,
+		}},
+	}, {
+		name: "noop, 42%",
+		goal: 42,
+		prev: &ConfigurationRollout{
+			Percent: 42,
+			Revisions: []RevisionRollout{{
+				Percent: 21,
+			}, {
+				Percent: 21,
+			}},
+		},
+		want: []RevisionRollout{{
+			Percent: 21,
+		}, {
+			Percent: 21,
+		}},
+	}, {
+		name: "raise, 42% -> 75%",
+		goal: 75,
+		prev: &ConfigurationRollout{
+			Percent: 42,
+			Revisions: []RevisionRollout{{
+				Percent: 21,
+			}, {
+				Percent: 21,
+			}},
+		},
+		want: []RevisionRollout{{
+			Percent: 21,
+		}, {
+			Percent: 54,
+		}},
+	}, {
+		name: "lower, 75%->42%, lose 1",
+		goal: 42,
+		prev: &ConfigurationRollout{
+			Percent: 75,
+			Revisions: []RevisionRollout{{
+				Percent: 21,
+			}, {
+				Percent: 54,
+			}},
+		},
+		want: []RevisionRollout{{
+			Percent: 42,
+		}},
+	}, {
+		name: "lower, 75%->42%, lose 1, update 2, keep 3",
+		goal: 42,
+		prev: &ConfigurationRollout{
+			Percent: 75,
+			Revisions: []RevisionRollout{{
+				Percent: 21,
+			}, {
+				Percent: 22,
+			}, {
+				Percent: 32,
+			}},
+		},
+		want: []RevisionRollout{{
+			Percent: 10,
+		}, {
+			Percent: 32,
+		}},
+	}, {
+		name: "lower, 75%->42%, lose 2, update 3",
+		goal: 42,
+		prev: &ConfigurationRollout{
+			Percent: 75,
+			Revisions: []RevisionRollout{{
+				Percent: 10,
+			}, {
+				Percent: 5,
+			}, {
+				Percent: 60,
+			}},
+		},
+		want: []RevisionRollout{{
+			Percent: 42,
+		}},
+	}, {
+		name: "go to 0%",
+		goal: 0,
+		prev: &ConfigurationRollout{
+			Percent: 75,
+			Revisions: []RevisionRollout{{
+				Percent: 10,
+			}, {
+				Percent: 5,
+			}, {
+				Percent: 60,
+			}},
+		},
+		want: []RevisionRollout{},
+	}}
+	for _, tc := range tests {
+		t.Run(tc.name, func(t *testing.T) {
+			adjustPercentage(tc.goal, tc.prev)
+			if got, want := tc.prev.Revisions, tc.want; !cmp.Equal(got, want) {
+				t.Errorf("Rollout Mistmatch(-want,+got):\n%s", cmp.Diff(want, got))
+			}
+		})
+	}
+}
diff --git a/test/config/100-namespace.yaml b/test/config/100-namespace.yaml
index b1414b416..1fcb556f4 100644
--- a/test/config/100-namespace.yaml
+++ b/test/config/100-namespace.yaml
@@ -24,10 +24,5 @@ metadata:
 ---
 apiVersion: v1
 kind: Namespace
-metadata:
-  name: serving-tests-security
----
-apiVersion: v1
-kind: Namespace
 metadata:
   name: tls
diff --git a/test/config/security/peerauthentication.yaml b/test/config/security/peerauthentication.yaml
deleted file mode 100644
index ab285965a..000000000
--- a/test/config/security/peerauthentication.yaml
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2019 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
-#
-#     https://www.apache.org/licenses/LICENSE-2.0
-#
-# 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.
-
-apiVersion: "security.istio.io/v1beta1"
-kind: "PeerAuthentication"
-metadata:
-  name: "default"
-  namespace: "istio-system"
-  labels:
-    test.knative.dev/dependency: istio-sidecar
-spec:
-  mtls:
-    mode: STRICT
----
-apiVersion: "security.istio.io/v1beta1"
-kind: "PeerAuthentication"
-metadata:
-  name: "default"
-  namespace: "serving-tests"
-  labels:
-    test.knative.dev/dependency: istio-sidecar
-spec:
-  mtls:
-    mode: STRICT
----
-apiVersion: "security.istio.io/v1beta1"
-kind: "PeerAuthentication"
-metadata:
-  name: "default"
-  namespace: "knative-serving"
-  labels:
-    test.knative.dev/dependency: istio-sidecar
-spec:
-  mtls:
-    mode: PERMISSIVE
diff --git a/test/conformance/api/v1/service_test.go b/test/conformance/api/v1/service_test.go
index 2d9b8f5df..b35151899 100644
--- a/test/conformance/api/v1/service_test.go
+++ b/test/conformance/api/v1/service_test.go
@@ -598,35 +598,32 @@ func TestServiceCreateWithMultipleContainers(t *testing.T) {
 
 	names := test.ResourceNames{
 		Service: test.ObjectNameForTest(t),
+		Image:   test.ServingContainer,
+		Sidecars: []string{
+			test.SidecarContainer,
+		},
 	}
 
 	// Clean up on test failure or interrupt
 	test.EnsureTearDown(t, clients, &names)
-	// images are used to validate digest in validateControlPlane function
-	images := map[string]string{
-		"serving-container": test.ServingContainer,
-		"sidecar-container": test.SidecarContainer,
-	}
 	containers := []corev1.Container{{
-		Name:  "serving-container",
-		Image: pkgTest.ImagePath(test.ServingContainer),
+		Image: pkgTest.ImagePath(names.Image),
 		Ports: []corev1.ContainerPort{{
 			ContainerPort: 8881,
 		}},
 	}, {
-		Name:  "sidecar-container",
-		Image: pkgTest.ImagePath(test.SidecarContainer),
+		Image: pkgTest.ImagePath(names.Sidecars[0]),
 	}}
 
 	// Setup initial Service
-	if _, err := v1test.CreateServiceReadyForMultiContainer(t, clients, &names, func(svc *v1.Service) {
+	if _, err := v1test.CreateServiceReady(t, clients, &names, func(svc *v1.Service) {
 		svc.Spec.Template.Spec.Containers = containers
 	}); err != nil {
 		t.Fatalf("Failed to create initial Service %v: %v", names.Service, err)
 	}
 
 	// Validate State after Creation
-	if err := validateControlPlane(t, clients, names, "1" /*1 is the expected generation value*/, images); err != nil {
+	if err := validateControlPlane(t, clients, names, "1" /*1 is the expected generation value*/); err != nil {
 		t.Error(err)
 	}
 
diff --git a/test/conformance/api/v1/util.go b/test/conformance/api/v1/util.go
index bf453a0e3..5d5f9d6f0 100644
--- a/test/conformance/api/v1/util.go
+++ b/test/conformance/api/v1/util.go
@@ -121,26 +121,17 @@ func validateDataPlane(t testing.TB, clients *test.Clients, names test.ResourceN
 // Validates the state of Configuration, Revision, and Route objects for a runLatest Service.
 // The checks in this method should be able to be performed at any point in a
 // runLatest Service's lifecycle so long as the service is in a "Ready" state.
-func validateControlPlane(t *testing.T, clients *test.Clients, names test.ResourceNames, expectedGeneration string, imagesForMultipleContainers ...map[string]string) error {
+func validateControlPlane(t *testing.T, clients *test.Clients, names test.ResourceNames, expectedGeneration string) error {
 	t.Log("Checking to ensure Revision is in desired state with", "generation", expectedGeneration)
 	if err := v1test.CheckRevisionState(clients.ServingClient, names.Revision, func(r *v1.Revision) (bool, error) {
 		if ready, err := v1test.IsRevisionReady(r); !ready {
 			return false, fmt.Errorf("revision %s did not become ready to serve traffic: %w", names.Revision, err)
 		}
-		// for multi containers there will be more than one container and names.Image is a string,
-		// so in order to validate imageDigest for each images validateControlPlane accepting optional field called imagesForMultipleContainers
-		if names.Image == "" {
-			for _, value := range imagesForMultipleContainers {
-				for _, v := range r.Status.ContainerStatuses {
-					if image, ok := value[v.Name]; ok {
-						if validDigest, err := shared.ValidateImageDigest(t, image, v.ImageDigest); !validDigest {
-							return false, fmt.Errorf("imageDigest %s is not valid for imageName %s: %w", v.ImageDigest, image, err)
-						}
-					}
-				}
+		images := append([]string{names.Image}, names.Sidecars...)
+		for i, v := range r.Status.ContainerStatuses {
+			if validDigest, err := shared.ValidateImageDigest(t, images[i], v.ImageDigest); !validDigest {
+				return false, fmt.Errorf("imageDigest %s is not valid for imageName %s: %w", v.ImageDigest, images[i], err)
 			}
-		} else if validDigest, err := shared.ValidateImageDigest(t, names.Image, r.Status.ContainerStatuses[0].ImageDigest); !validDigest {
-			return false, fmt.Errorf("imageDigest %s is not valid for imageName %s: %w", r.Status.ContainerStatuses[0].ImageDigest, names.Image, err)
 		}
 		return true, nil
 	}); err != nil {
diff --git a/test/crd.go b/test/crd.go
index 9f45c8b53..260fdd7d4 100644
--- a/test/crd.go
+++ b/test/crd.go
@@ -33,6 +33,7 @@ type ResourceNames struct {
 	TrafficTarget string
 	URL           *url.URL
 	Image         string
+	Sidecars      []string
 }
 
 // AppendRandomString will generate a random string that begins with prefix. This is useful
diff --git a/test/e2e-common.sh b/test/e2e-common.sh
index 34a3b8dea..2c65c7af0 100644
--- a/test/e2e-common.sh
+++ b/test/e2e-common.sh
@@ -238,7 +238,7 @@ function install_knative_serving_standard() {
     install_kong || return 1
   else
     if [[ "$1" == "HEAD" ]]; then
-      install_istio "./third_party/net-istio.yaml" || return 1
+      install_istio "./third_party/istio-latest/net-istio.yaml" || return 1
     else
       # Download the latest release of net-istio.
       local url="https://github.com/knative/net-istio/releases/download/${LATEST_NET_ISTIO_RELEASE_VERSION}"
@@ -406,8 +406,6 @@ function test_setup() {
   if (( MESH )); then
     kubectl label namespace serving-tests istio-injection=enabled
     kubectl label namespace serving-tests-alt istio-injection=enabled
-    kubectl label namespace serving-tests-security istio-injection=enabled
-    ko apply ${KO_FLAGS} -f ${TEST_CONFIG_DIR}/security/ --selector=test.knative.dev/dependency=istio-sidecar || return 1
   fi
 
   echo ">> Uploading test images..."
@@ -420,6 +418,12 @@ function test_setup() {
   wait_until_ingress_running || return 1
 }
 
+# Apply the logging config for testing. This should be called after test_setup has been triggered.
+function test_logging_config_setup() {
+  echo ">> Setting up test logging config..."
+  ko apply ${KO_FLAGS} -f ${TMP_DIR}/test/config/config-logging.yaml || return 1
+}
+
 # Delete test resources
 function test_teardown() {
   local TEST_CONFIG_DIR=${TMP_DIR}/test/config
@@ -433,8 +437,6 @@ function test_teardown() {
   kubectl delete --ignore-not-found --now --timeout 60s namespace serving-tests
   kubectl delete all --all --ignore-not-found --now --timeout 60s -n serving-tests-alt
   kubectl delete --ignore-not-found --now --timeout 60s namespace serving-tests-alt
-  kubectl delete all --all --ignore-not-found --now --timeout 60s -n serving-tests-security
-  kubectl delete --ignore-not-found --now --timeout 60s namespace serving-tests-security
 }
 
 # Dump more information when test fails.
diff --git a/test/e2e-tests.sh b/test/e2e-tests.sh
index 098c28333..7feac7b0a 100755
--- a/test/e2e-tests.sh
+++ b/test/e2e-tests.sh
@@ -54,8 +54,6 @@ fi
 
 if (( HTTPS )); then
   use_https="--https"
-  # TODO: parallel 1 is necessary until https://github.com/knative/serving/issues/7406 is solved.
-  parallelism="-parallel 1"
   toggle_feature autoTLS Enabled config-network
   kubectl apply -f ${TMP_DIR}/test/config/autotls/certmanager/caissuer/
   add_trap "kubectl delete -f ${TMP_DIR}/test/config/autotls/certmanager/caissuer/ --ignore-not-found" SIGKILL SIGTERM SIGQUIT
@@ -88,10 +86,12 @@ sleep 30
 
 # Run conformance and e2e tests.
 
-# Currently only Istio and Contour implement the alpha features.
-# TODO(#9874): Remove this guard once other ingresses implement these too.
+# Currently only Istio, Contour and Kourier implement the alpha features.
 alpha=""
-if [[ -z "${INGRESS_CLASS}" || "${INGRESS_CLASS}" == "istio.ingress.networking.knative.dev" || "${INGRESS_CLASS}" == "contour.ingress.networking.knative.dev" ]]; then
+if [[ -z "${INGRESS_CLASS}" \
+  || "${INGRESS_CLASS}" == "istio.ingress.networking.knative.dev" \
+  || "${INGRESS_CLASS}" == "contour.ingress.networking.knative.dev" \
+  || "${INGRESS_CLASS}" == "kourier.ingress.networking.knative.dev" ]]; then
   alpha="--enable-alpha"
 fi
 
diff --git a/test/e2e-upgrade-tests.sh b/test/e2e-upgrade-tests.sh
index 462e176be..c6d1d43ee 100755
--- a/test/e2e-upgrade-tests.sh
+++ b/test/e2e-upgrade-tests.sh
@@ -53,6 +53,7 @@ function install_latest_release() {
 
   install_knative_serving latest-release \
       || fail_test "Knative latest release installation failed"
+  test_logging_config_setup
   wait_until_pods_running ${SYSTEM_NAMESPACE}
   wait_until_batch_job_complete ${SYSTEM_NAMESPACE}
 }
@@ -60,6 +61,7 @@ function install_latest_release() {
 function install_head() {
   header "Installing Knative head release"
   install_knative_serving || fail_test "Knative head release installation failed"
+  test_logging_config_setup
   wait_until_pods_running ${SYSTEM_NAMESPACE}
   wait_until_batch_job_complete ${SYSTEM_NAMESPACE}
 }
diff --git a/test/e2e/activator_probe_permitted_test.go b/test/e2e/activator_probe_permitted_test.go
deleted file mode 100644
index a1a8cb820..000000000
--- a/test/e2e/activator_probe_permitted_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// +build e2e
-
-/*
-Copyright 2020 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
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-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.
-*/
-
-package e2e
-
-import (
-	"context"
-	"net/http"
-	"testing"
-
-	pkgTest "knative.dev/pkg/test"
-	"knative.dev/serving/test"
-	v1test "knative.dev/serving/test/v1"
-)
-
-//This test checks if the activator can probe
-//the service when istio end user auth policy is
-//applied on the service.
-//This test needs istio side car injected and
-//istio policy check enabled.
-//policy is present in test/config/security/policy.yaml
-//apply policy before running this test
-func TestAllowedProbes(t *testing.T) {
-	t.Parallel()
-
-	clients := SetupServingNamespaceforSecurityTesting(t)
-
-	names := test.ResourceNames{
-		Service: test.ObjectNameForTest(t),
-		Image:   "helloworld",
-	}
-
-	test.EnsureTearDown(t, clients, &names)
-
-	t.Log("Creating a new Service")
-	resources, err := v1test.CreateServiceReady(t, clients, &names)
-	if err != nil {
-		t.Fatalf("Failed to create initial Service: %v: %v", names.Service, err)
-	}
-
-	url := resources.Route.Status.URL.URL()
-	if _, err := pkgTest.WaitForEndpointState(
-		context.Background(),
-		clients.KubeClient,
-		t.Logf,
-		url,
-		v1test.RetryingRouteInconsistency(pkgTest.MatchesAllOf(pkgTest.IsOneOfStatusCodes(http.StatusUnauthorized))),
-		"HelloWorldServesAuthFailed",
-		test.ServingFlags.ResolvableDomain,
-		test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS),
-	); err != nil {
-		// check if side car is injected before reporting error
-		if _, err := getContainer(clients.KubeClient, resources.Service.Name, "istio-proxy", resources.Service.Namespace); err != nil {
-			t.Skip("Side car not enabled, skipping test")
-		}
-		t.Fatalf("The endpoint %s for Route %s didn't serve the expected status %d: %v", url, names.Route, http.StatusUnauthorized, err)
-	}
-}
diff --git a/test/e2e/autotls/auto_tls_test.go b/test/e2e/autotls/auto_tls_test.go
index 364c45504..442ff4bef 100644
--- a/test/e2e/autotls/auto_tls_test.go
+++ b/test/e2e/autotls/auto_tls_test.go
@@ -83,7 +83,7 @@ func TestTLSDisabledWithAnnotation(t *testing.T) {
 	}
 
 	httpClient := createHTTPClient(t, clients, objects)
-	runtimeRequest(t, httpClient, objects.Route.Status.URL.String())
+	ingress.RuntimeRequest(context.Background(), t, httpClient, objects.Route.Status.URL.String())
 }
 
 func testAutoTLS(t *testing.T) {
@@ -114,7 +114,7 @@ func testAutoTLS(t *testing.T) {
 	certName := getCertificateName(t, clients, objects)
 	rootCAs := createRootCAs(t, clients, objects.Route.Namespace, certName)
 	httpsClient := createHTTPSClient(t, clients, objects, rootCAs)
-	runtimeRequest(t, httpsClient, objects.Service.Status.URL.String())
+	ingress.RuntimeRequest(context.Background(), t, httpsClient, objects.Service.Status.URL.String())
 
 	t.Run("Tag route", func(t *testing.T) {
 		// Probe main URL while we update the route
@@ -161,7 +161,7 @@ func testAutoTLS(t *testing.T) {
 		}
 		httpsClient := createHTTPSClient(t, clients, objects, rootCAs)
 		for _, traffic := range route.Status.Traffic {
-			runtimeRequest(t, httpsClient, traffic.URL.String())
+			ingress.RuntimeRequest(context.Background(), t, httpsClient, traffic.URL.String())
 		}
 	})
 }
diff --git a/test/e2e/autotls/util.go b/test/e2e/autotls/util.go
deleted file mode 100644
index 751a29e7e..000000000
--- a/test/e2e/autotls/util.go
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-Copyright 2019 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
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-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.
-*/
-
-package autotls
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"net"
-	"net/http"
-	"net/http/httputil"
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-
-	"knative.dev/serving/test/types"
-)
-
-type requestOption func(*http.Request)
-type responseExpectation func(response *http.Response) error
-
-func runtimeRequest(t *testing.T, client *http.Client, url string, opts ...requestOption) *types.RuntimeInfo {
-	t.Helper()
-	return runtimeRequestWithExpectations(t, client, url,
-		[]responseExpectation{statusCodeExpectation(sets.NewInt(http.StatusOK))},
-		false,
-		opts...)
-}
-
-// runtimeRequestWithExpectations attempts to make a request to url and return runtime information.
-// If connection is successful only then it will validate all response expectations.
-// If allowDialError is set to true then function will not fail if connection is a dial error.
-func runtimeRequestWithExpectations(t *testing.T, client *http.Client, url string,
-	responseExpectations []responseExpectation,
-	allowDialError bool,
-	opts ...requestOption) *types.RuntimeInfo {
-	t.Helper()
-
-	req, err := http.NewRequest(http.MethodGet, url, nil)
-	if err != nil {
-		t.Error("Error creating Request:", err)
-		return nil
-	}
-
-	for _, opt := range opts {
-		opt(req)
-	}
-
-	resp, err := client.Do(req)
-
-	if err != nil {
-		if !allowDialError || !isDialError(err) {
-			t.Error("Error making GET request:", err)
-		}
-		return nil
-	}
-
-	defer resp.Body.Close()
-
-	for _, e := range responseExpectations {
-		if err := e(resp); err != nil {
-			t.Error("Error meeting response expectations:", err)
-			dumpResponse(t, resp)
-			return nil
-		}
-	}
-
-	if resp.StatusCode == http.StatusOK {
-		b, err := ioutil.ReadAll(resp.Body)
-		if err != nil {
-			t.Error("Unable to read response body:", err)
-			dumpResponse(t, resp)
-			return nil
-		}
-		ri := &types.RuntimeInfo{}
-		if err := json.Unmarshal(b, ri); err != nil {
-			t.Error("Unable to parse runtime image's response payload:", err)
-			return nil
-		}
-		return ri
-	}
-	return nil
-}
-
-func dumpResponse(t *testing.T, resp *http.Response) {
-	t.Helper()
-	b, err := httputil.DumpResponse(resp, true)
-	if err != nil {
-		t.Error("Error dumping response:", err)
-	}
-	t.Log(string(b))
-}
-
-func statusCodeExpectation(statusCodes sets.Int) responseExpectation {
-	return func(response *http.Response) error {
-		if !statusCodes.Has(response.StatusCode) {
-			return fmt.Errorf("got unexpected status: %d, expected %v", response.StatusCode, statusCodes)
-		}
-		return nil
-	}
-}
-
-func isDialError(err error) bool {
-	var errNetOp *net.OpError
-	if !errors.As(err, &errNetOp) {
-		return false
-	}
-	return errNetOp.Op == "dial"
-}
diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go
index 22817f92e..02572a22b 100644
--- a/test/e2e/e2e.go
+++ b/test/e2e/e2e.go
@@ -58,12 +58,6 @@ func SetupAlternativeNamespace(t *testing.T) *test.Clients {
 	return SetupWithNamespace(t, test.AlternativeServingNamespace)
 }
 
-//SetupServingNamespaceforSecurityTesting creates the client objects needed in e2e tests
-// under the security testing namespace.
-func SetupServingNamespaceforSecurityTesting(t *testing.T) *test.Clients {
-	return SetupWithNamespace(t, test.ServingNamespaceforSecurityTesting)
-}
-
 // SetupWithNamespace creates the client objects needed in the e2e tests under the specified namespace.
 func SetupWithNamespace(t *testing.T, namespace string) *test.Clients {
 	t.Helper()
diff --git a/test/e2e/multicontainer/multicontainer_test.go b/test/e2e/multicontainer/multicontainer_test.go
index 0138deac3..1f1e735de 100644
--- a/test/e2e/multicontainer/multicontainer_test.go
+++ b/test/e2e/multicontainer/multicontainer_test.go
@@ -36,23 +36,27 @@ func TestMultiContainer(t *testing.T) {
 
 	clients := e2e.Setup(t)
 
+	names := test.ResourceNames{
+		Service: test.ObjectNameForTest(t),
+		Image:   test.ServingContainer,
+		Sidecars: []string{
+			test.SidecarContainer,
+		},
+	}
+
 	containers := []corev1.Container{{
-		Image: pkgTest.ImagePath(test.ServingContainer),
+		Image: pkgTest.ImagePath(names.Image),
 		Ports: []corev1.ContainerPort{{
 			ContainerPort: 8881,
 		}},
 	}, {
-		Image: pkgTest.ImagePath(test.SidecarContainer),
+		Image: pkgTest.ImagePath(names.Sidecars[0]),
 	}}
 
-	names := test.ResourceNames{
-		Service: test.ObjectNameForTest(t),
-	}
-
 	test.EnsureTearDown(t, clients, &names)
 	t.Log("Creating a new Service")
 
-	resources, err := v1test.CreateServiceReadyForMultiContainer(t, clients, &names, func(svc *v1.Service) {
+	resources, err := v1test.CreateServiceReady(t, clients, &names, func(svc *v1.Service) {
 		svc.Spec.Template.Spec.Containers = containers
 	})
 	if err != nil {
diff --git a/test/e2e_constants.go b/test/e2e_constants.go
index b58e1fd93..d1fb41e31 100644
--- a/test/e2e_constants.go
+++ b/test/e2e_constants.go
@@ -28,9 +28,6 @@ const (
 	// namespace tests in.
 	AlternativeServingNamespace = "serving-tests-alt"
 
-	// ServingNamespaceforSecurityTesting is the namespace for security tests.
-	ServingNamespaceforSecurityTesting = "serving-tests-security"
-
 	// TLSNamespace is the namespace for serving tls tests
 	TLSNamespace = "tls"
 
diff --git a/test/performance/performance-tests.sh b/test/performance/performance-tests.sh
index 9273f1e09..56b1c20d2 100755
--- a/test/performance/performance-tests.sh
+++ b/test/performance/performance-tests.sh
@@ -48,7 +48,7 @@ function update_knative() {
 
   # Create the ${SYSTEM_NAMESPACE} is it does not exist.
   kubectl get ns "${SYSTEM_NAMESPACE}" || kubectl create namespace "${SYSTEM_NAMESPACE}"
-  install_istio "./third_party/net-istio.yaml" || abort "Failed to install Istio"
+  install_istio "./third_party/istio-latest/net-istio.yaml" || abort "Failed to install Istio"
 
   # Overprovision the Istio gateways and pilot.
   kubectl patch hpa -n istio-system istio-ingressgateway \
diff --git a/test/v1/service.go b/test/v1/service.go
index 572154c9f..4415ec9cb 100644
--- a/test/v1/service.go
+++ b/test/v1/service.go
@@ -87,20 +87,6 @@ func GetResourceObjects(clients *test.Clients, names test.ResourceNames) (*Resou
 	}, nil
 }
 
-// CreateServiceReadyForMultiContainer creates a new Service for multi container in 'Ready' state . This function expects Service
-// name passed in through 'names'. Names is updated with the Route and Configuration created by the Service
-// and ResourceObjects is returned with the Service, Route, and Configuration objects.
-// Returns error if the service does not come up correctly.
-func CreateServiceReadyForMultiContainer(t testing.TB, clients *test.Clients, names *test.ResourceNames, fopt ...rtesting.ServiceOption) (*ResourceObjects, error) {
-	t.Log("Creating a new Service", "service", names.Service)
-	svc := rtesting.ServiceWithoutNamespace(names.Service, fopt...)
-	svc, err := createService(t, clients, svc)
-	if err != nil {
-		return nil, err
-	}
-	return getResourceObjects(t, clients, names, svc)
-}
-
 // CreateServiceReady creates a new Service in state 'Ready'. This function expects Service and Image name
 // passed in through 'names'.  Names is updated with the Route and Configuration created by the Service
 // and ResourceObjects is returned with the Service, Route, and Configuration objects.
@@ -227,10 +213,13 @@ func WaitForServiceLatestRevision(clients *test.Clients, names test.ResourceName
 // Service returns a Service object in namespace with the name names.Service
 // that uses the image specified by names.Image.
 func Service(names test.ResourceNames, fopt ...rtesting.ServiceOption) *v1.Service {
-	a := append([]rtesting.ServiceOption{
-		rtesting.WithConfigSpec(ConfigurationSpec(pkgTest.ImagePath(names.Image))),
-	}, fopt...)
-	return rtesting.ServiceWithoutNamespace(names.Service, a...)
+	if names.Image != "" && len(names.Sidecars) == 0 {
+		a := append([]rtesting.ServiceOption{
+			rtesting.WithConfigSpec(ConfigurationSpec(pkgTest.ImagePath(names.Image))),
+		}, fopt...)
+		return rtesting.ServiceWithoutNamespace(names.Service, a...)
+	}
+	return rtesting.ServiceWithoutNamespace(names.Service, fopt...)
 }
 
 // WaitForServiceState polls the status of the Service called name
diff --git a/third_party/cert-manager-latest/net-certmanager.yaml b/third_party/cert-manager-latest/net-certmanager.yaml
index b4b0c8111..43bb920b1 100644
--- a/third_party/cert-manager-latest/net-certmanager.yaml
+++ b/third_party/cert-manager-latest/net-certmanager.yaml
@@ -18,7 +18,7 @@ metadata:
   # These are the permissions needed by the `cert-manager` `Certificate` implementation.
   name: knative-serving-certmanager
   labels:
-    serving.knative.dev/release: "v20201103-a782da1"
+    serving.knative.dev/release: "v20201110-859a9fd"
     serving.knative.dev/controller: "true"
     networking.knative.dev/certificate-provider: cert-manager
 rules:
@@ -49,7 +49,7 @@ kind: ValidatingWebhookConfiguration
 metadata:
   name: config.webhook.net-certmanager.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201103-a782da1"
+    serving.knative.dev/release: "v20201110-859a9fd"
 webhooks:
   - admissionReviewVersions:
       - v1beta1
@@ -86,7 +86,7 @@ metadata:
   name: net-certmanager-webhook-certs
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a782da1"
+    serving.knative.dev/release: "v20201110-859a9fd"
 
 ---
 # Copyright 2020 The Knative Authors
@@ -109,7 +109,7 @@ metadata:
   name: config-certmanager
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a782da1"
+    serving.knative.dev/release: "v20201110-859a9fd"
     networking.knative.dev/certificate-provider: cert-manager
 data:
   _example: |
@@ -156,7 +156,7 @@ metadata:
   name: networking-certmanager
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a782da1"
+    serving.knative.dev/release: "v20201110-859a9fd"
     networking.knative.dev/certificate-provider: cert-manager
 spec:
   selector:
@@ -168,14 +168,14 @@ spec:
         cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
       labels:
         app: networking-certmanager
-        serving.knative.dev/release: "v20201103-a782da1"
+        serving.knative.dev/release: "v20201110-859a9fd"
     spec:
       serviceAccountName: controller
       containers:
         - name: networking-certmanager
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/controller@sha256:1092a284982c8498c8b7de0fa3061f83b3a43b0acb9f16b5ce3f6deddc4bc4d5
+          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/controller@sha256:385ddbf5b1799b16cf6f0a1aed0b7f26fd2aabe017fb7f83a9632168bc9f7ed1
           resources:
             requests:
               cpu: 30m
@@ -213,7 +213,7 @@ kind: Service
 metadata:
   labels:
     app: networking-certmanager
-    serving.knative.dev/release: "v20201103-a782da1"
+    serving.knative.dev/release: "v20201110-859a9fd"
     networking.knative.dev/certificate-provider: cert-manager
   name: networking-certmanager
   namespace: knative-serving
@@ -250,7 +250,7 @@ metadata:
   name: net-certmanager-webhook
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201103-a782da1"
+    serving.knative.dev/release: "v20201110-859a9fd"
 spec:
   selector:
     matchLabels:
@@ -263,14 +263,14 @@ spec:
       labels:
         app: net-certmanager-webhook
         role: net-certmanager-webhook
-        serving.knative.dev/release: "v20201103-a782da1"
+        serving.knative.dev/release: "v20201110-859a9fd"
     spec:
       serviceAccountName: controller
       containers:
         - name: webhook
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/webhook@sha256:eb7188705442f0553c6016df5363b0c526ef82ddf2f656fc142a96d8ad86a58a
+          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/webhook@sha256:e6843cdc1adb80952c88946abad7e1eedca64cab7d6787adb7f82ad02bb72a7f
           resources:
             requests:
               cpu: 20m
@@ -329,7 +329,7 @@ metadata:
   namespace: knative-serving
   labels:
     role: net-certmanager-webhook
-    serving.knative.dev/release: "v20201103-a782da1"
+    serving.knative.dev/release: "v20201110-859a9fd"
 spec:
   ports:
     # Define metrics and profiling for them to be accessible within service meshes.
diff --git a/third_party/contour-latest/contour.yaml b/third_party/contour-latest/contour.yaml
index 67213576f..62e0a8f5a 100644
--- a/third_party/contour-latest/contour.yaml
+++ b/third_party/contour-latest/contour.yaml
@@ -1482,7 +1482,7 @@ spec:
     spec:
       containers:
         - name: contour
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:08aaa5c526c2521734069ae0d9e4930fb80759c6c62deb402e0888e582cf019b
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
           imagePullPolicy: Always
           command:
             - contour
@@ -1709,7 +1709,7 @@ spec:
             - --contour-key-file=/certs/tls.key
             - --config-path=/config/contour.yaml
           command: ["contour"]
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:08aaa5c526c2521734069ae0d9e4930fb80759c6c62deb402e0888e582cf019b
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
           imagePullPolicy: IfNotPresent
           name: contour
           ports:
@@ -1795,7 +1795,7 @@ spec:
           args:
             - envoy
             - shutdown-manager
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:08aaa5c526c2521734069ae0d9e4930fb80759c6c62deb402e0888e582cf019b
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
           imagePullPolicy: IfNotPresent
           lifecycle:
             preStop:
@@ -1871,7 +1871,7 @@ spec:
             - --envoy-key-file=/certs/tls.key
           command:
             - contour
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:08aaa5c526c2521734069ae0d9e4930fb80759c6c62deb402e0888e582cf019b
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
           imagePullPolicy: IfNotPresent
           name: envoy-initconfig
           volumeMounts:
@@ -3381,7 +3381,7 @@ spec:
     spec:
       containers:
         - name: contour
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:08aaa5c526c2521734069ae0d9e4930fb80759c6c62deb402e0888e582cf019b
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
           imagePullPolicy: Always
           command:
             - contour
@@ -3608,7 +3608,7 @@ spec:
             - --contour-key-file=/certs/tls.key
             - --config-path=/config/contour.yaml
           command: ["contour"]
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:08aaa5c526c2521734069ae0d9e4930fb80759c6c62deb402e0888e582cf019b
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
           imagePullPolicy: IfNotPresent
           name: contour
           ports:
@@ -3694,7 +3694,7 @@ spec:
           args:
             - envoy
             - shutdown-manager
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:08aaa5c526c2521734069ae0d9e4930fb80759c6c62deb402e0888e582cf019b
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
           imagePullPolicy: IfNotPresent
           lifecycle:
             preStop:
@@ -3770,7 +3770,7 @@ spec:
             - --envoy-key-file=/certs/tls.key
           command:
             - contour
-          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:08aaa5c526c2521734069ae0d9e4930fb80759c6c62deb402e0888e582cf019b
+          image: gcr.io/knative-nightly/github.com/projectcontour/contour/cmd/contour@sha256:f73508daff3d31f7f52101711b10a84d68c1ab420687335b21950681006e78f4
           imagePullPolicy: IfNotPresent
           name: envoy-initconfig
           volumeMounts:
diff --git a/third_party/contour-latest/net-contour.yaml b/third_party/contour-latest/net-contour.yaml
index 6f9678ab7..00330d23c 100644
--- a/third_party/contour-latest/net-contour.yaml
+++ b/third_party/contour-latest/net-contour.yaml
@@ -34,7 +34,7 @@ metadata:
   namespace: knative-serving
   labels:
     networking.knative.dev/ingress-provider: contour
-    serving.knative.dev/release: "v20201103-ce9941b4"
+    serving.knative.dev/release: "v20201110-2ae0c66f"
 data:
   _example: |
     ################################
@@ -105,7 +105,7 @@ spec:
         - name: controller
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-contour/cmd/controller@sha256:0cddf7db0a4855bed145208e507a34890b00786cad81f4e9630fa6d6fbb9a262
+          image: gcr.io/knative-nightly/knative.dev/net-contour/cmd/controller@sha256:79097613e8368fc0a29e64cbf7e00197a4075279faf18f2ab1200bc27bb45dc6
           resources:
             requests:
               cpu: 40m
diff --git a/third_party/kourier-latest/kourier.yaml b/third_party/kourier-latest/kourier.yaml
index 66013d2b5..7d63e78d4 100644
--- a/third_party/kourier-latest/kourier.yaml
+++ b/third_party/kourier-latest/kourier.yaml
@@ -1,31 +1,183 @@
+# Copyright 2020 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
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
 apiVersion: v1
 kind: Namespace
 metadata:
   name: kourier-system
   labels:
     networking.knative.dev/ingress-provider: kourier
+
+---
+# Copyright 2020 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
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: 3scale-kourier
+  namespace: knative-serving
+  labels:
+    networking.knative.dev/ingress-provider: kourier
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: 3scale-kourier
+  namespace: knative-serving
+  labels:
+    networking.knative.dev/ingress-provider: kourier
+rules:
+  - apiGroups: [""]
+    resources: ["events"]
+    verbs: ["create", "update", "patch"]
+  - apiGroups: [""]
+    resources: ["pods", "endpoints", "services", "secrets"]
+    verbs: ["get", "list", "watch"]
+  - apiGroups: [""]
+    resources: ["configmaps"]
+    verbs: ["get", "list", "watch"]
+  - apiGroups: ["coordination.k8s.io"]
+    resources: ["leases"]
+    verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
+  - apiGroups: ["networking.internal.knative.dev"]
+    resources: ["ingresses"]
+    verbs: ["get", "list", "watch", "patch"]
+  - apiGroups: ["networking.internal.knative.dev"]
+    resources: ["ingresses/status"]
+    verbs: ["update"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: 3scale-kourier
+  labels:
+    networking.knative.dev/ingress-provider: kourier
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: 3scale-kourier
+subjects:
+  - kind: ServiceAccount
+    name: 3scale-kourier
+    namespace: knative-serving
+
+---
+# Copyright 2020 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
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: 3scale-kourier-control
+  namespace: knative-serving
+  labels:
+    networking.knative.dev/ingress-provider: kourier
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: 3scale-kourier-control
+  template:
+    metadata:
+      labels:
+        app: 3scale-kourier-control
+    spec:
+      containers:
+        - image: gcr.io/knative-nightly/knative.dev/net-kourier/cmd/kourier@sha256:28183c42d1b02e927db16861ed9984c653cc9c0cc72b5d9ab450f3c229c2872e
+          name: kourier-control
+          env:
+            - name: CERTS_SECRET_NAMESPACE
+              value: ""
+            - name: CERTS_SECRET_NAME
+              value: ""
+            - name: SYSTEM_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+            - name: METRICS_DOMAIN
+              value: "knative.dev/samples"
+            - name: KOURIER_GATEWAY_NAMESPACE
+              value: "kourier-system"
+          ports:
+            - name: http2-xds
+              containerPort: 18000
+              protocol: TCP
+          securityContext:
+            allowPrivilegeEscalation: false
+            readOnlyRootFilesystem: true
+            runAsNonRoot: true
+            capabilities:
+              drop:
+                - all
+      restartPolicy: Always
+      serviceAccountName: 3scale-kourier
 ---
 apiVersion: v1
 kind: Service
 metadata:
-  name: kourier
-  namespace: kourier-system
+  name: kourier-control
+  namespace: knative-serving
   labels:
     networking.knative.dev/ingress-provider: kourier
 spec:
   ports:
-    - name: http2
-      port: 80
-      protocol: TCP
-      targetPort: 8080
-    - name: https
-      port: 443
+    - name: grpc-xds
+      port: 18000
       protocol: TCP
-      targetPort: 8443
+      targetPort: 18000
   selector:
-    app: 3scale-kourier-gateway
-  type: LoadBalancer
+    app: 3scale-kourier-control
+  type: ClusterIP
+
 ---
+# Copyright 2020 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
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
 apiVersion: apps/v1
 kind: Deployment
 metadata:
@@ -91,110 +243,10 @@ spec:
             name: kourier-bootstrap
       restartPolicy: Always
 ---
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: 3scale-kourier-control
-  namespace: knative-serving
-  labels:
-    networking.knative.dev/ingress-provider: kourier
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: 3scale-kourier-control
-  template:
-    metadata:
-      labels:
-        app: 3scale-kourier-control
-    spec:
-      containers:
-        - image: gcr.io/knative-nightly/knative.dev/net-kourier/cmd/kourier@sha256:f5c21531acb30a445f0a3b1d13f1636abc30145623a008ad78e82a0bcba2621d
-          name: kourier-control
-          env:
-            - name: CERTS_SECRET_NAMESPACE
-              value: ""
-            - name: CERTS_SECRET_NAME
-              value: ""
-            - name: SYSTEM_NAMESPACE
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.namespace
-            - name: METRICS_DOMAIN
-              value: "knative.dev/samples"
-            - name: KOURIER_GATEWAY_NAMESPACE
-              value: "kourier-system"
-          ports:
-            - name: http2-xds
-              containerPort: 18000
-              protocol: TCP
-          securityContext:
-            allowPrivilegeEscalation: false
-            readOnlyRootFilesystem: true
-            runAsNonRoot: true
-            capabilities:
-              drop:
-                - all
-      restartPolicy: Always
-      serviceAccountName: 3scale-kourier
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: ClusterRole
-metadata:
-  name: 3scale-kourier
-  namespace: knative-serving
-  labels:
-    networking.knative.dev/ingress-provider: kourier
-rules:
-  - apiGroups: [""]
-    resources: ["events"]
-    verbs: ["create", "update", "patch"]
-  - apiGroups: [""]
-    resources: ["pods", "endpoints", "namespaces", "services", "secrets"]
-    verbs: ["get", "list", "watch"]
-  - apiGroups: [""]
-    resources: ["configmaps"]
-    verbs: ["get", "list", "watch", "update", "create"]
-  - apiGroups: ["coordination.k8s.io"]
-    resources: ["leases"]
-    verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
-  - apiGroups: ["networking.internal.knative.dev"]
-    resources: ["ingresses"]
-    verbs: ["get", "list", "watch", "patch"]
-  - apiGroups: ["networking.internal.knative.dev"]
-    resources: ["ingresses/status"]
-    verbs: ["update"]
-  - apiGroups: ["apiextensions.k8s.io"]
-    resources: ["customresourcedefinitions"]
-    verbs: ["get", "list", "watch"]
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: 3scale-kourier
-  namespace: knative-serving
-  labels:
-    networking.knative.dev/ingress-provider: kourier
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: ClusterRoleBinding
-metadata:
-  name: 3scale-kourier
-  labels:
-    networking.knative.dev/ingress-provider: kourier
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: ClusterRole
-  name: 3scale-kourier
-subjects:
-  - kind: ServiceAccount
-    name: 3scale-kourier
-    namespace: knative-serving
----
 apiVersion: v1
 kind: Service
 metadata:
-  name: kourier-internal
+  name: kourier
   namespace: kourier-system
   labels:
     networking.knative.dev/ingress-provider: kourier
@@ -203,26 +255,30 @@ spec:
     - name: http2
       port: 80
       protocol: TCP
-      targetPort: 8081
+      targetPort: 8080
+    - name: https
+      port: 443
+      protocol: TCP
+      targetPort: 8443
   selector:
     app: 3scale-kourier-gateway
-  type: ClusterIP
+  type: LoadBalancer
 ---
 apiVersion: v1
 kind: Service
 metadata:
-  name: kourier-control
-  namespace: knative-serving
+  name: kourier-internal
+  namespace: kourier-system
   labels:
     networking.knative.dev/ingress-provider: kourier
 spec:
   ports:
-    - name: grpc-xds
-      port: 18000
+    - name: http2
+      port: 80
       protocol: TCP
-      targetPort: 18000
+      targetPort: 8081
   selector:
-    app: 3scale-kourier-control
+    app: 3scale-kourier-gateway
   type: ClusterIP
 ---
 apiVersion: v1