mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master'
This commit is contained in:
		@@ -1,232 +1,245 @@
 | 
			
		||||
<!-- BEGIN MUNGE: GENERATED_TOC -->
 | 
			
		||||
 | 
			
		||||
- [v1.19.15](#v11915)
 | 
			
		||||
  - [Downloads for v1.19.15](#downloads-for-v11915)
 | 
			
		||||
- [v1.19.16](#v11916)
 | 
			
		||||
  - [Downloads for v1.19.16](#downloads-for-v11916)
 | 
			
		||||
    - [Source Code](#source-code)
 | 
			
		||||
    - [Client Binaries](#client-binaries)
 | 
			
		||||
    - [Server Binaries](#server-binaries)
 | 
			
		||||
    - [Node Binaries](#node-binaries)
 | 
			
		||||
  - [Changelog since v1.19.14](#changelog-since-v11914)
 | 
			
		||||
  - [Important Security Information](#important-security-information)
 | 
			
		||||
    - [CVE-2021-25741: Symlink Exchange Can Allow Host Filesystem Access](#cve-2021-25741-symlink-exchange-can-allow-host-filesystem-access)
 | 
			
		||||
  - [Changelog since v1.19.15](#changelog-since-v11915)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake)
 | 
			
		||||
  - [Dependencies](#dependencies)
 | 
			
		||||
    - [Added](#added)
 | 
			
		||||
    - [Changed](#changed)
 | 
			
		||||
    - [Removed](#removed)
 | 
			
		||||
- [v1.19.14](#v11914)
 | 
			
		||||
  - [Downloads for v1.19.14](#downloads-for-v11914)
 | 
			
		||||
- [v1.19.15](#v11915)
 | 
			
		||||
  - [Downloads for v1.19.15](#downloads-for-v11915)
 | 
			
		||||
    - [Source Code](#source-code-1)
 | 
			
		||||
    - [Client Binaries](#client-binaries-1)
 | 
			
		||||
    - [Server Binaries](#server-binaries-1)
 | 
			
		||||
    - [Node Binaries](#node-binaries-1)
 | 
			
		||||
  - [Changelog since v1.19.13](#changelog-since-v11913)
 | 
			
		||||
  - [Changelog since v1.19.14](#changelog-since-v11914)
 | 
			
		||||
  - [Important Security Information](#important-security-information)
 | 
			
		||||
    - [CVE-2021-25741: Symlink Exchange Can Allow Host Filesystem Access](#cve-2021-25741-symlink-exchange-can-allow-host-filesystem-access)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-1)
 | 
			
		||||
    - [Feature](#feature)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-1)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake)
 | 
			
		||||
  - [Dependencies](#dependencies-1)
 | 
			
		||||
    - [Added](#added-1)
 | 
			
		||||
    - [Changed](#changed-1)
 | 
			
		||||
    - [Removed](#removed-1)
 | 
			
		||||
- [v1.19.13](#v11913)
 | 
			
		||||
  - [Downloads for v1.19.13](#downloads-for-v11913)
 | 
			
		||||
- [v1.19.14](#v11914)
 | 
			
		||||
  - [Downloads for v1.19.14](#downloads-for-v11914)
 | 
			
		||||
    - [Source Code](#source-code-2)
 | 
			
		||||
    - [Client Binaries](#client-binaries-2)
 | 
			
		||||
    - [Server Binaries](#server-binaries-2)
 | 
			
		||||
    - [Node Binaries](#node-binaries-2)
 | 
			
		||||
  - [Changelog since v1.19.12](#changelog-since-v11912)
 | 
			
		||||
  - [Changelog since v1.19.13](#changelog-since-v11913)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-2)
 | 
			
		||||
    - [Feature](#feature-1)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-1)
 | 
			
		||||
    - [Feature](#feature)
 | 
			
		||||
  - [Dependencies](#dependencies-2)
 | 
			
		||||
    - [Added](#added-2)
 | 
			
		||||
    - [Changed](#changed-2)
 | 
			
		||||
    - [Removed](#removed-2)
 | 
			
		||||
- [v1.19.12](#v11912)
 | 
			
		||||
  - [Downloads for v1.19.12](#downloads-for-v11912)
 | 
			
		||||
- [v1.19.13](#v11913)
 | 
			
		||||
  - [Downloads for v1.19.13](#downloads-for-v11913)
 | 
			
		||||
    - [Source Code](#source-code-3)
 | 
			
		||||
    - [Client Binaries](#client-binaries-3)
 | 
			
		||||
    - [Server Binaries](#server-binaries-3)
 | 
			
		||||
    - [Node Binaries](#node-binaries-3)
 | 
			
		||||
  - [Changelog since v1.19.11](#changelog-since-v11911)
 | 
			
		||||
  - [Changelog since v1.19.12](#changelog-since-v11912)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-3)
 | 
			
		||||
    - [Feature](#feature-2)
 | 
			
		||||
    - [Failing Test](#failing-test)
 | 
			
		||||
    - [Feature](#feature-1)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-2)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-1)
 | 
			
		||||
  - [Dependencies](#dependencies-3)
 | 
			
		||||
    - [Added](#added-3)
 | 
			
		||||
    - [Changed](#changed-3)
 | 
			
		||||
    - [Removed](#removed-3)
 | 
			
		||||
- [v1.19.11](#v11911)
 | 
			
		||||
  - [Downloads for v1.19.11](#downloads-for-v11911)
 | 
			
		||||
- [v1.19.12](#v11912)
 | 
			
		||||
  - [Downloads for v1.19.12](#downloads-for-v11912)
 | 
			
		||||
    - [Source Code](#source-code-4)
 | 
			
		||||
    - [Client Binaries](#client-binaries-4)
 | 
			
		||||
    - [Server Binaries](#server-binaries-4)
 | 
			
		||||
    - [Node Binaries](#node-binaries-4)
 | 
			
		||||
  - [Changelog since v1.19.10](#changelog-since-v11910)
 | 
			
		||||
  - [Changelog since v1.19.11](#changelog-since-v11911)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-4)
 | 
			
		||||
    - [API Change](#api-change)
 | 
			
		||||
    - [Feature](#feature-3)
 | 
			
		||||
    - [Feature](#feature-2)
 | 
			
		||||
    - [Failing Test](#failing-test)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-3)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-1)
 | 
			
		||||
  - [Dependencies](#dependencies-4)
 | 
			
		||||
    - [Added](#added-4)
 | 
			
		||||
    - [Changed](#changed-4)
 | 
			
		||||
    - [Removed](#removed-4)
 | 
			
		||||
- [v1.19.10](#v11910)
 | 
			
		||||
  - [Downloads for v1.19.10](#downloads-for-v11910)
 | 
			
		||||
- [v1.19.11](#v11911)
 | 
			
		||||
  - [Downloads for v1.19.11](#downloads-for-v11911)
 | 
			
		||||
    - [Source Code](#source-code-5)
 | 
			
		||||
    - [Client binaries](#client-binaries-5)
 | 
			
		||||
    - [Server binaries](#server-binaries-5)
 | 
			
		||||
    - [Node binaries](#node-binaries-5)
 | 
			
		||||
  - [Changelog since v1.19.9](#changelog-since-v1199)
 | 
			
		||||
  - [Important Security Information](#important-security-information)
 | 
			
		||||
    - [CVE-2021-25735: Validating Admission Webhook does not observe some previous fields](#cve-2021-25735-validating-admission-webhook-does-not-observe-some-previous-fields)
 | 
			
		||||
    - [Client Binaries](#client-binaries-5)
 | 
			
		||||
    - [Server Binaries](#server-binaries-5)
 | 
			
		||||
    - [Node Binaries](#node-binaries-5)
 | 
			
		||||
  - [Changelog since v1.19.10](#changelog-since-v11910)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-5)
 | 
			
		||||
    - [API Change](#api-change-1)
 | 
			
		||||
    - [Feature](#feature-4)
 | 
			
		||||
    - [API Change](#api-change)
 | 
			
		||||
    - [Feature](#feature-3)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-4)
 | 
			
		||||
  - [Dependencies](#dependencies-5)
 | 
			
		||||
    - [Added](#added-5)
 | 
			
		||||
    - [Changed](#changed-5)
 | 
			
		||||
    - [Removed](#removed-5)
 | 
			
		||||
- [v1.19.9](#v1199)
 | 
			
		||||
  - [Downloads for v1.19.9](#downloads-for-v1199)
 | 
			
		||||
- [v1.19.10](#v11910)
 | 
			
		||||
  - [Downloads for v1.19.10](#downloads-for-v11910)
 | 
			
		||||
    - [Source Code](#source-code-6)
 | 
			
		||||
    - [Client binaries](#client-binaries-6)
 | 
			
		||||
    - [Server binaries](#server-binaries-6)
 | 
			
		||||
    - [Node binaries](#node-binaries-6)
 | 
			
		||||
  - [Changelog since v1.19.8](#changelog-since-v1198)
 | 
			
		||||
  - [Changelog since v1.19.9](#changelog-since-v1199)
 | 
			
		||||
  - [Important Security Information](#important-security-information-1)
 | 
			
		||||
    - [CVE-2021-25735: Validating Admission Webhook does not observe some previous fields](#cve-2021-25735-validating-admission-webhook-does-not-observe-some-previous-fields)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-6)
 | 
			
		||||
    - [Failing Test](#failing-test-1)
 | 
			
		||||
    - [API Change](#api-change-1)
 | 
			
		||||
    - [Feature](#feature-4)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-5)
 | 
			
		||||
  - [Dependencies](#dependencies-6)
 | 
			
		||||
    - [Added](#added-6)
 | 
			
		||||
    - [Changed](#changed-6)
 | 
			
		||||
    - [Removed](#removed-6)
 | 
			
		||||
- [v1.19.8](#v1198)
 | 
			
		||||
  - [Downloads for v1.19.8](#downloads-for-v1198)
 | 
			
		||||
- [v1.19.9](#v1199)
 | 
			
		||||
  - [Downloads for v1.19.9](#downloads-for-v1199)
 | 
			
		||||
    - [Source Code](#source-code-7)
 | 
			
		||||
    - [Client binaries](#client-binaries-7)
 | 
			
		||||
    - [Server binaries](#server-binaries-7)
 | 
			
		||||
    - [Node binaries](#node-binaries-7)
 | 
			
		||||
  - [Changelog since v1.19.7](#changelog-since-v1197)
 | 
			
		||||
  - [Changelog since v1.19.8](#changelog-since-v1198)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-7)
 | 
			
		||||
    - [API Change](#api-change-2)
 | 
			
		||||
    - [Failing Test](#failing-test-1)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-6)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-2)
 | 
			
		||||
  - [Dependencies](#dependencies-7)
 | 
			
		||||
    - [Added](#added-7)
 | 
			
		||||
    - [Changed](#changed-7)
 | 
			
		||||
    - [Removed](#removed-7)
 | 
			
		||||
- [v1.19.7](#v1197)
 | 
			
		||||
  - [Downloads for v1.19.7](#downloads-for-v1197)
 | 
			
		||||
- [v1.19.8](#v1198)
 | 
			
		||||
  - [Downloads for v1.19.8](#downloads-for-v1198)
 | 
			
		||||
    - [Source Code](#source-code-8)
 | 
			
		||||
    - [Client binaries](#client-binaries-8)
 | 
			
		||||
    - [Server binaries](#server-binaries-8)
 | 
			
		||||
    - [Node binaries](#node-binaries-8)
 | 
			
		||||
  - [Changelog since v1.19.6](#changelog-since-v1196)
 | 
			
		||||
  - [Changelog since v1.19.7](#changelog-since-v1197)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-8)
 | 
			
		||||
    - [API Change](#api-change-2)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-7)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-2)
 | 
			
		||||
  - [Dependencies](#dependencies-8)
 | 
			
		||||
    - [Added](#added-8)
 | 
			
		||||
    - [Changed](#changed-8)
 | 
			
		||||
    - [Removed](#removed-8)
 | 
			
		||||
- [v1.19.6](#v1196)
 | 
			
		||||
  - [Downloads for v1.19.6](#downloads-for-v1196)
 | 
			
		||||
- [v1.19.7](#v1197)
 | 
			
		||||
  - [Downloads for v1.19.7](#downloads-for-v1197)
 | 
			
		||||
    - [Source Code](#source-code-9)
 | 
			
		||||
    - [Client binaries](#client-binaries-9)
 | 
			
		||||
    - [Server binaries](#server-binaries-9)
 | 
			
		||||
    - [Node binaries](#node-binaries-9)
 | 
			
		||||
  - [Changelog since v1.19.5](#changelog-since-v1195)
 | 
			
		||||
  - [Changelog since v1.19.6](#changelog-since-v1196)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-9)
 | 
			
		||||
    - [Feature](#feature-5)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-8)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-3)
 | 
			
		||||
  - [Dependencies](#dependencies-9)
 | 
			
		||||
    - [Added](#added-9)
 | 
			
		||||
    - [Changed](#changed-9)
 | 
			
		||||
    - [Removed](#removed-9)
 | 
			
		||||
- [v1.19.5](#v1195)
 | 
			
		||||
  - [Downloads for v1.19.5](#downloads-for-v1195)
 | 
			
		||||
- [v1.19.6](#v1196)
 | 
			
		||||
  - [Downloads for v1.19.6](#downloads-for-v1196)
 | 
			
		||||
    - [Source Code](#source-code-10)
 | 
			
		||||
    - [Client binaries](#client-binaries-10)
 | 
			
		||||
    - [Server binaries](#server-binaries-10)
 | 
			
		||||
    - [Node binaries](#node-binaries-10)
 | 
			
		||||
  - [Changelog since v1.19.4](#changelog-since-v1194)
 | 
			
		||||
  - [Changelog since v1.19.5](#changelog-since-v1195)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-10)
 | 
			
		||||
    - [Feature](#feature-6)
 | 
			
		||||
    - [Failing Test](#failing-test-2)
 | 
			
		||||
    - [Feature](#feature-5)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-9)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-3)
 | 
			
		||||
  - [Dependencies](#dependencies-10)
 | 
			
		||||
    - [Added](#added-10)
 | 
			
		||||
    - [Changed](#changed-10)
 | 
			
		||||
    - [Removed](#removed-10)
 | 
			
		||||
- [v1.19.4](#v1194)
 | 
			
		||||
  - [Downloads for v1.19.4](#downloads-for-v1194)
 | 
			
		||||
- [v1.19.5](#v1195)
 | 
			
		||||
  - [Downloads for v1.19.5](#downloads-for-v1195)
 | 
			
		||||
    - [Source Code](#source-code-11)
 | 
			
		||||
    - [Client binaries](#client-binaries-11)
 | 
			
		||||
    - [Server binaries](#server-binaries-11)
 | 
			
		||||
    - [Node binaries](#node-binaries-11)
 | 
			
		||||
  - [Changelog since v1.19.3](#changelog-since-v1193)
 | 
			
		||||
  - [Changelog since v1.19.4](#changelog-since-v1194)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-11)
 | 
			
		||||
    - [Feature](#feature-6)
 | 
			
		||||
    - [Failing Test](#failing-test-2)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-10)
 | 
			
		||||
  - [Dependencies](#dependencies-11)
 | 
			
		||||
    - [Added](#added-11)
 | 
			
		||||
    - [Changed](#changed-11)
 | 
			
		||||
    - [Removed](#removed-11)
 | 
			
		||||
- [v1.19.3](#v1193)
 | 
			
		||||
  - [Downloads for v1.19.3](#downloads-for-v1193)
 | 
			
		||||
- [v1.19.4](#v1194)
 | 
			
		||||
  - [Downloads for v1.19.4](#downloads-for-v1194)
 | 
			
		||||
    - [Source Code](#source-code-12)
 | 
			
		||||
    - [Client binaries](#client-binaries-12)
 | 
			
		||||
    - [Server binaries](#server-binaries-12)
 | 
			
		||||
    - [Node binaries](#node-binaries-12)
 | 
			
		||||
  - [Changelog since v1.19.2](#changelog-since-v1192)
 | 
			
		||||
  - [Changelog since v1.19.3](#changelog-since-v1193)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-12)
 | 
			
		||||
    - [Feature](#feature-7)
 | 
			
		||||
    - [Design](#design)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-11)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-4)
 | 
			
		||||
  - [Dependencies](#dependencies-12)
 | 
			
		||||
    - [Added](#added-12)
 | 
			
		||||
    - [Changed](#changed-12)
 | 
			
		||||
    - [Removed](#removed-12)
 | 
			
		||||
- [v1.19.2](#v1192)
 | 
			
		||||
  - [Downloads for v1.19.2](#downloads-for-v1192)
 | 
			
		||||
- [v1.19.3](#v1193)
 | 
			
		||||
  - [Downloads for v1.19.3](#downloads-for-v1193)
 | 
			
		||||
    - [Source Code](#source-code-13)
 | 
			
		||||
    - [Client binaries](#client-binaries-13)
 | 
			
		||||
    - [Server binaries](#server-binaries-13)
 | 
			
		||||
    - [Node binaries](#node-binaries-13)
 | 
			
		||||
  - [Changelog since v1.19.1](#changelog-since-v1191)
 | 
			
		||||
  - [Changelog since v1.19.2](#changelog-since-v1192)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-13)
 | 
			
		||||
    - [API Change](#api-change-3)
 | 
			
		||||
    - [Feature](#feature-7)
 | 
			
		||||
    - [Design](#design)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-12)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-5)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-4)
 | 
			
		||||
  - [Dependencies](#dependencies-13)
 | 
			
		||||
    - [Added](#added-13)
 | 
			
		||||
    - [Changed](#changed-13)
 | 
			
		||||
    - [Removed](#removed-13)
 | 
			
		||||
- [v1.19.1](#v1191)
 | 
			
		||||
  - [Downloads for v1.19.1](#downloads-for-v1191)
 | 
			
		||||
- [v1.19.2](#v1192)
 | 
			
		||||
  - [Downloads for v1.19.2](#downloads-for-v1192)
 | 
			
		||||
    - [Source Code](#source-code-14)
 | 
			
		||||
    - [Client binaries](#client-binaries-14)
 | 
			
		||||
    - [Server binaries](#server-binaries-14)
 | 
			
		||||
    - [Node binaries](#node-binaries-14)
 | 
			
		||||
  - [Changelog since v1.19.0](#changelog-since-v1190)
 | 
			
		||||
  - [Changelog since v1.19.1](#changelog-since-v1191)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-14)
 | 
			
		||||
    - [API Change](#api-change-3)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-13)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-6)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-5)
 | 
			
		||||
  - [Dependencies](#dependencies-14)
 | 
			
		||||
    - [Added](#added-14)
 | 
			
		||||
    - [Changed](#changed-14)
 | 
			
		||||
    - [Removed](#removed-14)
 | 
			
		||||
- [v1.19.1](#v1191)
 | 
			
		||||
  - [Downloads for v1.19.1](#downloads-for-v1191)
 | 
			
		||||
    - [Source Code](#source-code-15)
 | 
			
		||||
    - [Client binaries](#client-binaries-15)
 | 
			
		||||
    - [Server binaries](#server-binaries-15)
 | 
			
		||||
    - [Node binaries](#node-binaries-15)
 | 
			
		||||
  - [Changelog since v1.19.0](#changelog-since-v1190)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-15)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-14)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-6)
 | 
			
		||||
  - [Dependencies](#dependencies-15)
 | 
			
		||||
    - [Added](#added-15)
 | 
			
		||||
    - [Changed](#changed-15)
 | 
			
		||||
    - [Removed](#removed-15)
 | 
			
		||||
- [v1.19.0](#v1190)
 | 
			
		||||
  - [Downloads for v1.19.0](#downloads-for-v1190)
 | 
			
		||||
    - [Source Code](#source-code-15)
 | 
			
		||||
    - [Client Binaries](#client-binaries-15)
 | 
			
		||||
    - [Server Binaries](#server-binaries-15)
 | 
			
		||||
    - [Node Binaries](#node-binaries-15)
 | 
			
		||||
    - [Source Code](#source-code-16)
 | 
			
		||||
    - [Client Binaries](#client-binaries-16)
 | 
			
		||||
    - [Server Binaries](#server-binaries-16)
 | 
			
		||||
    - [Node Binaries](#node-binaries-16)
 | 
			
		||||
  - [Changelog since v1.18.0](#changelog-since-v1180)
 | 
			
		||||
  - [What’s New (Major Themes)](#whats-new-major-themes)
 | 
			
		||||
    - [Deprecation warnings](#deprecation-warnings)
 | 
			
		||||
@@ -250,177 +263,177 @@
 | 
			
		||||
  - [Known Issues](#known-issues)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-15)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-16)
 | 
			
		||||
    - [Deprecation](#deprecation)
 | 
			
		||||
    - [API Change](#api-change-4)
 | 
			
		||||
    - [Feature](#feature-8)
 | 
			
		||||
    - [Documentation](#documentation)
 | 
			
		||||
    - [Failing Test](#failing-test-3)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-14)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-15)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-7)
 | 
			
		||||
  - [Dependencies](#dependencies-15)
 | 
			
		||||
    - [Added](#added-15)
 | 
			
		||||
    - [Changed](#changed-15)
 | 
			
		||||
    - [Removed](#removed-15)
 | 
			
		||||
  - [Dependencies](#dependencies-16)
 | 
			
		||||
    - [Added](#added-16)
 | 
			
		||||
    - [Changed](#changed-16)
 | 
			
		||||
    - [Removed](#removed-16)
 | 
			
		||||
- [v1.19.0-rc.4](#v1190-rc4)
 | 
			
		||||
  - [Downloads for v1.19.0-rc.4](#downloads-for-v1190-rc4)
 | 
			
		||||
    - [Source Code](#source-code-16)
 | 
			
		||||
    - [Client binaries](#client-binaries-16)
 | 
			
		||||
    - [Server binaries](#server-binaries-16)
 | 
			
		||||
    - [Node binaries](#node-binaries-16)
 | 
			
		||||
  - [Changelog since v1.19.0-rc.3](#changelog-since-v1190-rc3)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-16)
 | 
			
		||||
    - [Deprecation](#deprecation-1)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-15)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-8)
 | 
			
		||||
  - [Dependencies](#dependencies-17)
 | 
			
		||||
    - [Added](#added-17)
 | 
			
		||||
    - [Changed](#changed-17)
 | 
			
		||||
    - [Removed](#removed-17)
 | 
			
		||||
- [v1.19.0-rc.3](#v1190-rc3)
 | 
			
		||||
  - [Downloads for v1.19.0-rc.3](#downloads-for-v1190-rc3)
 | 
			
		||||
- [v1.19.0-rc.4](#v1190-rc4)
 | 
			
		||||
  - [Downloads for v1.19.0-rc.4](#downloads-for-v1190-rc4)
 | 
			
		||||
    - [Source Code](#source-code-17)
 | 
			
		||||
    - [Client binaries](#client-binaries-17)
 | 
			
		||||
    - [Server binaries](#server-binaries-17)
 | 
			
		||||
    - [Node binaries](#node-binaries-17)
 | 
			
		||||
  - [Changelog since v1.19.0-rc.2](#changelog-since-v1190-rc2)
 | 
			
		||||
  - [Changelog since v1.19.0-rc.3](#changelog-since-v1190-rc3)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-17)
 | 
			
		||||
    - [API Change](#api-change-5)
 | 
			
		||||
    - [Deprecation](#deprecation-1)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-16)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-8)
 | 
			
		||||
  - [Dependencies](#dependencies-18)
 | 
			
		||||
    - [Added](#added-18)
 | 
			
		||||
    - [Changed](#changed-18)
 | 
			
		||||
    - [Removed](#removed-18)
 | 
			
		||||
- [v1.19.0-rc.2](#v1190-rc2)
 | 
			
		||||
  - [Downloads for v1.19.0-rc.2](#downloads-for-v1190-rc2)
 | 
			
		||||
- [v1.19.0-rc.3](#v1190-rc3)
 | 
			
		||||
  - [Downloads for v1.19.0-rc.3](#downloads-for-v1190-rc3)
 | 
			
		||||
    - [Source Code](#source-code-18)
 | 
			
		||||
    - [Client binaries](#client-binaries-18)
 | 
			
		||||
    - [Server binaries](#server-binaries-18)
 | 
			
		||||
    - [Node binaries](#node-binaries-18)
 | 
			
		||||
  - [Changelog since v1.19.0-rc.1](#changelog-since-v1190-rc1)
 | 
			
		||||
  - [Changelog since v1.19.0-rc.2](#changelog-since-v1190-rc2)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-18)
 | 
			
		||||
    - [API Change](#api-change-6)
 | 
			
		||||
    - [Feature](#feature-9)
 | 
			
		||||
    - [API Change](#api-change-5)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-17)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-9)
 | 
			
		||||
  - [Dependencies](#dependencies-19)
 | 
			
		||||
    - [Added](#added-19)
 | 
			
		||||
    - [Changed](#changed-19)
 | 
			
		||||
    - [Removed](#removed-19)
 | 
			
		||||
- [v1.19.0-rc.1](#v1190-rc1)
 | 
			
		||||
  - [Downloads for v1.19.0-rc.1](#downloads-for-v1190-rc1)
 | 
			
		||||
- [v1.19.0-rc.2](#v1190-rc2)
 | 
			
		||||
  - [Downloads for v1.19.0-rc.2](#downloads-for-v1190-rc2)
 | 
			
		||||
    - [Source Code](#source-code-19)
 | 
			
		||||
    - [Client binaries](#client-binaries-19)
 | 
			
		||||
    - [Server binaries](#server-binaries-19)
 | 
			
		||||
    - [Node binaries](#node-binaries-19)
 | 
			
		||||
  - [Changelog since v1.19.0-rc.0](#changelog-since-v1190-rc0)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-1)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-1)
 | 
			
		||||
  - [Changelog since v1.19.0-rc.1](#changelog-since-v1190-rc1)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-19)
 | 
			
		||||
    - [Deprecation](#deprecation-2)
 | 
			
		||||
    - [API Change](#api-change-7)
 | 
			
		||||
    - [Feature](#feature-10)
 | 
			
		||||
    - [Failing Test](#failing-test-4)
 | 
			
		||||
    - [API Change](#api-change-6)
 | 
			
		||||
    - [Feature](#feature-9)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-18)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-10)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-9)
 | 
			
		||||
  - [Dependencies](#dependencies-20)
 | 
			
		||||
    - [Added](#added-20)
 | 
			
		||||
    - [Changed](#changed-20)
 | 
			
		||||
    - [Removed](#removed-20)
 | 
			
		||||
- [v1.19.0-beta.2](#v1190-beta2)
 | 
			
		||||
  - [Downloads for v1.19.0-beta.2](#downloads-for-v1190-beta2)
 | 
			
		||||
- [v1.19.0-rc.1](#v1190-rc1)
 | 
			
		||||
  - [Downloads for v1.19.0-rc.1](#downloads-for-v1190-rc1)
 | 
			
		||||
    - [Source Code](#source-code-20)
 | 
			
		||||
    - [Client binaries](#client-binaries-20)
 | 
			
		||||
    - [Server binaries](#server-binaries-20)
 | 
			
		||||
    - [Node binaries](#node-binaries-20)
 | 
			
		||||
  - [Changelog since v1.19.0-beta.1](#changelog-since-v1190-beta1)
 | 
			
		||||
  - [Changelog since v1.19.0-rc.0](#changelog-since-v1190-rc0)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-1)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-1)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-20)
 | 
			
		||||
    - [Deprecation](#deprecation-3)
 | 
			
		||||
    - [API Change](#api-change-8)
 | 
			
		||||
    - [Feature](#feature-11)
 | 
			
		||||
    - [Deprecation](#deprecation-2)
 | 
			
		||||
    - [API Change](#api-change-7)
 | 
			
		||||
    - [Feature](#feature-10)
 | 
			
		||||
    - [Failing Test](#failing-test-4)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-19)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-11)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-10)
 | 
			
		||||
  - [Dependencies](#dependencies-21)
 | 
			
		||||
    - [Added](#added-21)
 | 
			
		||||
    - [Changed](#changed-21)
 | 
			
		||||
    - [Removed](#removed-21)
 | 
			
		||||
- [v1.19.0-beta.1](#v1190-beta1)
 | 
			
		||||
  - [Downloads for v1.19.0-beta.1](#downloads-for-v1190-beta1)
 | 
			
		||||
- [v1.19.0-beta.2](#v1190-beta2)
 | 
			
		||||
  - [Downloads for v1.19.0-beta.2](#downloads-for-v1190-beta2)
 | 
			
		||||
    - [Source Code](#source-code-21)
 | 
			
		||||
    - [Client binaries](#client-binaries-21)
 | 
			
		||||
    - [Server binaries](#server-binaries-21)
 | 
			
		||||
    - [Node binaries](#node-binaries-21)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.3](#changelog-since-v1190-alpha3)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-2)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-2)
 | 
			
		||||
  - [Changelog since v1.19.0-beta.1](#changelog-since-v1190-beta1)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-21)
 | 
			
		||||
    - [API Change](#api-change-9)
 | 
			
		||||
    - [Feature](#feature-12)
 | 
			
		||||
    - [Deprecation](#deprecation-3)
 | 
			
		||||
    - [API Change](#api-change-8)
 | 
			
		||||
    - [Feature](#feature-11)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-20)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-12)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-11)
 | 
			
		||||
  - [Dependencies](#dependencies-22)
 | 
			
		||||
    - [Added](#added-22)
 | 
			
		||||
    - [Changed](#changed-22)
 | 
			
		||||
    - [Removed](#removed-22)
 | 
			
		||||
- [v1.19.0-beta.0](#v1190-beta0)
 | 
			
		||||
  - [Downloads for v1.19.0-beta.0](#downloads-for-v1190-beta0)
 | 
			
		||||
- [v1.19.0-beta.1](#v1190-beta1)
 | 
			
		||||
  - [Downloads for v1.19.0-beta.1](#downloads-for-v1190-beta1)
 | 
			
		||||
    - [Source Code](#source-code-22)
 | 
			
		||||
    - [Client binaries](#client-binaries-22)
 | 
			
		||||
    - [Server binaries](#server-binaries-22)
 | 
			
		||||
    - [Node binaries](#node-binaries-22)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.3](#changelog-since-v1190-alpha3-1)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.3](#changelog-since-v1190-alpha3)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-2)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-2)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-22)
 | 
			
		||||
    - [API Change](#api-change-10)
 | 
			
		||||
    - [Feature](#feature-13)
 | 
			
		||||
    - [API Change](#api-change-9)
 | 
			
		||||
    - [Feature](#feature-12)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-21)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-13)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-12)
 | 
			
		||||
  - [Dependencies](#dependencies-23)
 | 
			
		||||
    - [Added](#added-23)
 | 
			
		||||
    - [Changed](#changed-23)
 | 
			
		||||
    - [Removed](#removed-23)
 | 
			
		||||
- [v1.19.0-beta.0](#v1190-beta0)
 | 
			
		||||
  - [Downloads for v1.19.0-beta.0](#downloads-for-v1190-beta0)
 | 
			
		||||
    - [Source Code](#source-code-23)
 | 
			
		||||
    - [Client binaries](#client-binaries-23)
 | 
			
		||||
    - [Server binaries](#server-binaries-23)
 | 
			
		||||
    - [Node binaries](#node-binaries-23)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.3](#changelog-since-v1190-alpha3-1)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-23)
 | 
			
		||||
    - [API Change](#api-change-10)
 | 
			
		||||
    - [Feature](#feature-13)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-22)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-13)
 | 
			
		||||
  - [Dependencies](#dependencies-24)
 | 
			
		||||
    - [Added](#added-24)
 | 
			
		||||
    - [Changed](#changed-24)
 | 
			
		||||
    - [Removed](#removed-24)
 | 
			
		||||
- [v1.19.0-alpha.3](#v1190-alpha3)
 | 
			
		||||
  - [Downloads for v1.19.0-alpha.3](#downloads-for-v1190-alpha3)
 | 
			
		||||
    - [Source Code](#source-code-23)
 | 
			
		||||
    - [Client Binaries](#client-binaries-23)
 | 
			
		||||
    - [Server Binaries](#server-binaries-23)
 | 
			
		||||
    - [Node Binaries](#node-binaries-23)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.2](#changelog-since-v1190-alpha2)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-3)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-3)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-23)
 | 
			
		||||
    - [Deprecation](#deprecation-4)
 | 
			
		||||
    - [API Change](#api-change-11)
 | 
			
		||||
    - [Feature](#feature-14)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-22)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-14)
 | 
			
		||||
- [v1.19.0-alpha.2](#v1190-alpha2)
 | 
			
		||||
  - [Downloads for v1.19.0-alpha.2](#downloads-for-v1190-alpha2)
 | 
			
		||||
    - [Source Code](#source-code-24)
 | 
			
		||||
    - [Client Binaries](#client-binaries-24)
 | 
			
		||||
    - [Server Binaries](#server-binaries-24)
 | 
			
		||||
    - [Node Binaries](#node-binaries-24)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.1](#changelog-since-v1190-alpha1)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-4)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-4)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.2](#changelog-since-v1190-alpha2)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-3)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-3)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-24)
 | 
			
		||||
    - [API Change](#api-change-12)
 | 
			
		||||
    - [Feature](#feature-15)
 | 
			
		||||
    - [Deprecation](#deprecation-4)
 | 
			
		||||
    - [API Change](#api-change-11)
 | 
			
		||||
    - [Feature](#feature-14)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-23)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-15)
 | 
			
		||||
- [v1.19.0-alpha.1](#v1190-alpha1)
 | 
			
		||||
  - [Downloads for v1.19.0-alpha.1](#downloads-for-v1190-alpha1)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-14)
 | 
			
		||||
- [v1.19.0-alpha.2](#v1190-alpha2)
 | 
			
		||||
  - [Downloads for v1.19.0-alpha.2](#downloads-for-v1190-alpha2)
 | 
			
		||||
    - [Source Code](#source-code-25)
 | 
			
		||||
    - [Client Binaries](#client-binaries-25)
 | 
			
		||||
    - [Server Binaries](#server-binaries-25)
 | 
			
		||||
    - [Node Binaries](#node-binaries-25)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.1](#changelog-since-v1190-alpha1)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-4)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-4)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-25)
 | 
			
		||||
    - [API Change](#api-change-12)
 | 
			
		||||
    - [Feature](#feature-15)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-24)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-15)
 | 
			
		||||
- [v1.19.0-alpha.1](#v1190-alpha1)
 | 
			
		||||
  - [Downloads for v1.19.0-alpha.1](#downloads-for-v1190-alpha1)
 | 
			
		||||
    - [Source Code](#source-code-26)
 | 
			
		||||
    - [Client Binaries](#client-binaries-26)
 | 
			
		||||
    - [Server Binaries](#server-binaries-26)
 | 
			
		||||
    - [Node Binaries](#node-binaries-26)
 | 
			
		||||
  - [Changelog since v1.19.0-alpha.0](#changelog-since-v1190-alpha0)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-5)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-5)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-25)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-26)
 | 
			
		||||
    - [Deprecation](#deprecation-5)
 | 
			
		||||
    - [API Change](#api-change-13)
 | 
			
		||||
    - [Feature](#feature-16)
 | 
			
		||||
@@ -429,6 +442,75 @@
 | 
			
		||||
 | 
			
		||||
<!-- END MUNGE: GENERATED_TOC -->
 | 
			
		||||
 | 
			
		||||
# v1.19.16
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Downloads for v1.19.16
 | 
			
		||||
 | 
			
		||||
### Source Code
 | 
			
		||||
 | 
			
		||||
filename | sha512 hash
 | 
			
		||||
-------- | -----------
 | 
			
		||||
[kubernetes.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes.tar.gz) | 5e1ef2158744bea5dab6bb7e8229fe07ffd829269a79b496af820c4cd3000b265ffcc6c6164842de7e3419b3f0bb47ebef3db74724f6524a57333df8b5c84bed
 | 
			
		||||
[kubernetes-src.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-src.tar.gz) | 59bdd7de5c70c31158d4b16f13930fbca6dd29a584e47a6a2a81f2df16cda5aed1f059d0db8907cc1cb99b4f0e8263ae26fea2f494238dc0eb3f1eb211a6b2c3
 | 
			
		||||
 | 
			
		||||
### Client Binaries
 | 
			
		||||
 | 
			
		||||
filename | sha512 hash
 | 
			
		||||
-------- | -----------
 | 
			
		||||
[kubernetes-client-darwin-amd64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-darwin-amd64.tar.gz) | 1c90e3e01b345f70ca94c7e89c6a10dab5ed2623b4f66674aefbcdae7a857cb240f39b9f84447e37c4dba815ce10aa648620cb268246261af1cbae5c080aeff4
 | 
			
		||||
[kubernetes-client-linux-386.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-linux-386.tar.gz) | 967a79de8533aeae18cc5f8273b57ed75e8a40b0ed9e6472ca79fe5195d99768b9422c7361812237d5bba177939e934a08052c6a7ff29976f27ecd0691d30295
 | 
			
		||||
[kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-linux-amd64.tar.gz) | 9524a026af932ac9ca1895563060f7fb3b89f1387016e69a1a73cf7ce0f9baa54775b00c886557a97bae9b6dbc1b49c045da5dcea9ca2c1452c18c5c45fefd55
 | 
			
		||||
[kubernetes-client-linux-arm.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-linux-arm.tar.gz) | 5853f42c40ebbe620435bea036ac098a9ea206fd63dc13845e97a43c422fd3b47977b90fdbf76b6d13ea908210a77b5410066dc388dacccd88b47c1cb5ccef75
 | 
			
		||||
[kubernetes-client-linux-arm64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-linux-arm64.tar.gz) | eaf958630e85a2f71bd928736c65b97fb8e8bb376ab83a7e6c584e0379d51e98e355a6b94a40eaa40f641c2b10723c6b5844223a52143ec4e0690baeb6ba9151
 | 
			
		||||
[kubernetes-client-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-linux-ppc64le.tar.gz) | f3b7790a2343c2cc327af115172dac136a7b3977e5921a71146bf2f4626660b93844c1dab02e3f63293b281b52ba2c3d8562c0ce405f4a4611542470fd562ef9
 | 
			
		||||
[kubernetes-client-linux-s390x.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-linux-s390x.tar.gz) | 6e832b268b09bef05a932780c4c442a1dde37bd0ea29e318697c38a97a6b24acc13516eb8a7253f0b96dc3beeddd3b69c07813d7726a6b9955c6ff626847c933
 | 
			
		||||
[kubernetes-client-windows-386.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-windows-386.tar.gz) | ce7bde796184c28f25d0bc4bde0e453241e72f067cc84f716cf8f01e1a9e1e98af73a656e73bb1eb2792a90f953bb76d0157317dc2c76dfe0eb2dee9637d12ea
 | 
			
		||||
[kubernetes-client-windows-amd64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-client-windows-amd64.tar.gz) | 95d487bc5c575b27f5121de8fadeb955a4d5baf6260fecb490bebdac5891f7a679878cbf76266496eef7f95e18fde08f445eb26cb7761165002831f0f6b5712f
 | 
			
		||||
 | 
			
		||||
### Server Binaries
 | 
			
		||||
 | 
			
		||||
filename | sha512 hash
 | 
			
		||||
-------- | -----------
 | 
			
		||||
[kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-server-linux-amd64.tar.gz) | c6007430e6e568728ec694d13d69315d2f97054f17552e04b10d628b45679382c0eaf9a4a7264b6c19e2aad18d20a6df1d3882781f88a3d746ab57e102becdae
 | 
			
		||||
[kubernetes-server-linux-arm.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-server-linux-arm.tar.gz) | 0d52e1b495e752afa99a059a752225f5b7f45a4ce3bc43ed830f68fdeb7699a8825cbfded154ea82741aac81a123a63111ca4ffe558576929f10474b5097a34f
 | 
			
		||||
[kubernetes-server-linux-arm64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-server-linux-arm64.tar.gz) | 07ef317adeb556649fdff27a3cd0c831536adb8b626d507d83a223b3c3edf00a6d26e52fc49f73e7a30809496e889fa2e0cf3c4b7052fe1ab9f6eb9328285d74
 | 
			
		||||
[kubernetes-server-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-server-linux-ppc64le.tar.gz) | 49b0ce4a7feb2214a0d964f7c5c4911ebdc740375fbf211b7a7f7d53187f9ac80243a7e826ff4586d49c998e3951d737495c18f1598d0915b700747626e8f3a9
 | 
			
		||||
[kubernetes-server-linux-s390x.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-server-linux-s390x.tar.gz) | 18c02a42b07533d61c4cc9419d010355d46400a4bd69d8bbfb17c2c8a29df5f214c39cee84e701e5d87130b3c456cfc19d2256cc266f769b43f9d4a4b4b71959
 | 
			
		||||
 | 
			
		||||
### Node Binaries
 | 
			
		||||
 | 
			
		||||
filename | sha512 hash
 | 
			
		||||
-------- | -----------
 | 
			
		||||
[kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-node-linux-amd64.tar.gz) | fa3a29eae5e047ec99049a789d4793e05bdbdc9a31c0216a20cb60bc7aada2750d90bdfc6746e04d77e84390d2149a68f466aab4222e32dcf50ffb527e4c97e1
 | 
			
		||||
[kubernetes-node-linux-arm.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-node-linux-arm.tar.gz) | ee84c6a9a1c3b3a060f9bc731230fa9797e2dc0c5f071ac747542e0f0f121d93a26b415a754d921b198abb6f8953d3830d54e78962a11bd6914f4507fa5c5630
 | 
			
		||||
[kubernetes-node-linux-arm64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-node-linux-arm64.tar.gz) | 07326ef4e2fee2ada9eb16852b0e62f999ed0f116782624fa336a9dbc99353080a07ccc7990effb88f82f922ef2063a19e7c85b094590bbac1d4967f38db68fe
 | 
			
		||||
[kubernetes-node-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-node-linux-ppc64le.tar.gz) | 4e13492dd80cc3b147a3f0621e6a2d0568ba3aa4d902dfa1269c69c4756321c715b129e5d6914932931ba73136a2c5ceb3770c1d90a7c2a2a14c826ee92cb39a
 | 
			
		||||
[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-node-linux-s390x.tar.gz) | 4448a179b09f8d1b288c06cfa0183938697f66ec26882cf76032a7d06876a9cda8cbfb83aa725314e1aa10ab2ca5ddfd5b0984d8feaf8bd5f77a1bbdd967ef33
 | 
			
		||||
[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.19.16/kubernetes-node-windows-amd64.tar.gz) | 02ec4b58a484b1c5fb2a0b6e10d337a44df1f89b666cbd73622d5b3782467b57953a56444e18c4c886c9e6c421846d0232b8663563ebd7e70ec7887c4b243529
 | 
			
		||||
 | 
			
		||||
## Changelog since v1.19.15
 | 
			
		||||
 | 
			
		||||
## Changes by Kind
 | 
			
		||||
 | 
			
		||||
### Bug or Regression
 | 
			
		||||
 | 
			
		||||
- Fix detach from non-existant nodes and support dangling volumes (#104912, @gnufied) [SIG Cloud Provider and Storage]
 | 
			
		||||
- Revert PR #102925 which introduced unexpected scheduling behavior based on balanced resource allocation (#105526, @harisund) [SIG Scheduling]
 | 
			
		||||
 | 
			
		||||
## Dependencies
 | 
			
		||||
 | 
			
		||||
### Added
 | 
			
		||||
_Nothing has changed._
 | 
			
		||||
 | 
			
		||||
### Changed
 | 
			
		||||
_Nothing has changed._
 | 
			
		||||
 | 
			
		||||
### Removed
 | 
			
		||||
_Nothing has changed._
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# v1.19.15
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,171 +1,186 @@
 | 
			
		||||
<!-- BEGIN MUNGE: GENERATED_TOC -->
 | 
			
		||||
 | 
			
		||||
- [v1.20.11](#v12011)
 | 
			
		||||
  - [Downloads for v1.20.11](#downloads-for-v12011)
 | 
			
		||||
- [v1.20.12](#v12012)
 | 
			
		||||
  - [Downloads for v1.20.12](#downloads-for-v12012)
 | 
			
		||||
    - [Source Code](#source-code)
 | 
			
		||||
    - [Client Binaries](#client-binaries)
 | 
			
		||||
    - [Server Binaries](#server-binaries)
 | 
			
		||||
    - [Node Binaries](#node-binaries)
 | 
			
		||||
  - [Changelog since v1.20.10](#changelog-since-v12010)
 | 
			
		||||
  - [Important Security Information](#important-security-information)
 | 
			
		||||
    - [CVE-2021-25741: Symlink Exchange Can Allow Host Filesystem Access](#cve-2021-25741-symlink-exchange-can-allow-host-filesystem-access)
 | 
			
		||||
  - [Changelog since v1.20.11](#changelog-since-v12011)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind)
 | 
			
		||||
    - [API Change](#api-change)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake)
 | 
			
		||||
  - [Dependencies](#dependencies)
 | 
			
		||||
    - [Added](#added)
 | 
			
		||||
    - [Changed](#changed)
 | 
			
		||||
    - [Removed](#removed)
 | 
			
		||||
- [v1.20.10](#v12010)
 | 
			
		||||
  - [Downloads for v1.20.10](#downloads-for-v12010)
 | 
			
		||||
- [v1.20.11](#v12011)
 | 
			
		||||
  - [Downloads for v1.20.11](#downloads-for-v12011)
 | 
			
		||||
    - [Source Code](#source-code-1)
 | 
			
		||||
    - [Client Binaries](#client-binaries-1)
 | 
			
		||||
    - [Server Binaries](#server-binaries-1)
 | 
			
		||||
    - [Node Binaries](#node-binaries-1)
 | 
			
		||||
  - [Changelog since v1.20.9](#changelog-since-v1209)
 | 
			
		||||
  - [Changelog since v1.20.10](#changelog-since-v12010)
 | 
			
		||||
  - [Important Security Information](#important-security-information)
 | 
			
		||||
    - [CVE-2021-25741: Symlink Exchange Can Allow Host Filesystem Access](#cve-2021-25741-symlink-exchange-can-allow-host-filesystem-access)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-1)
 | 
			
		||||
    - [Feature](#feature)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-1)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-1)
 | 
			
		||||
  - [Dependencies](#dependencies-1)
 | 
			
		||||
    - [Added](#added-1)
 | 
			
		||||
    - [Changed](#changed-1)
 | 
			
		||||
    - [Removed](#removed-1)
 | 
			
		||||
- [v1.20.9](#v1209)
 | 
			
		||||
  - [Downloads for v1.20.9](#downloads-for-v1209)
 | 
			
		||||
- [v1.20.10](#v12010)
 | 
			
		||||
  - [Downloads for v1.20.10](#downloads-for-v12010)
 | 
			
		||||
    - [Source Code](#source-code-2)
 | 
			
		||||
    - [Client Binaries](#client-binaries-2)
 | 
			
		||||
    - [Server Binaries](#server-binaries-2)
 | 
			
		||||
    - [Node Binaries](#node-binaries-2)
 | 
			
		||||
  - [Changelog since v1.20.8](#changelog-since-v1208)
 | 
			
		||||
  - [Changelog since v1.20.9](#changelog-since-v1209)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-2)
 | 
			
		||||
    - [Feature](#feature-1)
 | 
			
		||||
    - [Feature](#feature)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-2)
 | 
			
		||||
  - [Dependencies](#dependencies-2)
 | 
			
		||||
    - [Added](#added-2)
 | 
			
		||||
    - [Changed](#changed-2)
 | 
			
		||||
    - [Removed](#removed-2)
 | 
			
		||||
- [v1.20.8](#v1208)
 | 
			
		||||
  - [Downloads for v1.20.8](#downloads-for-v1208)
 | 
			
		||||
- [v1.20.9](#v1209)
 | 
			
		||||
  - [Downloads for v1.20.9](#downloads-for-v1209)
 | 
			
		||||
    - [Source Code](#source-code-3)
 | 
			
		||||
    - [Client Binaries](#client-binaries-3)
 | 
			
		||||
    - [Server Binaries](#server-binaries-3)
 | 
			
		||||
    - [Node Binaries](#node-binaries-3)
 | 
			
		||||
  - [Changelog since v1.20.7](#changelog-since-v1207)
 | 
			
		||||
  - [Changelog since v1.20.8](#changelog-since-v1208)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-3)
 | 
			
		||||
    - [Feature](#feature-2)
 | 
			
		||||
    - [Failing Test](#failing-test)
 | 
			
		||||
    - [Feature](#feature-1)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-3)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-1)
 | 
			
		||||
  - [Dependencies](#dependencies-3)
 | 
			
		||||
    - [Added](#added-3)
 | 
			
		||||
    - [Changed](#changed-3)
 | 
			
		||||
    - [Removed](#removed-3)
 | 
			
		||||
- [v1.20.7](#v1207)
 | 
			
		||||
  - [Downloads for v1.20.7](#downloads-for-v1207)
 | 
			
		||||
- [v1.20.8](#v1208)
 | 
			
		||||
  - [Downloads for v1.20.8](#downloads-for-v1208)
 | 
			
		||||
    - [Source Code](#source-code-4)
 | 
			
		||||
    - [Client Binaries](#client-binaries-4)
 | 
			
		||||
    - [Server Binaries](#server-binaries-4)
 | 
			
		||||
    - [Node Binaries](#node-binaries-4)
 | 
			
		||||
  - [Changelog since v1.20.6](#changelog-since-v1206)
 | 
			
		||||
  - [Changelog since v1.20.7](#changelog-since-v1207)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-4)
 | 
			
		||||
    - [API Change](#api-change)
 | 
			
		||||
    - [Feature](#feature-3)
 | 
			
		||||
    - [Feature](#feature-2)
 | 
			
		||||
    - [Failing Test](#failing-test)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-4)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-2)
 | 
			
		||||
  - [Dependencies](#dependencies-4)
 | 
			
		||||
    - [Added](#added-4)
 | 
			
		||||
    - [Changed](#changed-4)
 | 
			
		||||
    - [Removed](#removed-4)
 | 
			
		||||
- [v1.20.6](#v1206)
 | 
			
		||||
  - [Downloads for v1.20.6](#downloads-for-v1206)
 | 
			
		||||
- [v1.20.7](#v1207)
 | 
			
		||||
  - [Downloads for v1.20.7](#downloads-for-v1207)
 | 
			
		||||
    - [Source Code](#source-code-5)
 | 
			
		||||
    - [Client binaries](#client-binaries-5)
 | 
			
		||||
    - [Server binaries](#server-binaries-5)
 | 
			
		||||
    - [Node binaries](#node-binaries-5)
 | 
			
		||||
  - [Changelog since v1.20.5](#changelog-since-v1205)
 | 
			
		||||
  - [Important Security Information](#important-security-information-1)
 | 
			
		||||
    - [CVE-2021-25735: Validating Admission Webhook does not observe some previous fields](#cve-2021-25735-validating-admission-webhook-does-not-observe-some-previous-fields)
 | 
			
		||||
    - [Client Binaries](#client-binaries-5)
 | 
			
		||||
    - [Server Binaries](#server-binaries-5)
 | 
			
		||||
    - [Node Binaries](#node-binaries-5)
 | 
			
		||||
  - [Changelog since v1.20.6](#changelog-since-v1206)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-5)
 | 
			
		||||
    - [API Change](#api-change-1)
 | 
			
		||||
    - [Feature](#feature-4)
 | 
			
		||||
    - [Feature](#feature-3)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-5)
 | 
			
		||||
    - [Uncategorized](#uncategorized)
 | 
			
		||||
  - [Dependencies](#dependencies-5)
 | 
			
		||||
    - [Added](#added-5)
 | 
			
		||||
    - [Changed](#changed-5)
 | 
			
		||||
    - [Removed](#removed-5)
 | 
			
		||||
- [v1.20.5](#v1205)
 | 
			
		||||
  - [Downloads for v1.20.5](#downloads-for-v1205)
 | 
			
		||||
- [v1.20.6](#v1206)
 | 
			
		||||
  - [Downloads for v1.20.6](#downloads-for-v1206)
 | 
			
		||||
    - [Source Code](#source-code-6)
 | 
			
		||||
    - [Client binaries](#client-binaries-6)
 | 
			
		||||
    - [Server binaries](#server-binaries-6)
 | 
			
		||||
    - [Node binaries](#node-binaries-6)
 | 
			
		||||
  - [Changelog since v1.20.4](#changelog-since-v1204)
 | 
			
		||||
  - [Changelog since v1.20.5](#changelog-since-v1205)
 | 
			
		||||
  - [Important Security Information](#important-security-information-1)
 | 
			
		||||
    - [CVE-2021-25735: Validating Admission Webhook does not observe some previous fields](#cve-2021-25735-validating-admission-webhook-does-not-observe-some-previous-fields)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-6)
 | 
			
		||||
    - [Failing Test](#failing-test-1)
 | 
			
		||||
    - [API Change](#api-change-2)
 | 
			
		||||
    - [Feature](#feature-4)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-6)
 | 
			
		||||
    - [Uncategorized](#uncategorized)
 | 
			
		||||
  - [Dependencies](#dependencies-6)
 | 
			
		||||
    - [Added](#added-6)
 | 
			
		||||
    - [Changed](#changed-6)
 | 
			
		||||
    - [Removed](#removed-6)
 | 
			
		||||
- [v1.20.4](#v1204)
 | 
			
		||||
  - [Downloads for v1.20.4](#downloads-for-v1204)
 | 
			
		||||
- [v1.20.5](#v1205)
 | 
			
		||||
  - [Downloads for v1.20.5](#downloads-for-v1205)
 | 
			
		||||
    - [Source Code](#source-code-7)
 | 
			
		||||
    - [Client binaries](#client-binaries-7)
 | 
			
		||||
    - [Server binaries](#server-binaries-7)
 | 
			
		||||
    - [Node binaries](#node-binaries-7)
 | 
			
		||||
  - [Changelog since v1.20.3](#changelog-since-v1203)
 | 
			
		||||
  - [Changelog since v1.20.4](#changelog-since-v1204)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-7)
 | 
			
		||||
    - [Failing Test](#failing-test-1)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-7)
 | 
			
		||||
  - [Dependencies](#dependencies-7)
 | 
			
		||||
    - [Added](#added-7)
 | 
			
		||||
    - [Changed](#changed-7)
 | 
			
		||||
    - [Removed](#removed-7)
 | 
			
		||||
- [v1.20.3](#v1203)
 | 
			
		||||
  - [Downloads for v1.20.3](#downloads-for-v1203)
 | 
			
		||||
- [v1.20.4](#v1204)
 | 
			
		||||
  - [Downloads for v1.20.4](#downloads-for-v1204)
 | 
			
		||||
    - [Source Code](#source-code-8)
 | 
			
		||||
    - [Client binaries](#client-binaries-8)
 | 
			
		||||
    - [Server binaries](#server-binaries-8)
 | 
			
		||||
    - [Node binaries](#node-binaries-8)
 | 
			
		||||
  - [Changelog since v1.20.2](#changelog-since-v1202)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-7)
 | 
			
		||||
    - [API Change](#api-change-2)
 | 
			
		||||
    - [Failing Test](#failing-test-2)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-7)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-2)
 | 
			
		||||
  - [Changelog since v1.20.3](#changelog-since-v1203)
 | 
			
		||||
  - [Dependencies](#dependencies-8)
 | 
			
		||||
    - [Added](#added-8)
 | 
			
		||||
    - [Changed](#changed-8)
 | 
			
		||||
    - [Removed](#removed-8)
 | 
			
		||||
- [v1.20.2](#v1202)
 | 
			
		||||
  - [Downloads for v1.20.2](#downloads-for-v1202)
 | 
			
		||||
- [v1.20.3](#v1203)
 | 
			
		||||
  - [Downloads for v1.20.3](#downloads-for-v1203)
 | 
			
		||||
    - [Source Code](#source-code-9)
 | 
			
		||||
    - [Client binaries](#client-binaries-9)
 | 
			
		||||
    - [Server binaries](#server-binaries-9)
 | 
			
		||||
    - [Node binaries](#node-binaries-9)
 | 
			
		||||
  - [Changelog since v1.20.1](#changelog-since-v1201)
 | 
			
		||||
  - [Changelog since v1.20.2](#changelog-since-v1202)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-8)
 | 
			
		||||
    - [API Change](#api-change-3)
 | 
			
		||||
    - [Failing Test](#failing-test-2)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-8)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-3)
 | 
			
		||||
  - [Dependencies](#dependencies-9)
 | 
			
		||||
    - [Added](#added-9)
 | 
			
		||||
    - [Changed](#changed-9)
 | 
			
		||||
    - [Removed](#removed-9)
 | 
			
		||||
- [v1.20.1](#v1201)
 | 
			
		||||
  - [Downloads for v1.20.1](#downloads-for-v1201)
 | 
			
		||||
- [v1.20.2](#v1202)
 | 
			
		||||
  - [Downloads for v1.20.2](#downloads-for-v1202)
 | 
			
		||||
    - [Source Code](#source-code-10)
 | 
			
		||||
    - [Client binaries](#client-binaries-10)
 | 
			
		||||
    - [Server binaries](#server-binaries-10)
 | 
			
		||||
    - [Node binaries](#node-binaries-10)
 | 
			
		||||
  - [Changelog since v1.20.0](#changelog-since-v1200)
 | 
			
		||||
  - [Changelog since v1.20.1](#changelog-since-v1201)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-9)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-9)
 | 
			
		||||
  - [Dependencies](#dependencies-10)
 | 
			
		||||
    - [Added](#added-10)
 | 
			
		||||
    - [Changed](#changed-10)
 | 
			
		||||
    - [Removed](#removed-10)
 | 
			
		||||
- [v1.20.1](#v1201)
 | 
			
		||||
  - [Downloads for v1.20.1](#downloads-for-v1201)
 | 
			
		||||
    - [Source Code](#source-code-11)
 | 
			
		||||
    - [Client binaries](#client-binaries-11)
 | 
			
		||||
    - [Server binaries](#server-binaries-11)
 | 
			
		||||
    - [Node binaries](#node-binaries-11)
 | 
			
		||||
  - [Changelog since v1.20.0](#changelog-since-v1200)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-10)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-10)
 | 
			
		||||
  - [Dependencies](#dependencies-11)
 | 
			
		||||
    - [Added](#added-11)
 | 
			
		||||
    - [Changed](#changed-11)
 | 
			
		||||
    - [Removed](#removed-11)
 | 
			
		||||
- [v1.20.0](#v1200)
 | 
			
		||||
  - [Downloads for v1.20.0](#downloads-for-v1200)
 | 
			
		||||
    - [Source Code](#source-code-11)
 | 
			
		||||
    - [Client Binaries](#client-binaries-11)
 | 
			
		||||
    - [Server Binaries](#server-binaries-11)
 | 
			
		||||
    - [Node Binaries](#node-binaries-11)
 | 
			
		||||
    - [Source Code](#source-code-12)
 | 
			
		||||
    - [Client Binaries](#client-binaries-12)
 | 
			
		||||
    - [Server Binaries](#server-binaries-12)
 | 
			
		||||
    - [Node Binaries](#node-binaries-12)
 | 
			
		||||
  - [Changelog since v1.19.0](#changelog-since-v1190)
 | 
			
		||||
  - [What's New (Major Themes)](#whats-new-major-themes)
 | 
			
		||||
    - [Dockershim deprecation](#dockershim-deprecation)
 | 
			
		||||
@@ -182,159 +197,240 @@
 | 
			
		||||
    - [Introducing Graceful Node Shutdown (Alpha)](#introducing-graceful-node-shutdown-alpha)
 | 
			
		||||
    - [Runtime log sanitation](#runtime-log-sanitation)
 | 
			
		||||
    - [Pod resource metrics](#pod-resource-metrics)
 | 
			
		||||
    - [Introducing <code>RootCAConfigMap</code>](#introducing-)
 | 
			
		||||
    - [<code>kubectl debug</code> graduates to Beta](#-graduates-to-beta)
 | 
			
		||||
    - [Introducing <code>RootCAConfigMap</code>](#introducing-rootcaconfigmap)
 | 
			
		||||
    - [<code>kubectl debug</code> graduates to Beta](#kubectl-debug-graduates-to-beta)
 | 
			
		||||
    - [Removing deprecated flags in kubeadm](#removing-deprecated-flags-in-kubeadm)
 | 
			
		||||
    - [Pod Hostname as FQDN graduates to Beta](#pod-hostname-as-fqdn-graduates-to-beta)
 | 
			
		||||
    - [<code>TokenRequest</code> / <code>TokenRequestProjection</code> graduates to General Availability](#---graduates-to-general-availability)
 | 
			
		||||
    - [<code>TokenRequest</code> / <code>TokenRequestProjection</code> graduates to General Availability](#tokenrequest--tokenrequestprojection-graduates-to-general-availability)
 | 
			
		||||
    - [RuntimeClass feature graduates to General Availability.](#runtimeclass-feature-graduates-to-general-availability)
 | 
			
		||||
    - [Cloud Controller Manager now exclusively shipped by Cloud Provider](#cloud-controller-manager-now-exclusively-shipped-by-cloud-provider)
 | 
			
		||||
  - [Known Issues](#known-issues)
 | 
			
		||||
    - [Summary API in kubelet doesn't have accelerator metrics](#summary-api-in-kubelet-doesnt-have-accelerator-metrics)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-10)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-11)
 | 
			
		||||
    - [Deprecation](#deprecation)
 | 
			
		||||
    - [API Change](#api-change-3)
 | 
			
		||||
    - [API Change](#api-change-4)
 | 
			
		||||
    - [Feature](#feature-5)
 | 
			
		||||
    - [Documentation](#documentation)
 | 
			
		||||
    - [Failing Test](#failing-test-3)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-10)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-3)
 | 
			
		||||
  - [Dependencies](#dependencies-11)
 | 
			
		||||
    - [Added](#added-11)
 | 
			
		||||
    - [Changed](#changed-11)
 | 
			
		||||
    - [Removed](#removed-11)
 | 
			
		||||
- [v1.20.0-rc.0](#v1200-rc0)
 | 
			
		||||
  - [Downloads for v1.20.0-rc.0](#downloads-for-v1200-rc0)
 | 
			
		||||
    - [Source Code](#source-code-12)
 | 
			
		||||
    - [Client binaries](#client-binaries-12)
 | 
			
		||||
    - [Server binaries](#server-binaries-12)
 | 
			
		||||
    - [Node binaries](#node-binaries-12)
 | 
			
		||||
  - [Changelog since v1.20.0-beta.2](#changelog-since-v1200-beta2)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-11)
 | 
			
		||||
    - [Feature](#feature-6)
 | 
			
		||||
    - [Failing Test](#failing-test-4)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-11)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-4)
 | 
			
		||||
  - [Dependencies](#dependencies-12)
 | 
			
		||||
    - [Added](#added-12)
 | 
			
		||||
    - [Changed](#changed-12)
 | 
			
		||||
    - [Removed](#removed-12)
 | 
			
		||||
- [v1.20.0-beta.2](#v1200-beta2)
 | 
			
		||||
  - [Downloads for v1.20.0-beta.2](#downloads-for-v1200-beta2)
 | 
			
		||||
- [v1.20.0-rc.0](#v1200-rc0)
 | 
			
		||||
  - [Downloads for v1.20.0-rc.0](#downloads-for-v1200-rc0)
 | 
			
		||||
    - [Source Code](#source-code-13)
 | 
			
		||||
    - [Client binaries](#client-binaries-13)
 | 
			
		||||
    - [Server binaries](#server-binaries-13)
 | 
			
		||||
    - [Node binaries](#node-binaries-13)
 | 
			
		||||
  - [Changelog since v1.20.0-beta.1](#changelog-since-v1200-beta1)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-1)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-1)
 | 
			
		||||
  - [Changelog since v1.20.0-beta.2](#changelog-since-v1200-beta2)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-12)
 | 
			
		||||
    - [Deprecation](#deprecation-1)
 | 
			
		||||
    - [API Change](#api-change-4)
 | 
			
		||||
    - [Feature](#feature-7)
 | 
			
		||||
    - [Documentation](#documentation-1)
 | 
			
		||||
    - [Feature](#feature-6)
 | 
			
		||||
    - [Failing Test](#failing-test-4)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-12)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-4)
 | 
			
		||||
  - [Dependencies](#dependencies-13)
 | 
			
		||||
    - [Added](#added-13)
 | 
			
		||||
    - [Changed](#changed-13)
 | 
			
		||||
    - [Removed](#removed-13)
 | 
			
		||||
- [v1.20.0-beta.1](#v1200-beta1)
 | 
			
		||||
  - [Downloads for v1.20.0-beta.1](#downloads-for-v1200-beta1)
 | 
			
		||||
- [v1.20.0-beta.2](#v1200-beta2)
 | 
			
		||||
  - [Downloads for v1.20.0-beta.2](#downloads-for-v1200-beta2)
 | 
			
		||||
    - [Source Code](#source-code-14)
 | 
			
		||||
    - [Client binaries](#client-binaries-14)
 | 
			
		||||
    - [Server binaries](#server-binaries-14)
 | 
			
		||||
    - [Node binaries](#node-binaries-14)
 | 
			
		||||
  - [Changelog since v1.20.0-beta.0](#changelog-since-v1200-beta0)
 | 
			
		||||
  - [Changelog since v1.20.0-beta.1](#changelog-since-v1200-beta1)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-1)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-1)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-13)
 | 
			
		||||
    - [Deprecation](#deprecation-2)
 | 
			
		||||
    - [Deprecation](#deprecation-1)
 | 
			
		||||
    - [API Change](#api-change-5)
 | 
			
		||||
    - [Feature](#feature-8)
 | 
			
		||||
    - [Documentation](#documentation-2)
 | 
			
		||||
    - [Feature](#feature-7)
 | 
			
		||||
    - [Documentation](#documentation-1)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-13)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-5)
 | 
			
		||||
  - [Dependencies](#dependencies-14)
 | 
			
		||||
    - [Added](#added-14)
 | 
			
		||||
    - [Changed](#changed-14)
 | 
			
		||||
    - [Removed](#removed-14)
 | 
			
		||||
- [v1.20.0-beta.0](#v1200-beta0)
 | 
			
		||||
  - [Downloads for v1.20.0-beta.0](#downloads-for-v1200-beta0)
 | 
			
		||||
- [v1.20.0-beta.1](#v1200-beta1)
 | 
			
		||||
  - [Downloads for v1.20.0-beta.1](#downloads-for-v1200-beta1)
 | 
			
		||||
    - [Source Code](#source-code-15)
 | 
			
		||||
    - [Client binaries](#client-binaries-15)
 | 
			
		||||
    - [Server binaries](#server-binaries-15)
 | 
			
		||||
    - [Node binaries](#node-binaries-15)
 | 
			
		||||
  - [Changelog since v1.20.0-alpha.3](#changelog-since-v1200-alpha3)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-2)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-2)
 | 
			
		||||
  - [Changelog since v1.20.0-beta.0](#changelog-since-v1200-beta0)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-14)
 | 
			
		||||
    - [Deprecation](#deprecation-3)
 | 
			
		||||
    - [Deprecation](#deprecation-2)
 | 
			
		||||
    - [API Change](#api-change-6)
 | 
			
		||||
    - [Feature](#feature-9)
 | 
			
		||||
    - [Documentation](#documentation-3)
 | 
			
		||||
    - [Feature](#feature-8)
 | 
			
		||||
    - [Documentation](#documentation-2)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-14)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-6)
 | 
			
		||||
  - [Dependencies](#dependencies-15)
 | 
			
		||||
    - [Added](#added-15)
 | 
			
		||||
    - [Changed](#changed-15)
 | 
			
		||||
    - [Removed](#removed-15)
 | 
			
		||||
- [v1.20.0-alpha.3](#v1200-alpha3)
 | 
			
		||||
  - [Downloads for v1.20.0-alpha.3](#downloads-for-v1200-alpha3)
 | 
			
		||||
- [v1.20.0-beta.0](#v1200-beta0)
 | 
			
		||||
  - [Downloads for v1.20.0-beta.0](#downloads-for-v1200-beta0)
 | 
			
		||||
    - [Source Code](#source-code-16)
 | 
			
		||||
    - [Client binaries](#client-binaries-16)
 | 
			
		||||
    - [Server binaries](#server-binaries-16)
 | 
			
		||||
    - [Node binaries](#node-binaries-16)
 | 
			
		||||
  - [Changelog since v1.20.0-alpha.2](#changelog-since-v1200-alpha2)
 | 
			
		||||
  - [Changelog since v1.20.0-alpha.3](#changelog-since-v1200-alpha3)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-2)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-2)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-15)
 | 
			
		||||
    - [Deprecation](#deprecation-3)
 | 
			
		||||
    - [API Change](#api-change-7)
 | 
			
		||||
    - [Feature](#feature-10)
 | 
			
		||||
    - [Feature](#feature-9)
 | 
			
		||||
    - [Documentation](#documentation-3)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-15)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-7)
 | 
			
		||||
  - [Dependencies](#dependencies-16)
 | 
			
		||||
    - [Added](#added-16)
 | 
			
		||||
    - [Changed](#changed-16)
 | 
			
		||||
    - [Removed](#removed-16)
 | 
			
		||||
- [v1.20.0-alpha.2](#v1200-alpha2)
 | 
			
		||||
  - [Downloads for v1.20.0-alpha.2](#downloads-for-v1200-alpha2)
 | 
			
		||||
- [v1.20.0-alpha.3](#v1200-alpha3)
 | 
			
		||||
  - [Downloads for v1.20.0-alpha.3](#downloads-for-v1200-alpha3)
 | 
			
		||||
    - [Source Code](#source-code-17)
 | 
			
		||||
    - [Client binaries](#client-binaries-17)
 | 
			
		||||
    - [Server binaries](#server-binaries-17)
 | 
			
		||||
    - [Node binaries](#node-binaries-17)
 | 
			
		||||
  - [Changelog since v1.20.0-alpha.1](#changelog-since-v1200-alpha1)
 | 
			
		||||
  - [Changelog since v1.20.0-alpha.2](#changelog-since-v1200-alpha2)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-16)
 | 
			
		||||
    - [Deprecation](#deprecation-4)
 | 
			
		||||
    - [API Change](#api-change-8)
 | 
			
		||||
    - [Feature](#feature-11)
 | 
			
		||||
    - [Feature](#feature-10)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-16)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-8)
 | 
			
		||||
  - [Dependencies](#dependencies-17)
 | 
			
		||||
    - [Added](#added-17)
 | 
			
		||||
    - [Changed](#changed-17)
 | 
			
		||||
    - [Removed](#removed-17)
 | 
			
		||||
- [v1.20.0-alpha.1](#v1200-alpha1)
 | 
			
		||||
  - [Downloads for v1.20.0-alpha.1](#downloads-for-v1200-alpha1)
 | 
			
		||||
- [v1.20.0-alpha.2](#v1200-alpha2)
 | 
			
		||||
  - [Downloads for v1.20.0-alpha.2](#downloads-for-v1200-alpha2)
 | 
			
		||||
    - [Source Code](#source-code-18)
 | 
			
		||||
    - [Client binaries](#client-binaries-18)
 | 
			
		||||
    - [Server binaries](#server-binaries-18)
 | 
			
		||||
    - [Node binaries](#node-binaries-18)
 | 
			
		||||
  - [Changelog since v1.20.0-alpha.0](#changelog-since-v1200-alpha0)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-3)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-3)
 | 
			
		||||
  - [Changelog since v1.20.0-alpha.1](#changelog-since-v1200-alpha1)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-17)
 | 
			
		||||
    - [Deprecation](#deprecation-5)
 | 
			
		||||
    - [Deprecation](#deprecation-4)
 | 
			
		||||
    - [API Change](#api-change-9)
 | 
			
		||||
    - [Feature](#feature-12)
 | 
			
		||||
    - [Documentation](#documentation-4)
 | 
			
		||||
    - [Failing Test](#failing-test-5)
 | 
			
		||||
    - [Feature](#feature-11)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-17)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-9)
 | 
			
		||||
  - [Dependencies](#dependencies-18)
 | 
			
		||||
    - [Added](#added-18)
 | 
			
		||||
    - [Changed](#changed-18)
 | 
			
		||||
    - [Removed](#removed-18)
 | 
			
		||||
- [v1.20.0-alpha.1](#v1200-alpha1)
 | 
			
		||||
  - [Downloads for v1.20.0-alpha.1](#downloads-for-v1200-alpha1)
 | 
			
		||||
    - [Source Code](#source-code-19)
 | 
			
		||||
    - [Client binaries](#client-binaries-19)
 | 
			
		||||
    - [Server binaries](#server-binaries-19)
 | 
			
		||||
    - [Node binaries](#node-binaries-19)
 | 
			
		||||
  - [Changelog since v1.20.0-alpha.0](#changelog-since-v1200-alpha0)
 | 
			
		||||
  - [Urgent Upgrade Notes](#urgent-upgrade-notes-3)
 | 
			
		||||
    - [(No, really, you MUST read this before you upgrade)](#no-really-you-must-read-this-before-you-upgrade-3)
 | 
			
		||||
  - [Changes by Kind](#changes-by-kind-18)
 | 
			
		||||
    - [Deprecation](#deprecation-5)
 | 
			
		||||
    - [API Change](#api-change-10)
 | 
			
		||||
    - [Feature](#feature-12)
 | 
			
		||||
    - [Documentation](#documentation-4)
 | 
			
		||||
    - [Failing Test](#failing-test-5)
 | 
			
		||||
    - [Bug or Regression](#bug-or-regression-18)
 | 
			
		||||
    - [Other (Cleanup or Flake)](#other-cleanup-or-flake-10)
 | 
			
		||||
  - [Dependencies](#dependencies-19)
 | 
			
		||||
    - [Added](#added-19)
 | 
			
		||||
    - [Changed](#changed-19)
 | 
			
		||||
    - [Removed](#removed-19)
 | 
			
		||||
 | 
			
		||||
<!-- END MUNGE: GENERATED_TOC -->
 | 
			
		||||
 | 
			
		||||
# v1.20.12
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Downloads for v1.20.12
 | 
			
		||||
 | 
			
		||||
### Source Code
 | 
			
		||||
 | 
			
		||||
filename | sha512 hash
 | 
			
		||||
-------- | -----------
 | 
			
		||||
[kubernetes.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes.tar.gz) | f550a84d3c17f81d282d65cf5c04060524de9ceac9875a4264686981dfb1b4d039ea25d84c4720c0c19c8ce641080598c2297abdca417264103b306bcca5946b
 | 
			
		||||
[kubernetes-src.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-src.tar.gz) | 148c3bc5dc3f705b0e2fd6806b0973cf2e264618297c1ab1813aef26a27e39da28e8910eef6f799a90711bc650a26dbdd058f4cc3a8799ec191657662b1f4dc9
 | 
			
		||||
 | 
			
		||||
### Client Binaries
 | 
			
		||||
 | 
			
		||||
filename | sha512 hash
 | 
			
		||||
-------- | -----------
 | 
			
		||||
[kubernetes-client-darwin-amd64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-darwin-amd64.tar.gz) | c925d724f025a444060a97b04c9cd08091474c03b223acf99cf0ab867e34ada178b26b59ee32b3c849efbd106f057e762257430ef0a7dfb5078ddf0ccf79a735
 | 
			
		||||
[kubernetes-client-linux-386.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-linux-386.tar.gz) | bb1a66c919ae86bc596ba4638652ad71b9e5b6dfea313becd03b0e74aad00a69fed7ea681a9a105b301ff242bf2832a43b3997aeada5f3cc260d7d8ab8df4e39
 | 
			
		||||
[kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-linux-amd64.tar.gz) | a8f667828b815678f508f9a355755a9a84ae0f3cc09613f34c334bcac60ed7469e02af790d149729666a976a7b08f13111735c291e4396f1b15d87466813c03a
 | 
			
		||||
[kubernetes-client-linux-arm.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-linux-arm.tar.gz) | 4fa83c283557bd96b6cd5c8a08b205a4c9cac6122c4c28dfa66f086704e4d1c80ea551bd836c3aa850d0609553dc1256f7c4105975a68db8b2235fd1ac3d291a
 | 
			
		||||
[kubernetes-client-linux-arm64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-linux-arm64.tar.gz) | 5147261a92f6e073027eaf98c7a6808f85d86c9c6d3577ae2b3c6ed4a69b1597242fbfffdf9c69585dc56e395e93234026c0e3aac3258ffe7172291c16850811
 | 
			
		||||
[kubernetes-client-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-linux-ppc64le.tar.gz) | 49f24b976798f5e0fbc65f314853969471f2105100baa321bf95f2cf779ac4ecdc8bd5ecfa5071880705ece6fc7432b33214f4e4ca016d32e513e659aa133ed4
 | 
			
		||||
[kubernetes-client-linux-s390x.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-linux-s390x.tar.gz) | ac77cbea55562c711f7bd14d3d325f7d350205fe9c638f5d364b70b8e318b00a2714ee7159584eab34025f0d1a372b01a21df84b64f7d0e09f9c8c16e066fe02
 | 
			
		||||
[kubernetes-client-windows-386.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-windows-386.tar.gz) | 8312584bd7d6b101f7854da1f48f2762e3818096a70a029f2144e7db945c8952a73f92e487c6ff7a1f854f70bab46cdb6d855fdd16e9d58b02d48a9207949fbb
 | 
			
		||||
[kubernetes-client-windows-amd64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-client-windows-amd64.tar.gz) | 158db7d15496342a98ce290fd4e995448afc36191cbc2d8937272b9a990b1c1033e58dd8cfb3c11b9328bfedd2aa5956b6659fbdbd32d4d8c6c01792cf166fd4
 | 
			
		||||
 | 
			
		||||
### Server Binaries
 | 
			
		||||
 | 
			
		||||
filename | sha512 hash
 | 
			
		||||
-------- | -----------
 | 
			
		||||
[kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-server-linux-amd64.tar.gz) | f2b1579e5fc496a9ba5038f73fe6fd90e9f0c6df8d835b906113f773d1f36d760dbce1f08b84ded5b488c8f9c2f95b6a24ee9b4e68d0251d4baa126477190d37
 | 
			
		||||
[kubernetes-server-linux-arm.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-server-linux-arm.tar.gz) | 299b3ee742bea839faa62839f91039d958e61f4d37900457528973de0e8b57d1116d8c7af2e6eb20dd0f69cce7aeb50786bce44a25f688140d661c2572cb49ab
 | 
			
		||||
[kubernetes-server-linux-arm64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-server-linux-arm64.tar.gz) | 9bb11c91770b49080c388c5f8ce808633f563976b8d9b2c0795540d789823c2a5a2374a3659c99613694b42c92192411e0a92124aadf58f2b13a4798767282b2
 | 
			
		||||
[kubernetes-server-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-server-linux-ppc64le.tar.gz) | acbfb224f318687c51fcb9f16e5e13009b7f6f1db694a093cc49d24cbc2098074ade277218b5d45490f5e1d96a34e7d3741602555f022b2cb85da7f2bf8c3676
 | 
			
		||||
[kubernetes-server-linux-s390x.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-server-linux-s390x.tar.gz) | 045664a13274a34296f059b815f323516d146a52f0ecf6087b65219874c1629f25a53e6febf0fa63112cc5dd52e2d7221234028a9bba014d8fbe6783bef035be
 | 
			
		||||
 | 
			
		||||
### Node Binaries
 | 
			
		||||
 | 
			
		||||
filename | sha512 hash
 | 
			
		||||
-------- | -----------
 | 
			
		||||
[kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-node-linux-amd64.tar.gz) | 05b965ca07a109b0e5499b0235c1c09caf2122feb5ffb3fef9114299cdd5d8835c5d1d2278a4b8b9b8c8bb643703c32ba31362604e35ae7b4193937dd1c720e0
 | 
			
		||||
[kubernetes-node-linux-arm.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-node-linux-arm.tar.gz) | 2def2fe68258da3395c57eac7eb2e1a98dbc9f5485c4b8d24c71fc44d2f2454a48db5a7dbceb60879eb4f1ac5f0282c73cf579738d8055138d85c6a072ac3249
 | 
			
		||||
[kubernetes-node-linux-arm64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-node-linux-arm64.tar.gz) | a34b027dc8b92e63e78993baf6e8ad8cb45869b6c86a5cb2cf052ea308f285b18beb1d8058824d781bca223f1c3a54a407d2238ecccadc9f90eb5d9de4f8c489
 | 
			
		||||
[kubernetes-node-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-node-linux-ppc64le.tar.gz) | 7bf833e8f05f86ef390f317521dcce8b7ba2665af54db038abd114d4b94530a77ebc0e62276e7d59de7696c759ae8de17504520625b174623981acedac47a04c
 | 
			
		||||
[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-node-linux-s390x.tar.gz) | ab6aa43089b4df8f855de3cc62457dfb7ef2ecd6a0a77eab245fd373ae470aefedfe4bd7dfc2de278cb5d5c03eb1635c6fa9fbcf5a861e8d3bddcc1e240c6367
 | 
			
		||||
[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.20.12/kubernetes-node-windows-amd64.tar.gz) | c86e5c4f2695a5a82b08dff37996e6b7917088598a6ded41e201c577a9e70334a23649ffde34e9d79802ef2f9dbef4242c42aec49ec4f4e935233b7d8961c7dd
 | 
			
		||||
 | 
			
		||||
## Changelog since v1.20.11
 | 
			
		||||
 | 
			
		||||
## Changes by Kind
 | 
			
		||||
 | 
			
		||||
### API Change
 | 
			
		||||
 | 
			
		||||
- Kube-apiserver: Fixes handling of CRD schemas containing literal null values in enums (#104990, @liggitt) [SIG API Machinery, Apps and Network]
 | 
			
		||||
 | 
			
		||||
### Bug or Regression
 | 
			
		||||
 | 
			
		||||
- Detach volumes from vSphere nodes not tracked by attach-detach controller (#104910, @gnufied) [SIG Cloud Provider and Storage]
 | 
			
		||||
- Fix: consolidate logs for instance not found error (#105364, @nilo19) [SIG Cloud Provider]
 | 
			
		||||
- Fix: ignore not a VMSS error for VMAS nodes in EnsureBackendPoolDeleted. (#105404, @ialidzhikov) [SIG Cloud Provider]
 | 
			
		||||
- Fix: ignore the case when updating Azure tags (#104687, @nilo19) [SIG Cloud Provider]
 | 
			
		||||
- Revert PR #102925 which introduced unexpected scheduling behavior based on balanced resource allocation (#105239, @damemi) [SIG Scheduling]
 | 
			
		||||
- Updates golang.org/x/text to v0.3.6 to fix CVE-2020-28852 (#102602, @jonesbr17) [SIG API Machinery, CLI, Cloud Provider, Cluster Lifecycle, Instrumentation and Node]
 | 
			
		||||
 | 
			
		||||
### Other (Cleanup or Flake)
 | 
			
		||||
 | 
			
		||||
- Allow CSI drivers to just run offline expansion tests (#102665, @gnufied) [SIG Storage and Testing]
 | 
			
		||||
 | 
			
		||||
## Dependencies
 | 
			
		||||
 | 
			
		||||
### Added
 | 
			
		||||
_Nothing has changed._
 | 
			
		||||
 | 
			
		||||
### Changed
 | 
			
		||||
- golang.org/x/text: v0.3.4 → v0.3.6
 | 
			
		||||
 | 
			
		||||
### Removed
 | 
			
		||||
_Nothing has changed._
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# v1.20.11
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -297,17 +297,18 @@ func (o *DrainCmdOptions) RunDrain() error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printObj, err := o.ToPrinter("drained")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drainedNodes := sets.NewString()
 | 
			
		||||
	var fatal error
 | 
			
		||||
 | 
			
		||||
	for _, info := range o.nodeInfos {
 | 
			
		||||
		if err := o.deleteOrEvictPodsSimple(info); err == nil {
 | 
			
		||||
			drainedNodes.Insert(info.Name)
 | 
			
		||||
 | 
			
		||||
			printObj, err := o.ToPrinter("drained")
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			printObj(info.Object, o.Out)
 | 
			
		||||
		} else {
 | 
			
		||||
			if o.drainer.IgnoreErrors && len(o.nodeInfos) > 1 {
 | 
			
		||||
 
 | 
			
		||||
@@ -546,16 +546,18 @@ func TestDrain(t *testing.T) {
 | 
			
		||||
		expectWarning              string
 | 
			
		||||
		expectFatal                bool
 | 
			
		||||
		expectDelete               bool
 | 
			
		||||
		expectOutputToContain      string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			description:  "RC-managed pod",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{rcPod},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{rc},
 | 
			
		||||
			args:         []string{"node"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "RC-managed pod",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{rcPod},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "DS-managed pod",
 | 
			
		||||
@@ -568,14 +570,15 @@ func TestDrain(t *testing.T) {
 | 
			
		||||
			expectDelete: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "DS-managed terminated pod",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{dsTerminatedPod},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{rc},
 | 
			
		||||
			args:         []string{"node"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "DS-managed terminated pod",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{dsTerminatedPod},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "orphaned DS-managed pod",
 | 
			
		||||
@@ -588,76 +591,83 @@ func TestDrain(t *testing.T) {
 | 
			
		||||
			expectDelete: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:   "orphaned DS-managed pod with --force",
 | 
			
		||||
			node:          node,
 | 
			
		||||
			expected:      cordonedNode,
 | 
			
		||||
			pods:          []corev1.Pod{orphanedDsPod},
 | 
			
		||||
			rcs:           []corev1.ReplicationController{},
 | 
			
		||||
			args:          []string{"node", "--force"},
 | 
			
		||||
			expectFatal:   false,
 | 
			
		||||
			expectDelete:  true,
 | 
			
		||||
			expectWarning: "WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: default/bar",
 | 
			
		||||
			description:           "orphaned DS-managed pod with --force",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{orphanedDsPod},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{},
 | 
			
		||||
			args:                  []string{"node", "--force"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectWarning:         "WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: default/bar",
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "DS-managed pod with --ignore-daemonsets",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{dsPod},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{rc},
 | 
			
		||||
			args:         []string{"node", "--ignore-daemonsets"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: false,
 | 
			
		||||
			description:           "DS-managed pod with --ignore-daemonsets",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{dsPod},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node", "--ignore-daemonsets"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          false,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:   "DS-managed pod with emptyDir with --ignore-daemonsets",
 | 
			
		||||
			node:          node,
 | 
			
		||||
			expected:      cordonedNode,
 | 
			
		||||
			pods:          []corev1.Pod{dsPodWithEmptyDir},
 | 
			
		||||
			rcs:           []corev1.ReplicationController{rc},
 | 
			
		||||
			args:          []string{"node", "--ignore-daemonsets"},
 | 
			
		||||
			expectWarning: "WARNING: ignoring DaemonSet-managed Pods: default/bar",
 | 
			
		||||
			expectFatal:   false,
 | 
			
		||||
			expectDelete:  false,
 | 
			
		||||
			description:           "DS-managed pod with emptyDir with --ignore-daemonsets",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{dsPodWithEmptyDir},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node", "--ignore-daemonsets"},
 | 
			
		||||
			expectWarning:         "WARNING: ignoring DaemonSet-managed Pods: default/bar",
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          false,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "Job-managed pod with local storage",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{jobPod},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{rc},
 | 
			
		||||
			args:         []string{"node", "--force", "--delete-emptydir-data=true"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "Job-managed pod with local storage",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{jobPod},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node", "--force", "--delete-emptydir-data=true"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "Ensure compatibility for --delete-local-data until fully deprecated",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{jobPod},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{rc},
 | 
			
		||||
			args:         []string{"node", "--force", "--delete-local-data=true"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "Ensure compatibility for --delete-local-data until fully deprecated",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{jobPod},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node", "--force", "--delete-local-data=true"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "Job-managed terminated pod",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{terminatedJobPodWithLocalStorage},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{rc},
 | 
			
		||||
			args:         []string{"node"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "Job-managed terminated pod",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{terminatedJobPodWithLocalStorage},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "RS-managed pod",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{rsPod},
 | 
			
		||||
			replicaSets:  []appsv1.ReplicaSet{rs},
 | 
			
		||||
			args:         []string{"node"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "RS-managed pod",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{rsPod},
 | 
			
		||||
			replicaSets:           []appsv1.ReplicaSet{rs},
 | 
			
		||||
			args:                  []string{"node"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "naked pod",
 | 
			
		||||
@@ -670,14 +680,15 @@ func TestDrain(t *testing.T) {
 | 
			
		||||
			expectDelete: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "naked pod with --force",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{nakedPod},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{},
 | 
			
		||||
			args:         []string{"node", "--force"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "naked pod with --force",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{nakedPod},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{},
 | 
			
		||||
			args:                  []string{"node", "--force"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "pod with EmptyDir",
 | 
			
		||||
@@ -689,33 +700,36 @@ func TestDrain(t *testing.T) {
 | 
			
		||||
			expectDelete: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "terminated pod with emptyDir",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{emptydirTerminatedPod},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{rc},
 | 
			
		||||
			args:         []string{"node"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "terminated pod with emptyDir",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{emptydirTerminatedPod},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "pod with EmptyDir and --delete-emptydir-data",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{emptydirPod},
 | 
			
		||||
			args:         []string{"node", "--force", "--delete-emptydir-data=true"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: true,
 | 
			
		||||
			description:           "pod with EmptyDir and --delete-emptydir-data",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{emptydirPod},
 | 
			
		||||
			args:                  []string{"node", "--force", "--delete-emptydir-data=true"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          true,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:  "empty node",
 | 
			
		||||
			node:         node,
 | 
			
		||||
			expected:     cordonedNode,
 | 
			
		||||
			pods:         []corev1.Pod{},
 | 
			
		||||
			rcs:          []corev1.ReplicationController{rc},
 | 
			
		||||
			args:         []string{"node"},
 | 
			
		||||
			expectFatal:  false,
 | 
			
		||||
			expectDelete: false,
 | 
			
		||||
			description:           "empty node",
 | 
			
		||||
			node:                  node,
 | 
			
		||||
			expected:              cordonedNode,
 | 
			
		||||
			pods:                  []corev1.Pod{},
 | 
			
		||||
			rcs:                   []corev1.ReplicationController{rc},
 | 
			
		||||
			args:                  []string{"node"},
 | 
			
		||||
			expectFatal:           false,
 | 
			
		||||
			expectDelete:          false,
 | 
			
		||||
			expectOutputToContain: "node/node drained",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:                "fail to list pods",
 | 
			
		||||
@@ -859,7 +873,7 @@ func TestDrain(t *testing.T) {
 | 
			
		||||
				}
 | 
			
		||||
				tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
 | 
			
		||||
 | 
			
		||||
				ioStreams, _, _, errBuf := genericclioptions.NewTestIOStreams()
 | 
			
		||||
				ioStreams, _, outBuf, errBuf := genericclioptions.NewTestIOStreams()
 | 
			
		||||
				cmd := NewCmdDrain(tf, ioStreams)
 | 
			
		||||
 | 
			
		||||
				var recovered interface{}
 | 
			
		||||
@@ -925,6 +939,13 @@ func TestDrain(t *testing.T) {
 | 
			
		||||
						t.Fatalf("%s: actual warning message did not match expected warning message.\n Expecting:\n%v\n  Got:\n%v", test.description, e, a)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if len(test.expectOutputToContain) > 0 {
 | 
			
		||||
					out := outBuf.String()
 | 
			
		||||
					if !strings.Contains(out, test.expectOutputToContain) {
 | 
			
		||||
						t.Fatalf("%s: expected output to contain: %s\nGot:\n%s", test.description, test.expectOutputToContain, out)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								staging/src/k8s.io/pod-security-admission/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								staging/src/k8s.io/pod-security-admission/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
# Webhook binary
 | 
			
		||||
pod-security-webhook
 | 
			
		||||
 | 
			
		||||
# Directory containing pki files
 | 
			
		||||
pki/
 | 
			
		||||
@@ -41,8 +41,8 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	namespaceMaxPodsToCheck  = 3000
 | 
			
		||||
	namespacePodCheckTimeout = 1 * time.Second
 | 
			
		||||
	defaultNamespaceMaxPodsToCheck  = 3000
 | 
			
		||||
	defaultNamespacePodCheckTimeout = 1 * time.Second
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Admission implements the core admission logic for the Pod Security Admission controller.
 | 
			
		||||
@@ -64,6 +64,9 @@ type Admission struct {
 | 
			
		||||
	PodLister       PodLister
 | 
			
		||||
 | 
			
		||||
	defaultPolicy api.Policy
 | 
			
		||||
 | 
			
		||||
	namespaceMaxPodsToCheck  int
 | 
			
		||||
	namespacePodCheckTimeout time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type NamespaceGetter interface {
 | 
			
		||||
@@ -152,6 +155,8 @@ func (a *Admission) CompleteConfiguration() error {
 | 
			
		||||
			a.defaultPolicy = p
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	a.namespaceMaxPodsToCheck = defaultNamespaceMaxPodsToCheck
 | 
			
		||||
	a.namespacePodCheckTimeout = defaultNamespacePodCheckTimeout
 | 
			
		||||
 | 
			
		||||
	if a.PodSpecExtractor == nil {
 | 
			
		||||
		a.PodSpecExtractor = &DefaultPodSpecExtractor{}
 | 
			
		||||
@@ -173,6 +178,9 @@ func (a *Admission) ValidateConfiguration() error {
 | 
			
		||||
			return fmt.Errorf("default policy does not match; CompleteConfiguration() was not called before ValidateConfiguration()")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if a.namespaceMaxPodsToCheck == 0 || a.namespacePodCheckTimeout == 0 {
 | 
			
		||||
		return fmt.Errorf("namespace configuration not set; CompleteConfiguration() was not called before ValidateConfiguration()")
 | 
			
		||||
	}
 | 
			
		||||
	if a.Metrics == nil {
 | 
			
		||||
		return fmt.Errorf("Metrics recorder required")
 | 
			
		||||
	}
 | 
			
		||||
@@ -409,14 +417,14 @@ func (a *Admission) EvaluatePod(ctx context.Context, nsPolicy api.Policy, nsPoli
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if klog.V(5).Enabled() {
 | 
			
		||||
		klog.InfoS("Pod Security evaluation", "policy", fmt.Sprintf("%v", nsPolicy), "op", attrs.GetOperation(), "resource", attrs.GetResource(), "namespace", attrs.GetNamespace(), "name", attrs.GetName())
 | 
			
		||||
		klog.InfoS("PodSecurity evaluation", "policy", fmt.Sprintf("%v", nsPolicy), "op", attrs.GetOperation(), "resource", attrs.GetResource(), "namespace", attrs.GetNamespace(), "name", attrs.GetName())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	response := allowedResponse()
 | 
			
		||||
	if enforce {
 | 
			
		||||
		if result := policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Enforce, podMetadata, podSpec)); !result.Allowed {
 | 
			
		||||
			response = forbiddenResponse(fmt.Sprintf(
 | 
			
		||||
				"Pod violates PodSecurity %q: %s",
 | 
			
		||||
				"pod violates PodSecurity %q: %s",
 | 
			
		||||
				nsPolicy.Enforce.String(),
 | 
			
		||||
				result.ForbiddenDetail(),
 | 
			
		||||
			))
 | 
			
		||||
@@ -429,7 +437,7 @@ func (a *Admission) EvaluatePod(ctx context.Context, nsPolicy api.Policy, nsPoli
 | 
			
		||||
	// TODO: reuse previous evaluation if audit level+version is the same as enforce level+version
 | 
			
		||||
	if result := policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Audit, podMetadata, podSpec)); !result.Allowed {
 | 
			
		||||
		auditAnnotations["audit"] = fmt.Sprintf(
 | 
			
		||||
			"Would violate PodSecurity %q: %s",
 | 
			
		||||
			"would violate PodSecurity %q: %s",
 | 
			
		||||
			nsPolicy.Audit.String(),
 | 
			
		||||
			result.ForbiddenDetail(),
 | 
			
		||||
		)
 | 
			
		||||
@@ -442,7 +450,7 @@ func (a *Admission) EvaluatePod(ctx context.Context, nsPolicy api.Policy, nsPoli
 | 
			
		||||
		if result := policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Warn, podMetadata, podSpec)); !result.Allowed {
 | 
			
		||||
			// TODO: Craft a better user-facing warning message
 | 
			
		||||
			response.Warnings = append(response.Warnings, fmt.Sprintf(
 | 
			
		||||
				"Would violate PodSecurity %q: %s",
 | 
			
		||||
				"would violate PodSecurity %q: %s",
 | 
			
		||||
				nsPolicy.Warn.String(),
 | 
			
		||||
				result.ForbiddenDetail(),
 | 
			
		||||
			))
 | 
			
		||||
@@ -464,9 +472,10 @@ type podCount struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *Admission) EvaluatePodsInNamespace(ctx context.Context, namespace string, enforce api.LevelVersion) []string {
 | 
			
		||||
	timeout := namespacePodCheckTimeout
 | 
			
		||||
	// start with the default timeout
 | 
			
		||||
	timeout := a.namespacePodCheckTimeout
 | 
			
		||||
	if deadline, ok := ctx.Deadline(); ok {
 | 
			
		||||
		timeRemaining := time.Duration(0.9 * float64(time.Until(deadline))) // Leave a little time to respond.
 | 
			
		||||
		timeRemaining := time.Until(deadline) / 2 // don't take more than half the remaining time
 | 
			
		||||
		if timeout > timeRemaining {
 | 
			
		||||
			timeout = timeRemaining
 | 
			
		||||
		}
 | 
			
		||||
@@ -477,8 +486,8 @@ func (a *Admission) EvaluatePodsInNamespace(ctx context.Context, namespace strin
 | 
			
		||||
 | 
			
		||||
	pods, err := a.PodLister.ListPods(ctx, namespace)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		klog.ErrorS(err, "Failed to list pods", "namespace", namespace)
 | 
			
		||||
		return []string{"Failed to list pods"}
 | 
			
		||||
		klog.ErrorS(err, "failed to list pods", "namespace", namespace)
 | 
			
		||||
		return []string{"failed to list pods while checking new PodSecurity enforce level"}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
@@ -487,11 +496,12 @@ func (a *Admission) EvaluatePodsInNamespace(ctx context.Context, namespace strin
 | 
			
		||||
		podWarnings        []string
 | 
			
		||||
		podWarningsToCount = make(map[string]podCount)
 | 
			
		||||
	)
 | 
			
		||||
	if len(pods) > namespaceMaxPodsToCheck {
 | 
			
		||||
		warnings = append(warnings, fmt.Sprintf("Large namespace: only checking the first %d of %d pods", namespaceMaxPodsToCheck, len(pods)))
 | 
			
		||||
		pods = pods[0:namespaceMaxPodsToCheck]
 | 
			
		||||
	totalPods := len(pods)
 | 
			
		||||
	if len(pods) > a.namespaceMaxPodsToCheck {
 | 
			
		||||
		pods = pods[0:a.namespaceMaxPodsToCheck]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	checkedPods := len(pods)
 | 
			
		||||
	for i, pod := range pods {
 | 
			
		||||
		// short-circuit on exempt runtimeclass
 | 
			
		||||
		if a.exemptRuntimeClass(pod.Spec.RuntimeClassName) {
 | 
			
		||||
@@ -510,12 +520,20 @@ func (a *Admission) EvaluatePodsInNamespace(ctx context.Context, namespace strin
 | 
			
		||||
			c.podCount++
 | 
			
		||||
			podWarningsToCount[warning] = c
 | 
			
		||||
		}
 | 
			
		||||
		if time.Now().After(deadline) {
 | 
			
		||||
			warnings = append(warnings, fmt.Sprintf("Timeout reached after checking %d pods", i+1))
 | 
			
		||||
		if err := ctx.Err(); err != nil { // deadline exceeded or context was cancelled
 | 
			
		||||
			checkedPods = i + 1
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if checkedPods < totalPods {
 | 
			
		||||
		warnings = append(warnings, fmt.Sprintf("new PodSecurity enforce level only checked against the first %d of %d existing pods", checkedPods, totalPods))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(podWarnings) > 0 {
 | 
			
		||||
		warnings = append(warnings, fmt.Sprintf("existing pods in namespace %q violate the new PodSecurity enforce level %q", namespace, enforce.String()))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// prepend pod names to warnings
 | 
			
		||||
	decoratePodWarnings(podWarningsToCount, podWarnings)
 | 
			
		||||
	// put warnings in a deterministic order
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
 | 
			
		||||
@@ -174,9 +175,14 @@ func TestDefaultHasPodSpec(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
type testEvaluator struct {
 | 
			
		||||
	lv api.LevelVersion
 | 
			
		||||
 | 
			
		||||
	delay time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *testEvaluator) EvaluatePod(lv api.LevelVersion, meta *metav1.ObjectMeta, spec *corev1.PodSpec) []policy.CheckResult {
 | 
			
		||||
	if t.delay > 0 {
 | 
			
		||||
		time.Sleep(t.delay)
 | 
			
		||||
	}
 | 
			
		||||
	t.lv = lv
 | 
			
		||||
	if meta.Annotations["error"] != "" {
 | 
			
		||||
		return []policy.CheckResult{{Allowed: false, ForbiddenReason: meta.Annotations["error"]}}
 | 
			
		||||
@@ -196,10 +202,17 @@ func (t *testNamespaceGetter) GetNamespace(ctx context.Context, name string) (*c
 | 
			
		||||
type testPodLister struct {
 | 
			
		||||
	called bool
 | 
			
		||||
	pods   []*corev1.Pod
 | 
			
		||||
	delay  time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *testPodLister) ListPods(ctx context.Context, namespace string) ([]*corev1.Pod, error) {
 | 
			
		||||
	t.called = true
 | 
			
		||||
	if t.delay > 0 {
 | 
			
		||||
		time.Sleep(t.delay)
 | 
			
		||||
	}
 | 
			
		||||
	if err := ctx.Err(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return t.pods, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -218,6 +231,10 @@ func TestValidateNamespace(t *testing.T) {
 | 
			
		||||
		oldLabels map[string]string
 | 
			
		||||
		// list of pods to return
 | 
			
		||||
		pods []*corev1.Pod
 | 
			
		||||
		// time to sleep while listing
 | 
			
		||||
		delayList time.Duration
 | 
			
		||||
		// time to sleep while evaluating
 | 
			
		||||
		delayEvaluation time.Duration
 | 
			
		||||
 | 
			
		||||
		expectAllowed  bool
 | 
			
		||||
		expectError    string
 | 
			
		||||
@@ -352,7 +369,11 @@ func TestValidateNamespace(t *testing.T) {
 | 
			
		||||
			expectAllowed:  true,
 | 
			
		||||
			expectListPods: true,
 | 
			
		||||
			expectEvaluate: api.LevelVersion{Level: api.LevelRestricted, Version: api.LatestVersion()},
 | 
			
		||||
			expectWarnings: []string{"noruntimeclasspod (and 2 other pods): message", "runtimeclass3pod: message, message2"},
 | 
			
		||||
			expectWarnings: []string{
 | 
			
		||||
				`existing pods in namespace "test" violate the new PodSecurity enforce level "restricted:latest"`,
 | 
			
		||||
				"noruntimeclasspod (and 2 other pods): message",
 | 
			
		||||
				"runtimeclass3pod: message, message2",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:                 "update with runtimeclass exempt pods",
 | 
			
		||||
@@ -362,11 +383,57 @@ func TestValidateNamespace(t *testing.T) {
 | 
			
		||||
			expectAllowed:        true,
 | 
			
		||||
			expectListPods:       true,
 | 
			
		||||
			expectEvaluate:       api.LevelVersion{Level: api.LevelRestricted, Version: api.LatestVersion()},
 | 
			
		||||
			expectWarnings:       []string{"noruntimeclasspod (and 1 other pod): message", "runtimeclass3pod: message, message2"},
 | 
			
		||||
			expectWarnings: []string{
 | 
			
		||||
				`existing pods in namespace "test" violate the new PodSecurity enforce level "restricted:latest"`,
 | 
			
		||||
				"noruntimeclasspod (and 1 other pod): message",
 | 
			
		||||
				"runtimeclass3pod: message, message2",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:           "timeout on list",
 | 
			
		||||
			newLabels:      map[string]string{api.EnforceLevelLabel: string(api.LevelRestricted)},
 | 
			
		||||
			oldLabels:      map[string]string{api.EnforceLevelLabel: string(api.LevelBaseline)},
 | 
			
		||||
			delayList:      time.Second + 100*time.Millisecond,
 | 
			
		||||
			expectAllowed:  true,
 | 
			
		||||
			expectListPods: true,
 | 
			
		||||
			expectWarnings: []string{
 | 
			
		||||
				`failed to list pods while checking new PodSecurity enforce level`,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:            "timeout on evaluate",
 | 
			
		||||
			newLabels:       map[string]string{api.EnforceLevelLabel: string(api.LevelRestricted)},
 | 
			
		||||
			oldLabels:       map[string]string{api.EnforceLevelLabel: string(api.LevelBaseline)},
 | 
			
		||||
			delayEvaluation: (time.Second + 100*time.Millisecond) / 2, // leave time for two evaluations
 | 
			
		||||
			expectAllowed:   true,
 | 
			
		||||
			expectListPods:  true,
 | 
			
		||||
			expectEvaluate:  api.LevelVersion{Level: api.LevelRestricted, Version: api.LatestVersion()},
 | 
			
		||||
			expectWarnings: []string{
 | 
			
		||||
				`new PodSecurity enforce level only checked against the first 2 of 4 existing pods`,
 | 
			
		||||
				`existing pods in namespace "test" violate the new PodSecurity enforce level "restricted:latest"`,
 | 
			
		||||
				`noruntimeclasspod (and 1 other pod): message`,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:      "bound number of pods",
 | 
			
		||||
			newLabels: map[string]string{api.EnforceLevelLabel: string(api.LevelRestricted)},
 | 
			
		||||
			oldLabels: map[string]string{api.EnforceLevelLabel: string(api.LevelBaseline)},
 | 
			
		||||
			pods: []*corev1.Pod{
 | 
			
		||||
				{ObjectMeta: metav1.ObjectMeta{Name: "pod1", Annotations: map[string]string{"error": "message"}}},
 | 
			
		||||
				{ObjectMeta: metav1.ObjectMeta{Name: "pod2", Annotations: map[string]string{"error": "message"}}},
 | 
			
		||||
				{ObjectMeta: metav1.ObjectMeta{Name: "pod3", Annotations: map[string]string{"error": "message"}}},
 | 
			
		||||
				{ObjectMeta: metav1.ObjectMeta{Name: "pod4", Annotations: map[string]string{"error": "message"}}},
 | 
			
		||||
				{ObjectMeta: metav1.ObjectMeta{Name: "pod5", Annotations: map[string]string{"error": "message"}}},
 | 
			
		||||
			},
 | 
			
		||||
			expectAllowed:  true,
 | 
			
		||||
			expectListPods: true,
 | 
			
		||||
			expectEvaluate: api.LevelVersion{Level: api.LevelRestricted, Version: api.LatestVersion()},
 | 
			
		||||
			expectWarnings: []string{
 | 
			
		||||
				`new PodSecurity enforce level only checked against the first 4 of 5 existing pods`,
 | 
			
		||||
				`existing pods in namespace "test" violate the new PodSecurity enforce level "restricted:latest"`,
 | 
			
		||||
				`pod1 (and 3 other pods): message`,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		// TODO: test for bounding evalution time with a warning
 | 
			
		||||
		// TODO: test for bounding pod count with a warning
 | 
			
		||||
		// TODO: test for prioritizing evaluating pods from unique controllers
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -428,8 +495,8 @@ func TestValidateNamespace(t *testing.T) {
 | 
			
		||||
					},
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			podLister := &testPodLister{pods: pods}
 | 
			
		||||
			evaluator := &testEvaluator{}
 | 
			
		||||
			podLister := &testPodLister{pods: pods, delay: tc.delayList}
 | 
			
		||||
			evaluator := &testEvaluator{delay: tc.delayEvaluation}
 | 
			
		||||
			a := &Admission{
 | 
			
		||||
				PodLister: podLister,
 | 
			
		||||
				Evaluator: evaluator,
 | 
			
		||||
@@ -441,6 +508,9 @@ func TestValidateNamespace(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
				Metrics:       NewMockRecorder(),
 | 
			
		||||
				defaultPolicy: defaultPolicy,
 | 
			
		||||
 | 
			
		||||
				namespacePodCheckTimeout: time.Second,
 | 
			
		||||
				namespaceMaxPodsToCheck:  4,
 | 
			
		||||
			}
 | 
			
		||||
			result := a.ValidateNamespace(context.TODO(), attrs)
 | 
			
		||||
			if result.Allowed != tc.expectAllowed {
 | 
			
		||||
@@ -567,16 +637,16 @@ func TestValidatePodController(t *testing.T) {
 | 
			
		||||
			desc:                   "bad deploy creates produce correct user-visible warnings and correct auditAnnotations",
 | 
			
		||||
			newObject:              &badDeploy,
 | 
			
		||||
			gvr:                    schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
 | 
			
		||||
			expectAuditAnnotations: map[string]string{"audit": "Would violate PodSecurity \"baseline:latest\": forbidden sysctls (unknown)"},
 | 
			
		||||
			expectWarnings:         []string{"Would violate PodSecurity \"baseline:latest\": forbidden sysctls (unknown)"},
 | 
			
		||||
			expectAuditAnnotations: map[string]string{"audit": "would violate PodSecurity \"baseline:latest\": forbidden sysctls (unknown)"},
 | 
			
		||||
			expectWarnings:         []string{"would violate PodSecurity \"baseline:latest\": forbidden sysctls (unknown)"},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			desc:                   "bad spec updates don't block on enforce failures and returns correct information",
 | 
			
		||||
			newObject:              &badDeploy,
 | 
			
		||||
			oldObject:              &goodDeploy,
 | 
			
		||||
			gvr:                    schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
 | 
			
		||||
			expectAuditAnnotations: map[string]string{"audit": "Would violate PodSecurity \"baseline:latest\": forbidden sysctls (unknown)"},
 | 
			
		||||
			expectWarnings:         []string{"Would violate PodSecurity \"baseline:latest\": forbidden sysctls (unknown)"},
 | 
			
		||||
			expectAuditAnnotations: map[string]string{"audit": "would violate PodSecurity \"baseline:latest\": forbidden sysctls (unknown)"},
 | 
			
		||||
			expectWarnings:         []string{"would violate PodSecurity \"baseline:latest\": forbidden sysctls (unknown)"},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								staging/src/k8s.io/pod-security-admission/webhook/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								staging/src/k8s.io/pod-security-admission/webhook/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
# Copyright 2021 The Kubernetes 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.
 | 
			
		||||
 | 
			
		||||
FROM gcr.io/distroless/static:latest
 | 
			
		||||
 | 
			
		||||
COPY pod-security-webhook /pod-security-webhook
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT [ "/pod-security-webhook" ]
 | 
			
		||||
							
								
								
									
										66
									
								
								staging/src/k8s.io/pod-security-admission/webhook/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								staging/src/k8s.io/pod-security-admission/webhook/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
# Copyright 2021 The Kubernetes 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.
 | 
			
		||||
 | 
			
		||||
.PHONY: build container push clean
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT = "../cmd/webhook/webhook.go"
 | 
			
		||||
EXECUTABLE = "pod-security-webhook"
 | 
			
		||||
 | 
			
		||||
# Relative to location in staging dir
 | 
			
		||||
KUBE_ROOT = "../../../../.."
 | 
			
		||||
 | 
			
		||||
IMAGE_DOCKERFILE = "Dockerfile"
 | 
			
		||||
REGISTRY ?= "gcr.io/k8s-staging-sig-auth"
 | 
			
		||||
IMAGE ?= "$(REGISTRY)/pod-security-webhook"
 | 
			
		||||
TAG ?= "latest"
 | 
			
		||||
 | 
			
		||||
OS ?= linux
 | 
			
		||||
ARCH ?= amd64
 | 
			
		||||
 | 
			
		||||
# Builds the PodSecurity webhook binary.
 | 
			
		||||
build:
 | 
			
		||||
	@echo Building PodSecurity webhook...
 | 
			
		||||
	@LDFLAGS=`cd -P . && /usr/bin/env bash -c '. $(KUBE_ROOT)/hack/lib/version.sh && KUBE_ROOT=$(KUBE_ROOT) KUBE_GO_PACKAGE=k8s.io/kubernetes kube::version::ldflags'`; \
 | 
			
		||||
	GOOS=$(OS) GOARCH=$(ARCH) CGO_ENABLED=0 go build -o $(EXECUTABLE) -ldflags "$$LDFLAGS" $(ENTRYPOINT)
 | 
			
		||||
	@echo Done!
 | 
			
		||||
 | 
			
		||||
# Builds the PodSecurity webhook Docker image.
 | 
			
		||||
container: build
 | 
			
		||||
	@echo Building PodSecurity webhook image...
 | 
			
		||||
	@docker build \
 | 
			
		||||
		-f $(IMAGE_DOCKERFILE) \
 | 
			
		||||
		-t $(IMAGE):$(TAG) .
 | 
			
		||||
	@echo Done!
 | 
			
		||||
 | 
			
		||||
# Creates a CA and serving certificate valid for webhook.pod-security-webhook.svc
 | 
			
		||||
certs:
 | 
			
		||||
	rm -fr pki
 | 
			
		||||
	mkdir -p pki
 | 
			
		||||
	openssl genrsa -out pki/ca.key 2048
 | 
			
		||||
	openssl req -new -x509 -days 3650 -key pki/ca.key -subj "/CN=pod-security-webhook-ca-$(date +%s)" -out pki/ca.crt
 | 
			
		||||
 | 
			
		||||
	openssl req -newkey rsa:2048 -nodes -keyout pki/tls.key -subj "/CN=webhook.pod-security-webhook.svc" -out pki/tls.csr
 | 
			
		||||
 | 
			
		||||
	echo "subjectAltName=DNS:webhook.pod-security-webhook.svc" > pki/extensions.txt
 | 
			
		||||
	echo "extendedKeyUsage=serverAuth" >> pki/extensions.txt
 | 
			
		||||
	openssl x509 -req -extfile pki/extensions.txt -days 730 -in pki/tls.csr -CA pki/ca.crt -CAkey pki/ca.key -CAcreateserial -out pki/tls.crt
 | 
			
		||||
 | 
			
		||||
# Publishes the PodSecurity webhook Docker image to the configured registry.
 | 
			
		||||
push:
 | 
			
		||||
	@docker push $(IMAGE):$(TAG)
 | 
			
		||||
 | 
			
		||||
# Removes Pod Security Webhook artifacts.
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f $(EXECUTABLE)
 | 
			
		||||
	rm -fr pki
 | 
			
		||||
							
								
								
									
										33
									
								
								staging/src/k8s.io/pod-security-admission/webhook/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								staging/src/k8s.io/pod-security-admission/webhook/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
# Pod Security Admission Webhook
 | 
			
		||||
 | 
			
		||||
This directory contains files for a _Validating Admission Webhook_ that checks for conformance to the Pod Security Standards. It is built with the same Go package as the [Pod Security Admission Controller](https://kubernetes.io/docs/concepts/security/pod-security-admission/). The webhook is suitable for environments where the built-in PodSecurity admission controller cannot be used.
 | 
			
		||||
 | 
			
		||||
For more information, see the [Dynamic Admission Control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) documentation on the Kubernetes website.
 | 
			
		||||
 | 
			
		||||
## Getting Started
 | 
			
		||||
 | 
			
		||||
The webhook is available as a Docker image that lives within the SIG-Auth container registry. In addition to the `Dockerfile` for the webhook, this directory also contains sample Kubernetes manifests that can be used to deploy the webhook to a Kubernetes cluster.
 | 
			
		||||
 | 
			
		||||
### Configuring the Webhook Certificate
 | 
			
		||||
 | 
			
		||||
Run `make certs` to generate a CA and serving certificate valid for `https://webhook.pod-security-webhook.svc`.
 | 
			
		||||
 | 
			
		||||
### Deploying the Webhook
 | 
			
		||||
 | 
			
		||||
Apply the manifests to install the webhook in your cluster:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
kubectl apply -k .
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This applies the manifests in the `manifests` subdirectory,
 | 
			
		||||
creates a secret containing the serving certificate,
 | 
			
		||||
and injects the CA bundle to the validating webhook.
 | 
			
		||||
 | 
			
		||||
### Configuring the Webhook
 | 
			
		||||
 | 
			
		||||
Similar to the Pod Security Admission Controller, the webhook requires a configuration file to determine how incoming resources are validated. For real-world deployments, we highly recommend reviewing our [documentation on selecting appropriate policy levels](https://kubernetes.io/docs/tasks/configure-pod-container/migrate-from-psp/#steps).
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
Please see the [contributing guidelines](../CONTRIBUTING.md) in the parent directory for general information about contributing to this project.
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
# include the manifests
 | 
			
		||||
bases:
 | 
			
		||||
- ./manifests
 | 
			
		||||
 | 
			
		||||
# generate the secret
 | 
			
		||||
# this depends on pki files, which can be created (or regenerated) with `make certs`
 | 
			
		||||
secretGenerator:
 | 
			
		||||
- name: pod-security-webhook
 | 
			
		||||
  namespace: pod-security-webhook
 | 
			
		||||
  type: kubernetes.io/tls
 | 
			
		||||
  options:
 | 
			
		||||
    disableNameSuffixHash: true
 | 
			
		||||
  files:
 | 
			
		||||
  - pki/ca.crt
 | 
			
		||||
  - pki/tls.crt
 | 
			
		||||
  - pki/tls.key
 | 
			
		||||
 | 
			
		||||
# inject the CA into the validating webhook
 | 
			
		||||
replacements:
 | 
			
		||||
- source:
 | 
			
		||||
    kind: Secret
 | 
			
		||||
    name: pod-security-webhook
 | 
			
		||||
    namespace: pod-security-webhook
 | 
			
		||||
    fieldPath: data.ca\.crt
 | 
			
		||||
  targets:
 | 
			
		||||
  - select:
 | 
			
		||||
      kind: ValidatingWebhookConfiguration
 | 
			
		||||
      name: pod-security-webhook.kubernetes.io
 | 
			
		||||
    fieldPaths:
 | 
			
		||||
     - webhooks.0.clientConfig.caBundle
 | 
			
		||||
     - webhooks.1.clientConfig.caBundle
 | 
			
		||||
    options:
 | 
			
		||||
      create: true
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
apiVersion: v1
 | 
			
		||||
kind: Namespace
 | 
			
		||||
metadata:
 | 
			
		||||
  name: pod-security-webhook
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
apiVersion: v1
 | 
			
		||||
kind: ConfigMap
 | 
			
		||||
metadata:
 | 
			
		||||
  name: pod-security-webhook
 | 
			
		||||
  namespace: pod-security-webhook
 | 
			
		||||
data:
 | 
			
		||||
  podsecurityconfiguration.yaml: |
 | 
			
		||||
    apiVersion: pod-security.admission.config.k8s.io/v1alpha1
 | 
			
		||||
    kind: PodSecurityConfiguration
 | 
			
		||||
    # Defaults applied when a mode label is not set.
 | 
			
		||||
    #
 | 
			
		||||
    # Level label values must be one of:
 | 
			
		||||
    # - "privileged" (default)
 | 
			
		||||
    # - "baseline"
 | 
			
		||||
    # - "restricted"
 | 
			
		||||
    #
 | 
			
		||||
    # Version label values must be one of:
 | 
			
		||||
    # - "latest" (default) 
 | 
			
		||||
    # - specific version like "v1.22"
 | 
			
		||||
    defaults:
 | 
			
		||||
      enforce: "privileged"
 | 
			
		||||
      enforce-version: "latest"
 | 
			
		||||
      audit: "privileged"
 | 
			
		||||
      audit-version: "latest"
 | 
			
		||||
      warn: "privileged"
 | 
			
		||||
      warn-version: "latest"
 | 
			
		||||
    exemptions:
 | 
			
		||||
      # Array of authenticated usernames to exempt.
 | 
			
		||||
      usernames: []
 | 
			
		||||
      # Array of runtime class names to exempt.
 | 
			
		||||
      runtimeClasses: []
 | 
			
		||||
      # Array of namespaces to exempt.
 | 
			
		||||
      namespaces: []
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
apiVersion: v1
 | 
			
		||||
kind: ResourceQuota
 | 
			
		||||
metadata:
 | 
			
		||||
  name: pod-security-webhook
 | 
			
		||||
  namespace: pod-security-webhook
 | 
			
		||||
spec:
 | 
			
		||||
  hard:
 | 
			
		||||
    pods: 3
 | 
			
		||||
  scopeSelector:
 | 
			
		||||
    matchExpressions:
 | 
			
		||||
    - operator: In
 | 
			
		||||
      scopeName: PriorityClass
 | 
			
		||||
      values:
 | 
			
		||||
      - system-cluster-critical
 | 
			
		||||
@@ -0,0 +1,5 @@
 | 
			
		||||
apiVersion: v1
 | 
			
		||||
kind: ServiceAccount
 | 
			
		||||
metadata:
 | 
			
		||||
  name: pod-security-webhook
 | 
			
		||||
  namespace: pod-security-webhook
 | 
			
		||||
@@ -0,0 +1,8 @@
 | 
			
		||||
apiVersion: rbac.authorization.k8s.io/v1
 | 
			
		||||
kind: ClusterRole
 | 
			
		||||
metadata:
 | 
			
		||||
  name: pod-security-webhook
 | 
			
		||||
rules:
 | 
			
		||||
  - apiGroups: [""]
 | 
			
		||||
    resources: ["pods", "namespaces"]
 | 
			
		||||
    verbs: ["get", "watch", "list"]
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
apiVersion: rbac.authorization.k8s.io/v1
 | 
			
		||||
kind: ClusterRoleBinding
 | 
			
		||||
metadata:
 | 
			
		||||
  name: pod-security-webhook
 | 
			
		||||
subjects:
 | 
			
		||||
  - kind: ServiceAccount
 | 
			
		||||
    name: pod-security-webhook
 | 
			
		||||
    namespace: pod-security-webhook
 | 
			
		||||
roleRef:
 | 
			
		||||
  kind: ClusterRole
 | 
			
		||||
  name: pod-security-webhook
 | 
			
		||||
  apiGroup: rbac.authorization.k8s.io
 | 
			
		||||
@@ -0,0 +1,63 @@
 | 
			
		||||
apiVersion: apps/v1
 | 
			
		||||
kind: Deployment
 | 
			
		||||
metadata:
 | 
			
		||||
  name: pod-security-webhook
 | 
			
		||||
  namespace: pod-security-webhook
 | 
			
		||||
  labels:
 | 
			
		||||
    app: pod-security-webhook
 | 
			
		||||
spec:
 | 
			
		||||
  selector:
 | 
			
		||||
    matchLabels:
 | 
			
		||||
      app: pod-security-webhook
 | 
			
		||||
  template:
 | 
			
		||||
    metadata:
 | 
			
		||||
      labels:
 | 
			
		||||
        app: pod-security-webhook
 | 
			
		||||
    spec:
 | 
			
		||||
      serviceAccountName: pod-security-webhook
 | 
			
		||||
      priorityClassName: system-cluster-critical
 | 
			
		||||
      volumes:
 | 
			
		||||
        - name: config
 | 
			
		||||
          configMap:
 | 
			
		||||
            name: pod-security-webhook
 | 
			
		||||
        - name: pki
 | 
			
		||||
          secret:
 | 
			
		||||
            secretName: pod-security-webhook
 | 
			
		||||
      containers:
 | 
			
		||||
        - name: pod-security-webhook
 | 
			
		||||
          image: k8s.gcr.io/sig-auth/pod-security-webhook:v1.22-alpha.0
 | 
			
		||||
          terminationMessagePolicy: FallbackToLogsOnError
 | 
			
		||||
          ports:
 | 
			
		||||
            - containerPort: 8443
 | 
			
		||||
          args:
 | 
			
		||||
            [
 | 
			
		||||
              "--config",
 | 
			
		||||
              "/etc/config/podsecurityconfiguration.yaml",
 | 
			
		||||
              "--tls-cert-file",
 | 
			
		||||
              "/etc/pki/tls.crt",
 | 
			
		||||
              "--tls-private-key-file",
 | 
			
		||||
              "/etc/pki/tls.key",
 | 
			
		||||
              "--secure-port",
 | 
			
		||||
              "8443",
 | 
			
		||||
            ]
 | 
			
		||||
          resources:
 | 
			
		||||
            requests:
 | 
			
		||||
              cpu: 100m
 | 
			
		||||
            limits:
 | 
			
		||||
              cpu: 500m
 | 
			
		||||
          securityContext:
 | 
			
		||||
            allowPrivilegeEscalation: false
 | 
			
		||||
            capabilities:
 | 
			
		||||
              drop:
 | 
			
		||||
                - ALL
 | 
			
		||||
            runAsNonRoot: true
 | 
			
		||||
            runAsUser: 1000
 | 
			
		||||
            seccompProfile:
 | 
			
		||||
              type: RuntimeDefault
 | 
			
		||||
          volumeMounts:
 | 
			
		||||
            - name: config
 | 
			
		||||
              mountPath: "/etc/config"
 | 
			
		||||
              readOnly: true
 | 
			
		||||
            - name: pki
 | 
			
		||||
              mountPath: "/etc/pki"
 | 
			
		||||
              readOnly: true
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
apiVersion: v1
 | 
			
		||||
kind: Service
 | 
			
		||||
metadata:
 | 
			
		||||
  name: webhook
 | 
			
		||||
  namespace: pod-security-webhook
 | 
			
		||||
  labels:
 | 
			
		||||
    app: pod-security-webhook
 | 
			
		||||
spec:
 | 
			
		||||
  ports:
 | 
			
		||||
    - port: 443
 | 
			
		||||
      targetPort: 8443
 | 
			
		||||
      protocol: TCP
 | 
			
		||||
      name: https
 | 
			
		||||
  selector:
 | 
			
		||||
    app: pod-security-webhook
 | 
			
		||||
@@ -0,0 +1,74 @@
 | 
			
		||||
apiVersion: admissionregistration.k8s.io/v1
 | 
			
		||||
kind: ValidatingWebhookConfiguration
 | 
			
		||||
metadata:
 | 
			
		||||
  name: "pod-security-webhook.kubernetes.io"
 | 
			
		||||
webhooks:
 | 
			
		||||
  # Audit annotations will be prefixed with this name
 | 
			
		||||
  - name: "pod-security-webhook.kubernetes.io"
 | 
			
		||||
    # Fail-closed admission webhooks can present operational challenges.
 | 
			
		||||
    # You may want to consider using a failure policy of Ignore, but should 
 | 
			
		||||
    # consider the security tradeoffs.
 | 
			
		||||
    failurePolicy: Fail
 | 
			
		||||
    namespaceSelector:
 | 
			
		||||
      # Exempt the webhook itself to avoid a circular dependency.
 | 
			
		||||
      matchExpressions:
 | 
			
		||||
        - key: kubernetes.io/metadata.name
 | 
			
		||||
          operator: NotIn
 | 
			
		||||
          values: ["pod-security-webhook"]
 | 
			
		||||
    rules:
 | 
			
		||||
      - apiGroups: [""]
 | 
			
		||||
        apiVersions: ["v1"]
 | 
			
		||||
        operations: ["CREATE", "UPDATE"]
 | 
			
		||||
        resources:
 | 
			
		||||
          - namespaces
 | 
			
		||||
          - pods
 | 
			
		||||
          - pods/ephemeralcontainers
 | 
			
		||||
    clientConfig:
 | 
			
		||||
      # Populate with the CA for the serving certificate
 | 
			
		||||
      caBundle: ""
 | 
			
		||||
      service:
 | 
			
		||||
        namespace: "pod-security-webhook"
 | 
			
		||||
        name: "webhook"
 | 
			
		||||
    admissionReviewVersions: ["v1"]
 | 
			
		||||
    sideEffects: None
 | 
			
		||||
    timeoutSeconds: 5
 | 
			
		||||
 | 
			
		||||
  # Audit annotations will be prefixed with this name
 | 
			
		||||
  - name: "advisory.pod-security-webhook.kubernetes.io"
 | 
			
		||||
    # Non-enforcing resources can safely fail-open.
 | 
			
		||||
    failurePolicy: Ignore
 | 
			
		||||
    namespaceSelector:
 | 
			
		||||
      matchExpressions:
 | 
			
		||||
        - key: kubernetes.io/metadata.name
 | 
			
		||||
          operator: NotIn
 | 
			
		||||
          values: ["pod-security-webhook"]
 | 
			
		||||
    rules:
 | 
			
		||||
      - apiGroups: [""]
 | 
			
		||||
        apiVersions: ["v1"]
 | 
			
		||||
        operations: ["CREATE", "UPDATE"]
 | 
			
		||||
        resources:
 | 
			
		||||
          - podtemplates
 | 
			
		||||
          - replicationcontrollers
 | 
			
		||||
      - apiGroups: ["apps"]
 | 
			
		||||
        apiVersions: ["v1"]
 | 
			
		||||
        operations: ["CREATE", "UPDATE"]
 | 
			
		||||
        resources:
 | 
			
		||||
          - daemonsets
 | 
			
		||||
          - deployments
 | 
			
		||||
          - replicasets
 | 
			
		||||
          - statefulsets
 | 
			
		||||
      - apiGroups: ["batch"]
 | 
			
		||||
        apiVersions: ["v1"]
 | 
			
		||||
        operations: ["CREATE", "UPDATE"]
 | 
			
		||||
        resources:
 | 
			
		||||
          - cronjobs
 | 
			
		||||
          - jobs
 | 
			
		||||
    clientConfig:
 | 
			
		||||
      # Populate with the CA for the serving certificate
 | 
			
		||||
      caBundle: ""
 | 
			
		||||
      service:
 | 
			
		||||
        namespace: "pod-security-webhook"
 | 
			
		||||
        name: "webhook"
 | 
			
		||||
    admissionReviewVersions: ["v1"]
 | 
			
		||||
    sideEffects: None
 | 
			
		||||
    timeoutSeconds: 5
 | 
			
		||||
@@ -0,0 +1,10 @@
 | 
			
		||||
resources:
 | 
			
		||||
- 10-namespace.yaml
 | 
			
		||||
- 20-configmap.yaml
 | 
			
		||||
- 20-serviceaccount.yaml
 | 
			
		||||
- 20-resourcequota.yaml
 | 
			
		||||
- 30-clusterrole.yaml
 | 
			
		||||
- 40-clusterrolebinding.yaml
 | 
			
		||||
- 50-deployment.yaml
 | 
			
		||||
- 60-service.yaml
 | 
			
		||||
- 70-validatingwebhookconfiguration.yaml
 | 
			
		||||
@@ -491,7 +491,7 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
 | 
			
		||||
			StorageClassName: &emptyStorageClass,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pv, pvc, err := e2epv.CreatePVPVC(c, pvConfig, pvcConfig, f.Namespace.Name, false)
 | 
			
		||||
		pv, pvc, err := e2epv.CreatePVPVC(c, f.Timeouts, pvConfig, pvcConfig, f.Namespace.Name, false)
 | 
			
		||||
		framework.ExpectNoError(err)
 | 
			
		||||
		framework.ExpectNoError(e2epv.WaitOnPVandPVC(c, f.Timeouts, f.Namespace.Name, pv, pvc))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,8 +19,11 @@ package framework
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/test/e2e/storage/utils"
 | 
			
		||||
 | 
			
		||||
	"github.com/onsi/ginkgo"
 | 
			
		||||
@@ -295,17 +298,40 @@ func DeletePVCandValidatePVGroup(c clientset.Interface, timeouts *framework.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create the PV resource. Fails test on error.
 | 
			
		||||
func createPV(c clientset.Interface, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
 | 
			
		||||
	pv, err := c.CoreV1().PersistentVolumes().Create(context.TODO(), pv, metav1.CreateOptions{})
 | 
			
		||||
func createPV(c clientset.Interface, timeouts *framework.TimeoutContext, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
 | 
			
		||||
	var resultPV *v1.PersistentVolume
 | 
			
		||||
	var lastCreateErr error
 | 
			
		||||
	err := wait.PollImmediate(29*time.Second, timeouts.PVCreate, func() (done bool, err error) {
 | 
			
		||||
		resultPV, lastCreateErr = c.CoreV1().PersistentVolumes().Create(context.TODO(), pv, metav1.CreateOptions{})
 | 
			
		||||
		if lastCreateErr != nil {
 | 
			
		||||
			// If we hit a quota problem, we are not done and should retry again.  This happens to be the quota failure string for GCP.
 | 
			
		||||
			// If quota failure strings are found for other platforms, they can be added to improve reliability when running
 | 
			
		||||
			// many parallel test jobs in a single cloud account.  This corresponds to controller-like behavior and
 | 
			
		||||
			// to what we would recommend for general clients.
 | 
			
		||||
			if strings.Contains(lastCreateErr.Error(), `googleapi: Error 403: Quota exceeded for quota group`) {
 | 
			
		||||
				return false, nil
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// if it was not a quota failure, fail immediately
 | 
			
		||||
			return false, lastCreateErr
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true, nil
 | 
			
		||||
	})
 | 
			
		||||
	// if we have an error from creating the PV, use that instead of a timeout error
 | 
			
		||||
	if lastCreateErr != nil {
 | 
			
		||||
		return nil, fmt.Errorf("PV Create API error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("PV Create API error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	return pv, nil
 | 
			
		||||
 | 
			
		||||
	return resultPV, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreatePV creates the PV resource. Fails test on error.
 | 
			
		||||
func CreatePV(c clientset.Interface, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
 | 
			
		||||
	return createPV(c, pv)
 | 
			
		||||
func CreatePV(c clientset.Interface, timeouts *framework.TimeoutContext, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
 | 
			
		||||
	return createPV(c, timeouts, pv)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreatePVC creates the PVC resource. Fails test on error.
 | 
			
		||||
@@ -323,7 +349,7 @@ func CreatePVC(c clientset.Interface, ns string, pvc *v1.PersistentVolumeClaim)
 | 
			
		||||
// Note: in the pre-bind case the real PVC name, which is generated, is not
 | 
			
		||||
//   known until after the PVC is instantiated. This is why the pvc is created
 | 
			
		||||
//   before the pv.
 | 
			
		||||
func CreatePVCPV(c clientset.Interface, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig, ns string, preBind bool) (*v1.PersistentVolume, *v1.PersistentVolumeClaim, error) {
 | 
			
		||||
func CreatePVCPV(c clientset.Interface, timeouts *framework.TimeoutContext, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig, ns string, preBind bool) (*v1.PersistentVolume, *v1.PersistentVolumeClaim, error) {
 | 
			
		||||
	// make the pvc spec
 | 
			
		||||
	pvc := MakePersistentVolumeClaim(pvcConfig, ns)
 | 
			
		||||
	preBindMsg := ""
 | 
			
		||||
@@ -344,7 +370,7 @@ func CreatePVCPV(c clientset.Interface, pvConfig PersistentVolumeConfig, pvcConf
 | 
			
		||||
	if preBind {
 | 
			
		||||
		pv.Spec.ClaimRef.Name = pvc.Name
 | 
			
		||||
	}
 | 
			
		||||
	pv, err = createPV(c, pv)
 | 
			
		||||
	pv, err = createPV(c, timeouts, pv)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, pvc, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -358,7 +384,7 @@ func CreatePVCPV(c clientset.Interface, pvConfig PersistentVolumeConfig, pvcConf
 | 
			
		||||
// Note: in the pre-bind case the real PV name, which is generated, is not
 | 
			
		||||
//   known until after the PV is instantiated. This is why the pv is created
 | 
			
		||||
//   before the pvc.
 | 
			
		||||
func CreatePVPVC(c clientset.Interface, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig, ns string, preBind bool) (*v1.PersistentVolume, *v1.PersistentVolumeClaim, error) {
 | 
			
		||||
func CreatePVPVC(c clientset.Interface, timeouts *framework.TimeoutContext, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig, ns string, preBind bool) (*v1.PersistentVolume, *v1.PersistentVolumeClaim, error) {
 | 
			
		||||
	preBindMsg := ""
 | 
			
		||||
	if preBind {
 | 
			
		||||
		preBindMsg = " pre-bound"
 | 
			
		||||
@@ -370,7 +396,7 @@ func CreatePVPVC(c clientset.Interface, pvConfig PersistentVolumeConfig, pvcConf
 | 
			
		||||
	pvc := MakePersistentVolumeClaim(pvcConfig, ns)
 | 
			
		||||
 | 
			
		||||
	// instantiate the pv
 | 
			
		||||
	pv, err := createPV(c, pv)
 | 
			
		||||
	pv, err := createPV(c, timeouts, pv)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -392,7 +418,7 @@ func CreatePVPVC(c clientset.Interface, pvConfig PersistentVolumeConfig, pvcConf
 | 
			
		||||
// sees an error returned, it needs to decide what to do about entries in the maps.
 | 
			
		||||
// Note: when the test suite deletes the namespace orphaned pvcs and pods are deleted. However,
 | 
			
		||||
//   orphaned pvs are not deleted and will remain after the suite completes.
 | 
			
		||||
func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, ns string, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig) (PVMap, PVCMap, error) {
 | 
			
		||||
func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig) (PVMap, PVCMap, error) {
 | 
			
		||||
	pvMap := make(PVMap, numpvs)
 | 
			
		||||
	pvcMap := make(PVCMap, numpvcs)
 | 
			
		||||
	extraPVCs := 0
 | 
			
		||||
@@ -405,7 +431,7 @@ func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, ns string, pvConf
 | 
			
		||||
 | 
			
		||||
	// create pvs and pvcs
 | 
			
		||||
	for i := 0; i < pvsToCreate; i++ {
 | 
			
		||||
		pv, pvc, err := CreatePVPVC(c, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
		pv, pvc, err := CreatePVPVC(c, timeouts, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return pvMap, pvcMap, err
 | 
			
		||||
		}
 | 
			
		||||
@@ -416,7 +442,7 @@ func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, ns string, pvConf
 | 
			
		||||
	// create extra pvs or pvcs as needed
 | 
			
		||||
	for i := 0; i < extraPVs; i++ {
 | 
			
		||||
		pv := MakePersistentVolume(pvConfig)
 | 
			
		||||
		pv, err := createPV(c, pv)
 | 
			
		||||
		pv, err := createPV(c, timeouts, pv)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return pvMap, pvcMap, err
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ const (
 | 
			
		||||
	claimBoundTimeout                = 3 * time.Minute
 | 
			
		||||
	pvReclaimTimeout                 = 3 * time.Minute
 | 
			
		||||
	pvBoundTimeout                   = 3 * time.Minute
 | 
			
		||||
	pvCreateTimeout                  = 3 * time.Minute
 | 
			
		||||
	pvDeleteTimeout                  = 3 * time.Minute
 | 
			
		||||
	pvDeleteSlowTimeout              = 20 * time.Minute
 | 
			
		||||
	snapshotCreateTimeout            = 5 * time.Minute
 | 
			
		||||
@@ -67,6 +68,9 @@ type TimeoutContext struct {
 | 
			
		||||
	// PVBound is how long PVs have to become bound.
 | 
			
		||||
	PVBound time.Duration
 | 
			
		||||
 | 
			
		||||
	// PVCreate is how long PVs have to be created.
 | 
			
		||||
	PVCreate time.Duration
 | 
			
		||||
 | 
			
		||||
	// PVDelete is how long PVs have to become deleted.
 | 
			
		||||
	PVDelete time.Duration
 | 
			
		||||
 | 
			
		||||
@@ -95,6 +99,7 @@ func NewTimeoutContextWithDefaults() *TimeoutContext {
 | 
			
		||||
		ClaimBound:                claimBoundTimeout,
 | 
			
		||||
		PVReclaim:                 pvReclaimTimeout,
 | 
			
		||||
		PVBound:                   pvBoundTimeout,
 | 
			
		||||
		PVCreate:                  pvCreateTimeout,
 | 
			
		||||
		PVDelete:                  pvDeleteTimeout,
 | 
			
		||||
		PVDeleteSlow:              pvDeleteSlowTimeout,
 | 
			
		||||
		SnapshotCreate:            snapshotCreateTimeout,
 | 
			
		||||
 
 | 
			
		||||
@@ -142,7 +142,7 @@ var _ = utils.SIGDescribe("[Feature:Flexvolumes] Mounted flexvolume expand[Slow]
 | 
			
		||||
			VolumeMode:       pvc.Spec.VolumeMode,
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		_, err = e2epv.CreatePV(c, pv)
 | 
			
		||||
		_, err = e2epv.CreatePV(c, f.Timeouts, pv)
 | 
			
		||||
		framework.ExpectNoError(err, "Error creating pv %v", err)
 | 
			
		||||
 | 
			
		||||
		ginkgo.By("Waiting for PVC to be in bound phase")
 | 
			
		||||
 
 | 
			
		||||
@@ -140,7 +140,7 @@ var _ = utils.SIGDescribe("Mounted flexvolume volume expand [Slow] [Feature:Expa
 | 
			
		||||
			VolumeMode:       pvc.Spec.VolumeMode,
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		_, err = e2epv.CreatePV(c, pv)
 | 
			
		||||
		_, err = e2epv.CreatePV(c, f.Timeouts, pv)
 | 
			
		||||
		framework.ExpectNoError(err, "Error creating pv %v", err)
 | 
			
		||||
 | 
			
		||||
		ginkgo.By("Waiting for PVC to be in bound phase")
 | 
			
		||||
 
 | 
			
		||||
@@ -259,7 +259,7 @@ func createPVCPV(
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	framework.Logf("Creating PVC and PV")
 | 
			
		||||
	pv, pvc, err := e2epv.CreatePVCPV(f.ClientSet, pvConfig, pvcConfig, f.Namespace.Name, false)
 | 
			
		||||
	pv, pvc, err := e2epv.CreatePVCPV(f.ClientSet, f.Timeouts, pvConfig, pvcConfig, f.Namespace.Name, false)
 | 
			
		||||
	framework.ExpectNoError(err, "PVC, PV creation failed")
 | 
			
		||||
 | 
			
		||||
	err = e2epv.WaitOnPVandPVC(f.ClientSet, f.Timeouts, f.Namespace.Name, pv, pvc)
 | 
			
		||||
 
 | 
			
		||||
@@ -161,7 +161,7 @@ var _ = utils.SIGDescribe("NFSPersistentVolumes[Disruptive][Flaky]", func() {
 | 
			
		||||
				PVSource:   *pvSource1,
 | 
			
		||||
				Prebind:    nil,
 | 
			
		||||
			}
 | 
			
		||||
			pv1, pvc1, err = e2epv.CreatePVPVC(c, pvConfig1, pvcConfig, ns, false)
 | 
			
		||||
			pv1, pvc1, err = e2epv.CreatePVPVC(c, f.Timeouts, pvConfig1, pvcConfig, ns, false)
 | 
			
		||||
			framework.ExpectNoError(err)
 | 
			
		||||
			framework.ExpectNoError(e2epv.WaitOnPVandPVC(c, f.Timeouts, ns, pv1, pvc1))
 | 
			
		||||
 | 
			
		||||
@@ -174,7 +174,7 @@ var _ = utils.SIGDescribe("NFSPersistentVolumes[Disruptive][Flaky]", func() {
 | 
			
		||||
				PVSource:   *pvSource2,
 | 
			
		||||
				Prebind:    nil,
 | 
			
		||||
			}
 | 
			
		||||
			pv2, pvc2, err = e2epv.CreatePVPVC(c, pvConfig2, pvcConfig, ns, false)
 | 
			
		||||
			pv2, pvc2, err = e2epv.CreatePVPVC(c, f.Timeouts, pvConfig2, pvcConfig, ns, false)
 | 
			
		||||
			framework.ExpectNoError(err)
 | 
			
		||||
			framework.ExpectNoError(e2epv.WaitOnPVandPVC(c, f.Timeouts, ns, pv2, pvc2))
 | 
			
		||||
 | 
			
		||||
@@ -293,7 +293,7 @@ func createGCEVolume() (*v1.PersistentVolumeSource, string) {
 | 
			
		||||
// initTestCase initializes spec resources (pv, pvc, and pod) and returns pointers to be consumed
 | 
			
		||||
// by the test.
 | 
			
		||||
func initTestCase(f *framework.Framework, c clientset.Interface, pvConfig e2epv.PersistentVolumeConfig, pvcConfig e2epv.PersistentVolumeClaimConfig, ns, nodeName string) (*v1.Pod, *v1.PersistentVolume, *v1.PersistentVolumeClaim) {
 | 
			
		||||
	pv, pvc, err := e2epv.CreatePVPVC(c, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
	pv, pvc, err := e2epv.CreatePVPVC(c, f.Timeouts, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			e2epv.DeletePersistentVolumeClaim(c, pvc.Name, ns)
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,7 @@ func verifyGCEDiskAttached(diskName string, nodeName types.NodeName) bool {
 | 
			
		||||
// initializeGCETestSpec creates a PV, PVC, and ClientPod that will run until killed by test or clean up.
 | 
			
		||||
func initializeGCETestSpec(c clientset.Interface, t *framework.TimeoutContext, ns string, pvConfig e2epv.PersistentVolumeConfig, pvcConfig e2epv.PersistentVolumeClaimConfig, isPrebound bool) (*v1.Pod, *v1.PersistentVolume, *v1.PersistentVolumeClaim) {
 | 
			
		||||
	ginkgo.By("Creating the PV and PVC")
 | 
			
		||||
	pv, pvc, err := e2epv.CreatePVPVC(c, pvConfig, pvcConfig, ns, isPrebound)
 | 
			
		||||
	pv, pvc, err := e2epv.CreatePVPVC(c, t, pvConfig, pvcConfig, ns, isPrebound)
 | 
			
		||||
	framework.ExpectNoError(err)
 | 
			
		||||
	framework.ExpectNoError(e2epv.WaitOnPVandPVC(c, t, ns, pv, pvc))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -463,7 +463,7 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
 | 
			
		||||
			for _, localVolumes := range allLocalVolumes {
 | 
			
		||||
				for _, localVolume := range localVolumes {
 | 
			
		||||
					pvConfig := makeLocalPVConfig(config, localVolume)
 | 
			
		||||
					localVolume.pv, err = e2epv.CreatePV(config.client, e2epv.MakePersistentVolume(pvConfig))
 | 
			
		||||
					localVolume.pv, err = e2epv.CreatePV(config.client, f.Timeouts, e2epv.MakePersistentVolume(pvConfig))
 | 
			
		||||
					framework.ExpectNoError(err)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@@ -505,7 +505,7 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
 | 
			
		||||
								err = config.client.CoreV1().PersistentVolumes().Delete(context.TODO(), pv.Name, metav1.DeleteOptions{})
 | 
			
		||||
								framework.ExpectNoError(err)
 | 
			
		||||
								pvConfig := makeLocalPVConfig(config, localVolume)
 | 
			
		||||
								localVolume.pv, err = e2epv.CreatePV(config.client, e2epv.MakePersistentVolume(pvConfig))
 | 
			
		||||
								localVolume.pv, err = e2epv.CreatePV(config.client, f.Timeouts, e2epv.MakePersistentVolume(pvConfig))
 | 
			
		||||
								framework.ExpectNoError(err)
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
@@ -637,7 +637,7 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
 | 
			
		||||
			}
 | 
			
		||||
			pvConfig := makeLocalPVConfig(config, localVolume)
 | 
			
		||||
			var err error
 | 
			
		||||
			pv, err = e2epv.CreatePV(config.client, e2epv.MakePersistentVolume(pvConfig))
 | 
			
		||||
			pv, err = e2epv.CreatePV(config.client, f.Timeouts, e2epv.MakePersistentVolume(pvConfig))
 | 
			
		||||
			framework.ExpectNoError(err)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
@@ -936,7 +936,7 @@ func createLocalPVCsPVs(config *localTestConfig, volumes []*localTestVolume, mod
 | 
			
		||||
		pvcConfig := makeLocalPVCConfig(config, volume.localVolumeType)
 | 
			
		||||
		pvConfig := makeLocalPVConfig(config, volume)
 | 
			
		||||
 | 
			
		||||
		volume.pv, volume.pvc, err = e2epv.CreatePVPVC(config.client, pvConfig, pvcConfig, config.ns, false)
 | 
			
		||||
		volume.pv, volume.pvc, err = e2epv.CreatePVPVC(config.client, config.timeouts, pvConfig, pvcConfig, config.ns, false)
 | 
			
		||||
		framework.ExpectNoError(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -166,7 +166,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
 | 
			
		||||
			// contains the claim. Verify that the PV and PVC bind correctly, and
 | 
			
		||||
			// that the pod can write to the nfs volume.
 | 
			
		||||
			ginkgo.It("should create a non-pre-bound PV and PVC: test write access ", func() {
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVPVC(c, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVPVC(c, f.Timeouts, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
				framework.ExpectNoError(err)
 | 
			
		||||
				completeTest(f, c, ns, pv, pvc)
 | 
			
		||||
			})
 | 
			
		||||
@@ -175,7 +175,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
 | 
			
		||||
			// pod that contains the claim. Verify that the PV and PVC bind
 | 
			
		||||
			// correctly, and that the pod can write to the nfs volume.
 | 
			
		||||
			ginkgo.It("create a PVC and non-pre-bound PV: test write access", func() {
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVCPV(c, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVCPV(c, f.Timeouts, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
				framework.ExpectNoError(err)
 | 
			
		||||
				completeTest(f, c, ns, pv, pvc)
 | 
			
		||||
			})
 | 
			
		||||
@@ -184,7 +184,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
 | 
			
		||||
			// and a pod that contains the claim. Verify that the PV and PVC bind
 | 
			
		||||
			// correctly, and that the pod can write to the nfs volume.
 | 
			
		||||
			ginkgo.It("create a PVC and a pre-bound PV: test write access", func() {
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVCPV(c, pvConfig, pvcConfig, ns, true)
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVCPV(c, f.Timeouts, pvConfig, pvcConfig, ns, true)
 | 
			
		||||
				framework.ExpectNoError(err)
 | 
			
		||||
				completeTest(f, c, ns, pv, pvc)
 | 
			
		||||
			})
 | 
			
		||||
@@ -193,7 +193,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
 | 
			
		||||
			// and a pod that contains the claim. Verify that the PV and PVC bind
 | 
			
		||||
			// correctly, and that the pod can write to the nfs volume.
 | 
			
		||||
			ginkgo.It("create a PV and a pre-bound PVC: test write access", func() {
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVPVC(c, pvConfig, pvcConfig, ns, true)
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVPVC(c, f.Timeouts, pvConfig, pvcConfig, ns, true)
 | 
			
		||||
				framework.ExpectNoError(err)
 | 
			
		||||
				completeTest(f, c, ns, pv, pvc)
 | 
			
		||||
			})
 | 
			
		||||
@@ -231,7 +231,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
 | 
			
		||||
			// Note: PVs are created before claims and no pre-binding
 | 
			
		||||
			ginkgo.It("should create 2 PVs and 4 PVCs: test write access", func() {
 | 
			
		||||
				numPVs, numPVCs := 2, 4
 | 
			
		||||
				pvols, claims, err = e2epv.CreatePVsPVCs(numPVs, numPVCs, c, ns, pvConfig, pvcConfig)
 | 
			
		||||
				pvols, claims, err = e2epv.CreatePVsPVCs(numPVs, numPVCs, c, f.Timeouts, ns, pvConfig, pvcConfig)
 | 
			
		||||
				framework.ExpectNoError(err)
 | 
			
		||||
				framework.ExpectNoError(e2epv.WaitAndVerifyBinds(c, f.Timeouts, ns, pvols, claims, true))
 | 
			
		||||
				framework.ExpectNoError(completeMultiTest(f, c, ns, pvols, claims, v1.VolumeReleased))
 | 
			
		||||
@@ -241,7 +241,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
 | 
			
		||||
			// Note: PVs are created before claims and no pre-binding
 | 
			
		||||
			ginkgo.It("should create 3 PVs and 3 PVCs: test write access", func() {
 | 
			
		||||
				numPVs, numPVCs := 3, 3
 | 
			
		||||
				pvols, claims, err = e2epv.CreatePVsPVCs(numPVs, numPVCs, c, ns, pvConfig, pvcConfig)
 | 
			
		||||
				pvols, claims, err = e2epv.CreatePVsPVCs(numPVs, numPVCs, c, f.Timeouts, ns, pvConfig, pvcConfig)
 | 
			
		||||
				framework.ExpectNoError(err)
 | 
			
		||||
				framework.ExpectNoError(e2epv.WaitAndVerifyBinds(c, f.Timeouts, ns, pvols, claims, true))
 | 
			
		||||
				framework.ExpectNoError(completeMultiTest(f, c, ns, pvols, claims, v1.VolumeReleased))
 | 
			
		||||
@@ -251,7 +251,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
 | 
			
		||||
			// Note: PVs are created before claims and no pre-binding.
 | 
			
		||||
			ginkgo.It("should create 4 PVs and 2 PVCs: test write access [Slow]", func() {
 | 
			
		||||
				numPVs, numPVCs := 4, 2
 | 
			
		||||
				pvols, claims, err = e2epv.CreatePVsPVCs(numPVs, numPVCs, c, ns, pvConfig, pvcConfig)
 | 
			
		||||
				pvols, claims, err = e2epv.CreatePVsPVCs(numPVs, numPVCs, c, f.Timeouts, ns, pvConfig, pvcConfig)
 | 
			
		||||
				framework.ExpectNoError(err)
 | 
			
		||||
				framework.ExpectNoError(e2epv.WaitAndVerifyBinds(c, f.Timeouts, ns, pvols, claims, true))
 | 
			
		||||
				framework.ExpectNoError(completeMultiTest(f, c, ns, pvols, claims, v1.VolumeReleased))
 | 
			
		||||
@@ -264,7 +264,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
 | 
			
		||||
		ginkgo.Context("when invoking the Recycle reclaim policy", func() {
 | 
			
		||||
			ginkgo.BeforeEach(func() {
 | 
			
		||||
				pvConfig.ReclaimPolicy = v1.PersistentVolumeReclaimRecycle
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVPVC(c, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVPVC(c, f.Timeouts, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
				framework.ExpectNoError(err, "BeforeEach: Failed to create PV/PVC")
 | 
			
		||||
				framework.ExpectNoError(e2epv.WaitOnPVandPVC(c, f.Timeouts, ns, pv, pvc), "BeforeEach: WaitOnPVandPVC failed")
 | 
			
		||||
			})
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ package storage
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/onsi/ginkgo"
 | 
			
		||||
	v1 "k8s.io/api/core/v1"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
@@ -110,7 +111,7 @@ func PodsUseStaticPVsOrFail(f *framework.Framework, podCount int, image string)
 | 
			
		||||
		className := ""
 | 
			
		||||
		pvcConfig := e2epv.PersistentVolumeClaimConfig{StorageClassName: &className}
 | 
			
		||||
 | 
			
		||||
		config.pv, config.pvc, err = e2epv.CreatePVPVC(c, pvConfig, pvcConfig, ns, true)
 | 
			
		||||
		config.pv, config.pvc, err = e2epv.CreatePVPVC(c, f.Timeouts, pvConfig, pvcConfig, ns, true)
 | 
			
		||||
		framework.ExpectNoError(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -598,7 +598,7 @@ var _ = utils.SIGDescribe("[Serial] Volume metrics", func() {
 | 
			
		||||
		ginkgo.It("should create unbound pv count metrics for pvc controller after creating pv only",
 | 
			
		||||
			func() {
 | 
			
		||||
				var err error
 | 
			
		||||
				pv, err = e2epv.CreatePV(c, pv)
 | 
			
		||||
				pv, err = e2epv.CreatePV(c, f.Timeouts, pv)
 | 
			
		||||
				framework.ExpectNoError(err, "Error creating pv: %v", err)
 | 
			
		||||
				waitForPVControllerSync(metricsGrabber, unboundPVKey, classKey)
 | 
			
		||||
				validator([]map[string]int64{nil, {className: 1}, nil, nil})
 | 
			
		||||
@@ -616,7 +616,7 @@ var _ = utils.SIGDescribe("[Serial] Volume metrics", func() {
 | 
			
		||||
		ginkgo.It("should create bound pv/pvc count metrics for pvc controller after creating both pv and pvc",
 | 
			
		||||
			func() {
 | 
			
		||||
				var err error
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVPVC(c, pvConfig, pvcConfig, ns, true)
 | 
			
		||||
				pv, pvc, err = e2epv.CreatePVPVC(c, f.Timeouts, pvConfig, pvcConfig, ns, true)
 | 
			
		||||
				framework.ExpectNoError(err, "Error creating pv pvc: %v", err)
 | 
			
		||||
				waitForPVControllerSync(metricsGrabber, boundPVKey, classKey)
 | 
			
		||||
				waitForPVControllerSync(metricsGrabber, boundPVCKey, namespaceKey)
 | 
			
		||||
@@ -627,7 +627,7 @@ var _ = utils.SIGDescribe("[Serial] Volume metrics", func() {
 | 
			
		||||
			func() {
 | 
			
		||||
				var err error
 | 
			
		||||
				dimensions := []string{pluginNameKey, volumeModeKey}
 | 
			
		||||
				pv, err = e2epv.CreatePV(c, pv)
 | 
			
		||||
				pv, err = e2epv.CreatePV(c, f.Timeouts, pv)
 | 
			
		||||
				framework.ExpectNoError(err, "Error creating pv: %v", err)
 | 
			
		||||
				waitForPVControllerSync(metricsGrabber, totalPVKey, pluginNameKey)
 | 
			
		||||
				controllerMetrics, err := metricsGrabber.GrabFromControllerManager()
 | 
			
		||||
 
 | 
			
		||||
@@ -94,7 +94,7 @@ var _ = utils.SIGDescribe("PersistentVolumes:vsphere [Feature:vsphere]", func()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		ginkgo.By("Creating the PV and PVC")
 | 
			
		||||
		pv, pvc, err = e2epv.CreatePVPVC(c, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
		pv, pvc, err = e2epv.CreatePVPVC(c, f.Timeouts, pvConfig, pvcConfig, ns, false)
 | 
			
		||||
		framework.ExpectNoError(err)
 | 
			
		||||
		framework.ExpectNoError(e2epv.WaitOnPVandPVC(c, f.Timeouts, ns, pv, pvc))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user