Merge branch 'master' into patch-1

This commit is contained in:
Ivan Font
2017-11-27 18:03:46 -08:00
committed by GitHub
73 changed files with 2238 additions and 708 deletions
+2
View File
@@ -24,6 +24,7 @@ toc:
- title: Extending Kubernetes
section:
- docs/concepts/overview/extending.md
- title: Extending the Kubernetes API
section:
- docs/concepts/api-extension/apiserver-aggregation.md
@@ -33,6 +34,7 @@ toc:
- docs/concepts/cluster-administration/network-plugins.md
- docs/concepts/cluster-administration/device-plugins.md
- docs/concepts/cluster-administration/sysctl-cluster.md
- docs/concepts/service-catalog/index.md
- title: Containers
section:
+9
View File
@@ -0,0 +1,9 @@
id: managed-service
name: Managed Service
tags:
- extension
short-description: >
A software offering maintained by a third-party provider.
long-description: >
Some examples of Managed Services are AWS EC2, Azure SQL Database, and GCP Pub/Sub, but they can be any software offering that can be used by an application.
[Service Catalog](/docs/concepts/service-catalog/) provides a way to list, provision, and bind with Managed Services offered by {% glossary_tooltip text="Service Brokers" term_id="service-broker" %}.
+2 -1
View File
@@ -2,9 +2,10 @@ id: platform-developer
name: Platform Developer
aka:
- Kubernetes Developer
- Extension Developer
tags:
- user-type
short-description: >
A person who customizes the Kubernetes platform to fit the needs of their project.
long-description: >
A platform developer may, for example, use [Custom Resources](/docs/concepts/api-extension/custom-resources/) or [Extend the Kubernetes API with the aggregation layer](/docs/concepts/api-extension/apiserver-aggregation/) to add functionality to their instance of Kubernetes, specifically for their application.
A platform developer may, for example, use [Custom Resources](/docs/concepts/api-extension/custom-resources/) or [Extend the Kubernetes API with the aggregation layer](/docs/concepts/api-extension/apiserver-aggregation/) to add functionality to their instance of Kubernetes, specifically for their application. Some Platform Developers are also {% glossary_tooltip text="contributors" term_id="contributor" %} and develop extensions which are contributed to the Kubernetes community. Others develop closed-source commercial or site-specific extensions.
+9
View File
@@ -0,0 +1,9 @@
id: service-broker
name: Service Broker
tags:
- extension
short-description: >
An endpoint for a set of {% glossary_tooltip text="Managed Services" term_id="managed-service" %} offered and maintained by a third-party.
long-description: >
{% glossary_tooltip text="Service Brokers" term_id="service-broker" %} implement the [Open Service Broker API spec](https://github.com/openservicebrokerapi/servicebroker/blob/v2.13/spec.md) and provide a standard interface for applications to use their Managed Services.
[Service Catalog](/docs/concepts/service-catalog/) provides a way to list, provision, and bind with Managed Services offered by Service Brokers.
+8
View File
@@ -0,0 +1,8 @@
id: service-catalog
name: Service Catalog
tags:
- extension
short-description: >
An extension API that enables applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider.
long-description: >
Service Catalog provides a way to list, provision, and bind with external {% glossary_tooltip text="Managed Services" term_id="managed-service" %} from {% glossary_tooltip text="Service Brokers" term_id="service-broker" %} without needing detailed knowledge about how those services are created or managed.
+3 -6
View File
@@ -64,11 +64,7 @@ toc:
- docs/user-guide/jsonpath.md
- docs/user-guide/kubectl-cheatsheet.md
- title: Cloud Controller Manager
section:
- docs/reference/generated/cloud-controller-manager.md
- title: Setup Tools
- title: Setup Tools Reference
section:
- docs/reference/generated/kubeadm.md
- title: Kubefed
@@ -80,7 +76,7 @@ toc:
- docs/reference/generated/kubefed_unjoin.md
- docs/reference/generated/kubefed_version.md
- title: Config Reference
- title: Command-line Tools Reference
section:
- docs/reference/generated/kubelet.md
- docs/admin/kubelet-authentication-authorization.md
@@ -89,6 +85,7 @@ toc:
- docs/reference/generated/kube-proxy.md
- docs/reference/generated/kube-scheduler.md
- docs/admin/kubelet-tls-bootstrapping.md
- docs/reference/generated/cloud-controller-manager.md
- docs/reference/generated/federation-apiserver.md
- docs/reference/generated/federation-controller-manager.md
+3 -3
View File
@@ -23,8 +23,8 @@ toc:
path: https://cloud.google.com/kubernetes-engine/docs/before-you-begin/
- title: Running Kubernetes on Azure Container Service
path: https://docs.microsoft.com/en-us/azure/container-service/container-service-kubernetes-walkthrough
- title: Running Kubernetes on IBM Bluemix Container Service
path: https://console.ng.bluemix.net/docs/containers/container_index.html
- title: Running Kubernetes on IBM Cloud Container Service
path: https://console.bluemix.net/docs/containers/container_index.html
- title: Turn-key Cloud Solutions
section:
@@ -33,7 +33,7 @@ toc:
- docs/getting-started-guides/azure.md
- docs/getting-started-guides/alibaba-cloud.md
- docs/getting-started-guides/clc.md
- title: Running Kubernetes on IBM Bluemix
- title: Running Kubernetes on IBM Cloud
path: https://github.com/patrocinio/kubernetes-softlayer
- docs/getting-started-guides/stackpoint.md
+3 -1
View File
@@ -100,7 +100,7 @@ toc:
- title: Use Explorer to Examine the Runtime Environment
path: https://github.com/kubernetes/kubernetes/tree/release-1.5/examples/explorer
- title: Access and Extend the Kubernetes API
- title: Extend Kubernetes
section:
- docs/tasks/access-kubernetes-api/http-proxy-access-api.md
- docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions.md
@@ -108,6 +108,8 @@ toc:
- docs/tasks/access-kubernetes-api/migrate-third-party-resource.md
- docs/tasks/access-kubernetes-api/configure-aggregation-layer.md
- docs/tasks/access-kubernetes-api/setup-extension-api-server.md
- docs/tasks/service-catalog/install-service-catalog-using-helm.md
- docs/tasks/service-catalog/install-service-catalog-using-sc.md
- title: TLS
section:
+66 -3
View File
@@ -432,7 +432,7 @@
name: 'Kublr',
logo: 'kublr',
link: 'http://kublr.com',
blurb: 'SSimplify and speed up the management of your containerized applications at scale.'
blurb: 'Simplify and speed up the management of your containerized applications at scale.'
},
{
type: 0,
@@ -614,7 +614,7 @@
name: 'Sphere Software, LLC',
logo: 'spheresoftware',
link: 'https://sphereinc.com/kubernetes/',
blurb: 'Architect and implement scalable applications using Kubernetes in Google Cloud, AWS, and Azure with our team of experts.'
blurb: 'The Sphere Software team of experts allows customers to architect and implement scalable applications using Kubernetes in Google Cloud, AWS, and Azure.'
},
{
type: 1,
@@ -742,6 +742,13 @@
link: 'https://caicloud.io/products/compass',
blurb: 'Caicloud - Compass'
},
{
type: 2,
name: 'Caicloud',
logo: 'caicloud',
link: 'https://caicloud.io/',
blurb: 'Founded by ex-Googlers,and early Kubernetes contributors, Caicloud leverages Kubernetes to provide container products which have successfully served Fortune 500 enterprises, and further utilizes Kubernetes as a vehicle to deliver ultra-speed deep learning experience.'
},
{
type: 3,
name: 'Alibaba',
@@ -788,7 +795,7 @@
type: 3,
name: 'Loodse',
logo: 'loodse',
link: 'https://loodse.io',
link: 'https://loodse.com',
blurb: 'Loodse - Kubermatic Container Engine'
},
{
@@ -798,6 +805,13 @@
link: 'https://github.com/Azure/acs-engine',
blurb: 'Microsoft - Azure acs-engine'
},
{
type: 3,
name: 'Microsoft',
logo: 'microsoft',
link: 'https://docs.microsoft.com/en-us/azure/aks/',
blurb: 'Microsoft - Azure Container Service AKS'
},
{
type: 3,
name: 'Oracle',
@@ -910,6 +924,20 @@
link: 'https://gopaddle.io',
blurb: 'goPaddle is a DevOps platform for Kubernetes developers. It simplifies the Kubernetes Service creation and maintenance through source to image conversion, build & version management, team management, access controls and audit logs, single click provision of Kubernetes Clusters across multiple clouds from a single console.'
},
{
type: 0,
name: 'Vexxhost',
logo: 'vexxhost',
link: 'https://vexxhost.com/public-cloud/container-services/kubernetes/',
blurb: 'VEXXHOST offers a high-performance container management service powered by Kubernetes and OpenStack Magnum.'
},
{
type: 1,
name: 'Component Soft',
logo: 'componentsoft',
link: 'https://www.componentsoft.eu/?p=3925',
blurb: 'Component Soft offers training, consultation and support around open cloud technologies like Kubernetes, Docker, Openstack and Ceph.'
},
{
type: 0,
name: 'Datera',
@@ -945,6 +973,41 @@
link: 'https://docs.portworx.com/scheduler/kubernetes/install.html',
blurb: 'With Portworx, you can manage any database or stateful service on any infrastructure using Kubernetes. You get a single data management layer for all of your stateful services, no matter where they run.'
},
{
type: 1,
name: 'Object Computing, Inc.',
logo: 'objectcomputing',
link: 'https://objectcomputing.com/services/software-engineering/devops/kubernetes-services',
blurb: 'Our portfolio of DevOps consulting services includes Kubernetes support, development, and training.'
},
{
type: 1,
name: 'Isotoma',
logo: 'isotoma',
link: 'https://www.isotoma.com/blog/2017/10/24/containerisation-tips-for-using-kubernetes-with-aws/',
blurb: 'Based in the North of England, Amazon partners who are delivering Kubernetes solutions on AWS for replatforming and native development.'
},
{
type: 1,
name: 'Servian',
logo: 'servian',
link: 'https://www.servian.com/cloud-and-technology/',
blurb: 'Based in Australia, Servian provides advisory, consulting and managed services to support both application and data centric kubernetes use cases.'
},
{
type: 1,
name: 'Redzara',
logo: 'redzara',
link: 'http://redzara.com/cloud-service',
blurb: 'Redzara has wide and in-depth experience in Cloud automation, now taking one giant step by providing container service offering and services to our customers.'
},
{
type: 0,
name: 'Dataspine',
logo: 'dataspine',
link: 'http://dataspine.xyz/',
blurb: 'Dataspine is building a secure, elastic and serverless deployment platform for production ML/AI workloads on top of k8s.'
},
{
type: 0,
name: 'Logdna',
@@ -45,7 +45,7 @@ Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经
如果创建该 ReplicaSet,然后查看 Pod 的 metadata 字段,能够看到 OwnerReferences 字段:
```shell
kubectl create -f https://k8s.io/docs/concepts/abstractions/controllers/my-repset.yaml
kubectl create -f https://k8s.io/docs/concepts/controllers/my-repset.yaml
kubectl get pods --output=yaml
```
@@ -0,0 +1,104 @@
---
title: 知名标签(Label)、注解(Annotation)和 Taints
---
Kubernetes 保留了 kubernetes.io 名字空间下的所有标签和注解。 本文描述了知名的
kubernetes.io 标签和注解。
本文既作为这些标签和注解值的参考,也就这些标签和注解的赋值进行了说明。
**目录:**
<!-- BEGIN MUNGE: GENERATED_TOC -->
- [知名标签、注解和 Taints](#well-known-labels-annotations-and-taints)
- [beta.kubernetes.io/arch](#betakubernetesioarch)
- [beta.kubernetes.io/os](#betakubernetesioos)
- [kubernetes.io/hostname](#kubernetesiohostname)
- [beta.kubernetes.io/instance-type](#betakubernetesioinstance-type)
- [failure-domain.beta.kubernetes.io/region](#failure-domainbetakubernetesioregion)
- [failure-domain.beta.kubernetes.io/zone](#failure-domainbetakubernetesiozone)
<!-- END MUNGE: GENERATED_TOC -->
## beta.kubernetes.io/arch
示例:`beta.kubernetes.io/arch=amd64`
用于:节点
Kubelet 用 Go 中定义的 `runtime.GOARCH` 值来填充该标签。 这在诸如混用 arm 和 x86 节点的情况下很有用。
## beta.kubernetes.io/os
示例:`beta.kubernetes.io/os=linux`
用于:节点
Kubelet 用该 Go 中定义的 `runtime.GOOS` 值来填充该标签。 这在集群中存在不同操作系统的节点时很有用(尽管当前 Kubernetes 只支持 Linux 操作系统)。
## kubernetes.io/hostname
示例:`kubernetes.io/hostname=ip-172-20-114-199.ec2.internal`
用于:节点
Kubelet 用 hostname 值来填充该标签。 注意:可以通过向 kubelet 传入 `--hostname-override`
参数对 “真正的” hostname 进行修改。
## beta.kubernetes.io/instance-type
示例:`beta.kubernetes.io/instance-type=m3.medium`
用于:节点
Kubelet 用 `cloudprovider` 中定义的实例类型来填充该标签。 未使用 `cloudprovider` 时不会设置该标签。
该标签在想要将某些负载定向到特定实例类型的节点上时会很有用,但通常用户更希望依赖 Kubernetes 调度器来执行基于资源的调度,所以用户应该致力于基于属性而不是实例类型来进行调度(例如:需要一个 CPU,而不是 `g2.2xlarge`)。
## failure-domain.beta.kubernetes.io/region
参考 [failure-domain.beta.kubernetes.io/zone](#failure-domainbetakubernetesiozone).
## failure-domain.beta.kubernetes.io/zone
示例:
`failure-domain.beta.kubernetes.io/region=us-east-1`
`failure-domain.beta.kubernetes.io/zone=us-east-1c`
用于:节点、PersistentVolume
用于节点: Kubelet 用 `cloudprovider` 中定义的区域(zone)信息来填充该标签。 未使用 `cloudprovider`
时不会设置该标签,但如果该标签在你的拓扑中有意义的话,应该考虑设置。
用于 PersistentVolume:在 GCE 和 AWS 中,`PersistentVolumeLabel` 准入控制器会自动添加区域标签。
在单区的集群中,Kubernetes 会自动将同一副本控制器或服务下的 pod 分散到不同的节点上 (以降低故障的影响)。
在多区的集群中,这种分散的行为扩展到跨区的层面 (以降低区域故障的影响)。 跨区分散通过 SelectorSpreadPriority
来实现。
这是一种尽力而为(best-effort)的处置方式, 如果集群中的区域是异构的 (例如:不同区域之间的节点数量、
节点类型或 pod 资源需求不同),可能使得 pod 在各区域间无法均匀分布。 如有需要,用户可以使用同质的区域
(节点数量和类型相同) 来减小 pod 分布不均的可能性。
由于卷不能跨区域挂载(attach),调度器 (通过 VolumeZonePredicate 断言) 也会保证需要特定卷的 pod
被调度到卷所在的区域中。
区域和地域(region)的实际值无关紧要,两者的层次含义也没有严格的定义。 最终期望是,除非整个地域故障,
否则某一区域节点的故障不应该影响到其他区域的节点。 例如,通常区域间应该避免共用同一个网络交换机。
具体的规划取决于特定的基础设备—— three-rack 设备所选择的设置与多数据中心截然不同。
如果 `PersistentVolumeLabel` 准入控制器不支持自动为 PersistentVolume 打标签,且用户希望防止 pod
跨区域进行卷的挂载,应考虑手动打标签 (或对 `PersistentVolumeLabel` 增加支持)。 如果用户的基础设施没有这种约束,则不需要为卷添加区域标签。
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![分析](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/api-reference/labels-annotations-taints.md?pixel)]()
<!-- END MUNGE: GENERATED_ANALYTICS -->
+1 -1
View File
@@ -7,7 +7,7 @@ cid: community
<section id="hero" class="light-text">
<h1>Community</h1>
</section>
<a href="https://goo.gl/nhbhXw"><img src="/images/KubeCon_NA_Community.png" alt="KubeConNA" width="100%" align="center"></a>
<a href="https://goo.gl/QsHxQH"><img src="/images/KubeCon_NA_Community.jpg" alt="KubeConNA" width="100%" align="center"></a>
<section id="mainContent">
<main>
<div class="content">
+4 -2
View File
@@ -31,8 +31,10 @@ A configuration example which uses HTTPS client auth:
clusters:
- name: name-of-remote-authz-service
cluster:
certificate-authority: /path/to/ca.pem # CA for verifying the remote service.
server: https://authz.example.com/authorize # URL of remote service to query. Must use 'https'.
# CA for verifying the remote service.
certificate-authority: /path/to/ca.pem
# URL of remote service to query. Must use 'https'. May not include parameters.
server: https://authz.example.com/authorize
# users refers to the API Server's webhook configuration.
users:
-18
View File
@@ -1,18 +0,0 @@
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: prometheus-node-exporter
spec:
template:
metadata:
name: prometheus-node-exporter
labels:
daemon: prom-node-exp
spec:
containers:
- name: c
image: prom/prometheus
ports:
- containerPort: 9090
hostPort: 9090
name: serverport
@@ -21,9 +21,6 @@ spec:
volumeMounts:
- mountPath: /var/log/kube-scheduler.log
name: logfile
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-s8ejd
readOnly: true
volumes:
- hostPath:
path: /var/log/kube-scheduler.log
+1 -1
View File
@@ -7,4 +7,4 @@ metadata:
spec:
containers:
- name: pod-with-no-annotation-container
image: gcr.io/google_containers/pause:2.0
image: gcr.io/google_containers/pause:2.0
@@ -1,17 +0,0 @@
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: my-repset
spec:
replicas: 3
selector:
matchLabels:
pod-is-for: garbage-collection-example
template:
metadata:
labels:
pod-is-for: garbage-collection-example
spec:
containers:
- name: nginx
image: nginx
@@ -213,6 +213,28 @@ provider configuration:
bs-version=v2
```
#### Metadata
These configuration options for the OpenStack provider pertain to metadata and
should appear in the `[Metadata]` section of the `cloud.conf` file:
* `search-order` (Optional): This configuration key influences the way that the
provider retrieves metadata relating to the instance(s) in which it runs. The
default value of `configDrive,metadataService` results in the provider
retrieving metadata relating to the instance from the config drive first if
available and then the metadata service. Alternative values are:
* `configDrive` - Only retrieve instance metadata from the configuration
drive.
* `metadataService` - Only retrieve instance metadata from the metadata
service.
* `metadataService,configDrive` - Retrieve instance metadata from the metadata
service first if available, then the configuration drive.
Influencing this behavior may be desirable as the metadata on the
configuration drive may grow stale over time, whereas the metadata service
always provides the most up to date view. Not all OpenStack clouds provide
both configuration drive and metadata service though and only one or the other
may be available which is why the default is to check both.
#### Router
These configuration options for the OpenStack provider pertain to routing and
should appear in the `[Route]` section of the `cloud.conf` file:
+12 -8
View File
@@ -37,15 +37,19 @@ This is a living document. If you think of something that is not on this list bu
## Services
- It's typically best to create a [service](/docs/concepts/services-networking/service/) before corresponding [replication controllers](/docs/concepts/workloads/controllers/replicationcontroller/). This lets the scheduler spread the pods that comprise the service.
- It's typically best to create a [service](/docs/concepts/services-networking/service/) before the corresponding [replication controllers](/docs/concepts/workloads/controllers/replicationcontroller/). This lets the scheduler spread the pods that comprise the service.
You can also use this process to ensure that at least one replica works before creating lots of them:
1. Create a replication controller without specifying replicas (this will set replicas=1);
2. Create a service;
3. Then scale up the replication controller.
- Don't use `hostPort` unless it is absolutely necessary (for example: for a node daemon). It specifies the port number to expose on the host. When you bind a Pod to a `hostPort`, there are a limited number of places to schedule a pod due to port conflicts— you can only schedule as many such Pods as there are nodes in your Kubernetes cluster.
- Don't use `hostPort` unless it is absolutely necessary (for example: for a node daemon).
It specifies the port number to expose on the host.
When you bind a Pod to a `hostPort`, there are a limited number of places to schedule a pod due to port conflicts.
The conflict comes from the requirement of an unique <hostIP,hostPort,protocol> combination.
Different <hostIP,hostPort,protocol> combinations mean different requirements.
For example, a pod that binds to host port 80 on 127.0.0.1 with TCP protocol has no conflict with another Pod that binds to host port 80 on 127.0.0.2 with TCP protocol.
*Special notes on hostIP and protocol*: If you don't specify the hostIP and protocol explicitly,
kubernetes will use 0.0.0.0 and TCP as the default hostIP and protocol,
where "0.0.0.0" is a wildcard IP that will match all <*,hostPort,protocol> on the node the pod is scheduled on.
Specifically, it will match all <IP,hostPort,protocol> tuples for all IPs on the host.
If you only need access to the port for debugging purposes, you can use the [kubectl proxy and apiserver proxy](/docs/tasks/access-kubernetes-api/http-proxy-access-api/) or [kubectl port-forward](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/).
You can use a [Service](/docs/concepts/services-networking/service/) object for external service access.
@@ -39,8 +39,7 @@ The following sections provide more information about these steps.
## Enabling priority and preemption
Pod priority and preemption is disabled by default in Kubernetes 1.8.
To enable the feature, set this command-line flag for the API server
and the scheduler:
To enable the feature, set this command-line flag for the API server, scheduler and kubelet:
```
--feature-gates=PodPriority=true
+215
View File
@@ -0,0 +1,215 @@
---
title: Extending your Kubernetes Cluster
approvers:
- erictune
- lavalamp
- cheftako
- chenopis
---
{% capture overview %}
Kubernetes is highly configurable and extensible. As a result,
there is rarely a need to fork or submit patches to the Kubernetes
project code.
This guide describes the options for customizing a Kubernetes
cluster. It is aimed at {% glossary_tooltip text="Cluster Operators" term_id="cluster-operator" %} who want to
understand how to adapt their Kubernetes cluster to the needs of
their work environment. Developers who are prospective {% glossary_tooltip text="Platform
Developers" term_id="platform-developer" %} or Kubernetes Project {% glossary_tooltip text="Contributors" term_id="contributor" %} will also find it
useful as an introduction to what extension points and patterns
exist, and their trade-offs and limitations.
{% endcapture %}
{% capture body %}
## Overview
Customization approaches can be broadly divided into *configuration*, which only involves changing flags, local configuration files, or API resources; and *extensions*, which involve running additional programs or services. This document is primarily about extensions.
## Configuration
*Configuration files* and *flags* are documented in the Reference section of the online documentation, under each binary:
* [kubelet](/docs/admin/kubelet/)
* [kube-apiserver](/docs/admin/kube-apiserver/)
* [kube-controller-manager](/docs/admin/kube-controller-manager/)
* [kube-scheduler](/docs/admin/kube-scheduler/).
Flags and configuration files may not always be changeable in a hosted Kubernetes service or a distribution with managed installation. When they are changeable, they are usually only changeable by the cluster administrator. Also, they are subject to change in future Kubernetes versions, and setting them may require restarting processes. For those reasons, they should be used only when there are no other options.
*Built-in Policy APIs*, such as [ResourceQuota](/docs/concepts/policy/resource-quotas/), [PodSecurityPolicies](/docs/concepts/policy/pod-security-policy/), [NetworkPolicy](/docs/concepts/services-networking/network-policies/) and Role-based Access Control ([RBAC](/docs/admin/authorization/rbac/)), are built-in Kubernetes APIs. APIs are typically used with hosted Kubernetes services and with managed Kubernetes installations. They are declarative and use the same conventions as other Kubernetes resources like pods, so new cluster configuration can be repeatable and be managed the same way as applications. And, where they are stable, they enjoy a [defined support policy](/docs/reference/deprecation-policy/) like other Kubernetes APIs. For these reasons, they are preferred over *configuration files* and *flags* where suitable.
## Extensions
Extensions are software components that extend and deeply integrate with Kubernetes.
They adapt it to support new types and new kinds of hardware.
Most cluster administrators will use a hosted or distribution
instance of Kubernetes. As a result, most Kubernetes users will need to
install extensions and fewer will need to author new ones.
## Extension Patterns
Kubernetes is designed to be automated by writing client programs. Any
program that reads and/or writes to the Kubernetes API can provide useful
automation. *Automation* can run on the cluster or off it. By following
the guidance in this doc you can write highly available and robust automation.
Automation generally works with any Kubernetes cluster, including hosted
clusters and managed installations.
There is a specific pattern for writing client programs that work well with
Kubernetes called the *Controller* pattern. Controllers typically read an
object's `.spec`, possibly do things, and then update the object's `.status`.
A controller is a client of Kubernetes. When Kubernetes is the client and
calls out to a remote service, it is called a *Webhook*. The remote service
is called a *Webhook Backend*. Like Controllers, Webhooks do add a point of
failure.
In the webhook model, Kubernetes makes a network request to a remote service.
In the *Binary Plugin* model, Kubernetes executes a binary (program).
Binary plugins are used by the kubelet (e.g. [Flex Volume
Plugins](https://github.com/kubernetes/community/blob/master/contributors/devel/flexvolume.md)
and [Network
Plugins](/docs/concepts/cluster-administration/network-plugins/))
and by kubectl.
Below is a diagram showing how the extensions points interact with the
Kubernetes control plane.
<img src="https://docs.google.com/drawings/d/e/2PACX-1vQBRWyXLVUlQPlp7BvxvV9S1mxyXSM6rAc_cbLANvKlu6kCCf-kGTporTMIeG5GZtUdxXz1xowN7RmL/pub?w=960&h=720">
<!-- image source drawing https://docs.google.com/drawings/d/1muJ7Oxuj_7Gtv7HV9-2zJbOnkQJnjxq-v1ym_kZfB-4/edit?ts=5a01e054 -->
## Extension Points
This diagram shows the extension points in a Kubernetes system.
<img src="https://docs.google.com/drawings/d/e/2PACX-1vSH5ZWUO2jH9f34YHenhnCd14baEb4vT-pzfxeFC7NzdNqRDgdz4DDAVqArtH4onOGqh0bhwMX0zGBb/pub?w=425&h=809">
<!-- image source diagrams: https://docs.google.com/drawings/d/1k2YdJgNTtNfW7_A8moIIkij-DmVgEhNrn3y2OODwqQQ/view -->
1. Users often interact with the Kubernetes API using `kubectl`. [Kubectl plugins](docs/tasks/extend-kubectl/kubectl-plugins) extend the kubectl binary. They only affect the individual user's local environment, and so cannot enforce site-wide policies.
2. The apiserver handles all requests. Several types of extension points in the apiserver allow authenticating requests, or blocking them based on their content, editing content, and handling deletion. These are described in the [API Access Extensions](docs/concepts/overview/extending#api-access-extensions) section.
3. The apiserver serves various kinds of *resources*. *Built-in resource kinds*, like `pods`, are defined by the Kubernetes project and can't be changed. You can also add resources that you define, or that other projects have defined, called *Custom Resources*, as explained in the [Custom Resources](docs/concepts/overview/extending#custom-resources) section. Custom Resources are often used with API Access Extensions.
4. The Kubernetes scheduler decides which nodes to place pods on. There are several ways to extend scheduling. These are described in the [Scheduler Extensions](docs/concepts/overview/extending#shceduler-extensions) section.
5. Much of the behavior of Kubernetes is implemented by programs called Controllers which are clients of the API-Server. Controllers are often used in conjunction with Custom Resources.
6. The kubelet runs on servers, and helps pods appear like virtual servers with their own IPs on the cluster network. [Network Plugins](docs/concepts/overview/extending#network-plugins) allow for different implementations of pod networking.
7. The kubelet also mounts and unmounts volumes for containers. New types of storage can be supported via [Storage Plugins](docs/concepts/overview/extending#storage-plugins).
If you are unsure where to start, this flowchart can help. Note that some solutions may involve several types of extensions.
<img src="https://docs.google.com/drawings/d/e/2PACX-1vRWXNNIVWFDqzDY0CsKZJY3AR8sDeFDXItdc5awYxVH8s0OLherMlEPVUpxPIB1CSUu7GPk7B2fEnzM/pub?w=1440&h=1080">
<!-- image source drawing: https://docs.google.com/drawings/d/1sdviU6lDz4BpnzJNHfNpQrqI9F19QZ07KnhnxVrp2yg/edit -->
## API Extensions
### User-Defined Types
Consider adding a Custom Resource to Kubernetes if you want to define new controllers, application configuration objects or other declarative APIs, and to manage them using Kubernetes tools, such as `kubectl`.
Do not use a Custom Resource as data storage for application, user, or monitoring data.
For more about Custom Resources, see the [Custom Resources concept guide](/docs/concepts/api-extension/custom-resources.md).
### Combining New APIs with Automation
Often, when you add a new API, you also add a control loop that reads and/or writes the new APIs. When the combination of a Custom API and a control loop is used to manage a specific, usually stateful, application, this is called the *Operator* pattern. Custom APIs and control loops can also be used to control other resources, such as storage, policies, and so on.
### Changing Built-in Resources
When you extend the Kubernetes API by adding custom resources, the added resources always fall into a new API Groups. You cannot replace or change existing API groups.
Adding an API does not directly let you affect the behavior of existing APIs (e.g. Pods), but API Access Extensions do.
### API Access Extensions
When a request reaches the Kubernetes API Server, it is first Authenticated, then Authorized, then subject to various types of Admission Control. See [[Accessing the API](/docs/admin/accessing-the-api/)] for more on this flow.
Each of these steps offers extension points.
Kubernetes has several built-in authentication methods that it supports. It can also sit behind an authenticating proxy, and it can send a token from an Authorization header to a remote service for verification (a webhook). All of these methods are covered in the [Authentication documentation](/docs/admin/authentication/).
### Authentication
[Authentication](/docs/admin/authentication) maps headers or certificates in all requests to a username for the client making the request.
Kubernetes provides several built-in authentication methods, and an [Authentication webhook](/docs/admin/authentication/#webhook-token-authentication) method if those don't meet your needs.
### Authorization
[Authorization](/docs/admin/authorization/webhook/) determines whether specific users can read, write, and do other operations on API resources. It just works at the level of whole resources -- it doesn't discriminate based on arbitrary object fields. If the built-in authorization options don't meet your needs, and [Authorization webhook](/docs/admin/authorization/webhook/) allows calling out to user-provided code to make an authorization decision.
### Dynamic Admission Control
After a request is authorized, if it is a write operation, it also t goes through [Admission Control](/docs/admin/admission-controllers/) steps. In addition to the built-in steps, there are several extensions:
* The [Image Policy webhook](/docs/admin/admission-controllers/#imagepolicywebhook) restricts what images can be run in containers.
* To make arbitrary admission control decisions, a general [Admission webhook](/docs/admin/extensible-admission-controllers/#external-admission-webhooks) can be used. Admission Webhooks can reject creations or updates.
* [Initializers](/docs/admin/extensible-admission-controllers/#initializers) are controllers that can modify objects before they are created. Initializers can modify initial object creations but cannot affect updates to objects. Initializers can also reject objects.
## Infrastructure Extensions
### Storage Plugins
[Flex Volumes](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/flexvolume-deployment.md
) allow users to mount volume types without built-in support by having the
Kubelet call a Binary Plugin to mount the volume.
### Device Plugins
Device plugins allow a node to discover new Node resources (in addition to the
builtin ones like cpu and memory) via a [Device
Plugin](/docs/concepts/cluster-administration/device-plugins/).
### Network Plugins
Different networking fabrics can be supported via node-level [Network Plugins](/docs/admin/network-plugins/).
### Scheduler Extensions
The scheduler is a special type of controller that watches pods, and assigns
pods to nodes. The default scheduler can be be replaced entirely, while
continuing to use other Kubernetes components, or [multiple
schedulers](/docs/tasks/administer-cluster/configure-multiple-schedulers/)
can run at the same time.
This is a significant undertaking, and almost all Kubernetes users find they
do not need to modify the scheduler.
The scheduler also supports a
[webhook](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/scheduler_extender.md)
that permits a webhook backend (scheduler extension) to filter and prioritize
the nodes chosen for a pod.
{% endcapture %}
{% capture whatsnext %}
* Learn more about [Custom Resources](/docs/concepts/api-extension/custom-resources/)
* Learn about [Dynamic admission control](/docs/admin/extensible-admission-controller)
* Learn more about Infrastructure extensions
* [Network Plugins](/docs/concepts/cluster-administration/network-plugin)
* [Device Plugins](/docs/concepts/cluster-administration/device-plugins.md)
* Learn about [kubectl plugins](/docs/tasks/extend-kubectl/kubectl-plugin)
* See examples of Automation
* [List of Operators](https://github.com/coreos/awesome-kubernetes-extensions)
{% endcapture %}
{% include templates/concept.md %}
@@ -4,6 +4,9 @@ metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
+234
View File
@@ -0,0 +1,234 @@
---
title: Service Catalog
approvers:
- chenopis
---
{% capture overview %}
{% glossary_definition term_id="service-catalog" length="all" prepend="Service Catalog is " %}
A *Service Broker*, as defined by the [Open Service Broker API spec](https://github.com/openservicebrokerapi/servicebroker/blob/v2.13/spec.md), is an endpoint for a set of Managed Services offered and maintained by a third-party, which could be a cloud provider such as AWS, GCP, or Azure.
Some examples of *Managed Services* are Microsoft Azure Cloud Queue, Amazon Simple Queue Service, and Google Cloud Pub/Sub, but they can be any software offering that can be used by an application.
Using Service Catalog, a {% glossary_tooltip text="Cluster Operator" term_id="cluster-operator" %} can browse the list of {% glossary_tooltip text="Managed Services" term_id="managed-service" %} offered by a {% glossary_tooltip text="Service Brokers" term_id="service-broker" %}, provision an instance of a Managed Service, and bind with it to make it available to an application within the Kubernetes cluster.
{% endcapture %}
{% capture body %}
## Example use case
An {% glossary_tooltip text="Application Developer" term_id="application-developer" %} wants to use message queuing as part of their application running in a Kubernetes cluster.
However, they do not want to deal with the overhead of setting such a service up and administering it themselves.
Fortunately, there is a cloud provider that offers message queuing as a *Managed Service* through their *Service Broker*.
A {% glossary_tooltip text="Cluster Operator" term_id="cluster-operator" %} can setup Service Catalog and use it to communicate with the cloud provider's {% glossary_tooltip text="Service Broker" term_id="service-broker" %} to provision an instance of the message queuing service and make it available to the application within the Kubernetes cluster.
The {% glossary_tooltip text="Application Developer" term_id="application-developer" %} therefore does not need to concern themselves with the implementation details or management of the message queue.
Their application can simply use it as a service.
## Architecture
Service Catalog uses the [Open Service Broker API](https://github.com/openservicebrokerapi/servicebroker) to communicate with Service Brokers, acting as an intermediary for the Kubernetes API Server in order to negotiate the initial provisioning and retrieve the credentials necessary for the application to use a Managed Service.
It is implemented as an extension API server and a controller manager, using Etcd for storage. It also uses the [aggregation layer](/docs/concepts/api-extension/apiserver-aggregation/) available in Kubernetes 1.7+ to present its API.
<br>
![Service Catalog Architecture](/images/docs/service-catalog-architecture.svg)
### API Resources
Service Catalog installs the `servicecatalog.k8s.io` API and provides the following Kubernetes resources:
* `ClusterServiceBroker`: An in-cluster representation of a Service Broker, encapsulating its server connection details.
These are created and managed by Cluster Operators who wish to use that broker server to make new types of Managed Services available within their cluster.
* `ClusterServiceClass`: A Managed Service offered by a particular Service Broker.
When a new `ClusterServiceBroker` resource is added to the cluster, the Service Catalog controller connects to the Service Broker to obtain a list of available Managed Services. It then creates a new `ClusterServiceClass` resource corresponding to each Managed Service.
* `ClusterServicePlan`: A specific offering of a Managed Service. For example, a Managed Service may have different plans available, such as a free tier or paid tier, or it may have different configuration options, such as using SSD storage or having more resources. Similar to `ClusterServiceClass`, when a new `ClusterServiceBroker` is added to the cluster, the Service Catalog creates a new `ClusterServicePlan` resource corresponding to each Service Plan available for each Managed Service.
* `ServiceInstance`: A provisioned instance of a `ClusterServiceClass`.
These are created by Cluster Operators to make a specific instance of a Managed Service available for use by one or more in-cluster applications.
When a new `ServiceInstance` resource is created, the Service Catalog controller will connect to the appropriate Service Broker and instruct it to provision the service instance.
* `ServiceBinding`: Access credentials to a `ServiceInstance`.
These are created by Cluster Operators who want their applications to make use of a Service `ServiceInstance`.
Upon creation, the Service Catalog controller will create a Kubernetes `Secret` containing connection details and credentials for the Service Instance, which can be mounted into Pods.
### Authentication
Service Catalog supports these methods of authentication:
* Basic (username/password)
* [OAuth 2.0 Bearer Token](https://tools.ietf.org/html/rfc6750)
## Usage
A {% glossary_tooltip text="Cluster Operator" term_id="cluster-operator" %} can use the Service Catalog API Resources to provision Managed Services and make them available within a Kubernetes cluster. The steps involved are:
1. Listing the Managed Services and Service Plans available from a Service Broker.
1. Provisioning a new instance of the Managed Service.
1. Binding to the Managed Service, which returns the connection credentials.
1. Mapping the connection credentials into the application.
### Listing Managed Services and Service Plans
First, a {% glossary_tooltip text="Cluster Operator" term_id="cluster-operator" %} must create a `ClusterServiceBroker` resource within the `servicecatalog.k8s.io` group. This resource contains the URL and connection details necessary to access a Service Broker endpoint.
This is an example of a `ClusterServiceBroker` resource:
```yaml
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ClusterServiceBroker
metadata:
name: cloud-broker
spec:
# Points to the endpoint of a Service Broker. (This example is not a working URL.)
url: https://servicebroker.somecloudprovider.com/v1alpha1/projects/service-catalog/brokers/default
#####
# Additional values can be added here, which may be used to communicate
# with the Service Broker, such as bearer token info or a caBundle for TLS.
#####
```
The following is a sequence diagram illustrating the steps involved in listing Managed Services and Plans available from a Service Broker:
![List Services](/images/docs/service-catalog-list.svg){:height="80%" width="80%"}
1. Once the `ClusterServiceBroker` resource is added to Service Catalog, it triggers a *List Services* call to the external Service Broker.
1. The Service Broker returns a list of available Managed Services and Service Plans, which are cached locally in `ClusterServiceClass` and `ClusterServicePlan` resources.
1. A {% glossary_tooltip text="Cluster Operator" term_id="cluster-operator" %} can then get the list of available Managed Services using the following command:
kubectl get clusterserviceclasses -o=custom-columns=SERVICE\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
It should output a list of service names with a format similar to:
SERVICE NAME EXTERNAL NAME
4f6e6cf6-ffdd-425f-a2c7-3c9258ad2468 cloud-provider-service
... ...
They can also view the Service Plans available using the following command:
kubectl get clusterserviceplans -o=custom-columns=PLAN\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
It should output a list of plan names with a format similar to:
PLAN NAME EXTERNAL NAME
86064792-7ea2-467b-af93-ac9694d96d52 service-plan-name
... ...
### Provisioning a new instance
A {% glossary_tooltip text="Cluster Operator" term_id="cluster-operator" %} can initiate the provisioning of a new instance by creating a `ServiceInstance` resource.
This is an example of a `ServiceInstance` resource:
```yaml
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
name: cloud-queue-instance
namespace: cloud-apps
spec:
# References one of the previously returned services
clusterServiceClassExternalName: cloud-provider-service
clusterServicePlanExternalName: service-plan-name
#####
# Additional parameters can be added here,
# which may be used by the Service Broker.
#####
```
The following sequence diagram illustrates the steps involved in provisioning a new instance of a Managed Service:
![Provision a Service](/images/docs/service-catalog-provision.svg){:height="80%" width="80%"}
1. When the `ServiceInstance` resource is created, Service Catalog initiates a *Provision Instance* call to the external Service Broker.
1. The Service Broker creates a new instance of the Managed Service and returns an HTTP response.
1. A {% glossary_tooltip text="Cluster Operator" term_id="cluster-operator" %} can then check the status of the instance to see if it is ready.
### Binding to a Managed Service
After a new instance has been provisioned, a {% glossary_tooltip text="Cluster Operator" term_id="cluster-operator" %} must bind to the Managed Service to get the connection credentials and service account details necessary for the application to use the service. This is done by creating a `ServiceBinding` resource.
The following is an example of a `ServiceBinding` resource:
```yaml
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
name: cloud-queue-binding
namespace: cloud-apps
spec:
instanceRef:
name: cloud-queue-instance
#####
# Additional information can be added here, such as a secretName or
# service account parameters, which may be used by the Service Broker.
#####
```
The following sequence diagram illustrates the steps involved in binding to a Managed Service instance:
![Bind to a Managed Service](/images/docs/service-catalog-bind.svg){:height="80%" width="80%"}
1. After the `ServiceBinding` is created, Service Catalog makes a *Bind Instance* call to the external Service Broker.
1. The Service Broker enables the application permissions/roles for the appropriate service account.
1. The Service Broker returns the information necessary to connect and access the Managed Service instance. This is provider and service-specific so the information returned may differ between Service Providers and their Managed Services.
### Mapping the connection credentials
After binding, the final step involves mapping the connection credentials and service-specific information into the application.
These pieces of information are stored in secrets that the application in the cluster can access and use to connect directly with the Managed Service.
<br>
![Map connection credentials](/images/docs/service-catalog-map.svg)
#### Pod Configuration File
One method to perform this mapping is to use a declarative Pod configuration.
The following example describes how to map service account credentials into the application. A key called `sa-key` is stored in a volume named `provider-cloud-key`, and the application mounts this volume at `/var/secrets/provider/key.json`. The environment variable `GOOGLE_APPLICATION_CREDENTIALS` is mapped from the value of the mounted file.
```yaml
...
spec:
volumes:
- name: provider-cloud-key
secret:
secretName: sa-key
containers:
...
volumeMounts:
- name: provider-cloud-key
mountPath: /var/secrets/provider
env:
- name: PROVIDER_APPLICATION_CREDENTIALS
value: "/var/secrets/provider/key.json"
```
The following example describes how to map secret values into application environment variables. In this example, the messaging queue topic name is mapped from a secret named `provider-queue-credentials` with a key named `topic` to the environment variable `TOPIC`.
```yaml
...
env:
- name: "TOPIC"
valueFrom:
secretKeyRef:
name: provider-queue-credentials
key: topic
```
{% endcapture %}
{% capture whatsnext %}
* If you are familiar with {% glossary_tooltip text="Helm Charts" term_id="helm-chart" %}, [install Service Catalog using Helm](/docs/tasks/service-catalog/install-service-catalog-using-helm/) into your Kubernetes cluster. Alternatively, you can [install Service Catalog using the SC tool](/docs/tasks/service-catalog/install-service-catalog-using-sc/).
* View [sample service brokers](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers).
* Explore the [kubernetes-incubator/service-catalog](https://github.com/kubernetes-incubator/service-catalog) project.
{% endcapture %}
{% include templates/concept.md %}
+25 -31
View File
@@ -117,7 +117,7 @@ subsets:
- port: 9376
```
NOTE: Endpoint IPs may not be loopback (127.0.0.0/8), link-local
**NOTE:** Endpoint IPs may not be loopback (127.0.0.0/8), link-local
(169.254.0.0/16), or link-local multicast (224.0.0.0/24).
Accessing a `Service` without a selector works the same as if it had a selector.
@@ -151,13 +151,11 @@ its pods, add appropriate selectors or endpoints and change the service `type`.
Every node in a Kubernetes cluster runs a `kube-proxy`. `kube-proxy` is
responsible for implementing a form of virtual IP for `Services` of type other
than `ExternalName`.
In Kubernetes v1.0 the proxy was purely in userspace. In Kubernetes v1.1 an
iptables proxy was added, but was not the default operating mode. Since
Kubernetes v1.2, the iptables proxy is the default.
As of Kubernetes v1.0, `Services` are a "layer 4" (TCP/UDP over IP) construct.
In Kubernetes v1.1 the `Ingress` API was added (beta) to represent "layer 7"
(HTTP) services.
In Kubernetes v1.0, `Services` are a "layer 4" (TCP/UDP over IP) construct, the
proxy was purely in userspace. In Kubernetes v1.1, the `Ingress` API was added
(beta) to represent "layer 7"(HTTP) services, iptables proxy was added too,
and become the default operating mode since Kubernetes v1.2. In Kubernetes v1.9-alpha,
ipvs proxy was added.
### Proxy-mode: userspace
@@ -169,37 +167,20 @@ will be proxied to one of the `Service`'s backend `Pods` (as reported in
`SessionAffinity` of the `Service`. Lastly, it installs iptables rules which
capture traffic to the `Service`'s `clusterIP` (which is virtual) and `Port`
and redirects that traffic to the proxy port which proxies the backend `Pod`.
The net result is that any traffic bound for the `Service`'s IP:Port is proxied
to an appropriate backend without the clients knowing anything about Kubernetes
or `Services` or `Pods`.
By default, the choice of backend is round robin. Client-IP based session affinity
can be selected by setting `service.spec.sessionAffinity` to `"ClientIP"` (the
default is `"None"`), and you can set the max session sticky time by setting the field
`service.spec.sessionAffinityConfig.clientIP.timeoutSeconds` if you have already set
`service.spec.sessionAffinity` to `"ClientIP"` (the default is "10800").
By default, the choice of backend is round robin.
![Services overview diagram for userspace proxy](/images/docs/services-userspace-overview.svg)
### Proxy-mode: iptables
In this mode, kube-proxy watches the Kubernetes master for the addition and
removal of `Service` and `Endpoints` objects. For each `Service` it installs
removal of `Service` and `Endpoints` objects. For each `Service`, it installs
iptables rules which capture traffic to the `Service`'s `clusterIP` (which is
virtual) and `Port` and redirects that traffic to one of the `Service`'s
backend sets. For each `Endpoints` object it installs iptables rules which
select a backend `Pod`.
backend sets. For each `Endpoints` object, it installs iptables rules which
select a backend `Pod`.By default, the choice of backend is random.
By default, the choice of backend is random. Client-IP based session affinity
can be selected by setting `service.spec.sessionAffinity` to `"ClientIP"` (the
default is `"None"`), and you can set the max session sticky time by setting the field
`service.spec.sessionAffinityConfig.clientIP.timeoutSeconds` if you have already set
`service.spec.sessionAffinity` to `"ClientIP"` (the default is "10800").
As with the userspace proxy, the net result is that any traffic bound for the
`Service`'s IP:Port is proxied to an appropriate backend without the clients
knowing anything about Kubernetes or `Services` or `Pods`. This should be
Obviously, iptables need not switch back between userspace and kernelspace, it should be
faster and more reliable than the userspace proxy. However, unlike the
userspace proxier, the iptables proxier cannot automatically retry another
`Pod` if the one it initially selects does not respond, so it depends on
@@ -231,12 +212,21 @@ options for load balancing algorithm, such as:
- nq: never queue
**Note:** ipvs mode assumed IPVS kernel modules are installed on the node
before running kube-proxy. When kube-proxy starts, if proxy mode is ipvs,
before running kube-proxy. When kube-proxy starts with ipvs proxy mode,
kube-proxy would validate if IPVS modules are installed on the node, if
it's not installed kube-proxy will fall back to iptables proxy mode.
![Services overview diagram for ipvs proxy](/images/docs/services-ipvs-overview.svg)
In any of proxy model, any traffic bound for the Services IP:Port is
proxied to an appropriate backend without the clients knowing anything
about Kubernetes or Services or Pods. Client-IP based session affinity
can be selected by setting service.spec.sessionAffinity to "ClientIP"
(the default is "None"), and you can set the max session sticky time by
setting the field service.spec.sessionAffinityConfig.clientIP.timeoutSeconds
if you have already set service.spec.sessionAffinity to "ClientIP"
(the default is “10800”).
## Multi-Port Services
Many `Services` need to expose more than one port. For this case, Kubernetes
@@ -708,6 +698,10 @@ work, and the client IP is not altered.
This same basic flow executes when traffic comes in through a node-port or
through a load-balancer, though in those cases the client IP does get altered.
#### Ipvs
Iptables operations slow down dramatically in large scale cluster e.g 10,000 Services. IPVS is designed for load balancing and based on in-kernel hash tables. So we can achieve performance consistency in large number of services from IPVS-based kube-proxy. Meanwhile, IPVS-based kube-proxy has more sophisticated load balancing algorithms (least conns, locality, weighted, persistence).
## API Object
Service is a top-level resource in the Kubernetes REST API. More details about the
+1 -4
View File
@@ -54,7 +54,7 @@ dynamic provisioning for themselves.
To enable dynamic storage provisioning based on storage class, the cluster administrator
needs to enable the `DefaultStorageClass` [admission controller](/docs/admin/admission-controllers/#defaultstorageclass)
on the API server. This can be done, for example, by ensuring that `DefaultStorageClass` is
among the comma-delimited, ordered list of values for the `--admission-control` flag of
among the comma-delimited, ordered list of values for the `--admission-control` flag of
the API server component. For more information on API server command line flags,
please check [kube-apiserver](/docs/admin/kube-apiserver/) documentation.
@@ -417,8 +417,6 @@ spec:
`PersistentVolumes` binds are exclusive, and since `PersistentVolumeClaims` are namespaced objects, mounting claims with "Many" modes (`ROX`, `RWX`) is only possible within one namespace.
``
## Writing Portable Configuration
If you're writing configuration templates or examples that run on a wide range of clusters
@@ -455,4 +453,3 @@ and need persistent storage, we recommend that you use the following pattern:
default.
At some point, the alpha annotation will cease to have meaning, but the unset
`storageClass` field on the PVC will have the desired effect.
+455 -436
View File
@@ -65,33 +65,118 @@ mount each volume.
Kubernetes supports several types of Volumes:
* `emptyDir`
* `hostPath`
* `gcePersistentDisk`
* `awsElasticBlockStore`
* `nfs`
* `iscsi`
* `fc (fibre channel)`
* `flocker`
* `glusterfs`
* `rbd`
* `cephfs`
* `gitRepo`
* `secret`
* `persistentVolumeClaim`
* `downwardAPI`
* `projected`
* `azureFileVolume`
* `azureDisk`
* `vsphereVolume`
* `Quobyte`
* `PortworxVolume`
* `ScaleIO`
* `StorageOS`
* `azureFile`
* `cephfs`
* `downwardAPI`
* `emptyDir`
* `fc` (fibre channel)
* `flocker`
* `gcePersistentDisk`
* `gitRepo`
* `glusterfs`
* `hostPath`
* `iscsi`
* `local`
* `nfs`
* `persistentVolumeClaim`
* `projected`
* `portworxVolume`
* `quobyte`
* `rbd`
* `scaleIO`
* `secret`
* `storageos`
* `vsphereVolume`
We welcome additional contributions.
### awsElasticBlockStore
An `awsElasticBlockStore` volume mounts an Amazon Web Services (AWS) [EBS
Volume](http://aws.amazon.com/ebs/) into your pod. Unlike
`emptyDir`, which is erased when a Pod is removed, the contents of an EBS
volume are preserved and the volume is merely unmounted. This means that an
EBS volume can be pre-populated with data, and that data can be "handed off"
between pods.
**Important:** You must create an EBS volume using `aws ec2 create-volume` or the AWS API before you can use it.
{: .caution}
There are some restrictions when using an awsElasticBlockStore volume:
* the nodes on which pods are running must be AWS EC2 instances
* those instances need to be in the same region and availability-zone as the EBS volume
* EBS only supports a single EC2 instance mounting a volume
#### Creating an EBS volume
Before you can use an EBS volume with a pod, you need to create it.
```shell
aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2
```
Make sure the zone matches the zone you brought up your cluster in. (And also check that the size and EBS volume
type are suitable for your use!)
#### AWS EBS Example configuration
```yaml
apiVersion: v1
kind: Pod
metadata:
name: test-ebs
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-ebs
name: test-volume
volumes:
- name: test-volume
# This AWS EBS volume must already exist.
awsElasticBlockStore:
volumeID: <volume-id>
fsType: ext4
```
### azureDisk
A `azureDisk` is used to mount a Microsoft Azure [Data Disk](https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-about-disks-vhds/) into a Pod.
More details can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/azure_disk/README.md).
### azureFile
A `azureFile` is used to mount a Microsoft Azure File Volume (SMB 2.1 and 3.0)
into a Pod.
More details can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/azure_file/README.md).
### cephfs
A `cephfs` volume allows an existing CephFS volume to be
mounted into your pod. Unlike `emptyDir`, which is erased when a Pod is
removed, the contents of a `cephfs` volume are preserved and the volume is merely
unmounted. This means that a CephFS volume can be pre-populated with data, and
that data can be "handed off" between pods. CephFS can be mounted by multiple
writers simultaneously.
**Important:** You must have your own Ceph server running with the share exported before you can use it.
{: .caution}
See the [CephFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/cephfs/) for more details.
### downwardAPI
A `downwardAPI` volume is used to make downward API data available to applications.
It mounts a directory and writes the requested data in plain text files.
See the [`downwardAPI` volume example](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) for more details.
### emptyDir
An `emptyDir` volume is first created when a Pod is assigned to a Node, and
@@ -138,6 +223,132 @@ spec:
emptyDir: {}
```
### fc (fibre channel)
An `fc` volume allows an existing fibre channel volume to be mounted in a pod.
You can specify single or multiple target World Wide Names using the parameter
`targetWWNs` in your volume configuration. If multiple WWNs are specified,
targetWWNs expect that those WWNs are from multi-path connections.
**Important:** You must configure FC SAN Zoning to allocate and mask those LUNs (volumes) to the target WWNs beforehand so that Kubernetes hosts can access them.
{: .caution}
See the [FC example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/fibre_channel) for more details.
### flocker
[Flocker](https://clusterhq.com/flocker) is an open-source clustered container data volume manager. It provides management
and orchestration of data volumes backed by a variety of storage backends.
A `flocker` volume allows a Flocker dataset to be mounted into a pod. If the
dataset does not already exist in Flocker, it needs to be first created with the Flocker
CLI or by using the Flocker API. If the dataset already exists it will be
reattached by Flocker to the node that the pod is scheduled. This means data
can be "handed off" between pods as required.
**Important:** You must have your own Flocker installation running before you can use it.
{: .caution}
See the [Flocker example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/flocker) for more details.
### gcePersistentDisk
A `gcePersistentDisk` volume mounts a Google Compute Engine (GCE) [Persistent
Disk](http://cloud.google.com/compute/docs/disks) into your pod. Unlike
`emptyDir`, which is erased when a Pod is removed, the contents of a PD are
preserved and the volume is merely unmounted. This means that a PD can be
pre-populated with data, and that data can be "handed off" between pods.
**Important:** You must create a PD using `gcloud` or the GCE API or UI before you can use it.
{: .caution}
There are some restrictions when using a `gcePersistentDisk`:
* the nodes on which pods are running must be GCE VMs
* those VMs need to be in the same GCE project and zone as the PD
A feature of PD is that they can be mounted as read-only by multiple consumers
simultaneously. This means that you can pre-populate a PD with your dataset
and then serve it in parallel from as many pods as you need. Unfortunately,
PDs can only be mounted by a single consumer in read-write mode - no
simultaneous writers allowed.
Using a PD on a pod controlled by a ReplicationController will fail unless
the PD is read-only or the replica count is 0 or 1.
#### Creating a PD
Before you can use a GCE PD with a pod, you need to create it.
```shell
gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk
```
#### Example pod
```yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
# This GCE PD must already exist.
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
```
### gitRepo
A `gitRepo` volume is an example of what can be done as a volume plugin. It
mounts an empty directory and clones a git repository into it for your pod to
use. In the future, such volumes may be moved to an even more decoupled model,
rather than extending the Kubernetes API for every such use case.
Here is an example for gitRepo volume:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: server
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /mypath
name: git-volume
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
```
### glusterfs
A `glusterfs` volume allows a [Glusterfs](http://www.gluster.org) (an open
source networked filesystem) volume to be mounted into your pod. Unlike
`emptyDir`, which is erased when a Pod is removed, the contents of a
`glusterfs` volume are preserved and the volume is merely unmounted. This
means that a glusterfs volume can be pre-populated with data, and that data can
be "handed off" between pods. GlusterFS can be mounted by multiple writers
simultaneously.
**Important:** You must have your own GlusterFS installation running before you can use it.
{: .caution}
See the [GlusterFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/glusterfs) for more details.
### hostPath
A `hostPath` volume mounts a file or directory from the host node's filesystem
@@ -202,126 +413,6 @@ spec:
type: Directory
```
### gcePersistentDisk
A `gcePersistentDisk` volume mounts a Google Compute Engine (GCE) [Persistent
Disk](http://cloud.google.com/compute/docs/disks) into your pod. Unlike
`emptyDir`, which is erased when a Pod is removed, the contents of a PD are
preserved and the volume is merely unmounted. This means that a PD can be
pre-populated with data, and that data can be "handed off" between pods.
**Important:** You must create a PD using `gcloud` or the GCE API or UI before you can use it.
{: .caution}
There are some restrictions when using a `gcePersistentDisk`:
* the nodes on which pods are running must be GCE VMs
* those VMs need to be in the same GCE project and zone as the PD
A feature of PD is that they can be mounted as read-only by multiple consumers
simultaneously. This means that you can pre-populate a PD with your dataset
and then serve it in parallel from as many pods as you need. Unfortunately,
PDs can only be mounted by a single consumer in read-write mode - no
simultaneous writers allowed.
Using a PD on a pod controlled by a ReplicationController will fail unless
the PD is read-only or the replica count is 0 or 1.
#### Creating a PD
Before you can use a GCE PD with a pod, you need to create it.
```shell
gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk
```
#### Example pod
```yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
# This GCE PD must already exist.
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
```
### awsElasticBlockStore
An `awsElasticBlockStore` volume mounts an Amazon Web Services (AWS) [EBS
Volume](http://aws.amazon.com/ebs/) into your pod. Unlike
`emptyDir`, which is erased when a Pod is removed, the contents of an EBS
volume are preserved and the volume is merely unmounted. This means that an
EBS volume can be pre-populated with data, and that data can be "handed off"
between pods.
**Important:** You must create an EBS volume using `aws ec2 create-volume` or the AWS API before you can use it.
{: .caution}
There are some restrictions when using an awsElasticBlockStore volume:
* the nodes on which pods are running must be AWS EC2 instances
* those instances need to be in the same region and availability-zone as the EBS volume
* EBS only supports a single EC2 instance mounting a volume
#### Creating an EBS volume
Before you can use an EBS volume with a pod, you need to create it.
```shell
aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2
```
Make sure the zone matches the zone you brought up your cluster in. (And also check that the size and EBS volume
type are suitable for your use!)
#### AWS EBS Example configuration
```yaml
apiVersion: v1
kind: Pod
metadata:
name: test-ebs
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-ebs
name: test-volume
volumes:
- name: test-volume
# This AWS EBS volume must already exist.
awsElasticBlockStore:
volumeID: <volume-id>
fsType: ext4
```
### nfs
An `nfs` volume allows an existing NFS (Network File System) share to be
mounted into your pod. Unlike `emptyDir`, which is erased when a Pod is
removed, the contents of an `nfs` volume are preserved and the volume is merely
unmounted. This means that an NFS volume can be pre-populated with data, and
that data can be "handed off" between pods. NFS can be mounted by multiple
writers simultaneously.
**Important:** You must have your own NFS server running with the share exported before you can use it.
{: .caution}
See the [NFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/nfs) for more details.
### iscsi
An `iscsi` volume allows an existing iSCSI (SCSI over IP) volume to be mounted
@@ -341,123 +432,71 @@ simultaneous writers allowed.
See the [iSCSI example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/iscsi) for more details.
### fc (fibre channel)
### local
An `fc` volume allows an existing fibre channel volume to be mounted in a pod.
You can specify single or multiple target World Wide Names using the parameter
`targetWWNs` in your volume configuration. If multiple WWNs are specified,
targetWWNs expect that those WWNs are from multi-path connections.
This volume type is alpha in 1.7.
**Important:** You must configure FC SAN Zoning to allocate and mask those LUNs (volumes) to the target WWNs beforehand so that Kubernetes hosts can access them.
{: .caution}
A `local` volume represents a mounted local storage device such as a disk,
partition or directory.
See the [FC example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/fibre_channel) for more details.
Local volumes can only be used as a statically created PersistentVolume.
### flocker
Compared to HostPath volumes, local volumes can be used in a durable manner
without manually scheduling pods to nodes, as the system is aware of the volume's
node constraints.
[Flocker](https://clusterhq.com/flocker) is an open-source clustered container data volume manager. It provides management
and orchestration of data volumes backed by a variety of storage backends.
However, local volumes are still subject to the availability of the underlying
node and are not suitable for all applications.
A `flocker` volume allows a Flocker dataset to be mounted into a pod. If the
dataset does not already exist in Flocker, it needs to be first created with the Flocker
CLI or by using the Flocker API. If the dataset already exists it will be
reattached by Flocker to the node that the pod is scheduled. This means data
can be "handed off" between pods as required.
The following is an example PersistentVolume spec using a `local` volume:
**Important:** You must have your own Flocker installation running before you can use it.
{: .caution}
See the [Flocker example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/flocker) for more details.
### glusterfs
A `glusterfs` volume allows a [Glusterfs](http://www.gluster.org) (an open
source networked filesystem) volume to be mounted into your pod. Unlike
`emptyDir`, which is erased when a Pod is removed, the contents of a
`glusterfs` volume are preserved and the volume is merely unmounted. This
means that a glusterfs volume can be pre-populated with data, and that data can
be "handed off" between pods. GlusterFS can be mounted by multiple writers
simultaneously.
**Important:** You must have your own GlusterFS installation running before you can use it.
{: .caution}
See the [GlusterFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/glusterfs) for more details.
### rbd
An `rbd` volume allows a [Rados Block
Device](http://ceph.com/docs/master/rbd/rbd/) volume to be mounted into your
pod. Unlike `emptyDir`, which is erased when a Pod is removed, the contents of
a `rbd` volume are preserved and the volume is merely unmounted. This
means that a RBD volume can be pre-populated with data, and that data can
be "handed off" between pods.
**Important:** You must have your own Ceph installation running before you can use RBD.
{: .caution}
A feature of RBD is that it can be mounted as read-only by multiple consumers
simultaneously. This means that you can pre-populate a volume with your dataset
and then serve it in parallel from as many pods as you need. Unfortunately,
RBD volumes can only be mounted by a single consumer in read-write mode - no
simultaneous writers allowed.
See the [RBD example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/rbd) for more details.
### cephfs
A `cephfs` volume allows an existing CephFS volume to be
mounted into your pod. Unlike `emptyDir`, which is erased when a Pod is
removed, the contents of a `cephfs` volume are preserved and the volume is merely
unmounted. This means that a CephFS volume can be pre-populated with data, and
that data can be "handed off" between pods. CephFS can be mounted by multiple
writers simultaneously.
**Important:** You must have your own Ceph server running with the share exported before you can use it.
{: .caution}
See the [CephFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/cephfs/) for more details.
### gitRepo
A `gitRepo` volume is an example of what can be done as a volume plugin. It
mounts an empty directory and clones a git repository into it for your pod to
use. In the future, such volumes may be moved to an even more decoupled model,
rather than extending the Kubernetes API for every such use case.
Here is an example for gitRepo volume:
```yaml
``` yaml
apiVersion: v1
kind: Pod
kind: PersistentVolume
metadata:
name: server
name: example-pv
annotations:
"volume.alpha.kubernetes.io/node-affinity": '{
"requiredDuringSchedulingIgnoredDuringExecution": {
"nodeSelectorTerms": [
{ "matchExpressions": [
{ "key": "kubernetes.io/hostname",
"operator": "In",
"values": ["example-node"]
}
]}
]}
}'
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /mypath
name: git-volume
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
capacity:
storage: 100Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
```
### secret
**Note:** The local PersistentVolume cleanup and deletion requires manual intervention without the external provisioner.
{: .note}
A `secret` volume is used to pass sensitive information, such as passwords, to
pods. You can store secrets in the Kubernetes API and mount them as files for
use by pods without coupling to Kubernetes directly. `secret` volumes are
backed by tmpfs (a RAM-backed filesystem) so they are never written to
non-volatile storage.
For details on the `local` volume type, see the [Local Persistent Storage
user guide](https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume).
**Important:** You must create a secret in the Kubernetes API before you can use it.
### nfs
An `nfs` volume allows an existing NFS (Network File System) share to be
mounted into your pod. Unlike `emptyDir`, which is erased when a Pod is
removed, the contents of an `nfs` volume are preserved and the volume is merely
unmounted. This means that an NFS volume can be pre-populated with data, and
that data can be "handed off" between pods. NFS can be mounted by multiple
writers simultaneously.
**Important:** You must have your own NFS server running with the share exported before you can use it.
{: .caution}
Secrets are described in more detail [here](/docs/user-guide/secrets).
See the [NFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/nfs) for more details.
### persistentVolumeClaim
@@ -469,13 +508,6 @@ iSCSI volume) without knowing the details of the particular cloud environment.
See the [PersistentVolumes example](/docs/concepts/storage/persistent-volumes/) for more
details.
### downwardAPI
A `downwardAPI` volume is used to make downward API data available to applications.
It mounts a directory and writes the requested data in plain text files.
See the [`downwardAPI` volume example](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) for more details.
### projected
A `projected` volume maps several existing volume sources into the same directory.
@@ -564,27 +596,189 @@ Each projected volume source is listed in the spec under `sources`. The
parameters are nearly the same with two exceptions:
* For secrets, the `secretName` field has been changed to `name` to be consistent
with ConfigMap naming.
with ConfigMap naming.
* The `defaultMode` can only be specified at the projected level and not for each
volume source. However, as illustrated above, you can explicitly set the `mode`
for each individual projection.
volume source. However, as illustrated above, you can explicitly set the `mode`
for each individual projection.
### AzureFileVolume
### portworxVolume
A `AzureFileVolume` is used to mount a Microsoft Azure File Volume (SMB 2.1 and 3.0)
into a Pod.
A `portworxVolume` is an elastic block storage layer that runs hyperconverged with
Kubernetes. Portworx fingerprints storage in a server, tiers based on capabilities,
and aggregates capacity across multiple servers. Portworx runs in-guest in virtual
machines or on bare metal Linux nodes.
More details can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/azure_file/README.md).
A `portworxVolume` can be dynamically created through Kubernetes or it can also
be pre-provisioned and referenced inside a Kubernetes pod.
Here is an example pod referencing a pre-provisioned PortworxVolume:
### AzureDiskVolume
```yaml
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# This Portworx volume must already exist.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
```
A `AzureDiskVolume` is used to mount a Microsoft Azure [Data Disk](https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-about-disks-vhds/) into a Pod.
**Important:** Make sure you have an existing PortworxVolume with name `pxvol`
before using it in the pod.
{: .caution}
More details can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/azure_disk/README.md).
More details and examples can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/portworx/README.md).
### quobyte
A `quobyte` volume allows an existing [Quobyte](http://www.quobyte.com) volume to
be mounted into your pod.
**Important:** You must have your own Quobyte setup running with the volumes
created before you can use it.
{: .caution}
See the [Quobyte example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/quobyte) for more details.
### rbd
An `rbd` volume allows a [Rados Block
Device](http://ceph.com/docs/master/rbd/rbd/) volume to be mounted into your
pod. Unlike `emptyDir`, which is erased when a Pod is removed, the contents of
a `rbd` volume are preserved and the volume is merely unmounted. This
means that a RBD volume can be pre-populated with data, and that data can
be "handed off" between pods.
**Important:** You must have your own Ceph installation running before you can use RBD.
{: .caution}
A feature of RBD is that it can be mounted as read-only by multiple consumers
simultaneously. This means that you can pre-populate a volume with your dataset
and then serve it in parallel from as many pods as you need. Unfortunately,
RBD volumes can only be mounted by a single consumer in read-write mode - no
simultaneous writers allowed.
See the [RBD example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/rbd) for more details.
### scaleIO
ScaleIO is a software-based storage platform that can use existing hardware to
create clusters of scalable shared block networked storage. The `scaleIO` volume
plugin allows deployed pods to access existing ScaleIO
volumes (or it can dynamically provision new volumes for persistent volume claims, see
[ScaleIO Persistent Volumes](/docs/concepts/storage/persistent-volumes/#scaleio)).
**Important:** You must have an existing ScaleIO cluster already setup and
running with the volumes created before you can use them.
{: .caution}
The following is an example pod configuration with ScaleIO:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-0
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: pod-0
volumeMounts:
- mountPath: /test-pd
name: vol-0
volumes:
- name: vol-0
scaleIO:
gateway: https://localhost:443/api
system: scaleio
protectionDomain: sd0
storagePool: sp1
volumeName: vol-0
secretRef:
name: sio-secret
fsType: xfs
```
For further detail, please the see the [ScaleIO examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/scaleio).
### secret
A `secret` volume is used to pass sensitive information, such as passwords, to
pods. You can store secrets in the Kubernetes API and mount them as files for
use by pods without coupling to Kubernetes directly. `secret` volumes are
backed by tmpfs (a RAM-backed filesystem) so they are never written to
non-volatile storage.
**Important:** You must create a secret in the Kubernetes API before you can use it.
{: .caution}
Secrets are described in more detail [here](/docs/user-guide/secrets).
### storageOS
A `storageos` volume allows an existing [StorageOS](https://www.storageos.com)
volume to be mounted into your pod.
StorageOS runs as a container within your Kubernetes environment, making local
or attached storage accessible from any node within the Kubernetes cluster.
Data can be replicated to protect against node failure. Thin provisioning and
compression can improve utilization and reduce cost.
At its core, StorageOS provides block storage to containers, accessible via a file system.
The StorageOS container requires 64-bit Linux and has no additional dependencies.
A free developer license is available.
**Important:** You must run the StorageOS container on each node that wants to
access StorageOS volumes or that will contribute storage capacity to the pool.
For installation instructions, consult the
[StorageOS documentation](https://docs.storageos.com).
{: .caution}
```yaml
apiVersion: v1
kind: Pod
metadata:
labels:
name: redis
role: master
name: test-storageos-redis
spec:
containers:
- name: master
image: kubernetes/redis:v1
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master-data
name: redis-data
volumes:
- name: redis-data
storageos:
# The `redis-vol01` volume must already exist within StorageOS in the `default` namespace.
volumeName: redis-vol01
fsType: ext4
```
For more information including Dynamic Provisioning and Persistent Volume Claims, please see the
[StorageOS examples](https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/storageos).
### vsphereVolume
**Prerequisite:** Kubernetes with vSphere Cloud Provider configured. For cloudprovider configuration please refer [vSphere getting started guide](/docs/getting-started-guides/vsphere/).
**Prerequisite:** Kubernetes with vSphere Cloud Provider configured. For cloudprovider
configuration please refer [vSphere getting started guide](/docs/getting-started-guides/vsphere/).
{: .note}
A `vsphereVolume` is used to mount a vSphere VMDK Volume into your Pod. The contents
@@ -638,185 +832,10 @@ spec:
volumePath: "[DatastoreName] volumes/myDisk"
fsType: ext4
```
More examples can be found [here](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere).
### Quobyte
A `Quobyte` volume allows an existing [Quobyte](http://www.quobyte.com) volume to be mounted into your pod.
**Important:** You must have your own Quobyte setup running with the volumes created before you can use it.
{: .caution}
See the [Quobyte example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/quobyte) for more details.
### PortworxVolume
A `PortworxVolume` is an elastic block storage layer that runs hyperconverged with Kubernetes. Portworx fingerprints storage in a
server, tiers based on capabilities, and aggregates capacity across multiple servers. Portworx runs in-guest in virtual machines or on bare metal
Linux nodes.
A `PortworxVolume` can be dynamically created through Kubernetes or it can also be pre-provisioned and referenced inside a Kubernetes pod.
Here is an example pod referencing a pre-provisioned PortworxVolume:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# This Portworx volume must already exist.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
```
**Important:** Make sure you have an existing PortworxVolume with name `pxvol` before using it in the pod.
{: .caution}
More details and examples can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/portworx/README.md).
### ScaleIO
ScaleIO is a software-based storage platform that can use existing hardware to create clusters of scalable
shared block networked storage. The ScaleIO volume plugin allows deployed pods to access existing ScaleIO
volumes (or it can dynamically provision new volumes for persistent volume claims, see
[ScaleIO Persistent Volumes](/docs/concepts/storage/persistent-volumes/#scaleio)).
**Important:** You must have an existing ScaleIO cluster already setup and running with the volumes created before you can use them.
{: .caution}
The following is an example pod configuration with ScaleIO:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-0
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: pod-0
volumeMounts:
- mountPath: /test-pd
name: vol-0
volumes:
- name: vol-0
scaleIO:
gateway: https://localhost:443/api
system: scaleio
protectionDomain: sd0
storagePool: sp1
volumeName: vol-0
secretRef:
name: sio-secret
fsType: xfs
```
For further detail, please the see the [ScaleIO examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/scaleio).
### StorageOS
A `storageos` volume allows an existing [StorageOS](https://www.storageos.com) volume to be mounted into your pod.
StorageOS runs as a container within your Kubernetes environment, making local or attached storage accessible from any node within the Kubernetes cluster. Data can be replicated to protect against node failure. Thin provisioning and compression can improve utilization and reduce cost.
At its core, StorageOS provides block storage to containers, accessible via a file system.
The StorageOS container requires 64-bit Linux and has no additional dependencies. A free developer licence is available.
**Important:** You must run the StorageOS container on each node that wants to access StorageOS volumes or that will contribute storage capacity to the pool. For installation instructions, consult the [StorageOS documentation](https://docs.storageos.com).
{: .caution}
```yaml
apiVersion: v1
kind: Pod
metadata:
labels:
name: redis
role: master
name: test-storageos-redis
spec:
containers:
- name: master
image: kubernetes/redis:v1
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master-data
name: redis-data
volumes:
- name: redis-data
storageos:
# The `redis-vol01` volume must already exist within StorageOS in the `default` namespace.
volumeName: redis-vol01
fsType: ext4
```
For more information including Dynamic Provisioning and Persistent Volume Claims, please see the
[StorageOS examples](https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/storageos).
### local
This volume type is alpha in 1.7.
A `local` volume represents a mounted local storage device such as a disk,
partition or directory.
Local volumes can only be used as a statically created PersistentVolume.
Compared to HostPath volumes, local volumes can be used in a durable manner
without manually scheduling pods to nodes, as the system is aware of the volume's
node constraints.
However, local volumes are still subject to the availability of the underlying
node and are not suitable for all applications.
The following is an example PersistentVolume spec using a `local` volume:
``` yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
annotations:
"volume.alpha.kubernetes.io/node-affinity": '{
"requiredDuringSchedulingIgnoredDuringExecution": {
"nodeSelectorTerms": [
{ "matchExpressions": [
{ "key": "kubernetes.io/hostname",
"operator": "In",
"values": ["example-node"]
}
]}
]}
}'
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
```
**Note:** The local PersistentVolume cleanup and deletion requires manual intervention without the external provisioner.
{: .note}
For details on the `local` volume type, see the [Local Persistent Storage
user guide](https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume).
## Using subPath
Sometimes, it is useful to share one volume for multiple uses in a single pod. The `volumeMounts.subPath`
@@ -129,6 +129,8 @@ labelled as critical, the Daemon pods are created with an additional
Note that all above `NoSchedule` taints above are created only in version 1.8 or later if the alpha feature `TaintNodesByCondition` is enabled.
Also note that the `node-role.kubernetes.io/master` `NoSchedule` toleration specified in the above example is needed on 1.6 or later to schedule on *master* nodes as this is not a default toleration.
## Communicating with Daemon Pods
Some possible patterns for communicating with Pods in a DaemonSet are:
@@ -1,4 +1,4 @@
apiVersion: apps/v1beta2 # for versions before 1.8.0 use apps/v1beta1
apiVersion: apps/v1beta2 # for versions before 1.8.0 use extensions/v1beta1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
@@ -14,6 +14,9 @@ spec:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: gcr.io/google-containers/fluentd-elasticsearch:1.20
@@ -40,7 +40,7 @@ If you create the ReplicaSet and then view the Pod metadata, you can see
OwnerReferences field:
```shell
kubectl create -f https://k8s.io/docs/concepts/abstractions/controllers/my-repset.yaml
kubectl create -f https://k8s.io/docs/concepts/controllers/my-repset.yaml
kubectl get pods --output=yaml
```
@@ -89,7 +89,7 @@ Here are some ideas for how to use Init Containers:
configuration file using Jinja.
More detailed usage examples can be found in the [StatefulSets documentation](/docs/concepts/workloads/controllers/statefulset/)
and the [Production Pods guide](/docs/tasks/#handling-initialization).
and the [Production Pods guide](/docs/tasks/configure-pod-container/configure-pod-initialization/).
### Init Containers in use
+6
View File
@@ -18,6 +18,12 @@ docs, follow the instructions on
**Note:** Kubernetes documentation uses [GitHub Flavored Markdown](https://github.github.com/gfm/).
{: .note}
## Language
Kubernetes documentation uses US English.
## Documentation formatting standards
### Use camel case for API objects
@@ -271,7 +271,7 @@ to pass bridged IPv4 traffic to iptables' chains. This is a requirement for some
please see [here](https://kubernetes.io/docs/concepts/cluster-administration/network-plugins/#network-plugin-requirements).
```shell
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.0/Documentation/kube-flannel.yml
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
```
- For more information about `flannel`, please see [here](https://github.com/coreos/flannel).
+15 -6
View File
@@ -86,15 +86,21 @@ apt-get update
apt-get install -y docker.io
```
or install Docker CE 17.03 from Docker's repositories for Ubuntu or Debian:
or install Docker CE 17.09 from Docker's repositories for Ubuntu or Debian:
```bash
apt-get update && apt-get install -y curl apt-transport-https
apt-get update
apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/docker.list
deb https://download.docker.com/linux/$(lsb_release -si | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable
EOF
apt-get update && apt-get install -y docker-ce=$(apt-cache madison docker-ce | grep 17.03 | head -1 | awk '{print $3}')
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) \
stable"
apt-get update && apt-get install -y docker-ce=$(apt-cache madison docker-ce | grep 17.09 | head -1 | awk '{print $3}')
```
{% endcapture %}
@@ -130,6 +136,9 @@ as Docker (e.g. `cgroupfs`).
{% include tabs.md %}
Refer to the [official Docker installation guides](https://docs.docker.com/engine/installation/)
for more information.
## Installing kubeadm, kubelet and kubectl
You will install these packages on all of your machines:
+2 -2
View File
@@ -55,7 +55,7 @@ a Kubernetes cluster from scratch.
* [OpenShift Online](https://www.openshift.com/features/) provides free hosted access for Kubernetes applications.
* [IBM Bluemix Container Service](https://console.ng.bluemix.net/docs/containers/container_index.html) offers managed Kubernetes clusters with isolation choice, operational tools, integrated security insight into images and containers, and integration with Watson, IoT, and data.
* [IBM Cloud Container Service](https://console.bluemix.net/docs/containers/container_index.html) offers managed Kubernetes clusters with isolation choice, operational tools, integrated security insight into images and containers, and integration with Watson, IoT, and data.
* [Giant Swarm](https://giantswarm.io/product/) offers managed Kubernetes clusters in their own datacenter, on-premises, or on public clouds.
@@ -70,7 +70,7 @@ few commands. These solutions are actively developed and have active community s
* [Azure](/docs/getting-started-guides/azure/)
* [Tectonic by CoreOS](https://coreos.com/tectonic)
* [CenturyLink Cloud](/docs/getting-started-guides/clc/)
* [IBM Bluemix](https://github.com/patrocinio/kubernetes-softlayer)
* [IBM Cloud](https://github.com/patrocinio/kubernetes-softlayer)
* [Stackpoint.io](/docs/getting-started-guides/stackpoint/)
* [KUBE2GO.io](https://kube2go.io/)
* [Madcore.Ai](https://madcore.ai/)
@@ -136,7 +136,7 @@ import (
// creates the clientset
clientset, _:= kubernetes.NewForConfig(config)
// access the API to list pods
pods, _:= clientset.Core().Pods("").List(v1.ListOptions{})
pods, _:= clientset.CoreV1().Pods("").List(v1.ListOptions{})
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
...
```
@@ -17,7 +17,7 @@ can develop their features independantly from the core Kubernetes release cycles
Before going into how to build your own cloud controller manager, some background on how it works under the hood is helpful. The cloud controller manager is code from `kube-controller-manager` utilizing Go interfaces to allow implementations from any cloud to be plugged in. Most of the scaffolding and generic controller implementations will be in core, but it will always exec out to the cloud interfaces it is provided, so long as the [cloud provider interface](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/cloud.go#L29-L50) is satisifed.
To dive a little deeper into implementation details, all cloud controller managers will import packages from Kubernetes core, the only difference being each project will register their own cloud providers by calling [cloudprovider.RegisterCloudProvier](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/plugins.go#L42-L52) where a global variable of available cloud providers is updated.
To dive a little deeper into implementation details, all cloud controller managers will import packages from Kubernetes core, the only difference being each project will register their own cloud providers by calling [cloudprovider.RegisterCloudProvider](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/plugins.go#L42-L52) where a global variable of available cloud providers is updated.
## Developing
@@ -67,7 +67,7 @@ status:
services.nodeports: "0"
```
## Create a PersistentVolumeClaim:
## Create a PersistentVolumeClaim
Here is the configuration file for a PersistentVolumeClaim object:
@@ -92,7 +92,7 @@ NAME STATUS
pvc-quota-demo Pending
```
## Attempt to create a second PersistentVolumeClaim:
## Attempt to create a second PersistentVolumeClaim
Here is the configuration file for a second PersistentVolumeClaim:
@@ -36,7 +36,9 @@ The data source corresponds to a key-value pair in the ConfigMap, where
* key = the file name or the key you provided on the command line, and
* value = the file contents or the literal value you provided on the command line.
You can use [`kubectl describe`](/docs/user-guide/kubectl/{{page.version}}/#describe) or [`kubectl get`](/docs/user-guide/kubectl/{{page.version}}/#get) to retrieve information about a ConfigMap. The former shows a summary of the ConfigMap, while the latter returns the full contents of the ConfigMap.
You can use [`kubectl describe`](/docs/user-guide/kubectl/{{page.version}}/#describe) or
[`kubectl get`](/docs/user-guide/kubectl/{{page.version}}/#get) to retrieve information
about a ConfigMap.
### Create ConfigMaps from directories
@@ -16,33 +16,12 @@ your pods. But there are a number of ways to get even more information about you
For this example we'll use a Deployment to create two pods, similar to the earlier example.
```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
```
{% include code.html language="yaml" file="nginx-dep.yaml" ghlink="/docs/tasks/debug-application-cluster/nginx-dep.yaml" %}
Copy this to a file *./my-nginx-dep.yaml*
Create deployment by running following command:
```shell
$ kubectl create -f ./my-nginx-dep.yaml
$ kubectl create -f https://k8s.io/docs/tasks/debug-application-cluster/nginx-dep.yaml
deployment "nginx-deployment" created
```
@@ -1,9 +1,9 @@
apiVersion: apps/v1beta1
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
replicas: 2
template:
metadata:
labels:
@@ -11,6 +11,10 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
@@ -371,44 +371,35 @@ For more information see
## Adding a cluster to a federation
Once you've deployed a federation control plane, you'll need to make
that control plane aware of the clusters it should manage. You can add
a cluster to your federation by using the [`kubefed join`](/docs/admin/kubefed_join/)
command. A new context will have been added to your kubeconfig named `fellowship`
(after the name of your federation). To join clusters into the federation, you will
need to change the context.
After you've deployed a federation control plane, you'll need to make that control plane aware of the clusters it should manage.
```
kubectl config use-context fellowship
```
To join clusters into the federation:
To use `kubefed join`, you'll need to provide the name of the cluster
you want to add to the federation, and the `--host-cluster-context`
for the federation control plane's host cluster.
1. Change the context:
> Note: The name that you provide to the `join` command is used as the
joining cluster's identity in federation. This name should adhere to
the rules described in the
[identifiers doc](/docs/concepts/overview/working-with-objects/names/). If the context
corresponding to your joining cluster conforms to these rules then you
can use the same name in the join command. Otherwise, you will have to
choose a different name for your cluster's identity. For more
information, please see the
[naming rules and customization](#naming-rules-and-customization)
section below.
kubectl config use-context fellowship
The following example command adds the cluster `gondor` to the
federation running on host cluster `rivendell`:
1. If you are using a managed cluster service, allow the service to access the cluster. To do this, create a `clusterrolebinding` for the account associated with your cluster service:
```
kubefed join gondor --host-cluster-context=rivendell
```
kubectl create clusterrolebinding <your_user>-cluster-admin-binding --clusterrole=cluster-admin --user=<your_user>@example.org --context=<joining_cluster_context
1. Join the cluster to the federation, using `kubefed join`, and make sure you provide the following:
* The name of the cluster that you are joining to the federation
* `--host-cluster-context`, the kubeconfig context for the host cluster
For example, this command adds the cluster `gondor` to the federation running on host cluster `rivendell`:
```
kubefed join gondor --host-cluster-context=rivendell
```
A new context has now been added to your kubeconfig named `fellowship` (after the name of your federation).
> Note: The name that you provide to the `join` command is used as the joining cluster's identity in federation. If this name adheres to the rules described in the [identifiers doc](/docs/concepts/overview/working-with-objects/names/). If the context
corresponding to your joining cluster conforms to these rules then you can use the same name in the join command. Otherwise, you will have to choose a different name for your cluster's identity.
> Note: Kubernetes requires that you manually join clusters to a
federation because the federation control plane manages only those
clusters that it is responsible for managing. Adding a cluster tells
the federation control plane that it is responsible for managing that
cluster.
### Naming rules and customization
@@ -37,7 +37,7 @@ username and password:
1. Create the Secret
kubectl create -f secret.yaml
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret.yaml
**Note:** If you want to skip the Base64 encoding step, you can create a Secret
by using the `kubectl create secret` command:
@@ -81,7 +81,7 @@ Here is a configuration file you can use to create a Pod:
1. Create the Pod:
kubectl create -f secret-pod.yaml
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-pod.yaml
1. Verify that your Pod is running:
@@ -128,7 +128,7 @@ Here is a configuration file you can use to create a Pod:
1. Create the Pod:
kubectl create -f secret-envars-pod.yaml
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-envars-pod.yaml
1. Verify that your Pod is running:
@@ -10,7 +10,7 @@ metadata:
spec:
containers:
- name: website
image: ecorp/website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
@@ -2,7 +2,6 @@ apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
namespace: myns
spec:
selector:
matchLabels:
@@ -8,7 +8,7 @@ metadata:
spec:
containers:
- name: website
image: ecorp/website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
@@ -2,7 +2,6 @@ apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
namespace: myns
spec:
selector:
matchLabels:
@@ -10,7 +10,7 @@ metadata:
spec:
containers:
- name: website
image: ecorp/website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
@@ -11,7 +11,7 @@ metadata:
spec:
containers:
- name: website
image: ecorp/website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
@@ -8,7 +8,7 @@ metadata:
spec:
containers:
- name: website
image: ecorp/website
image: nginx
ports:
- containerPort: 80
@@ -2,7 +2,6 @@ apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
namespace: myns
spec:
selector:
matchLabels:
@@ -2,7 +2,6 @@ apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: proxy
namespace: myns
spec:
selector:
matchLabels:
@@ -20,18 +20,50 @@ You can get an overview of PodPresets at
This is a simple example to show how a Pod spec is modified by the Pod
Preset.
**User submitted pod spec:**
{% include code.html language="yaml" file="podpreset-preset.yaml" ghlink="/docs/tasks/inject-data-application/podpreset-preset.yaml" %}
Create the PodPreset:
```shell
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/podpreset-preset.yaml
```
Examine the created PodPreset:
```shell
$ kubectl get podpreset
NAME AGE
allow-database 1m
```
The new PodPreset will act upon any pod that has label `role: frontend`.
{% include code.html language="yaml" file="podpreset-pod.yaml" ghlink="/docs/tasks/inject-data-application/podpreset-pod.yaml" %}
**Example Pod Preset:**
Create a pod:
{% include code.html language="yaml" file="podpreset-preset.yaml" ghlink="/docs/tasks/inject-data-application/podpreset-preset.yaml" %}
```shell
$ kubectl create -f https://k8s.io/docs/tasks/inject-data-application/podpreset-pod.yaml
```
List the running Pods:
```shell
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
website 1/1 Running 0 4m
```
**Pod spec after admission controller:**
{% include code.html language="yaml" file="podpreset-merged.yaml" ghlink="/docs/tasks/inject-data-application/podpreset-merged.yaml" %}
To see above output, run the following command:
```shell
$ kubectl get pod website -o yaml
```
### Pod Spec with `ConfigMap` Example
This is an example to show how a Pod spec is modified by the Pod Preset
@@ -113,7 +145,7 @@ when there is a conflict.
**If we run `kubectl describe...` we can see the event:**
```
```shell
$ kubectl describe ...
....
Events:
@@ -0,0 +1,100 @@
---
title: Install Service Catalog using Helm
approvers:
- chenopis
---
{% capture overview %}
{% glossary_definition term_id="service-catalog" length="long" %}
Use [Helm](https://helm.sh/) to install Service Catalog on your Kubernetes cluster. Up to date information on this process can be found at the [kubernetes-incubator/service-catalog](https://github.com/kubernetes-incubator/service-catalog/blob/master/docs/install.md) repo.
{% endcapture %}
{% capture prerequisites %}
* Understand the key concepts of [Service Catalog](/docs/concepts/service-catalog/).
* Service Catalog requires a Kubernetes cluster running version 1.7 or higher.
* You must have a Kubernetes cluster with cluster DNS enabled.
* If you are using a cloud-based Kubernetes cluster or {% glossary_tooltip text="Minikube" term_id="minikube" %}, you may already have cluster DNS enabled.
* If you are using `hack/local-up-cluster.sh`, ensure that the `KUBE_ENABLE_CLUSTER_DNS` environment variable is set, then run the install script.
* [Install and setup kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) v1.7 or higher. Make sure it is configured to connect to the Kubernetes cluster.
* Install [Helm](http://helm.sh/) v2.7.0 or newer.
* Follow the [Helm install instructions](https://github.com/kubernetes/helm/blob/master/docs/install.md).
* If you already have an appropriate version of Helm installed, execute `helm init` to install Tiller, the server-side component of Helm.
{% endcapture %}
{% capture steps %}
## Add the service-catalog Helm repository
Once Helm is installed, add the *service-catalog* Helm repository to your local machine by executing the following command:
```shell
helm repo add svc-cat https://svc-catalog-charts.storage.googleapis.com
```
Check to make sure that it installed successfully by executing the following command:
```shell
helm search service-catalog
```
If the installation was successful, the command should output the following:
```
NAME VERSION DESCRIPTION
svc-cat/catalog 0.0.1 service-catalog API server and controller-manag...
```
## Enable RBAC
Your Kubernetes cluster must have RBAC enabled, which requires your Tiller Pod(s) to have `cluster-admin` access.
If you are using {% glossary_tooltip text="Minikube" term_id="minikube" %}, run the `minikube start` command with the following flag:
```shell
minikube start --extra-config=apiserver.Authorization.Mode=RBAC
```
If you are using `hack/local-up-cluster.sh`, set the `AUTHORIZATION_MODE` environment variable with the following values:
```
AUTHORIZATION_MODE=Node,RBAC hack/local-up-cluster.sh -O
```
By default, `helm init` installs the Tiller Pod into the `kube-system` namespace, with Tiller configured to use the `default` service account.
**NOTE:** If you used the `--tiller-namespace` or `--service-account` flags when running `helm init`, the `--serviceaccount` flag in the following command needs to be adjusted to reference the appropriate namespace and ServiceAccount name.
{: .note}
Configure Tiller to have `cluster-admin` access:
```shell
kubectl create clusterrolebinding tiller-cluster-admin \
--clusterrole=cluster-admin \
--serviceaccount=kube-system:default
```
## Install Service Catalog in your Kubernetes cluster
Install Service Catalog from the root of the Helm repository using the following command:
```shell
helm install svc-cat/catalog \
--name catalog --namespace catalog
```
{% endcapture %}
{% capture whatsnext %}
* View [sample service brokers](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers).
* Explore the [kubernetes-incubator/service-catalog](https://github.com/kubernetes-incubator/service-catalog) project.
{% endcapture %}
{% include templates/task.md %}
@@ -0,0 +1,77 @@
---
title: Install Service Catalog using SC
approvers:
- chenopis
---
{% capture overview %}
{% glossary_definition term_id="service-catalog" length="long" %}
Use the [Service Catalog Installer](https://github.com/GoogleCloudPlatform/k8s-service-catalog#installation) tool to easily install or uninstall Service Catalog on your Kubernetes cluster. This CLI tool is installed as `sc` in your local environment.
{% endcapture %}
{% capture prerequisites %}
* Understand the key concepts of [Service Catalog](/docs/concepts/service-catalog/).
* Install [Go 1.6+](https://golang.org/dl/) and set the `GOPATH`.
* Install the [cfssl](https://github.com/cloudflare/cfssl) tool needed for generating SSL artifacts.
* Service Catalog requires Kubernetes version 1.7+.
* [Install and setup kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) so that it is configured to connect to a Kubernetes v1.7+ cluster.
* The kubectl user must be bound to the *cluster-admin* role for it to install Service Catalog. To ensure that this is true, run the following command:
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=<user-name>
{% endcapture %}
{% capture steps %}
## Install `sc` in your local environment
Install the `sc` CLI tool using the `go get` command:
```Go
go get github.com/GoogleCloudPlatform/k8s-service-catalog/installer/cmd/sc
```
After running the above command, `sc` should be installed in your `GOPATH/bin` directory.
## Install Service Catalog in your Kubernetes cluster
First, verify that all dependencies have been installed. Run:
```shell
sc check
```
If the check is successful, it should return:
```
Dependency check passed. You are good to go.
```
Next, run the install command and specify the `storageclass` that you want to use for the backup:
```shell
sc install --etcd-backup-storageclass "standard"
```
## Uninstall Service Catalog
If you would like to uninstall Service Catalog from your Kubernetes cluster using the `sc` tool, run:
```shell
sc uninstall
```
{% endcapture %}
{% capture whatsnext %}
* View [sample service brokers](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers).
* Explore the [kubernetes-incubator/service-catalog](https://github.com/kubernetes-incubator/service-catalog) project.
{% endcapture %}
{% include templates/task.md %}
@@ -100,7 +100,7 @@ Open a command terminal, and use
manifest.
```shell
kubectl apply -f https://k8s.io/docs/tutorials/stateful-application/zookeeper.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/docs/tutorials/stateful-application/zookeeper.yaml
```
This creates the `zk-hs` Headless Service, the `zk-cs` Service,
+11
View File
@@ -264,6 +264,17 @@ $ kubectl describe pods <rc-name>
$ kubectl describe pods --include-uninitialized=false
```
**Note:** The `kubectl get` command is usually used for retrieving one or more
resources of the same resource type. It features a rich set of flags that allows
you to customize the output format using the `-o` or `--output` flag, for example.
You can specify the `-w` or `--watch` flag to start watching updates to a particular
object. The `kubectl describe` command is more focused on describing the many
related aspects of a specified resource. It may invoke several API calls to the
API server to build a view for the user. For example, the `kubectl describe node`
command retrieves not only the information about the node, but also a summary of
the pods running on it, the events generated for the node etc.
{: .note}
`kubectl delete` - Delete resources either from a file, stdin, or specifying label selectors, names, resource selectors, or resources.
```shell
+2 -2
View File
@@ -97,8 +97,8 @@ volumes:
```yaml
volumeMounts:
# name must match the volume name below
- name: redis-persistent-storage
   # name must match the volume name defined in volumes
   - name: redis-persistent-storage
# mount path within the container
mountPath: /data/redis
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="-1 -1 841 457" width="841pt" height="457pt" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata> Produced by OmniGraffle 7.5
<dc:date>2017-11-17 22:47:47 +0000</dc:date>
</metadata>
<defs>
<font-face font-family="Arial" font-size="16" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="16" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="14" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="14" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="12" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" viewBox="-1 -3 7 6" markerWidth="7" markerHeight="6" color="gray">
<g>
<path d="M 4.8 0 L 0 -1.8 L 0 1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_2" viewBox="-6 -3 7 6" markerWidth="7" markerHeight="6" color="gray">
<g>
<path d="M -4.8 0 L 0 1.8 L 0 -1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_3" viewBox="-1 -3 7 6" markerWidth="7" markerHeight="6" color="gray">
<g>
<path d="M 4.8 0 L 0 -1.8 L 0 1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_4" viewBox="-6 -3 7 6" markerWidth="7" markerHeight="6" color="gray">
<g>
<path d="M -4.8 0 L 0 1.8 L 0 -1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<font-face font-family="Arial" font-size="12" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
</defs>
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<title>architecture</title>
<g>
<title>Layer 1</title>
<path d="M 0 0 L 600 0 L 600 420 L 0 420 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/>
<rect x="640" y="0" width="200" height="280" fill="#d9d9d9"/>
<text transform="translate(650 30)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" fill="black" x="30.421875" y="14" textLength="109.36719">Service Broker </tspan>
<tspan font-family="Arial" font-size="16" font-weight="500" fill="black" x="138.90625" y="14" textLength="10.671875">A</tspan>
</text>
<rect x="10" y="10" width="170" height="400" fill="#4285f5"/>
<text transform="translate(20 30)" fill="white">
<tspan font-family="Arial" font-size="16" font-weight="bold" fill="white" x="34.53125" y="14" textLength="80.9375">API Server</tspan>
</text>
<rect x="215" y="10" width="170" height="190" fill="#4285f5"/>
<text transform="translate(227 30)" fill="white">
<tspan font-family="Arial" font-size="16" font-weight="bold" fill="white" x="12.972656" y="14" textLength="120.05469">Service Catalog</tspan>
<tspan font-family="Arial" font-size="14" font-weight="bold" fill="white" x=".23828125" y="62.52344" textLength="145.52344">servicecatalog.k8s.io:</tspan>
<tspan font-family="Arial" font-size="14" font-weight="500" fill="white" x="0" y="94.98145" textLength="132.26172">ClusterServiceBroker</tspan>
<tspan font-family="Arial" font-size="14" font-weight="500" fill="white" x="0" y="111.43945" textLength="126.03418">ClusterServiceClass</tspan>
<tspan font-family="Arial" font-size="14" font-weight="500" fill="white" x="0" y="127.89746" textLength="119.04785">ClusterServicePlan</tspan>
<tspan font-family="Arial" font-size="14" font-weight="500" fill="white" x="0" y="144.35547" textLength="99.60645">ServiceInstance</tspan>
<tspan font-family="Arial" font-size="14" font-weight="500" fill="white" x="0" y="160.81348" textLength="93.38574">ServiceBinding</tspan>
</text>
<rect x="420" y="220" width="170" height="190" fill="#4285f5"/>
<text transform="translate(430 240)" fill="white">
<tspan font-family="Arial" font-size="16" font-weight="bold" fill="white" x="31.445312" y="14" textLength="87.10938">Application</tspan>
</text>
<rect x="640" y="300" width="200" height="40" fill="#d9d9d9"/>
<text transform="translate(650 311.23828)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" fill="black" x="82" y="14" textLength="16"></tspan>
</text>
<rect x="640" y="360" width="200" height="60" fill="#d9d9d9"/>
<text transform="translate(650 381.2383)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" x="30.429688" y="14" textLength="119.14062">Service Broker Z</tspan>
</text>
<rect x="650" y="150" width="180" height="40" fill="white"/>
<text transform="translate(660 161.23828)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" x="11.070312" y="14" textLength="137.85938">Managed Service 2</tspan>
</text>
<rect x="650" y="230" width="180" height="40" fill="white"/>
<text transform="translate(660 241.23828)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" x="9.742188" y="14" textLength="140.51562">Managed Service N</tspan>
</text>
<rect x="650" y="100" width="180" height="40" fill="white"/>
<text transform="translate(660 111.23828)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" x="11.070312" y="14" textLength="137.85938">Managed Service 1</tspan>
</text>
<path d="M 384.9481 39.49993 L 410.0271 19.566032 L 410.00054 29.631994 L 614.9472 30.172747 L 614.9738 20.106784 L 639.9472 40.172747 L 614.86825 60.106645 L 614.8948 50.040683 L 409.9481 49.49993 L 409.92156 59.56589 Z" fill="gray"/>
<text transform="translate(421.804 32.87919) rotate(-.1511748)" fill="white">
<tspan font-family="Arial" font-size="12" font-weight="500" fill="white" x="23.927734" y="11" textLength="114.71484">Open Service Broker </tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" fill="white" x="137.98047" y="11" textLength="19.341797">API</tspan>
</text>
<text transform="translate(455 58.91113)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x="0" y="11" textLength="68.021484">List Services</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" x="0" y="25.392578" textLength="98.05078">Provision Instance</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" x="0" y="39.785156" textLength="72.71484">Bind Instance</tspan>
</text>
<line x1="602.9" y1="249.5" x2="637.1" y2="249.5" marker-end="url(#FilledArrow_Marker)" marker-start="url(#FilledArrow_Marker_2)" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<rect x="650" y="200" width="180" height="20" fill="white"/>
<text transform="translate(655 201.23828)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" x="77" y="14" textLength="16"></tspan>
</text>
<line x1="192.9" y1="39.33634" x2="202.1" y2="39.33634" marker-end="url(#FilledArrow_Marker_3)" marker-start="url(#FilledArrow_Marker_4)" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path d="M 300 212.9 L 300 215.9 L 300 315.5 L 369.5 315.5 L 404.1 315 L 407.1 315" marker-end="url(#FilledArrow_Marker)" marker-start="url(#FilledArrow_Marker_2)" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(307.63672 323.3037)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" fill="black" x=".14257812" y="11" textLength="72.71484">Bind Instance</tspan>
</text>
<rect x="430" y="285" width="150" height="60" fill="white"/>
<text transform="translate(440 293.41113)" fill="#383838">
<tspan font-family="Arial" font-size="12" font-weight="bold" fill="#383838" x="0" y="11" textLength="40.6875">Secret:</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" fill="#383838" x="0" y="25.392578" textLength="124.74023">Connection Credentials</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" fill="#383838" x="0" y="39.785156" textLength="80.02734">Service Details</tspan>
</text>
<text transform="translate(259 432.2383)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" x=".08203125" y="14" textLength="81.83594">Kubernetes</tspan>
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

+115
View File
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="71 1472 560 377" width="560pt" height="377pt" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata> Produced by OmniGraffle 7.5
<dc:date>2017-11-17 22:45:14 +0000</dc:date>
</metadata>
<defs>
<filter id="Shadow" filterUnits="userSpaceOnUse">
<feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="1.308"/>
<feOffset in="blur" result="offset" dx="0" dy="2"/>
<feFlood flood-color="black" flood-opacity=".5" result="flood"/>
<feComposite in="flood" in2="offset" operator="in"/>
</filter>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" viewBox="-1 -6 14 12" markerWidth="14" markerHeight="12" color="black">
<g>
<path d="M 11.428568 0 L 0 -4.285713 L 0 4.285713 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<font-face font-family="Arial" font-size="12" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.68359" underline-thickness="49.316406" slope="0" x-height="522.9492" cap-height="717.28516" ascent="770.0195" descent="-229.98047" font-weight="500">
<font-face-src>
<font-face-name name="Helvetica"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="12" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="16" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
</defs>
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<title>V2b</title>
<g>
<title>Layer 1</title>
<g>
<xl:use xl:href="#id126_Graphic" filter="url(#Shadow)"/>
<xl:use xl:href="#id134_Graphic" filter="url(#Shadow)"/>
<xl:use xl:href="#id189_Graphic" filter="url(#Shadow)"/>
</g>
<line x1="118.75" y1="1497.456" x2="118.75" y2="1847.456" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<line x1="324.25" y1="1497.456" x2="324.25" y2="1847.456" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<line x1="529.75" y1="1497.456" x2="529.75" y2="1847.456" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<line x1="341.25" y1="1575.8496" x2="502.3641" y2="1618.443" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="386.2558" y="1586.219" width="83" height="25" fill="white"/>
<text transform="translate(391.2558 1591.5227)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".14257812" y="11" textLength="72.71484">Bind Instance</tspan>
</text>
<line x1="515.25" y1="1657.9107" x2="350.17202" y2="1699.6439" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="384.2893" y="1662.544" width="71" height="39" fill="white"/>
<text transform="translate(389.2893 1667.6514)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".14550781" y="11" textLength="60.708984">Connection</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" x=".48535156" y="25.392578" textLength="60.0293">Information</tspan>
</text>
<rect x="279.25" y="1710.5152" width="91" height="38" fill="white"/>
<text transform="translate(284.25 1715.5152)" fill="black">
<tspan font-family="Helvetica" font-size="12" font-weight="500" x=".47753906" y="11" textLength="80.04492">ServiceBinding</tspan>
<tspan font-family="Helvetica" font-size="12" font-weight="500" x="14.821289" y="25" textLength="51.35742">Resource</tspan>
</text>
<rect x="279.25" y="1538.0866" width="91" height="38" fill="white"/>
<text transform="translate(284.25 1543.0866)" fill="black">
<tspan font-family="Helvetica" font-size="12" font-weight="500" x=".47753906" y="11" textLength="80.04492">ServiceBinding</tspan>
<tspan font-family="Helvetica" font-size="12" font-weight="500" x="14.821289" y="25" textLength="51.35742">Resource</tspan>
</text>
<line x1="130" y1="1556.5866" x2="260.87955" y2="1557.4745" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="279" y="1472.5" width="101" height="39" fill="white"/>
<text transform="translate(284 1477.6074)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".4794922" y="11" textLength="90.04102">Service Catalog</tspan>
<tspan font-family="Arial" font-size="12" font-weight="bold" x="15.148438" y="25.392578" textLength="60.703125">API Server</tspan>
</text>
<rect x="488" y="1472.5" width="95" height="25" fill="white"/>
<text transform="translate(493 1477.8037)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".13964844" y="11" textLength="84.7207">Service Broker</tspan>
</text>
<rect x="71.5" y="1472.5" width="106" height="25" fill="white"/>
<text transform="translate(76.5 1477.8037)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".32226562" y="11" textLength="95.35547">Cluster Operator</tspan>
</text>
<g id="id126_Graphic">
<rect x="408.7893" y="1556.5866" width="22" height="25" fill="white"/>
<rect x="408.7893" y="1556.5866" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(413.7893 1561.8904)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">1.</tspan>
</text>
</g>
<g id="id134_Graphic">
<rect x="408.7893" y="1702.9107" width="22" height="25" fill="white"/>
<rect x="408.7893" y="1702.9107" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(413.7893 1708.2144)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">3.</tspan>
</text>
</g>
<path d="M 558 1619.956 L 617.5 1619.956 C 624.538 1619.956 630.25 1629.476 630.25 1641.206 C 630.25 1652.936 624.538 1662.456 617.5 1662.456 L 558 1662.456 C 550.962 1662.456 545.25 1652.936 545.25 1641.206 C 545.25 1629.476 550.962 1619.956 558 1619.956" fill="white"/>
<path d="M 558 1619.956 L 617.5 1619.956 C 624.538 1619.956 630.25 1629.476 630.25 1641.206 C 630.25 1652.936 624.538 1662.456 617.5 1662.456 L 558 1662.456 C 550.962 1662.456 545.25 1652.936 545.25 1641.206 C 545.25 1629.476 550.962 1619.956 558 1619.956" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(558.75 1632.4443)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="bold" x=".53125" y="14" textLength="56.9375">Service</tspan>
</text>
<g id="id189_Graphic">
<rect x="576.75" y="1586.3496" width="22" height="25" fill="white"/>
<rect x="576.75" y="1586.3496" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(581.75 1591.6533)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">2.</tspan>
</text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

+136
View File
@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="66 512 566 375" width="566pt" height="375pt" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata> Produced by OmniGraffle 7.5
<dc:date>2017-11-17 22:45:14 +0000</dc:date>
</metadata>
<defs>
<filter id="Shadow" filterUnits="userSpaceOnUse">
<feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="1.308"/>
<feOffset in="blur" result="offset" dx="0" dy="2"/>
<feFlood flood-color="black" flood-opacity=".5" result="flood"/>
<feComposite in="flood" in2="offset" operator="in"/>
</filter>
<font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.68359" underline-thickness="49.316406" slope="0" x-height="522.9492" cap-height="717.28516" ascent="770.0195" descent="-229.98047" font-weight="500">
<font-face-src>
<font-face-name name="Helvetica"/>
</font-face-src>
</font-face>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" viewBox="-1 -6 14 12" markerWidth="14" markerHeight="12" color="black">
<g>
<path d="M 11.428568 0 L 0 -4.285713 L 0 4.285713 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<font-face font-family="Arial" font-size="12" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="12" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="13" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="11" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
</defs>
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<title>V2b</title>
<g>
<title>Layer 1</title>
<g>
<xl:use xl:href="#id114_Graphic" filter="url(#Shadow)"/>
<xl:use xl:href="#id115_Graphic" filter="url(#Shadow)"/>
<xl:use xl:href="#id66_Graphic" filter="url(#Shadow)"/>
</g>
<line x1="118.75" y1="535.5" x2="118.75" y2="885.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<line x1="324.25" y1="535.5" x2="324.25" y2="885.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<rect x="263.75" y="704.522" width="122" height="38" fill="white"/>
<text transform="translate(268.75 709.522)" fill="black">
<tspan font-family="Helvetica" font-size="12" font-weight="500" x="1.9853516" y="11" textLength="111.36328">ClusterServiceClass </tspan>
<tspan font-family="Helvetica" font-size="12" font-weight="500" x="30.32129" y="25" textLength="51.35742">Resource</tspan>
</text>
<line x1="529.75" y1="535.5" x2="529.75" y2="885.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<line x1="336.2558" y1="619.1546" x2="506.0406" y2="674.8217" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<line x1="515.25" y1="710.9325" x2="350.17202" y2="752.6657" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="273.75" y="512.5" width="101" height="39" fill="white"/>
<text transform="translate(278.75 517.6074)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".4794922" y="11" textLength="90.04102">Service Catalog</tspan>
<tspan font-family="Arial" font-size="12" font-weight="bold" x="15.148438" y="25.392578" textLength="60.703125">API Server</tspan>
</text>
<rect x="482.75" y="512.5" width="95" height="25" fill="white"/>
<text transform="translate(487.75 517.8037)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".13964844" y="11" textLength="84.7207">Service Broker</tspan>
</text>
<rect x="391.18543" y="637.6151" width="79" height="25" fill="white"/>
<text transform="translate(396.18543 642.9188)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".4892578" y="11" textLength="68.021484">List Services</tspan>
</text>
<rect x="261.0526" y="580.1922" width="124" height="39" fill="white"/>
<text transform="translate(266.0526 585.2996)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".31640625" y="11" textLength="113.36719">ClusterServiceBroker</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" x="31.32129" y="25.392578" textLength="51.35742">Resource</tspan>
</text>
<line x1="132.88842" y1="754.9325" x2="248.85003" y2="755.8099" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<line x1="311" y1="791.5658" x2="145.92202" y2="833.299" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="66.25" y="512.5" width="106" height="25" fill="white"/>
<text transform="translate(71.25 517.8037)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".32226562" y="11" textLength="95.35547">Cluster Operator</tspan>
</text>
<g id="id114_Graphic">
<rect x="422.1116" y="748.5" width="22" height="25" fill="white"/>
<rect x="422.1116" y="748.5" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(427.1116 753.8037)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">2.</tspan>
</text>
</g>
<g id="id115_Graphic">
<rect x="211" y="830.5" width="22" height="25" fill="white"/>
<rect x="211" y="830.5" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(216 835.8037)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">3.</tspan>
</text>
</g>
<g id="id66_Graphic">
<rect x="422.1116" y="606.6151" width="22" height="25" fill="white"/>
<rect x="422.1116" y="606.6151" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(427.1116 611.9188)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">1.</tspan>
</text>
</g>
<rect x="545.25" y="670" width="85" height="55" fill="white"/>
<rect x="545.25" y="670" width="85" height="55" stroke="#a5a5a5" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(550.25 674.3621)" fill="black">
<tspan font-family="Arial" font-size="13" font-weight="500" fill="black" x="20.158203" y="12" textLength="38.29541">List of </tspan>
<tspan font-family="Arial" font-size="13" font-weight="500" fill="black" x="10.77002" y="27.425293" textLength="57.07178">Services, </tspan>
<tspan font-family="Arial" font-size="13" font-weight="500" fill="black" x="21.240479" y="42.850586" textLength="32.519043">Plans</tspan>
</text>
<line x1="133" y1="599.1922" x2="248.9616" y2="600.0696" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="265.0526" y="763.5658" width="116" height="38" fill="white"/>
<text transform="translate(270.0526 768.5658)" fill="black">
<tspan font-family="Helvetica" font-size="12" font-weight="500" x="1.9794922" y="11" textLength="105.375">ClusterServicePlan </tspan>
<tspan font-family="Helvetica" font-size="12" font-weight="500" x="27.32129" y="25" textLength="51.35742">Resource</tspan>
</text>
<rect x="386.6116" y="719.1978" width="93" height="25" fill="white"/>
<text transform="translate(391.6116 724.5015)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".15039062" y="11" textLength="82.69922">Services, Plans</tspan>
</text>
<rect x="129.88842" y="764.2202" width="133" height="23" fill="white"/>
<text transform="translate(134.88842 769.5402)" fill="black">
<tspan font-family="Arial" font-size="11" font-weight="500" x="0" y="10" textLength="111.88525">get clusterserviceplans</tspan>
</text>
<rect x="129.88842" y="718.5518" width="133" height="23" fill="white"/>
<text transform="translate(134.88842 723.8719)" fill="black">
<tspan font-family="Arial" font-size="11" font-weight="500" x="0" y="10" textLength="122.26758">get clusterserviceclasses</tspan>
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

+100
View File
@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="-1 -1 841 457" width="841pt" height="457pt" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata> Produced by OmniGraffle 7.5
<dc:date>2017-11-07 08:04:59 +0000</dc:date>
</metadata>
<defs>
<font-face font-family="Arial" font-size="16" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="16" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="14" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="14" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="12" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" viewBox="-1 -3 7 6" markerWidth="7" markerHeight="6" color="gray">
<g>
<path d="M 4.8 0 L 0 -1.8 L 0 1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_2" viewBox="-6 -3 7 6" markerWidth="7" markerHeight="6" color="gray">
<g>
<path d="M -4.8 0 L 0 1.8 L 0 -1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<font-face font-family="Arial" font-size="12" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
</defs>
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<title>map creds</title>
<g>
<title>Layer 1</title>
<path d="M 0 0 L 600 0 L 600 420 L 0 420 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/>
<rect x="640" y="0" width="200" height="420" fill="#d9d9d9"/>
<text transform="translate(650 30)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" fill="black" x="37.539062" y="14" textLength="104.92188">Service Broker</tspan>
</text>
<rect x="10" y="10" width="170" height="400" fill="#4285f5"/>
<text transform="translate(20 30)" fill="white">
<tspan font-family="Arial" font-size="16" font-weight="bold" fill="white" x="34.53125" y="14" textLength="80.9375">API Server</tspan>
</text>
<rect x="215" y="10" width="170" height="190" fill="#4285f5"/>
<text transform="translate(227 30)" fill="white">
<tspan font-family="Arial" font-size="16" font-weight="bold" fill="white" x="12.972656" y="14" textLength="120.05469">Service Catalog</tspan>
<tspan font-family="Arial" font-size="14" font-weight="bold" fill="white" x=".23828125" y="120.52344" textLength="145.52344">servicecatalog.k8s.io:</tspan>
<tspan font-family="Arial" font-size="14" font-weight="500" fill="white" x="0" y="152.98145" textLength="93.38574">ServiceBinding</tspan>
</text>
<rect x="420" y="220" width="170" height="190" fill="#4285f5"/>
<text transform="translate(430 240)" fill="white">
<tspan font-family="Arial" font-size="16" font-weight="bold" fill="white" x="31.445312" y="14" textLength="87.10938">Application</tspan>
</text>
<rect x="650" y="220" width="180" height="60" fill="white"/>
<text transform="translate(660 232.47656)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" x="17.742188" y="14" textLength="128.96094">Managed Service </tspan>
<tspan font-family="Arial" font-size="16" font-weight="500" x="49.75781" y="31.523438" textLength="60.484375">Instance</tspan>
</text>
<path d="M 384.9481 39.49993 L 410.0271 19.566032 L 410.00054 29.631994 L 614.9472 30.172747 L 614.9738 20.106784 L 639.9472 40.172747 L 614.86825 60.106645 L 614.8948 50.040683 L 409.9481 49.49993 L 409.92156 59.56589 Z" fill="gray"/>
<text transform="translate(421.804 32.87919) rotate(-.1511748)" fill="white">
<tspan font-family="Arial" font-size="12" font-weight="500" fill="white" x="54.26758" y="11" textLength="72.71484">Bind Instance</tspan>
</text>
<text transform="translate(462.4477 59.30371)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x="6.646484" y="11" textLength="86.70703">Service Account</tspan>
</text>
<line x1="602.9" y1="249.5" x2="637.1" y2="249.5" marker-end="url(#FilledArrow_Marker)" marker-start="url(#FilledArrow_Marker_2)" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<line x1="192.9" y1="39.33634" x2="202.1" y2="39.33634" marker-end="url(#FilledArrow_Marker)" marker-start="url(#FilledArrow_Marker_2)" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path d="M 300 200 L 300 215.9 L 300 315.5 L 369.5 315.5 L 404.1 315 L 407.1 315" marker-end="url(#FilledArrow_Marker)" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<rect x="430" y="285" width="150" height="80" fill="white"/>
<text transform="translate(440 296.21484)" fill="#383838">
<tspan font-family="Arial" font-size="12" font-weight="bold" fill="#383838" x="0" y="11" textLength="40.6875">Secret:</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" fill="#383838" x="0" y="25.392578" textLength="124.74023">Connection Credentials</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" fill="#383838" x="0" y="39.785156" textLength="43.347656">Service </tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" fill="#383838" x="42.685547" y="39.785156" textLength="83.37305">Account Details</tspan>
<tspan font-family="Arial" font-size="12" font-weight="500" fill="#383838" x="0" y="54.177734" textLength="12"></tspan>
</text>
<text transform="translate(259 432.2383)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="500" x=".08203125" y="14" textLength="81.83594">Kubernetes</tspan>
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.8 KiB

+125
View File
@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="71 1022 560 377" width="560pt" height="377pt" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata> Produced by OmniGraffle 7.5
<dc:date>2017-11-17 23:02:50 +0000</dc:date>
</metadata>
<defs>
<filter id="Shadow" filterUnits="userSpaceOnUse">
<feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="1.308"/>
<feOffset in="blur" result="offset" dx="0" dy="2"/>
<feFlood flood-color="black" flood-opacity=".5" result="flood"/>
<feComposite in="flood" in2="offset" operator="in"/>
</filter>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" viewBox="-1 -6 14 12" markerWidth="14" markerHeight="12" color="black">
<g>
<path d="M 11.428568 0 L 0 -4.285713 L 0 4.285713 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<font-face font-family="Arial" font-size="12" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.68359" underline-thickness="49.316406" slope="0" x-height="522.9492" cap-height="717.28516" ascent="770.0195" descent="-229.98047" font-weight="500">
<font-face-src>
<font-face-name name="Helvetica"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="11" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="73.24219" slope="0" x-height="518.5547" cap-height="716.3086" ascent="905.2734" descent="-211.91406" font-weight="500">
<font-face-src>
<font-face-name name="ArialMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="12" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
<font-face font-family="Arial" font-size="16" panose-1="2 11 7 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-105.95703" underline-thickness="104.98047" slope="0" x-height="518.5547" cap-height="715.8203" ascent="905.2734" descent="-211.91406" font-weight="bold">
<font-face-src>
<font-face-name name="Arial-BoldMT"/>
</font-face-src>
</font-face>
</defs>
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<title>V2b</title>
<g>
<title>Layer 1</title>
<g>
<xl:use xl:href="#id118_Graphic" filter="url(#Shadow)"/>
<xl:use xl:href="#id119_Graphic" filter="url(#Shadow)"/>
<xl:use xl:href="#id121_Graphic" filter="url(#Shadow)"/>
</g>
<line x1="118.75" y1="1047.5" x2="118.75" y2="1397.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<line x1="324.25" y1="1047.5" x2="324.25" y2="1397.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<line x1="529.75" y1="1047.5" x2="529.75" y2="1397.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<line x1="341.25" y1="1125.8936" x2="502.3641" y2="1168.487" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="373.2558" y="1136.263" width="109" height="25" fill="white"/>
<text transform="translate(378.2558 1141.5667)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".4746094" y="11" textLength="98.05078">Provision Instance</tspan>
</text>
<line x1="515.25" y1="1207.9547" x2="350.17202" y2="1249.6879" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="276.75" y="1260.5592" width="96" height="38" fill="white"/>
<text transform="translate(281.75 1265.5592)" fill="black">
<tspan font-family="Helvetica" font-size="12" font-weight="500" x=".31152344" y="11" textLength="85.37695">ServiceInstance</tspan>
<tspan font-family="Helvetica" font-size="12" font-weight="500" x="17.32129" y="25" textLength="51.35742">Resource</tspan>
</text>
<rect x="276.75" y="1088.1307" width="96" height="38" fill="white"/>
<text transform="translate(281.75 1093.1307)" fill="black">
<tspan font-family="Helvetica" font-size="12" font-weight="500" x=".31152344" y="11" textLength="85.37695">ServiceInstance</tspan>
<tspan font-family="Helvetica" font-size="12" font-weight="500" x="17.32129" y="25" textLength="51.35742">Resource</tspan>
</text>
<line x1="133.5" y1="1106.6307" x2="264.37955" y2="1107.5185" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<line x1="133.5" y1="1279.0592" x2="264.37955" y2="1279.947" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="147.41178" y="1268.0097" width="105" height="23" fill="white"/>
<text transform="translate(152.41178 1273.3298)" fill="black">
<tspan font-family="Arial" font-size="11" font-weight="500" x=".41967773" y="10" textLength="94.16064">get serviceinstance</tspan>
</text>
<line x1="311" y1="1310.1637" x2="145.92202" y2="1351.8969" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<rect x="189.53932" y="1321.797" width="52" height="25" fill="white"/>
<text transform="translate(194.53932 1327.1007)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".328125" y="11" textLength="41.34375">READY</tspan>
</text>
<rect x="279" y="1022.544" width="101" height="39" fill="white"/>
<text transform="translate(284 1027.6514)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".4794922" y="11" textLength="90.04102">Service Catalog</tspan>
<tspan font-family="Arial" font-size="12" font-weight="bold" x="15.148438" y="25.392578" textLength="60.703125">API Server</tspan>
</text>
<rect x="488" y="1022.544" width="95" height="25" fill="white"/>
<text transform="translate(493 1027.8477)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".13964844" y="11" textLength="84.7207">Service Broker</tspan>
</text>
<rect x="71.5" y="1022.544" width="106" height="25" fill="white"/>
<text transform="translate(76.5 1027.8477)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="bold" x=".32226562" y="11" textLength="95.35547">Cluster Operator</tspan>
</text>
<g id="id118_Graphic">
<rect x="198.8721" y="1294.3963" width="22" height="25" fill="white"/>
<rect x="198.8721" y="1294.3963" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(203.8721 1299.7)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">3.</tspan>
</text>
</g>
<g id="id119_Graphic">
<rect x="415.25" y="1106.263" width="22" height="25" fill="white"/>
<rect x="415.25" y="1106.263" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(420.25 1111.5667)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">1.</tspan>
</text>
</g>
<g id="id121_Graphic">
<rect x="576.75" y="1132.263" width="22" height="25" fill="white"/>
<rect x="576.75" y="1132.263" width="22" height="25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
<text transform="translate(581.75 1137.5667)" fill="black">
<tspan font-family="Arial" font-size="12" font-weight="500" x=".9960938" y="11" textLength="10.007812">2.</tspan>
</text>
</g>
<path d="M 558 1166 L 617.5 1166 C 624.538 1166 630.25 1175.52 630.25 1187.25 C 630.25 1198.98 624.538 1208.5 617.5 1208.5 L 558 1208.5 C 550.962 1208.5 545.25 1198.98 545.25 1187.25 C 545.25 1175.52 550.962 1166 558 1166" fill="white"/>
<path d="M 558 1166 L 617.5 1166 C 624.538 1166 630.25 1175.52 630.25 1187.25 C 630.25 1198.98 624.538 1208.5 617.5 1208.5 L 558 1208.5 C 550.962 1208.5 545.25 1198.98 545.25 1187.25 C 545.25 1175.52 550.962 1166 558 1166" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/>
<text transform="translate(558.75 1178.4883)" fill="black">
<tspan font-family="Arial" font-size="16" font-weight="bold" x=".53125" y="14" textLength="56.9375">Service</tspan>
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

+1 -1
View File
@@ -64,7 +64,7 @@ cid: home
<button id="desktopShowVideoButton" onclick="kub.showVideo()">Watch Video</button>
<br>
<br>
<a href="https://goo.gl/nhbhXw" button id= "desktopKCButton">Attend KubeCon in Austin, TX on December 6-8, 2017</a>
<a href="https://goo.gl/naJfWk" button id= "desktopKCButton">Attend KubeCon in Austin, TX on December 6-8, 2017</a>
</div>
<button id="mobileShowVideoButton" onclick="kub.showVideo()"></button>
</section>
+5 -5
View File
@@ -22,8 +22,8 @@ cid: partners
</div>
<div class="kscp_section">
<h3><a id="kcsp"></a>Kubernetes Certified Service Providers (KCSP)</h3>
<p>The KCSP program is a vetted tier of service providers who have deep experience helping enterprises successfully adopt Kubernetes. KCSP partners offer Kubernetes support, consulting, professional services and training for organizations embarking on their Kubernetes journey.</p>
<p>Interested in becoming a KCSP? <b><a href="https://www.cncf.io/certification/kcsp/">Learn more.</a></b></p>
<p>The KCSP program is a vetted tier of service providers who have deep experience helping enterprises successfully adopt Kubernetes. KCSP partners offer Kubernetes support, consulting, professional services and training for organizations embarking on their Kubernetes journey. Learn more about the program <b><a href="https://www.cncf.io/certification/kcsp/">here</a></b>.</p>
<p>Interested in becoming a KCSP? Please <b><a href="https://goo.gl/forms/lwKx3U24oIumFXvM2">fill out this form.</a></b></p>
<div id="kcspContainer"></div>
</div>
<div class="dist_section">
@@ -35,13 +35,13 @@ cid: partners
<div class="tech_section">
<h3><a id="technology"></a>Technology Partners</h3>
<p>Technology partners offer integrations and plugins that add features to Kubernetes applications.</p>
<p>Interested in becoming a Technology Partner? Please <b><a href="https://docs.google.com/forms/d/e/1FAIpQLSdN1KtSKX2VAOPGABFlShkSd6CajQynoL4QCVtY0dj76MNDKg/viewform">fill out this form.</a></b></p>
<p>Interested in becoming a Technology Partner? Please <b><a href="https://goo.gl/forms/lwKx3U24oIumFXvM2">fill out this form.</a></b></p>
<div id="isvContainer"></div>
</div>
<div class="service_Section">
<h3><a id="service"></a>Service Partners</h3>
<p>Service Partners offer consulting or management services to help companies implement and use Kubernetes in commercial applications.</p>
<p>Interested in becoming a Service Provider? Please <b><a href="https://docs.google.com/forms/d/e/1FAIpQLSdN1KtSKX2VAOPGABFlShkSd6CajQynoL4QCVtY0dj76MNDKg/viewform">fill out this form</a></b></p>
<p>Interested in becoming a Service Provider? Please <b><a href="https://goo.gl/forms/lwKx3U24oIumFXvM2">fill out this form.</a></b></p>
<div id="servContainer"></div>
</div>
</main>
@@ -53,4 +53,4 @@ cid: partners
<script>
{% include partner-script.js %}
</script>
</script>
+127 -69
View File
@@ -32,15 +32,17 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apimachinery/pkg/util/yaml"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/apis/core/validation"
"k8s.io/kubernetes/pkg/apis/apps"
apps_validation "k8s.io/kubernetes/pkg/apis/apps/validation"
"k8s.io/kubernetes/pkg/apis/autoscaling"
autoscaling_validation "k8s.io/kubernetes/pkg/apis/autoscaling/validation"
"k8s.io/kubernetes/pkg/apis/batch"
batch_validation "k8s.io/kubernetes/pkg/apis/batch/validation"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/core/validation"
"k8s.io/kubernetes/pkg/apis/extensions"
expvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation"
ext_validation "k8s.io/kubernetes/pkg/apis/extensions/validation"
"k8s.io/kubernetes/pkg/apis/policy"
policyvalidation "k8s.io/kubernetes/pkg/apis/policy/validation"
"k8s.io/kubernetes/pkg/apis/storage"
@@ -113,11 +115,21 @@ func validateObject(obj runtime.Object) (errors field.ErrorList) {
t.Namespace = api.NamespaceDefault
}
errors = validation.ValidateResourceQuota(t)
case *autoscaling.HorizontalPodAutoscaler:
if t.Namespace == "" {
t.Namespace = api.NamespaceDefault
}
errors = autoscaling_validation.ValidateHorizontalPodAutoscaler(t)
case *extensions.Deployment:
if t.Namespace == "" {
t.Namespace = api.NamespaceDefault
}
errors = expvalidation.ValidateDeployment(t)
errors = ext_validation.ValidateDeployment(t)
case *extensions.ReplicaSet:
if t.Namespace == "" {
t.Namespace = api.NamespaceDefault
}
errors = ext_validation.ValidateReplicaSet(t)
case *batch.Job:
if t.Namespace == "" {
t.Namespace = api.NamespaceDefault
@@ -130,14 +142,14 @@ func validateObject(obj runtime.Object) (errors field.ErrorList) {
if t.Namespace == "" {
t.Namespace = api.NamespaceDefault
}
errors = expvalidation.ValidateIngress(t)
errors = ext_validation.ValidateIngress(t)
case *extensions.DaemonSet:
if t.Namespace == "" {
t.Namespace = api.NamespaceDefault
}
errors = expvalidation.ValidateDaemonSet(t)
errors = ext_validation.ValidateDaemonSet(t)
case *extensions.PodSecurityPolicy:
errors = expvalidation.ValidatePodSecurityPolicy(t)
errors = ext_validation.ValidatePodSecurityPolicy(t)
case *batch.CronJob:
if t.Namespace == "" {
t.Namespace = api.NamespaceDefault
@@ -218,45 +230,76 @@ func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) er
}
func TestExampleObjectSchemas(t *testing.T) {
// Please help maintain the alphabeta order in the map
cases := map[string]map[string][]runtime.Object{
"../docs/user-guide/walkthrough": {
"deployment": {&extensions.Deployment{}},
"deployment-update": {&extensions.Deployment{}},
"pod-nginx": {&api.Pod{}},
"pod-nginx-with-label": {&api.Pod{}},
"pod-redis": {&api.Pod{}},
"pod-with-http-healthcheck": {&api.Pod{}},
"pod-with-tcp-socket-healthcheck": {&api.Pod{}},
"podtemplate": {&api.PodTemplate{}},
"service": {&api.Service{}},
"../docs/admin/high-availability": {
"etcd": {&api.Pod{}},
"kube-apiserver": {&api.Pod{}},
"kube-controller-manager": {&api.Pod{}},
"kube-scheduler": {&api.Pod{}},
"podmaster": {&api.Pod{}},
},
"../docs/user-guide/update-demo": {
"kitten-rc": {&api.ReplicationController{}},
"nautilus-rc": {&api.ReplicationController{}},
"../docs/admin/limitrange": {
"invalid-pod": {&api.Pod{}},
"limits": {&api.LimitRange{}},
"namespace": {&api.Namespace{}},
"valid-pod": {&api.Pod{}},
},
"../docs/admin/multiple-schedulers": {
"my-scheduler": {&extensions.Deployment{}},
"pod1": {&api.Pod{}},
"pod2": {&api.Pod{}},
"pod3": {&api.Pod{}},
},
"../docs/admin/namespaces": {
"namespace-dev": {&api.Namespace{}},
"namespace-prod": {&api.Namespace{}},
},
"../docs/admin/resourcequota": {
"best-effort": {&api.ResourceQuota{}},
"compute-resources": {&api.ResourceQuota{}},
"limits": {&api.LimitRange{}},
"namespace": {&api.Namespace{}},
"not-best-effort": {&api.ResourceQuota{}},
"object-counts": {&api.ResourceQuota{}},
},
"../docs/concepts/cluster-administration": {
"counter-pod": {&api.Pod{}},
"fluentd-sidecar-config": {&api.ConfigMap{}},
"nginx-app": {&api.Service{}, &extensions.Deployment{}},
"two-files-counter-pod": {&api.Pod{}},
"two-files-counter-pod-agent-sidecar": {&api.Pod{}},
"two-files-counter-pod-streaming-sidecar": {&api.Pod{}},
},
"../docs/concepts/configuration": {
"commands": {&api.Pod{}},
"pod": {&api.Pod{}},
"pod-with-node-affinity": {&api.Pod{}},
"pod-with-pod-affinity": {&api.Pod{}},
},
"../docs/concepts/overview/working-with-objects": {
"nginx-deployment": {&extensions.Deployment{}},
},
"../docs/concepts/policy": {
"psp": {&extensions.PodSecurityPolicy{}},
},
"../docs/user-guide/persistent-volumes/volumes": {
"local-01": {&api.PersistentVolume{}},
"local-02": {&api.PersistentVolume{}},
"gce": {&api.PersistentVolume{}},
"nfs": {&api.PersistentVolume{}},
"../docs/concepts/services-networking": {
"curlpod": {&extensions.Deployment{}},
"hostaliases-pod": {&api.Pod{}},
"ingress": {&extensions.Ingress{}},
"nginx-secure-app": {&api.Service{}, &extensions.Deployment{}},
"nginx-svc": {&api.Service{}},
"run-my-nginx": {&extensions.Deployment{}},
},
"../docs/user-guide/persistent-volumes/claims": {
"claim-01": {&api.PersistentVolumeClaim{}},
"claim-02": {&api.PersistentVolumeClaim{}},
"claim-03": {&api.PersistentVolumeClaim{}},
},
"../docs/user-guide/persistent-volumes/simpletest": {
"namespace": {&api.Namespace{}},
"pod": {&api.Pod{}},
"service": {&api.Service{}},
},
"../docs/user-guide/liveness": {
"exec-liveness": {&api.Pod{}},
"http-liveness": {&api.Pod{}},
"http-liveness-named-port": {&api.Pod{}},
"../docs/concepts/workloads/controllers": {
"cronjob": {&batch.CronJob{}},
"daemonset": {&extensions.DaemonSet{}},
"frontend": {&extensions.ReplicaSet{}},
"hpa-rs": {&autoscaling.HorizontalPodAutoscaler{}},
"job": {&batch.Job{}},
"my-repset": {&extensions.ReplicaSet{}},
"nginx-deployment": {&extensions.Deployment{}},
"replication": {&api.ReplicationController{}},
},
"../docs/tasks/job/coarse-parallel-processing-work-queue": {
"job": {&batch.Job{}},
@@ -266,6 +309,18 @@ func TestExampleObjectSchemas(t *testing.T) {
"redis-pod": {&api.Pod{}},
"redis-service": {&api.Service{}},
},
"../docs/tutorials/stateful-application": {
"gce-volume": {&api.PersistentVolume{}},
"mysql-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}},
"mysql-services": {&api.Service{}, &api.Service{}},
"mysql-configmap": {&api.ConfigMap{}},
"mysql-statefulset": {&apps.StatefulSet{}},
"cassandra-service": {&api.Service{}},
"cassandra-statefulset": {&apps.StatefulSet{}, &storage.StorageClass{}},
"web": {&api.Service{}, &apps.StatefulSet{}},
"webp": {&api.Service{}, &apps.StatefulSet{}},
"zookeeper": {&api.Service{}, &api.Service{}, &policy.PodDisruptionBudget{}, &apps.StatefulSet{}},
},
"../docs/user-guide": {
"bad-nginx-deployment": {&extensions.Deployment{}},
"counter-pod": {&api.Pod{}},
@@ -290,9 +345,6 @@ func TestExampleObjectSchemas(t *testing.T) {
"run-my-nginx": {&extensions.Deployment{}},
"cronjob": {&batch.CronJob{}},
},
"../docs/admin": {
"daemon": {&extensions.DaemonSet{}},
},
"../docs/user-guide/downward-api": {
"dapi-pod": {&api.Pod{}},
"dapi-container-resources": {&api.Pod{}},
@@ -301,45 +353,51 @@ func TestExampleObjectSchemas(t *testing.T) {
"dapi-volume": {&api.Pod{}},
"dapi-volume-resources": {&api.Pod{}},
},
"../docs/admin/namespaces": {
"namespace-dev": {&api.Namespace{}},
"namespace-prod": {&api.Namespace{}},
},
"../docs/admin/limitrange": {
"invalid-pod": {&api.Pod{}},
"limits": {&api.LimitRange{}},
"namespace": {&api.Namespace{}},
"valid-pod": {&api.Pod{}},
"../docs/user-guide/liveness": {
"exec-liveness": {&api.Pod{}},
"http-liveness": {&api.Pod{}},
"http-liveness-named-port": {&api.Pod{}},
},
"../docs/user-guide/node-selection": {
"pod": {&api.Pod{}},
"pod-with-node-affinity": {&api.Pod{}},
"pod-with-pod-affinity": {&api.Pod{}},
},
"../docs/admin/resourcequota": {
"best-effort": {&api.ResourceQuota{}},
"compute-resources": {&api.ResourceQuota{}},
"limits": {&api.LimitRange{}},
"namespace": {&api.Namespace{}},
"not-best-effort": {&api.ResourceQuota{}},
"object-counts": {&api.ResourceQuota{}},
"../docs/user-guide/persistent-volumes/volumes": {
"local-01": {&api.PersistentVolume{}},
"local-02": {&api.PersistentVolume{}},
"gce": {&api.PersistentVolume{}},
"nfs": {&api.PersistentVolume{}},
},
"../docs/user-guide/persistent-volumes/claims": {
"claim-01": {&api.PersistentVolumeClaim{}},
"claim-02": {&api.PersistentVolumeClaim{}},
"claim-03": {&api.PersistentVolumeClaim{}},
},
"../docs/user-guide/persistent-volumes/simpletest": {
"namespace": {&api.Namespace{}},
"pod": {&api.Pod{}},
"service": {&api.Service{}},
},
"../docs/user-guide/secrets": {
"secret-pod": {&api.Pod{}},
"secret": {&api.Secret{}},
"secret-env-pod": {&api.Pod{}},
},
"../docs/tutorials/stateful-application": {
"gce-volume": {&api.PersistentVolume{}},
"mysql-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}},
"mysql-services": {&api.Service{}, &api.Service{}},
"mysql-configmap": {&api.ConfigMap{}},
"mysql-statefulset": {&apps.StatefulSet{}},
"cassandra-service": {&api.Service{}},
"cassandra-statefulset": {&apps.StatefulSet{}, &storage.StorageClass{}},
"web": {&api.Service{}, &apps.StatefulSet{}},
"webp": {&api.Service{}, &apps.StatefulSet{}},
"zookeeper": {&api.Service{}, &api.Service{}, &policy.PodDisruptionBudget{}, &apps.StatefulSet{}},
"../docs/user-guide/update-demo": {
"kitten-rc": {&api.ReplicationController{}},
"nautilus-rc": {&api.ReplicationController{}},
},
"../docs/user-guide/walkthrough": {
"deployment": {&extensions.Deployment{}},
"deployment-update": {&extensions.Deployment{}},
"pod-nginx": {&api.Pod{}},
"pod-nginx-with-label": {&api.Pod{}},
"pod-redis": {&api.Pod{}},
"pod-with-http-healthcheck": {&api.Pod{}},
"pod-with-tcp-socket-healthcheck": {&api.Pod{}},
"podtemplate": {&api.PodTemplate{}},
"service": {&api.Service{}},
},
}