Resolving merge conflicts with master

This commit is contained in:
zacharysarah
2017-11-30 18:53:33 -06:00
5068 changed files with 25074 additions and 855452 deletions
@@ -14,7 +14,7 @@ Kubernetes CLI, `kubectl`.
To access a cluster, you need to know the location of the cluster and have credentials
to access it. Typically, this is automatically set-up when you work through
a [Getting started guide](/docs/getting-started-guides/),
a [Getting started guide](/docs/setup/),
or someone else setup the cluster and provided you with credentials and a location.
Check the location and credentials that kubectl knows about with this command:
@@ -23,8 +23,8 @@ Check the location and credentials that kubectl knows about with this command:
$ kubectl config view
```
Many of the [examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/) provide an introduction to using
kubectl and complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl/index).
Many of the [examples](/docs/user-guide/kubectl-cheatsheet) provide an introduction to using
kubectl and complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl-overview).
### Directly accessing the REST API
@@ -53,7 +53,7 @@ Run it like this:
$ kubectl proxy --port=8080 &
```
See [kubectl proxy](/docs/user-guide/kubectl/v1.6/#proxy) for more details.
See [kubectl proxy](/docs/user-guide/kubectl/{{page.version}}/#proxy) for more details.
Then you can explore the API with curl, wget, or a browser, like so:
@@ -195,7 +195,7 @@ You have several options for connecting to nodes, pods and services from outside
- Access services through public IPs.
- Use a service with type `NodePort` or `LoadBalancer` to make the service reachable outside
the cluster. See the [services](/docs/user-guide/services) and
[kubectl expose](/docs/user-guide/kubectl/v1.6/#expose) documentation.
[kubectl expose](/docs/user-guide/kubectl/{{page.version}}/#expose) documentation.
- Depending on your cluster environment, this may just expose the service to your corporate network,
or it may expose it to the internet. Think about whether the service being exposed is secure.
Does it do its own authentication?
@@ -211,7 +211,7 @@ You have several options for connecting to nodes, pods and services from outside
- Only works for HTTP/HTTPS.
- Described [here](#manually-constructing-apiserver-proxy-urls).
- Access from a node or pod in the cluster.
- Run a pod, and then connect to a shell in it using [kubectl exec](/docs/user-guide/kubectl/v1.6/#exec).
- Run a pod, and then connect to a shell in it using [kubectl exec](/docs/user-guide/kubectl/{{page.version}}/#exec).
Connect to other nodes, pods, and services from that shell.
- Some clusters may allow you to ssh to a node in the cluster. From there you may be able to
access cluster services. This is a non-standard method, and will work on some clusters but
@@ -293,14 +293,17 @@ The redirect capabilities have been deprecated and removed. Please use a proxy
There are several different proxies you may encounter when using Kubernetes:
1. The [kubectl proxy](#directly-accessing-the-rest-api):
1. The [kubectl proxy](#directly-accessing-the-rest-api):
- runs on a user's desktop or in a pod
- proxies from a localhost address to the Kubernetes apiserver
- client to proxy uses HTTP
- proxy to apiserver uses HTTPS
- locates apiserver
- adds authentication headers
1. The [apiserver proxy](#discovering-builtin-services):
1. The [apiserver proxy](#discovering-builtin-services):
- is a bastion built into the apiserver
- connects a user outside of the cluster to cluster IPs which otherwise might not be reachable
- runs in the apiserver processes
@@ -308,17 +311,23 @@ There are several different proxies you may encounter when using Kubernetes:
- proxy to target may use HTTP or HTTPS as chosen by proxy using available information
- can be used to reach a Node, Pod, or Service
- does load balancing when used to reach a Service
1. The [kube proxy](/docs/concepts/services-networking/service/#ips-and-vips):
1. The [kube proxy](/docs/concepts/services-networking/service/#ips-and-vips):
- runs on each node
- proxies UDP and TCP
- does not understand HTTP
- provides load balancing
- is just used to reach services
1. A Proxy/Load-balancer in front of apiserver(s):
1. A Proxy/Load-balancer in front of apiserver(s):
- existence and implementation varies from cluster to cluster (e.g. nginx)
- sits between all clients and one or more apiservers
- acts as load balancer if there are several apiservers.
1. Cloud Load Balancers on external services:
1. Cloud Load Balancers on external services:
- are provided by some cloud providers (e.g. AWS ELB, Google Cloud Load Balancer)
- are created automatically when the Kubernetes service has type `LoadBalancer`
- use UDP/TCP only
@@ -88,6 +88,8 @@ Get a shell to nginx Container:
In your shell, verify that nginx is running:
root@two-containers:/# apt-get update
root@two-containers:/# apt-get install curl procps
root@two-containers:/# ps aux
The output is similar to this:
@@ -98,8 +100,6 @@ The output is similar to this:
Recall that the debian Container created the `index.html` file in the nginx root
directory. Use `curl` to send a GET request to the nginx server:
root@two-containers:/# apt-get update
root@two-containers:/# apt-get install curl
root@two-containers:/# curl localhost
The output shows that nginx serves a web page written by the debian container:
@@ -193,7 +193,7 @@ kubectl config --kubeconfig=config-demo use-context exp-scratch
Now any `kubectl` command you give will apply to the default namespace of
the `scratch` cluster. And the command will use the credentials of the user
listed in the `exa-scratch` context.
listed in the `exp-scratch` context.
View configuration associated with the new current context, `exp-scratch`.
@@ -210,7 +210,7 @@ Change the current context to `dev-storage`:
kubectl config --kubeconfig=config-demo use-context dev-storage
```
View configuration associated with the new current context, `dev-storage.
View configuration associated with the new current context, `dev-storage`.
```shell
@@ -14,7 +14,7 @@ well as any provider specific details that may be necessary.
When using a Service with `spec.type: LoadBalancer`, you can specify the IP ranges that are allowed to access the load balancer
by using `spec.loadBalancerSourceRanges`. This field takes a list of IP CIDR ranges, which Kubernetes will use to configure firewall exceptions.
This feature is currently supported on Google Compute Engine, Google Container Engine and AWS. This field will be ignored if the cloud provider does not support the feature.
This feature is currently supported on Google Compute Engine, Google Kubernetes Engine and AWS. This field will be ignored if the cloud provider does not support the feature.
Assuming 10.0.0.0/8 is the internal subnet. In the following example, a load balancer will be created that is only accessible to cluster internal IPs.
This will not allow clients from outside of your Kubernetes cluster to access the load balancer.
@@ -65,7 +65,7 @@ Google Compute Engine firewalls are documented [elsewhere](https://cloud.google.
You can add a firewall with the `gcloud` command line tool:
```shell
$ gcloud compute firewall-rules create my-rule --allow=tcp:<port>
gcloud compute firewall-rules create my-rule --allow=tcp:<port>
```
**Note**
@@ -89,7 +89,7 @@ Consider:
the VM's external IP address.
Consequently, please be careful when opening firewalls in Google Compute Engine
or Google Container Engine. You may accidentally be exposing other services to
or Google Kubernetes Engine. You may accidentally be exposing other services to
the wilds of the internet.
This will be fixed in an upcoming release of Kubernetes.
@@ -104,7 +104,7 @@ The IP address is listed next to `LoadBalancer Ingress`.
Due to the implementation of this feature, the source IP seen in the target
container will *not be the original source IP* of the client. To enable
preservation of the client IP, the following fields can be configured in the
service spec (supported in GCE/GKE environments):
service spec (supported in GCE/Google Kubernetes Engine environments):
* `service.spec.externalTrafficPolicy` - denotes if this Service desires to route
external traffic to node-local or cluster-wide endpoints. There are two available
@@ -180,7 +180,7 @@ Known issues:
It is important to note that the datapath for this functionality is provided by a load balancer external to the Kubernetes cluster.
When the service type is set to `LoadBalancer`, Kubernetes provides functionality equivalent to `type=<ClusterIP>` to pods within the cluster and extends it by programming the (external to Kubernetes) load balancer with entries for the Kubernetes VMs. The Kubernetes service controller automates the creation of the external load balancer, health checks (if needed), firewall rules (if needed) and retrieves the external IP allocated by the cloud provider and populates it in the service object.
When the service type is set to `LoadBalancer`, Kubernetes provides functionality equivalent to `type=<ClusterIP>` to pods within the cluster and extends it by programming the (external to Kubernetes) load balancer with entries for the Kubernetes pods. The Kubernetes service controller automates the creation of the external load balancer, health checks (if needed), firewall rules (if needed) and retrieves the external IP allocated by the cloud provider and populates it in the service object.
## Caveats and Limitations when preserving source IPs
@@ -87,7 +87,7 @@ local workstation to debug the database that is running in the pod.
{% capture whatsnext %}
Learn more about [kubectl port-forward](/docs/user-guide/kubectl/v1.6/#port-forward).
Learn more about [kubectl port-forward](/docs/user-guide/kubectl/{{page.version}}/#port-forward).
{% endcapture %}
@@ -31,7 +31,7 @@ There are multiple ways you can access the Dashboard UI; either by using the kub
You can access Dashboard using the kubectl command-line tool by running the following command:
```
$ kubectl proxy
kubectl proxy
```
Kubectl will handle authentication with apiserver and make Dashboard available at http://localhost:8001/ui.
@@ -6,19 +6,26 @@ approvers:
---
{% capture overview %}
This page shows how to install a [custom resource](/docs/concepts/api-extension/custom-resources/)
into the Kubernetes API by creating a CustomResourceDefinition.
This page shows how to install a
[custom resource](/docs/concepts/api-extension/custom-resources/)
into the Kubernetes API by creating a
[CustomResourceDefinition](/docs/api-reference/{{page.version}}/#customresourcedefinition-v1beta1-apiextensions).
{% endcapture %}
{% capture prerequisites %}
* Read about [custom resources](/docs/concepts/api-extension/custom-resources/).
{% include task-tutorial-prereqs.md %}
* Make sure your Kubernetes cluster has a master version of 1.7.0 or higher.
* Read about [custom resources](/docs/concepts/api-extension/custom-resources/).
{% endcapture %}
{% capture steps %}
## Create a CustomResourceDefinition
When you create a new *CustomResourceDefinition* (CRD), the Kubernetes API Server
When you create a new CustomResourceDefinition (CRD), the Kubernetes API Server
reacts by creating a new RESTful resource path, either namespaced or cluster-scoped,
as specified in the CRD's `scope` field. As with existing built-in objects, deleting a
namespace deletes all custom objects in that namespace.
@@ -144,6 +151,23 @@ metadata:
resourceVersion: ""
selfLink: ""
```
## Delete a CustomResourceDefinition
When you delete a CustomResourceDefinition, the server will uninstall the RESTful API endpoint
and **delete all custom objects stored in it**.
```shell
kubectl delete -f resourcedefinition.yaml
kubectl get crontabs
```
```console
Error from server (NotFound): Unable to list "crontabs": the server could not find the requested resource (get crontabs.stable.example.com)
```
If you later recreate the same CustomResourceDefinition, it will start out empty.
{% endcapture %}
{% capture discussion %}
@@ -174,7 +198,8 @@ meaning all finalizers are done.
### Validation
Validation of custom objects is possible via [OpenAPI v3 schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject).
Validation of custom objects is possible via
[OpenAPI v3 schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject).
Additionally, the following restrictions are applied to the schema:
- The fields `default`, `nullable`, `discriminator`, `readOnly`, `writeOnly`, `xml` and
@@ -293,6 +318,7 @@ crontab "my-new-cron-object" created
{% capture whatsnext %}
* Learn how to [Migrate a ThirdPartyResource to CustomResourceDefinition](/docs/tasks/access-kubernetes-api/migrate-third-party-resource/).
* See [CustomResourceDefinition](/docs/api-reference/{{page.version}}/#customresourcedefinition-v1beta1-apiextensions).
{% endcapture %}
{% include templates/task.md %}
@@ -134,3 +134,11 @@ $ kubectl get crontab -o json
"selfLink": ""
}
```
## What's next
* [Migrate a ThirdPartyResource to a CustomResourceDefinition](/docs/tasks/access-kubernetes-api/migrate-third-party-resource/)
* [Extend the Kubernetes API with CustomResourceDefinitions](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)
* [ThirdPartyResource](/docs/api-reference/v1.7/#thirdpartyresource-v1beta1-extensions)
@@ -78,7 +78,7 @@ Get a list of pods:
{% endcapture %}
{% capture whatsnext %}
Learn more about [kubectl proxy](/docs/user-guide/kubectl/v1.6/#proxy).
Learn more about [kubectl proxy](/docs/user-guide/kubectl/{{page.version}}/#proxy).
{% endcapture %}
{% include templates/task.md %}
@@ -6,7 +6,8 @@ approvers:
---
{% capture overview %}
This page shows how to migrate data stored in a ThirdPartyResource (TPR) to a CustomResourceDefinition (CRD).
This page shows how to migrate data stored in a ThirdPartyResource (TPR) to a
[CustomResourceDefinition](/docs/api-reference/{{page.version}}/#customresourcedefinition-v1beta1-apiextensions) (CRD).
Kubernetes does not automatically migrate existing TPRs.
This is due to API changes introduced as part of
@@ -22,6 +23,8 @@ you **on a best-effort basis**.
{% endcapture %}
{% capture prerequisites %}
{% include task-tutorial-prereqs.md %}
* Make sure your Kubernetes cluster has a **master version of exactly 1.7.x** (any patch release),
as this is the only version that supports both TPR and CRD.
* If you use a TPR-based custom controller, check with the author of the controller first.
@@ -160,6 +163,7 @@ you **on a best-effort basis**.
{% capture whatsnext %}
* Learn more about [custom resources](/docs/concepts/api-extension/custom-resources/).
* Learn more about [using CustomResourceDefinitions](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/).
* See [CustomResourceDefinition](/docs/api-reference/{{page.version}}/#customresourcedefinition-v1beta1-apiextensions).
{% endcapture %}
{% include templates/task.md %}
@@ -23,7 +23,7 @@ Setting up an extension API server to work the aggregation layer allows the Kube
## Setup an extension api-server to work with the aggregation layer
The following steps describe how to set up an extension-apiserver *at a high level*. For a concrete example of how they can be implemented, you can look at the [sample-apiserver](https://github.com/kubernetes/sample-apiserver/blob/master/README.md) in the Kubernetes repo.
The following steps describe how to set up an extension-apiserver *at a high level*. These steps apply regardless if you're using YAML configs or using APIs. An attempt is made to specifically identify any differences between the two. For a concrete example of how they can be implemented using YAML configs, you can look at the [sample-apiserver](https://github.com/kubernetes/sample-apiserver/blob/master/README.md) in the Kubernetes repo.
Alternatively, you can use an existing 3rd party solution, such as [apiserver-builder](https://github.com/Kubernetes-incubator/apiserver-builder/blob/master/README.md), which should generate a skeleton and automate all of the following steps for you.
@@ -38,7 +38,7 @@ Alternatively, you can use an existing 3rd party solution, such as [apiserver-bu
1. Create a Kubernetes service account in your namespace.
1. Create a Kubernetes cluster role for the operations you want to allow on your resources.
1. Create a Kubernetes cluster role binding from the default service account in your namespace to the cluster role you just created.
1. Create a Kubernetes apiservice. The CA cert above should be base 64 encoded, stripped of new lines and used as the spec.caBundle in the apiservce. This should not be namespaced.
1. Create a Kubernetes apiservice. The CA cert above should be base64 encoded, stripped of new lines and used as the spec.caBundle in the apiservice. This should not be namespaced. If using the [kube-aggregator API](https://github.com/kubernetes/kube-aggregator/), only pass in the PEM encoded CA bundle because the base 64 encoding is done for you.
1. Use kubectl to get your resource. It should return "No resources found." Which means that everything worked but you currently have no objects of that resource type created yet.
{% endcapture %}
@@ -46,7 +46,7 @@ Alternatively, you can use an existing 3rd party solution, such as [apiserver-bu
{% capture whatsnext %}
* If you haven't already, [configure the aggregation layer](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/) and enable the apiserver flags.
* For a high level overview, see [Extending the Kubernetes API with the aggregation layer](/docs/concepts/api-extension/apiserver-aggregation/).
* For a high level overview, see [Extending the Kubernetes API with the aggregation layer](/docs/concepts/api-extension/apiserver-aggregation).
* Learn how to [Extend the Kubernetes API Using Custom Resource Definitions](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/).
{% endcapture %}
@@ -21,8 +21,8 @@ When accessing the Kubernetes API for the first time, use the
Kubernetes command-line tool, `kubectl`.
To access a cluster, you need to know the location of the cluster and have credentials
to access it. Typically, this is automatically set-up when you work through
a [Getting started guide](/docs/getting-started-guides/),
to access it. Typically, this is automatically set-up when you work through
a [Getting started guide](/docs/setup/),
or someone else setup the cluster and provided you with credentials and a location.
Check the location and credentials that kubectl knows about with this command:
@@ -32,22 +32,22 @@ $ kubectl config view
```
Many of the [examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/) provide an introduction to using
kubectl. Complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl/index).
kubectl. Complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl/index).
### Directly accessing the REST API
Kubectl handles locating and authenticating to the apiserver. If you want to directly access the REST API with an http client like
`curl` or `wget`, or a browser, there are multiple ways you can locate and authenticate against the apiserver:
kubectl handles locating and authenticating to the API server. If you want to directly access the REST API with an http client like
`curl` or `wget`, or a browser, there are multiple ways you can locate and authenticate against the API server:
1. Run kubectl in proxy mode (recommended). This method is recommended, since it uses the stored apiserver location abd verifies the identity of the apiserver using a self-signed cert. No Man-in-the-middle (MITM) attack is possible using this method .
1. Alternatively, you can provide the location and credentials directly to the http client. This works with for client code that is confused by proxies. To protect against man in the middle attacks, you'll need to import a root cert into your browser.
1. Run kubectl in proxy mode (recommended). This method is recommended, since it uses the stored apiserver location and verifies the identity of the API server using a self-signed cert. No man-in-the-middle (MITM) attack is possible using this method.
1. Alternatively, you can provide the location and credentials directly to the http client. This works with client code that is confused by proxies. To protect against man in the middle attacks, you'll need to import a root cert into your browser.
Using the Go or Python client libraries provides accessing kubectl in proxy mode.
#### Using kubectl proxy
The following command runs kubectl in a mode where it acts as a reverse proxy. It handles
locating the apiserver and authenticating.
The following command runs kubectl in a mode where it acts as a reverse proxy. It handles
locating the API server and authenticating.
Run it like this:
@@ -55,7 +55,7 @@ Run it like this:
$ kubectl proxy --port=8080 &
```
See [kubectl proxy](/docs/user-guide/kubectl/v1.6/#proxy) for more details.
See [kubectl proxy](/docs/user-guide/kubectl/{{page.version}}/#proxy) for more details.
Then you can explore the API with curl, wget, or a browser, like so:
@@ -77,7 +77,7 @@ $ curl http://localhost:8080/api/
#### Without kubectl proxy
It is possible to avoid using kubectl proxy by passing an authentication token
directly to the apiserver, like this:
directly to the API server, like this:
``` shell
$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
@@ -97,17 +97,17 @@ $ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
}
```
The above example uses the `--insecure` flag. This leaves it subject to MITM
attacks. When kubectl accesses the cluster it uses a stored root certificate
and client certificates to access the server. (These are installed in the
`~/.kube` directory). Since cluster certificates are typically self-signed, it
The above example uses the `--insecure` flag. This leaves it subject to MITM
attacks. When kubectl accesses the cluster it uses a stored root certificate
and client certificates to access the server. (These are installed in the
`~/.kube` directory). Since cluster certificates are typically self-signed, it
may take special configuration to get your http client to use root
certificate.
On some clusters, the apiserver does not require authentication; it may serve
on localhost, or be protected by a firewall. There is not a standard
for this. [Configuring Access to the API](/docs/admin/accessing-the-api)
describes how a cluster admin can configure this. Such approaches may conflict
On some clusters, the API server does not require authentication; it may serve
on localhost, or be protected by a firewall. There is not a standard
for this. [Configuring Access to the API](/docs/admin/accessing-the-api)
describes how a cluster admin can configure this. Such approaches may conflict
with future high-availability support.
### Programmatic access to the API
@@ -121,7 +121,7 @@ Kubernetes officially supports client libraries for [Go](#go-client) and
* Write an application atop of the client-go clients. Note that client-go defines its own API objects, so if needed, please import API definitions from client-go rather than from the main repository, e.g., `import "k8s.io/client-go/1.4/pkg/api/v1"` is correct.
The Go client can use the same [kubeconfig file](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)
as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://git.k8s.io/client-go/examples/out-of-cluster-client-configuration/main.go):
as the kubectl CLI does to locate and authenticate to the API server. See this [example](https://git.k8s.io/client-go/examples/out-of-cluster-client-configuration/main.go):
```golang
import (
@@ -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))
...
```
@@ -148,7 +148,7 @@ If the application is deployed as a Pod in the cluster, please refer to the [nex
To use [Python client](https://github.com/kubernetes-incubator/client-python), run the following command: `pip install kubernetes` See [Python Client Library page](https://github.com/kubernetes-incubator/client-python) for more installation options.
The Python client can use the same [kubeconfig file](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)
as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://github.com/kubernetes-incubator/client-python/tree/master/examples/example1.py):
as the kubectl CLI does to locate and authenticate to the API server. See this [example](https://github.com/kubernetes-incubator/client-python/tree/master/examples/example1.py):
```python
from kubernetes import client, config
@@ -168,37 +168,46 @@ There are [client libraries](/docs/reference/client-libraries/) for accessing th
### Accessing the API from a Pod
When accessing the API from a pod, locating and authenticating
When accessing the API from a Pod, locating and authenticating
to the API server are somewhat different.
The recommended way to locate the apiserver within the pod is with
the `kubernetes` DNS name, which resolves to a Service IP which in turn
will be routed to an apiserver.
The easiest way to use the Kubernetes API from a Pod is to use
one of the official [client libraries](/docs/reference/client-libraries/). These
libraries can automatically discover the API server and authenticate.
The recommended way to authenticate to the apiserver is with a
[service account](/docs/user-guide/service-accounts) credential. By kube-system, a pod
While running in a Pod, the Kubernetes apiserver is accessible via a Service named
`kubernetes` in the `default` namespace. Therefore, Pods can use the
`kubernetes.default` hostname to query the API server. Official client libraries
do this automatically.
From within a Pod, the recommended way to authenticate to the API server is with a
[service account](/docs/user-guide/service-accounts) credential. By default, a Pod
is associated with a service account, and a credential (token) for that
service account is placed into the filesystem tree of each container in that pod,
service account is placed into the filesystem tree of each container in that Pod,
at `/var/run/secrets/kubernetes.io/serviceaccount/token`.
If available, a certificate bundle is placed into the filesystem tree of each
container at `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`, and should be
used to verify the serving certificate of the apiserver.
used to verify the serving certificate of the API server.
Finally, the default namespace to be used for namespaced API operations is placed in a file
at `/var/run/secrets/kubernetes.io/serviceaccount/namespace` in each container.
From within a pod the recommended ways to connect to API are:
From within a Pod, the recommended ways to connect to the Kubernetes API are:
- run a kubectl proxy as one of the containers in the pod, or as a background
process within a container. This proxies the
Kubernetes API to the localhost interface of the pod, so that other processes
in any container of the pod can access it. See this [example of using kubectl proxy
in a pod](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/kubectl-container/).
- use the Go client library, and create a client using the `rest.InClusterConfig()` and `kubernetes.NewForConfig()` functions.
They handle locating and authenticating to the apiserver. [example](https://git.k8s.io/client-go/examples/in-cluster-client-configuration/main.go)
- Use one of the official [client libraries](/docs/reference/client-libraries/)
as they handle API host discovery and authentication automatically.
For Go client, the `rest.InClusterConfig()` function assists with this.
See [an example here](https://git.k8s.io/client-go/examples/in-cluster-client-configuration/main.go).
In each case, the credentials of the pod are used to communicate securely with the apiserver.
- If you would like to query the API without an official client library, you can run `kubectl proxy`
as the [command](/docs/tasks/inject-data-application/define-command-argument-container/)
of a new sidecar container in the Pod. This way, `kubectl proxy` will authenticate
to the API and expose it on the `localhost` interface of the Pod, so that other containers
in the Pod can use it directly.
In each case, the service account credentials of the Pod are used to communicate
securely with the API server.
{% endcapture %}
@@ -27,12 +27,12 @@ You have several options for connecting to nodes, pods and services from outside
- Access services through public IPs.
- Use a service with type `NodePort` or `LoadBalancer` to make the service reachable outside
the cluster. See the [services](/docs/user-guide/services) and
[kubectl expose](/docs/user-guide/kubectl/v1.6/#expose) documentation.
[kubectl expose](/docs/user-guide/kubectl/{{page.version}}/#expose) documentation.
- Depending on your cluster environment, this may just expose the service to your corporate network,
or it may expose it to the internet. Think about whether the service being exposed is secure.
Does it do its own authentication?
- Place pods behind services. To access one specific pod from a set of replicas, such as for debugging,
place a unique label on the pod it and create a new service which selects this label.
place a unique label on the pod and create a new service which selects this label.
- In most cases, it should not be necessary for application developer to directly access
nodes via their nodeIPs.
- Access services, nodes, or pods using the Proxy Verb.
@@ -43,11 +43,11 @@ You have several options for connecting to nodes, pods and services from outside
- Only works for HTTP/HTTPS.
- Described [here](#manually-constructing-apiserver-proxy-urls).
- Access from a node or pod in the cluster.
- Run a pod, and then connect to a shell in it using [kubectl exec](/docs/user-guide/kubectl/v1.6/#exec).
- Run a pod, and then connect to a shell in it using [kubectl exec](/docs/user-guide/kubectl/{{page.version}}/#exec).
Connect to other nodes, pods, and services from that shell.
- Some clusters may allow you to ssh to a node in the cluster. From there you may be able to
access cluster services. This is a non-standard method, and will work on some clusters but
not others. Browsers and other tools may or may not be installed. Cluster DNS may not work.
- Some clusters may allow you to ssh to a node in the cluster. From there you may be able to
access cluster services. This is a non-standard method, and will work on some clusters but
not others. Browsers and other tools may or may not be installed. Cluster DNS may not work.
### Discovering builtin services
@@ -102,7 +102,7 @@ If you haven't specified a name for your port, you don't have to specify *port_n
You may be able to put an apiserver proxy URL into the address bar of a browser. However:
- Web browsers cannot usually pass tokens, so you may need to use basic (password) auth. Apiserver can be configured to accept basic auth,
- Web browsers cannot usually pass tokens, so you may need to use basic (password) auth. Apiserver can be configured to accept basic auth,
but your cluster may not be configured to accept basic auth.
- Some web apps may not work, particularly those with client side javascript that construct URLs in a
way that is unaware of the proxy path prefix.
@@ -55,7 +55,7 @@ There are two main components to be aware of:
{% endcapture %}
{% capture whatsnext %}
Once your cluster is running, you can follow the [NetworkPolicy getting started guide](/docs/getting-started-guides/network-policy/walkthrough) to try out Kubernetes NetworkPolicy.
Once your cluster is running, you can follow the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/) to try out Kubernetes NetworkPolicy.
{% endcapture %}
{% include templates/task.md %}
@@ -21,7 +21,7 @@ PersistentVolume.
"Recycle", and "Delete". For dynamically provisioned `PersistentVolumes`,
the default reclaim policy is "Delete". This means that a dynamically provisioned
volume is automatically deleted when a user deletes the corresponding
`PeristentVolumeClaim`. This automatic behavior might be inappropriate if the volume
`PersistentVolumeClaim`. This automatic behavior might be inappropriate if the volume
contains precious data. In that case, it is more appropriate to use the "Retain"
policy. With the "Retain" policy, if a user deletes a `PersistentVolumeClaim`,
the corresponding `PersistentVolume` is not be deleted. Instead, it is moved to the
@@ -1,5 +1,5 @@
---
assignees:
approvers:
- danwent
title: Use Cilium for NetworkPolicy
---
@@ -72,7 +72,7 @@ There are two main components to be aware of:
{% endcapture %}
{% capture whatsnext %}
Once your cluster is running, you can follow the [NetworkPolicy getting started guide](/docs/getting-started-guides/network-policy/walkthrough) to try out Kubernetes NetworkPolicy with Cilium. Have fun, and if you have questions, contact us using the [Cilium Slack Channel](https://cilium.herokuapp.com/).
Once your cluster is running, you can follow the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/) to try out Kubernetes NetworkPolicy with Cilium. Have fun, and if you have questions, contact us using the [Cilium Slack Channel](https://cilium.herokuapp.com/).
{% endcapture %}
{% include templates/task.md %}
@@ -15,7 +15,7 @@ running cluster.
## Creating and configuring a Cluster
To install Kubernetes on a set of machines, consult one of the existing [Getting Started guides](/docs/getting-started-guides/) depending on your environment.
To install Kubernetes on a set of machines, consult one of the existing [Getting Started guides](/docs/setup/) depending on your environment.
## Upgrading a cluster
@@ -49,12 +49,11 @@ Alternatively, to upgrade your entire cluster to the latest stable release:
cluster/gce/upgrade.sh release/stable
```
### Upgrading Google Container Engine (GKE) clusters
### Upgrading Google Kubernetes Engine clusters
Google Container Engine automatically updates master components (e.g. `kube-apiserver`, `kube-scheduler`) to the latest
version. It also handles upgrading the operating system and other components that the master runs on.
Google Kubernetes Engine automatically updates master components (e.g. `kube-apiserver`, `kube-scheduler`) to the latest version. It also handles upgrading the operating system and other components that the master runs on.
The node upgrade process is user-initiated and is described in the [GKE documentation.](https://cloud.google.com/container-engine/docs/clusters/upgrade)
The node upgrade process is user-initiated and is described in the [Google Kubernetes Engine documentation](https://cloud.google.com/kubernetes-engine/docs/clusters/upgrade).
### Upgrading clusters on other platforms
@@ -68,7 +67,7 @@ Different providers, and tools, will manage upgrades differently. It is recomme
## Resizing a cluster
If your cluster runs short on resources you can easily add more machines to it if your cluster is running in [Node self-registration mode](/docs/admin/node/#self-registration-of-nodes).
If you're using GCE or GKE it's done by resizing Instance Group managing your Nodes. It can be accomplished by modifying number of instances on `Compute > Compute Engine > Instance groups > your group > Edit group` [Google Cloud Console page](https://console.developers.google.com) or using gcloud CLI:
If you're using GCE or Google Kubernetes Engine it's done by resizing Instance Group managing your Nodes. It can be accomplished by modifying number of instances on `Compute > Compute Engine > Instance groups > your group > Edit group` [Google Cloud Console page](https://console.developers.google.com) or using gcloud CLI:
```shell
gcloud compute instance-groups managed resize kubernetes-minion-group --size=42 --zone=$ZONE
@@ -80,7 +79,7 @@ In other environments you may need to configure the machine yourself and tell th
### Cluster autoscaling
If you are using GCE or GKE, you can configure your cluster so that it is automatically rescaled based on
If you are using GCE or Google Kubernetes Engine, you can configure your cluster so that it is automatically rescaled based on
pod needs.
As described in [Compute Resource](/docs/concepts/configuration/manage-compute-resources-container/), users can reserve how much CPU and memory is allocated to pods.
@@ -91,10 +90,10 @@ to wait until some pods are terminated or a new node is added.
Cluster autoscaler looks for the pods that cannot be scheduled and checks if adding a new node, similar
to the other in the cluster, would help. If yes, then it resizes the cluster to accommodate the waiting pods.
Cluster autoscaler also scales down the cluster if it notices that some node is not needed anymore for
Cluster autoscaler also scales down the cluster if it notices that one or more nodes are not needed anymore for
an extended period of time (10min but it may change in the future).
Cluster autoscaler is configured per instance group (GCE) or node pool (GKE).
Cluster autoscaler is configured per instance group (GCE) or node pool (Google Kubernetes Engine).
If you are using GCE then you can either enable it while creating a cluster with kube-up.sh script.
To configure cluster autoscaler you have to set three environment variables:
@@ -109,7 +108,7 @@ Example:
KUBE_ENABLE_CLUSTER_AUTOSCALER=true KUBE_AUTOSCALER_MIN_NODES=3 KUBE_AUTOSCALER_MAX_NODES=10 NUM_NODES=5 ./cluster/kube-up.sh
```
On GKE you configure cluster autoscaler either on cluster creation or update or when creating a particular node pool
On Google Kubernetes Engine you configure cluster autoscaler either on cluster creation or update or when creating a particular node pool
(which you want to be autoscaled) by passing flags `--enable-autoscaling` `--min-nodes` and `--max-nodes`
to the corresponding `gcloud` commands.
@@ -198,4 +197,4 @@ You can use `kubectl convert` command to convert config files between different
kubectl convert -f pod.yaml --output-version v1
```
For more options, please refer to the usage of [kubectl convert](/docs/user-guide/kubectl/v1.6/#convert) command.
For more options, please refer to the usage of [kubectl convert](/docs/user-guide/kubectl/{{page.version}}/#convert) command.
@@ -58,7 +58,7 @@ for this example. A [Deployment](/docs/concepts/workloads/controllers/deployment
thereby making the scheduler resilient to failures. Here is the deployment
config. Save it as `my-scheduler.yaml`:
{% include code.html language="yaml" file="my-scheduler.yaml" ghlink="/docs/tutorials/clusters/my-scheduler.yaml" %}
{% include code.html language="yaml" file="my-scheduler.yaml" ghlink="/docs/tasks/administer-cluster/my-scheduler.yaml" %}
An important thing to note here is that the name of the scheduler specified as an
argument to the scheduler command in the container spec should be unique. This is the name that is matched against the value of the optional `spec.schedulerName` on pods, to determine whether this scheduler is responsible for scheduling a particular pod.
@@ -131,7 +131,7 @@ scheduler in that pod spec. Let's look at three examples.
- Pod spec without any scheduler name
{% include code.html language="yaml" file="pod1.yaml" ghlink="/docs/tutorials/clusters/pod1.yaml" %}
{% include code.html language="yaml" file="pod1.yaml" ghlink="/docs/tasks/administer-cluster/pod1.yaml" %}
When no scheduler name is supplied, the pod is automatically scheduled using the
default-scheduler.
@@ -144,7 +144,7 @@ kubectl create -f pod1.yaml
- Pod spec with `default-scheduler`
{% include code.html language="yaml" file="pod2.yaml" ghlink="/docs/tutorials/clusters/pod2.yaml" %}
{% include code.html language="yaml" file="pod2.yaml" ghlink="/docs/tasks/administer-cluster/pod2.yaml" %}
A scheduler is specified by supplying the scheduler name as a value to `spec.schedulerName`. In this case, we supply the name of the
default scheduler which is `default-scheduler`.
@@ -157,7 +157,7 @@ kubectl create -f pod2.yaml
- Pod spec with `my-scheduler`
{% include code.html language="yaml" file="pod3.yaml" ghlink="/docs/tutorials/clusters/pod3.yaml" %}
{% include code.html language="yaml" file="pod3.yaml" ghlink="/docs/tasks/administer-cluster/pod3.yaml" %}
In this case, we specify that this pod should be scheduled using the scheduler that we
deployed - `my-scheduler`. Note that the value of `spec.schedulerName` should match the name supplied to the scheduler
@@ -40,9 +40,7 @@ Use a single-node etcd cluster only for testing purpose.
1. Run the following:
``` bash
./etcd --client-listen-urls=http://$PRIVATE_IP:2379 --client-advertise-urls=http://$PRIVATE_IP:2379
```
./etcd --client-listen-urls=http://$PRIVATE_IP:2379 --client-advertise-urls=http://$PRIVATE_IP:2379
2. Start Kubernetes API server with the flag `--etcd-servers=$PRIVATE_IP:2379`.
@@ -84,17 +82,18 @@ To secure etcd, either set up firewall rules or use the security features provid
To configure etcd with secure peer communication, specify flags `--peer-key-file=peer.key` and `--peer-cert-file=peer.cert`, and use https as URL schema.
Similarly, to configure etcd with secure client communication, specify flags `--key-file=peer.key` and `--cert-file=peer.cert`, and use https as URL schema.
Similarly, to configure etcd with secure client communication, specify flags `--key-file=k8sclient.key` and `--cert-file=k8sclient.cert`, and use https as URL schema.
### Limiting access of etcd clusters
After configuring secure communication, restrict the access of etcd cluster to only the Kubernetes API server. Use TLS authentication to do so.
For example, consider key pairs `k8sclient.key` and `k8sclient.cert` that are trusted by the CA `etcd.ca`. When etcd is configured with `--client-cert-auth` along with TLS, it verifies the certificates from clients by using system CAs or the CA passed in by `--trusted-ca-file` flag. Specifying flags `--client-cert-auth=true` and `--trust-ca-file=etcd.ca` will restrict the access to clients with the certificate `k8sclient.cert`.
For example, consider key pairs `k8sclient.key` and `k8sclient.cert` that are trusted by the CA `etcd.ca`. When etcd is configured with `--client-cert-auth` along with TLS, it verifies the certificates from clients by using system CAs or the CA passed in by `--trusted-ca-file` flag. Specifying flags `--client-cert-auth=true` and `--trusted-ca-file=etcd.ca` will restrict the access to clients with the certificate `k8sclient.cert`.
Once etcd is configured correctly, only clients with valid certificates can access it. To give Kubernetes API server the access, configure it with the flags `--etcd-certfile=k8sclient.cert` and `--etcd-keyfile=k8sclient.key`.
**Note**: etcd authentication is not currently supported by Kubernetes. For more information, see the related issue [Support Basic Auth for Etcd v2](https://github.com/kubernetes/kubernetes/issues/23398).
{: .note}
## Replacing a failed etcd member
@@ -130,12 +129,11 @@ Though etcd keeps unique member IDs internally, it is recommended to use a uniqu
4. Start the newly added member on a machine with the IP `10.0.0.4`:
```bash
export ETCD_NAME="member4"
export ETCD_INITIAL_CLUSTER="member2=http://10.0.0.2:2380,member3=http://10.0.0.3:2380,member4=http://10.0.0.4:2380"
export ETCD_INITIAL_CLUSTER_STATE=existing
etcd [flags]
```
export ETCD_NAME="member4"
export ETCD_INITIAL_CLUSTER="member2=http://10.0.0.2:2380,member3=http://10.0.0.3:2380,member4=http://10.0.0.4:2380"
export ETCD_INITIAL_CLUSTER_STATE=existing
etcd [flags]
5. Do either of the following:
1. Update its `--etcd-servers` flag to make Kubernetes aware of the configuration changes, then restart the Kubernetes API server.
@@ -186,7 +184,7 @@ Before starting the restore operation, a snapshot file must be present. It can e
If the access URLs of the restored cluster is changed from the previous cluster, the Kubernetes API server must be reconfigured accordingly. In this case, restart Kubernetes API server with the flag `--etcd-servers=$NEW_ETCD_CLUSTER` instead of the flag `--etcd-servers=$OLD_ETCD_CLUSTER`. Replace `$NEW_ETCD_CLUSTER` and `$OLD_ETCD_CLUSTER` with the respective IP addresses. If a load balancer is used in front of an etcd cluster, you might need to update the load balancer instead.
If the majority of etcd members have permanently failed, the etcd cluster is considered failed. In this scenario, Kubernetes cannot make any changes to its current state. Although the scheduled pods might continue to run, no new pods can be scheduled. In such cases, recover the etcd cluster and potentially reconfigure Kubernetes API server to fix the issue.
If the majority of etcd members have permanently failed, the etcd cluster is considered failed. In this scenario, Kubernetes cannot make any changes to its current state. Although the scheduled pods might continue to run, no new pods can be scheduled. In such cases, recover the etcd cluster and potentially reconfigure Kubernetes API server to fix the issue.
## Upgrading and rolling back etcd clusters
@@ -201,7 +199,8 @@ The upgrade procedure described in this document assumes that either:
etcd cluster. During the time the etcd cluster is shut down, the Kubernetes API Server will be read only.
**Warning**: Deviations from the assumptions are untested by continuous
integration, and deviations might create undesirable consequences. Additional information about operating an etcd cluster is available [from the etcd maintainers](https://github.com/coreos/etcd/tree/master/Documentation).
integration, and deviations might create undesirable consequences. Additional information about operating an etcd cluster is available [from the etcd maintainers](https://github.com/coreos/etcd/tree/master/Documentation).
{: .warning}
### Background
@@ -213,7 +212,7 @@ Note that we need to migrate both the etcd versions that we are using (from 2.2.
to at least 3.0.x) as well as the version of the etcd API that Kubernetes talks to. The etcd 3.0.x
binaries support both the v2 and v3 API.
This document describes how to do this migration. If you want to skip the
This document describes how to do this migration. If you want to skip the
background and cut right to the procedure, see [Upgrade
Procedure](#upgrade-procedure).
@@ -228,7 +227,7 @@ There are requirements on how an etcd cluster upgrade can be performed. The prim
Upgrade only one minor release at a time. For example, we cannot upgrade directly from 2.1.x to 2.3.x.
Within patch releases it is possible to upgrade and downgrade between arbitrary versions. Starting a cluster for
any intermediate minor release, waiting until the cluster is healthy, and then
shutting down the cluster down will perform the migration. For example, to upgrade from version 2.1.x to 2.3.y,
shutting down the cluster will perform the migration. For example, to upgrade from version 2.1.x to 2.3.y,
it is enough to start etcd in 2.2.z version, wait until it is healthy, stop it, and then start the
2.3.y version.
@@ -240,7 +239,7 @@ The etcd team has provided a [custom rollback tool](https://git.k8s.io/kubernete
but the rollback tool has these limitations:
* This custom rollback tool is not part of the etcd repo and does not receive the same
testing as the rest of etcd. We are testing it in a couple of end-to-end tests.
testing as the rest of etcd. We are testing it in a couple of end-to-end tests.
There is only community support here.
* The rollback can be done only from the 3.0.x version (that is using the v3 API) to the
@@ -253,6 +252,7 @@ but the rollback tool has these limitations:
**Warning**: If the data is not kept in `application/json` format (see [Upgrade
Procedure](#upgrade-procedure)), you will lose the option to roll back to etcd
2.2.
{: .warning}
The last bullet means that any component or user that has some logic
depending on resource versions may require restart after etcd rollback. This
@@ -263,13 +263,14 @@ rollback might require restarting all Kubernetes components on all nodes.
**Note**: At the time of writing, both Kubelet and KubeProxy are using “resource
version” only for watching (i.e. are not using resource versions for anything
else). And both are using reflector and/or informer frameworks for watching
(i.e. they dont send watch requests themselves). Both those frameworks if they
(i.e. they dont send watch requests themselves). Both those frameworks if they
cant renew watch, they will start from “current version” by doing “list + watch
from the resource version returned by list”. That means that if the apiserver
will be down for the period of rollback, all of node components should basically
restart their watches and start from “now” when apiserver is back. And it will
be back with new resource version. That would mean that restarting node
components is not needed. But the assumptions here may not hold forever.
components is not needed. But the assumptions here may not hold forever.
{: .note}
### Design
@@ -283,7 +284,7 @@ focus on them at all. We focus only on the upgrade/rollback here.
### New etcd Docker image
We decided to completely change the content of the etcd image and the way it works.
So far, the Docker image for etcd in version X has contained only the etcd and
So far, the Docker image for etcd in version X has contained only the etcd and
etcdctl binaries.
Going forward, the Docker image for etcd in version X will contain multiple
@@ -336,7 +337,7 @@ script works as follows:
1. Verify that the detected version is 3.0.x with the v3 API, and the
desired version is 2.2.1 with the v2 API. We dont support any other rollback.
1. If so, we run the custom tool provided by etcd team to do the offline
rollback. This tool reads the v3 formatted data and writes it back to disk
rollback. This tool reads the v3 formatted data and writes it back to disk
in v2 format.
1. Finally update the contents of the version file.
@@ -349,7 +350,7 @@ Simply modify the command line in the etcd manifest to:
Starting in Kubernetes version 1.6, this has been done in the manifests for new
Google Compute Engine clusters. You should also specify these environment
variables. In particular,you must keep `STORAGE_MEDIA_TYPE` set to
variables. In particular, you must keep `STORAGE_MEDIA_TYPE` set to
`application/json` if you wish to preserve the option to roll back.
```
@@ -7,7 +7,7 @@ title: Configure Minimum and Maximum CPU Constraints for a Namespace
This page shows how to set minimum and maximum values for the CPU resources used by Containers
and Pods in a namespace. You specify minimum and maximum CPU values in a
[LimitRange](/docs/api-reference/v1.6/#limitrange-v1-core)
[LimitRange](/docs/api-reference/{{page.version}}/#limitrange-v1-core)
object. If a Pod does not meet the constraints imposed by the LimitRange, it cannot be created
in the namespace.
@@ -79,6 +79,11 @@ CPU request and limit to the Container.
* Verify that the Container specifies a CPU limit that is less than or equal to 800 millicpu.
**Note:** When creating a `LimitRange` object, you can specify limits on huge-pages
or GPUs as well. However, when both `default` and `defaultRequest` are specified
on these resources, the two values must be the same.
{: .note}
Here's the configuration file for a Pod that has one Container. The Container manifest
specifies a CPU request of 500 millicpu and a CPU limit of 800 millicpu. These satisfy the
minimum and maximum CPU constraints imposed by the LimitRange.
@@ -95,7 +95,7 @@ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-defaults-pod-
View the Pod specification:
```
kubectl get pod cpu-limit-no-request --output=yaml --namespace=default-cpu-example
kubectl get pod default-cpu-demo-2 --output=yaml --namespace=default-cpu-example
```
The output shows that the Container's CPU request is set to match its CPU limit.
@@ -122,6 +122,12 @@ Create the Pod:
kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-defaults-pod-3.yaml --namespace=default-cpu-example
```
View the Pod specification:
```
kubectl get pod default-cpu-demo-3 --output=yaml --namespace=default-cpu-example
```
The output shows that the Container's CPU request is set to the value specified in the
Container's configuration file. The Container's CPU limit is set to 1 cpu, which is the
default CPU limit for the namespace.
@@ -8,7 +8,7 @@ title: Control CPU Management Policies on the Node
Kubernetes keeps many aspects of how pods execute on nodes abstracted
from the user. This is by design.  However, some workloads require
stronger guarantees in terms of latency and/or performance in order to operate
acceptably.  The kubelet provides methods to enable more complex workload
acceptably. The kubelet provides methods to enable more complex workload
placement policies while keeping the abstraction free from explicit placement
directives.
@@ -151,7 +151,7 @@ spec:
```
This pod runs in the `Guaranteed` QoS class because `requests` are equal to `limits`.
And the container's resource limit for the CPU resource is an integer greater than
And the container's resource limit for the CPU resource is an integer greater than
or equal to one. The `nginx` container is granted 2 exclusive CPUs.
@@ -186,7 +186,6 @@ spec:
```
This pod runs in the `Guaranteed` QoS class because only `limits` are specified
and `requests` are set equal to `limits` when not explicitly specified. And the
container's resource limit for the CPU resource is an integer greater than or
equal to one.The `nginx` container is granted 2 exclusive CPUs.
and `requests` are set equal to `limits` when not explicitly specified. And the
container's resource limit for the CPU resource is an integer greater than or
equal to one. The `nginx` container is granted 2 exclusive CPUs.
@@ -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
@@ -114,10 +114,10 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{“consul.local”: [“10.150.0.1”]}
namespace: kube-system
data:
stubDomains: |
{“consul.local”: [“10.150.0.1”]}
```
Note that the cluster administrator did not wish to override the nodes
@@ -136,10 +136,10 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
upstreamNameservers: |
[“172.16.0.1”]
namespace: kube-system
data:
upstreamNameservers: |
[“172.16.0.1”]
```
{% endcapture %}
@@ -28,7 +28,7 @@ The ip-masq-agent configures iptables rules to hide a pod's IP address behind th
* **Link Local**
A link-local address is a network address that is valid only for communications within the network segment or the broadcast domain that the host is connected to. Link-local addresses for IPv4 are defined in the address block 169.254.0.0/16 in CIDR notation.
The ip-masq-agent configures iptables rules to handle masquerading node/pod IP addresses when sending traffic to destinations outside the cluster node's IP and the Cluster IP range. This essentially hides pod IP addresses behind the cluster node's IP address. In some environments, traffic to "external" addresses must come from a known machine address. For example, in Google Cloud, any traffic to the internet must come from a VM's IP. When containers are used, as in GKE, the Pod IP will be rejected for egress. To avoid this, we must hide the Pod IP behind the VM's own IP address - generally known as "masquerade". By default, the agent is configured to treat the three private IP ranges specified by [RFC 1918](https://tools.ietf.org/html/rfc1918) as non-masquerade [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). These ranges are 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. The agent will also treat link-local (169.254.0.0/16) as a non-masquerade CIDR by default. The agent is configured to reload its configuration from the location */etc/config/ip-masq-agent* every 60 seconds, which is also configurable.
The ip-masq-agent configures iptables rules to handle masquerading node/pod IP addresses when sending traffic to destinations outside the cluster node's IP and the Cluster IP range. This essentially hides pod IP addresses behind the cluster node's IP address. In some environments, traffic to "external" addresses must come from a known machine address. For example, in Google Cloud, any traffic to the internet must come from a VM's IP. When containers are used, as in Google Kubernetes Engine, the Pod IP will be rejected for egress. To avoid this, we must hide the Pod IP behind the VM's own IP address - generally known as "masquerade". By default, the agent is configured to treat the three private IP ranges specified by [RFC 1918](https://tools.ietf.org/html/rfc1918) as non-masquerade [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). These ranges are 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. The agent will also treat link-local (169.254.0.0/16) as a non-masquerade CIDR by default. The agent is configured to reload its configuration from the location */etc/config/ip-masq-agent* every 60 seconds, which is also configurable.
![masq/non-masq example](/images/docs/ip-masq.png)
@@ -50,7 +50,7 @@ MASQUERADE all -- anywhere anywhere /* ip-masq-agent:
```
By default, in GCE/GKE starting with Kubernetes version 1.7.0, if network policy is enabled or you are using a cluster CIDR not in the 10.0.0.0/8 range, the ip-masq-agent will run in your cluster. If you are running in another environment, you can add the ip-masq-agent [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) to your cluster:
By default, in GCE/Google Kubernetes Engine starting with Kubernetes version 1.7.0, if network policy is enabled or you are using a cluster CIDR not in the 10.0.0.0/8 range, the ip-masq-agent will run in your cluster. If you are running in another environment, you can add the ip-masq-agent [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) to your cluster:
{% endcapture %}
@@ -18,8 +18,7 @@ The Kube-router Addon comes with a Network Policy Controller that watches Kubern
{% endcapture %}
{% capture whatsnext %}
Once you have installed the Kube-router addon, you can follow the [NetworkPolicy getting started guide](/docs/getting-started-guides/network-policy/walkthrough) to try out Kubernetes NetworkPolicy.
Once you have installed the Kube-router addon, you can follow the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/) to try out Kubernetes NetworkPolicy.
{% endcapture %}
{% include templates/task.md %}
@@ -41,6 +41,12 @@ $ export ARCH=amd64 # or: arm, arm64, ppc64le, s390x
$ curl -sSL https://dl.k8s.io/release/${VERSION}/bin/linux/${ARCH}/kubeadm > /usr/bin/kubeadm
$ chmod a+rx /usr/bin/kubeadm
```
**Caution:** Upgrading the `kubeadm` package on your system prior to
upgrading the control plane causes a failed upgrade. Even though
`kubeadm` is shipped in the Kubernetes repositories, it's important
to install `kubeadm` manually. The kubeadm team is working on fixing
this limitation.
{: .caution}
Verify that this download of kubeadm works, and has the expected version:
@@ -79,7 +85,7 @@ $ kubeadm upgrade plan
[upgrade/health] Checking Static Pod manifests exists on disk: All manifests exist on disk
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[upgrade] Fetching available versions to upgrade to:
[upgrade/versions] Cluster version: v1.7.1
[upgrade/versions] kubeadm version: v1.8.0
@@ -140,7 +146,7 @@ $ kubeadm upgrade apply v1.8.0
[upgrade/health] Checking Static Pod manifests exists on disk: All manifests exist on disk
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[upgrade/version] You have chosen to upgrade to version "v1.8.0"
[upgrade/versions] Cluster version: v1.7.1
[upgrade/versions] kubeadm version: v1.8.0
@@ -202,6 +208,12 @@ $ kubeadm upgrade apply v1.8.0
find your CNI provider and see if there are additional upgrade steps
necessary.
6. Add RBAC permissions for automated certificate rotation. In the future, kubeadm will perform this step automatically:
```shell
$ kubectl create clusterrolebinding kubeadm:node-autoapprove-certificate-rotation --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient --group=system:nodes
```
## Upgrading your master and node packages
For each host (referred to as `$HOST` below) in your cluster, upgrade `kubelet` by executing the following commands:
@@ -240,28 +252,13 @@ Now the new version of the `kubelet` should be running on the host. Verify this
$ systemctl status kubelet
```
3. Since certificate rotation is enabled by default, you may need to manually approve the new kubelet's CertificateSigningRequest before it can rejoin the cluster:
```shell
$ kubectl get csr | grep -v Approved
NAME AGE REQUESTOR CONDITION
node-csr-czl32tarZb_XYKnvXf0Q0o4spGUXzJhN2p4_ld7k1iM 2h system:bootstrap:033abb Pending
```
If you see any CSRs listed that aren't already approved, you can manually approve them using kubectl:
```shell
$ kubectl certificate approve node-csr-czl32tarZb_XYKnvXf0Q0o4spGUXzJhN2p4_ld7k1iM
certificatesigningrequest "node-csr-czl32tarZb_XYKnvXf0Q0o4spGUXzJhN2p4_ld7k1iM" approved
```
4. Bring the host back online by marking it schedulable:
3. Bring the host back online by marking it schedulable:
```shell
$ kubectl uncordon $HOST
```
5. After upgrading `kubelet` on each host in your cluster, verify that all nodes are available again by executing the following (from anywhere, for example, from outside the cluster):
4. After upgrading `kubelet` on each host in your cluster, verify that all nodes are available again by executing the following (from anywhere, for example, from outside the cluster):
```shell
$ kubectl get nodes
@@ -0,0 +1,70 @@
---
approvers:
- mtaufen
- dawnchen
title: Set Kubelet parameters via a config file
---
{% capture overview %}
{% include feature-state-alpha.md %}
As of Kubernetes 1.8, a subset of the Kubelet's configuration parameters may be
set via an on-disk config file, as a substitute for command-line flags. In the
future, most of the existing command-line flags will be deprecated in favor of
providing parameters via a config file, which simplifies node deployment.
{% endcapture %}
{% capture prerequisites %}
- A v1.8 or higher Kubelet binary must be installed.
{% endcapture %}
{% capture steps %}
## Create the config file
The subset of the Kubelet's configuration that can be configured via a file
is defined by the `KubeletConfiguration` struct
[here (v1alpha1)](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/apis/kubeletconfig/v1alpha1/types.go).
The configuration file must be a JSON or YAML representation of the parameters
in this struct. Note that this structure, and thus the config file API,
is still considered alpha and is not subject to stability gurarantees.
Create a file named `kubelet` in its own directory and make sure the directory
and file are both readable by the Kubelet. You should write your intended
Kubelet configuration in this `kubelet` file.
For a trick to generate a configuration file from a live node, see
[Reconfigure a Node's Kubelet in a Live Cluster](/docs/tasks/administer-cluster/reconfigure-kubelet).
## Start a Kubelet process configured via the config file
Start the Kubelet with the `KubeletConfigFile` feature gate enabled and the
Kubelet's `--init-config-dir` flag set to the location of the directory
containing the `kubelet` file. The Kubelet will then load the parameters defined
by `KubeletConfiguration` from the `kubelet` file, rather than from their
associated command-line flags.
{% endcapture %}
{% capture discussion %}
## Relationship to Dynamic Kubelet Config
If you are using the [Dynamic Kubelet Configuration](/docs/tasks/administer-cluster/reconfigure-kubelet)
feature, the configuration provided via `--init-config-dir` will be considered
the "last known good" configuration by the automatic rollback mechanism.
Note that the layout of the files in the `--init-config-dir` mirrors the layout
of data in the ConfigMaps used for Dynamic Kubelet Config; the file names are
the same as the keys of the ConfigMap, and the file contents are JSON or YAML
representations of the same structures. Today, the only pair is
`kubelet:KubeletConfiguration`, though more may emerge in the future.
See [Reconfigure a Node's Kubelet in a Live Cluster](/docs/tasks/administer-cluster/reconfigure-kubelet)
for more information.
{% endcapture %}
{% include templates/task.md %}
@@ -7,7 +7,7 @@ title: Limit Storage Consumption
This example demonstrates an easy way to limit the amount of storage consumed in a namespace.
The following resources are used in the demonstration: [ResourceQuota](/docs/concepts/policy/resource-quotas/),
[LimitRange](/docs/tasks/configure-pod-container/limit-range/),
[LimitRange](/docs/tasks/administer-cluster/memory-default-namespace/),
and [PersistentVolumeClaim](/docs/concepts/storage/persistent-volumes/).
{% endcapture %}
@@ -7,7 +7,7 @@ title: Configure Minimum and Maximum Memory Constraints for a Namespace
This page shows how to set minimum and maximum values for memory used by Containers
running in a namespace. You specify minimum and maximum memory values in a
[LimitRange](/docs/api-reference/v1.6/#limitrange-v1-core)
[LimitRange](/docs/api-reference/{{page.version}}/#limitrange-v1-core)
object. If a Pod does not meet the constraints imposed by the LimitRange,
it cannot be created in the namespace.
@@ -49,7 +49,7 @@ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-constraint
View detailed information about the LimitRange:
```shell
kubectl get limitrange cpu-min-max-demo --namespace=constraints-mem-example --output=yaml
kubectl get limitrange mem-min-max-demo-lr --namespace=constraints-mem-example --output=yaml
```
The output shows the minimum and maximum memory constraints as expected. But
@@ -15,7 +15,7 @@ Kubernetes assigns a default memory request under certain conditions that are ex
{% include task-tutorial-prereqs.md %}
Each node in your cluster must have at least 300 GiB of memory.
Each node in your cluster must have at least 2 GiB of memory.
{% endcapture %}
@@ -20,7 +20,7 @@ This example demonstrates how to use Kubernetes namespaces to subdivide your clu
This example assumes the following:
1. You have an [existing Kubernetes cluster](/docs/getting-started-guides/).
1. You have an [existing Kubernetes cluster](/docs/setup/).
2. You have a basic understanding of Kubernetes _[Pods](/docs/concepts/workloads/pods/pod/)_, _[Services](/docs/concepts/services-networking/service/)_, and _[Deployments](/docs/concepts/workloads/controllers/deployment/)_.
### Step One: Understand the default namespace
@@ -152,7 +152,7 @@ $ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2
```
We have just created a deployment whose replica size is 2 that is running the pod called snowflake with a basic container that just serves the hostname.
Note that `kubectl run` creates deployments only on Kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead.
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/v1.6/#run) for more details.
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/{{page.version}}/#run) for more details.
```shell
$ kubectl get deployment
+3 -3
View File
@@ -10,7 +10,7 @@ This page shows how to view, work in, and delete namespaces. The page also shows
{% endcapture %}
{% capture prerequisites %}
* Have an [existing Kubernetes cluster](/docs/getting-started-guides/).
* Have an [existing Kubernetes cluster](/docs/setup/).
* Have a basic understanding of Kubernetes _[Pods](/docs/concepts/workloads/pods/pod/)_, _[Services](/docs/concepts/services-networking/service/)_, and _[Deployments](/docs/concepts/workloads/controllers/deployment/)_.
{% endcapture %}
@@ -238,7 +238,7 @@ $ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2
```
We have just created a deployment whose replica size is 2 that is running the pod called snowflake with a basic container that just serves the hostname.
Note that `kubectl run` creates deployments only on Kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead.
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/v1.7/#run) for more details.
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/{{page.version}}/#run) for more details.
```shell
$ kubectl get deployment
@@ -334,7 +334,7 @@ Use cases include:
## Understanding namespaces and DNS
When you create a [Service](/docs/concepts/services-networking/service/), it creates a corresponding [DNS entry](/docs/admin/dns).
When you create a [Service](/docs/concepts/services-networking/service/), it creates a corresponding [DNS entry](/docs/concepts/services-networking/dns-pod-service/).
This entry is of the form `<service-name>.<namespace-name>.svc.cluster.local`, which means
that if a container just uses `<service-name>` it will resolve to the service which
is local to a namespace. This is useful for using the same configuration across
@@ -9,7 +9,7 @@ This page shows how to configure quotas for API objects, including
PersistentVolumeClaims and Services. A quota restricts the number of
objects, of a particular type, that can be created in a namespace.
You specify quotas in a
[ResourceQuota](/docs/api-reference/v1.7/#resourcequota-v1-core)
[ResourceQuota](/docs/api-reference/{{page.version}}/#resourcequota-v1-core)
object.
{% endcapture %}
@@ -53,7 +53,7 @@ kubectl get resourcequota object-quota-demo --namespace=quota-object-example --o
The output shows that in the quota-object-example namespace, there can be at most
one PersistentVolumeClaim, at most two Services of type LoadBalancer, and no Services
of type NodePort.
of type NodePort.
```yaml
status:
@@ -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:
@@ -7,7 +7,7 @@ title: Configure Memory and CPU Quotas for a Namespace
This page shows how to set quotas for the total amount memory and CPU that
can be used by all Containers running in a namespace. You specify quotas in a
[ResourceQuota](/docs/api-reference/v1.7/#resourcequota-v1-core)
[ResourceQuota](/docs/api-reference/{{page.version}}/#resourcequota-v1-core)
object.
{% endcapture %}
@@ -7,7 +7,7 @@ title: Configure a Pod Quota for a Namespace
This page shows how to set a quota for the total number of Pods that can run
in a namespace. You specify quotas in a
[ResourceQuota](/docs/api-reference/v1.7/#resourcequota-v1-core)
[ResourceQuota](/docs/api-reference/{{page.version}}/#resourcequota-v1-core)
object.
{% endcapture %}
@@ -89,12 +89,13 @@ and debug issues. The compromise, however, is that you must start with knowledge
of the existing configuration to ensure that you only change the fields you
intend to change.
In the future, the Kubelet will be bootstrapped from a file on disk, and you
will simply edit a copy of this file (which, as a best practice, should live in
version control) while creating the first Kubelet ConfigMap. Today, however, the
Kubelet is still bootstrapped with command-line flags. Fortunately, there is a
dirty trick you can use to generate a config file containing a Node's current
configuration. The trick involves hitting the Kubelet server's `configz`
In the future, the Kubelet will be bootstrapped from a file on disk
(see [Set Kubelet parameters via a config file](/docs/tasks/administer-cluster/kubelet-config-file)),
and you will simply edit a copy of this file (which, as a best practice, should
live in version control) while creating the first Kubelet ConfigMap. Today,
however, the Kubelet is still bootstrapped with command-line flags. Fortunately,
there is a dirty trick you can use to generate a config file containing a Node's
current configuration. The trick involves hitting the Kubelet server's `configz`
endpoint via the kubectl proxy. This endpoint, in its current implementation, is
intended to be used only as a debugging aid, which is part of why this is a
dirty trick. There is ongoing work to improve the endpoint, and in the future
@@ -158,7 +159,7 @@ because this ConfigMap configures a Kubernetes system component - the Kubelet.
The `--append-hash` option appends a short checksum of the ConfigMap contents
to the name. This is convenient for an edit->push workflow, as it will
automatically, yet deterministically, generate new names for new ConfigMaps.
automatically, yet deterministically, generate new names for new ConfigMaps.
We use the `-o yaml` output format so that the name, namespace, and uid are all
reported following creation. We will need these in the next step. We will refer
@@ -167,7 +168,7 @@ to the name as CONFIG_MAP_NAME and the uid as CONFIG_MAP_UID.
### Authorize your Node to read the new ConfigMap
Now that you've created a new ConfigMap, you need to authorize your node to
read it. First, create a Role for your new ConfigMap with the
read it. First, create a Role for your new ConfigMap with the
following commands:
```
@@ -182,7 +183,7 @@ $ kubectl -n kube-system create rolebinding ${CONFIG_MAP_NAME}-reader --role=${C
```
Once the Node Authorizer is updated to do this automatically, you will
be able to skip this step.
be able to skip this step.
### Set the Node to use the new configuration
@@ -255,7 +256,7 @@ as NEW_CONFIG_MAP_UID.
### Authorize your Node to read the new ConfigMap
Now that you've created a new ConfigMap, you need to authorize your node to
read it. First, create a Role for your new ConfigMap with the
read it. First, create a Role for your new ConfigMap with the
following commands:
```
@@ -270,7 +271,7 @@ $ kubectl -n kube-system create rolebinding ${NEW_CONFIG_MAP_NAME}-reader --role
```
Once the Node Authorizer is updated to do this automatically, you will
be able to skip this step.
be able to skip this step.
### Configure the Node to use the new configuration
@@ -27,19 +27,15 @@ Follow the [containerized installation guide](https://github.com/romana/romana/t
To apply network policies use one of the following:
* [Romana network policies](https://github.com/romana/romana/wiki/Romana-policies).
* [Example of Romana network policy](https://github.com/romana/core/tree/master/policy).
* [Example of Romana network policy](https://github.com/romana/core/blob/master/doc/policy.md).
* The NetworkPolicy API.
{% endcapture %}
{% capture whatsnext %}
Once your have installed Romana, you can follow the [NetworkPolicy getting started guide](/docs/getting-started-guides/network-policy/walkthrough) to try out Kubernetes NetworkPolicy.
Once your have installed Romana, you can follow the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/) to try out Kubernetes NetworkPolicy.
{% endcapture %}
{% include templates/task.md %}
@@ -40,8 +40,8 @@ Successfully running cloud-controller-manager requires some changes to your clus
Keep in mind that setting up your cluster to use cloud controller manager will change your cluster behaviour in a few ways:
* kubelets specifying `--cloud-provider=external` will add a taint `node.cloudprovider.kubernetes.io/uninitialized` with an effect `NoSchedule` during initialization. This marks the node as needing a second initialization from an external controller before it can be scheduled work. Note that in the event that cloud controller manager is not available, new nodes in the cluster will be left unscheduable. The taint is important since the scheduler may require cloud specific information about nodes such as it's region or type (high cpu, gpu, high memory, spot instance, etc).
* cloud information about nodes in the cluster will no longer be retrieved using local metadata, but instead all API calls to retreive node information will go through cloud controller manager. This may mean you can restrict access to your cloud API on the kubelets for better security. For larger clusters you may want to consider if cloud controller manager will hit rate limits since it is now responsible for almost all API calls to your cloud from within the cluster.
* kubelets specifying `--cloud-provider=external` will add a taint `node.cloudprovider.kubernetes.io/uninitialized` with an effect `NoSchedule` during initialization. This marks the node as needing a second initialization from an external controller before it can be scheduled work. Note that in the event that cloud controller manager is not available, new nodes in the cluster will be left unschedulable. The taint is important since the scheduler may require cloud specific information about nodes such as their region or type (high cpu, gpu, high memory, spot instance, etc).
* cloud information about nodes in the cluster will no longer be retrieved using local metadata, but instead all API calls to retrieve node information will go through cloud controller manager. This may mean you can restrict access to your cloud API on the kubelets for better security. For larger clusters you may want to consider if cloud controller manager will hit rate limits since it is now responsible for almost all API calls to your cloud from within the cluster.
As of v1.8, cloud controller manager can implement:
@@ -78,13 +78,13 @@ Cloud controller manager does not implement any of the volume controllers found
### Scalability
In the previous architecture for cloud providers, we relied on kubelets using a local metadata service to retreive node information about itself. With this new architecture, we now fully rely on the cloud controller managers to retrieve information for all nodes. For very larger clusters, you should consider possible bottle necks such as resource requirements and API rate limiting.
In the previous architecture for cloud providers, we relied on kubelets using a local metadata service to retrieve node information about itself. With this new architecture, we now fully rely on the cloud controller managers to retrieve information for all nodes. For very larger clusters, you should consider possible bottle necks such as resource requirements and API rate limiting.
### Chicken and Egg
The goal of the cloud controller manager project is to decouple development of cloud features from the core Kubernetes project. Unforunately, many aspects of the Kubernetes project has assumptions that cloud provider features are tightly integrated into the project. As a result, adopting this new architecture can create several situations where a request is being made for information from a cloud provider, but the cloud controller manager may not be able to return that information without the original request being complete.
The goal of the cloud controller manager project is to decouple development of cloud features from the core Kubernetes project. Unfortunately, many aspects of the Kubernetes project has assumptions that cloud provider features are tightly integrated into the project. As a result, adopting this new architecture can create several situations where a request is being made for information from a cloud provider, but the cloud controller manager may not be able to return that information without the original request being complete.
A good example of this is the TLS bootstrapping feature in the Kubelet. Currently, TLS bootstraping assumes that the Kubelet has the ability to ask the cloud provider (or a local metadata service) for all its address types (private, public, etc) but cloud controller manager cannot set a node's address types without being initialzed in the first place which requires that the kubelet has TLS certificates to communicate with the apiserver.
A good example of this is the TLS bootstrapping feature in the Kubelet. Currently, TLS bootstrapping assumes that the Kubelet has the ability to ask the cloud provider (or a local metadata service) for all its address types (private, public, etc) but cloud controller manager cannot set a node's address types without being initialized in the first place which requires that the kubelet has TLS certificates to communicate with the apiserver.
As this initiative evolves, changes will be made to address these issues in upcoming releases.
@@ -123,7 +123,7 @@ prevent cross talk, or advanced networking policy.
By default, there are no restrictions on which nodes may run a pod. Kubernetes offers a
[rich set of policies for controlling placement of pods onto nodes](/docs/concepts/configuration/assign-pod-node/)
and the [taint based pod placement and eviction](/docs/concepts/configuration/taint-and-toleration)
and the [taint based pod placement and eviction](/docs/concepts/configuration/taint-and-toleration/)
that are available to end users. For many clusters use of these policies to separate workloads
can be a convention that authors adopt or enforce via tooling.
@@ -151,7 +151,7 @@ access to a subset of the keyspace is strongly recommended.
### Enable audit logging
The [audit logger](/docs/admin/audit/) is an alpha feature that records actions taken by the
The [audit logger](/docs/tasks/debug-application-cluster/audit/) is an alpha feature that records actions taken by the
API for later analysis in the event of a compromise. It is recommended to enable audit logging
and archive the audit file on a secure server.
+22 -22
View File
@@ -6,9 +6,9 @@ title: Static Pods
**If you are running clustered Kubernetes and are using static pods to run a pod on every node, you should probably be using a [DaemonSet](/docs/concepts/workloads/controllers/daemonset/)!**
*Static pods* are managed directly by kubelet daemon on a specific node, without API server observing it. It does not have associated any replication controller, kubelet daemon itself watches it and restarts it when it crashes. There is no health check though. Static pods are always bound to one kubelet daemon and always run on the same node with it.
*Static pods* are managed directly by kubelet daemon on a specific node, without the API server observing it. It does not have an associated replication controller, and kubelet daemon itself watches it and restarts it when it crashes. There is no health check. Static pods are always bound to one kubelet daemon and always run on the same node with it.
Kubelet automatically creates so-called *mirror pod* on Kubernetes API server for each static pod, so the pods are visible there, but they cannot be controlled from the API server.
Kubelet automatically creates so-called *mirror pod* on the Kubernetes API server for each static pod, so the pods are visible there, but they cannot be controlled from the API server.
## Static pod creation
@@ -16,7 +16,7 @@ Static pod can be created in two ways: either by using configuration file(s) or
### Configuration files
The configuration files are just standard pod definition in json or yaml format in specific directory. Use `kubelet --pod-manifest-path=<the directory>` to start kubelet daemon, which periodically scans the directory and creates/deletes static pods as yaml/json files appear/disappear there.
The configuration files are just standard pod definitions in json or yaml format in a specific directory. Use `kubelet --pod-manifest-path=<the directory>` to start kubelet daemon, which periodically scans the directory and creates/deletes static pods as yaml/json files appear/disappear there.
Note that kubelet will ignore files starting with dots when scanning the specified directory.
For example, this is how to start a simple web server as a static pod:
@@ -29,25 +29,25 @@ For example, this is how to start a simple web server as a static pod:
2. Choose a directory, say `/etc/kubelet.d` and place a web server pod definition there, e.g. `/etc/kubelet.d/static-web.yaml`:
```
[root@my-node1 ~] $ mkdir /etc/kubelet.d/
[root@my-node1 ~] $ cat <<EOF >/etc/kubelet.d/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
```shell
[root@my-node1 ~] $ mkdir /etc/kubelet.d/
[root@my-node1 ~] $ cat <<EOF >/etc/kubelet.d/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
EOF
```
containerPort: 80
protocol: TCP
EOF
```
3. Configure your kubelet daemon on the node to use this directory by running it with `--pod-manifest-path=/etc/kubelet.d/` argument.
On Fedora edit `/etc/kubernetes/kubelet` to include this line:
@@ -64,7 +64,7 @@ For example, this is how to start a simple web server as a static pod:
[root@my-node1 ~] $ systemctl restart kubelet
```
## Pods created via HTTP
### Pods created via HTTP
Kubelet periodically downloads a file specified by `--manifest-url=<URL>` argument and interprets it as a json/yaml file with a pod definition. It works the same as `--pod-manifest-path=<directory>`, i.e. it's reloaded every now and then and changes are applied to running static pods (see below).
@@ -18,19 +18,15 @@ Complete steps 1, 2, and 3 of the [kubeadm getting started guide](/docs/getting-
{% capture steps %}
## Installing Weave Net addon
## Install the Weave Net addon
Follow the [Integrating Kubernetes via the Addon](https://www.weave.works/docs/net/latest/kube-addon/) guide.
The Weave Net Addon for Kubernetes comes with a [Network Policy Controller](https://www.weave.works/docs/net/latest/kube-addon/#npc) that automatically monitors Kubernetes for any NetworkPolicy annotations on all namespaces and configures `iptables` rules to allow or block traffic as directed by the policies.
{% endcapture %}
{% capture example %}
The Weave Net addon for Kubernetes comes with a [Network Policy Controller](https://www.weave.works/docs/net/latest/kube-addon/#npc) that automatically monitors Kubernetes for any NetworkPolicy annotations on all namespaces and configures `iptables` rules to allow or block traffic as directed by the policies.
## Namespace isolation example
1. Create a namespace with `DefaultDeny`.
1. Create a Namespace with `DefaultDeny`.
```yaml
kind: Namespace
@@ -46,7 +42,7 @@ metadata:
}
```
2. Create 2 pods inside this namespace.
2. Create 2 Pods inside this Namespace.
```yaml
kind: Pod
@@ -74,15 +70,15 @@ spec:
image: nginx
```
3. Get the IP addresses of the pods.
3. Get the IP addresses of the Pods.
```shell
kubectl get po -n myns -o wide
```
**Note:** If your cURL requests to pods are forbidden, try making cURL requests to other pods from within a pod.
**Note:** If your cURL requests to Pods are forbidden, try making cURL requests to other Pods from within a Pod.
{: .note}
4. Create a Kubernetes NetworkPolicy that allows pods within the same namespace to connect with each other.
4. Create a Kubernetes NetworkPolicy that allows Pods within the same Namespace to connect with each other.
```yaml
apiVersion: networking.k8s.io/v1
@@ -103,12 +99,84 @@ spec:
**Caution:** After applying the network policy, pods outside the namespace you specify may be unable to connect with pods inside the namespace.
{. :caution}
{% endcapture %}
## Test the installation
1. Verify that the weave works.
Enter the following command:
```shell
kubectl get po -n kube-system -o wide
```
The output is similar to this:
```
NAME READY STATUS RESTARTS AGE IP NODE
weave-net-1t1qg 2/2 Running 0 9d 192.168.2.10 workndoe3
weave-net-231d7 2/2 Running 1 7d 10.2.0.17 worknodegpu
weave-net-7nmwt 2/2 Running 3 9d 192.168.2.131 masternode
weave-net-pmw8w 2/2 Running 0 9d 192.168.2.216 worknode2
```
Each Node has a weave Pod, and all Pods are `Running` and `2/2 READY`. (`2/2` means that each Pod has `weave` and `weave-npc`.)
2. Create a Network Policy.
For more information, see "[Declare Network Policy](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/)".
3. Check the logs.
After creating a NetworkPolicy, check the logs:
```shell
kubectl logs -f weave-net-pmw8w weave-npc -n kube-system
```
Log output looks like this:
```log
INFO: 2017/08/14 02:22:32.511992 EVENT AddNetworkPolicy {"metadata":{"name":"aaa","namespace":"myns","selfLink":"/apis/extensions/v1beta1/namespaces/myns/networkpolicies/aaa","uid":"67b229fd-8097-11e7-92f3-005056a3bc75","resourceVersion":"1507955","generation":1,"creationTimestamp":"2017-08-14T02:22:22Z"},"spec":{"podSelector":{"matchExpressions":[{"key":"inns","operator":"In","values":["yes"]}]},"ingress":[{"from":[{"podSelector":{"matchExpressions":[{"key":"inns","operator":"In","values":["yes"]}]}}]}]}}
INFO: 2017/08/14 02:22:32.512103 creating ipset: &npc.selectorSpec{key:"inns in (yes)", selector:labels.internalSelector{labels.Requirement{key:"inns", operator:"in", strValues:[]string{"yes"}}}, ipsetType:"hash:ip", ipsetName:"weave-[T]a=ETzaKA{o*muaFe:2IX(t"}
INFO: 2017/08/14 02:22:32.538003 adding rule: [-m set --match-set weave-[T]a=ETzaKA{o*muaFe:2IX(t src -m set --match-set weave-[T]a=ETzaKA{o*muaFe:2IX(t dst -j ACCEPT]
^[^C
```
4. Finally, check the logs for iptables.
```shell
iptables -L
```
The output is similar to this:
```iptables
Chain WEAVE-NPC (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all -- anywhere base-address.mcast.net/4
WEAVE-NPC-DEFAULT all -- anywhere anywhere state NEW
WEAVE-NPC-INGRESS all -- anywhere anywhere state NEW
ACCEPT all -- anywhere anywhere ! match-set weave-local-pods dst
Chain WEAVE-NPC-DEFAULT (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere match-set weave-iuZcey(5DeXbzgRFs8Szo]+@p dst
ACCEPT all -- anywhere anywhere match-set weave-k?Z;25^M}|1s7P3|H9i;*;MhG dst
ACCEPT all -- anywhere anywhere match-set weave-4vtqMI+kx/2]jD%_c0S%thO%V dst
Chain WEAVE-NPC-INGRESS (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere match-set weave-[T]a=ETzaKA{o*muaFe:2IX(t src match-set weave-[T]a=ETzaKA{o*muaFe:2IX(t dst
```
The match-set labels have been applied to iptables, so the weave is working correctly.
{% endcapture %}
{% capture whatsnext %}
Once you have installed the Weave Net addon, you can follow the [NetworkPolicy getting started guide](/docs/getting-started-guides/network-policy/walkthrough) to try out Kubernetes NetworkPolicy.
Once you have installed the Weave Net addon, you can follow the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/) to try out Kubernetes NetworkPolicy.
{% endcapture %}
+6 -2
View File
@@ -34,10 +34,14 @@ kubectl --context=federation get clusters
The `--context=federation` flag tells kubectl to submit the
request to the Federation apiserver instead of sending it to a Kubernetes
cluster. If you submit it to a k8s cluster, you will receive an error saying
`the server doesn't have a resource type "clusters"`
```the server doesn't have a resource type "clusters"```
If you passed the correct Federation context but received a message error saying
`No resources found.`, it means that you haven't
```No resources found.```
it means that you haven't
added any cluster to the Federation yet.
## Creating a Federated Cluster
@@ -66,7 +66,7 @@ if you have 3 registered clusters and you create a Federated Deployment with
`spec.replicas = 9`, then each Deployment in the 3 clusters will have
`spec.replicas=3`.
To modify the number of replicas in each cluster, you can specify
[FederatedReplicaSetPreference](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/federation/apis/federation/types.go)
[FederatedReplicaSetPreference](https://github.com/kubernetes/federation/blob/{{page.githubbranch}}/apis/federation/types.go)
as an annotation with key `federation.kubernetes.io/deployment-preferences`
on Federated Deployment.
+2 -2
View File
@@ -12,14 +12,14 @@ This guide explains how to use events in federation control plane to help in deb
This guide assumes that you have a running Kubernetes Cluster
Federation installation. If not, then head over to the
[federation admin guide](/docs/admin/federation/) to learn how to
[federation admin guide](/docs/concepts/cluster-administration/federation/) to learn how to
bring up a cluster federation (or have your cluster administrator do
this for you). Other tutorials, for example
[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation)
by Kelsey Hightower, are also available to help you.
You are also expected to have a basic
[working knowledge of Kubernetes](/docs/getting-started-guides/) in
[working knowledge of Kubernetes](/docs/setup/) in
general.
## Overview
+11 -2
View File
@@ -21,7 +21,7 @@ needed most by manipulating the min and max limits of the HPA objects in the fed
* {% include federated-task-tutorial-prereqs.md %}
* You are also expected to have a basic
[working knowledge of Kubernetes](/docs/getting-started-guides/) in
[working knowledge of Kubernetes](/docs/setup/) in
general and [HPAs](/docs/tasks/run-application/horizontal-pod-autoscale/) in particular.
The federated HPA is an alpha feature. The API is not enabled by default on the
@@ -79,7 +79,7 @@ kubectl --context=gce-asia-east1a get HPA php-apache
The HPA in the underlying clusters will match the federation HPA
except in the number of min and max replicas. The federation control plane ensures that the sum of max replicas in each cluster matches the specified
max replicas on the federated HPA object, and the sum of minimum replicas will be greater
than or equal to the minimum specified on the federated HPA object.
than or equal to the minimum specified on the federated HPA object.
**Note:** A particular cluster cannot have a minimum replica sum of 0.
{: .note}
@@ -136,7 +136,11 @@ the interaction is almost identical to interacting with a normal Kubernetes clus
with a limited set of APIs that are federated). As both Deployments and
HorizontalPodAutoscalers are now federated, `kubectl` commands like `kubectl run`
and `kubectl autoscale` work on federation. Given this fact, the mechanism specified in
<<<<<<< HEAD
[horizontal pod autoscaler walkthrough](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough)
=======
[horizontal pod autoscaler walkthrough](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/)
>>>>>>> master
will also work when used with federation.
Care however will need to be taken that when
[generating load on a target deployment](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#step-three-increase-load),
@@ -161,8 +165,13 @@ and averaged current CPU utilization still higher than the target CPU utilizatio
are fields on local HPA object), then the target app in this cluster
needs more replicas, and the scaling is currently restricted by max replicas set on this local
HPA object. In such a scenario, the federated HPA controller scans all clusters and tries to
<<<<<<< HEAD
find clusters which do not have such a condition (meaning the the desired replicas are less
than the max, and current averaged cpu utilization is lower then the threshold). If it finds such
=======
find clusters which do not have such a condition (meaning the desired replicas are less
than the max, and current averaged CPU utilization is lower then the threshold). If it finds such
>>>>>>> master
a cluster, it reduces the max replica on the HPA in this cluster and increases the max replicas
on the HPA in the cluster which needed the replicas.
+4 -4
View File
@@ -6,7 +6,7 @@ title: Federated Ingress
This page explains how to use Kubernetes Federated Ingress to deploy
a common HTTP(S) virtual IP load balancer across a federated service running in
multiple Kubernetes clusters. As of v1.4, clusters hosted in Google
Cloud (both GKE and GCE, or both) are supported. This makes it
Cloud (both Google Kubernetes Engine and GCE, or both) are supported. This makes it
easy to deploy a service that reliably serves HTTP(S) traffic
originating from web clients around the globe on a single, static IP
address. Low network latency, high fault tolerance and easy administration are
@@ -19,7 +19,7 @@ automatically checks the health of the pods comprising the service,
and avoids sending requests to unresponsive or slow pods (or entire
unresponsive clusters).
Federated Ingress is released as an alpha feature, and supports Google Cloud Platform (GKE,
Federated Ingress is released as an alpha feature, and supports Google Cloud Platform (Google Kubernetes Engine,
GCE and hybrid scenarios involving both) in Kubernetes v1.4. Work is under way to support other cloud
providers such as AWS, and other hybrid cloud scenarios (e.g. services
spanning private on-premises as well as public cloud Kubernetes
@@ -66,7 +66,7 @@ this for you). Other tutorials, for example
by Kelsey Hightower, are also available to help you.
You must also have a basic
[working knowledge of Kubernetes](/docs/getting-started-guides/) in
[working knowledge of Kubernetes](/docs/setup/) in
general, and [Ingress](/docs/concepts/services-networking/ingress/) in particular.
{% endcapture %}
@@ -300,6 +300,6 @@ Check that:
{% capture whatsnext %}
* If you need assistance, use one of the [support channels](/docs/tasks/debug-application-cluster/troubleshooting/) to seek assistance.
* For details about use cases that motivated this work, see
[Federation proposal](https://git.k8s.io/community/contributors/design-proposals/federation/federation.md).
[Federation proposal](https://git.k8s.io/community/contributors/design-proposals/multicluster/federation.md).
{% endcapture %}
{% include templates/task.md %}
+5 -1
View File
@@ -16,7 +16,7 @@ parallelism and completions exist across the registered clusters.
* {% include federated-task-tutorial-prereqs.md %}
* You are also expected to have a basic
[working knowledge of Kubernetes](/docs/getting-started-guides/) in
[working knowledge of Kubernetes](/docs/setup/) in
general and [jobs](/docs/concepts/workloads/controllers/jobs-run-to-completion/) in particular.
{% endcapture %}
@@ -61,7 +61,11 @@ if you have 3 registered clusters and you create a federated job with
`spec.parallelism = 9` and `spec.completions = 18`, then each job in the 3 clusters has
`spec.parallelism = 3` and `spec.completions = 6`.
To modify the number of parallelism and completions in each cluster, you can specify
<<<<<<< HEAD
[ReplicaAllocationPreferences](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/federation/apis/federation/types.go)
=======
[ReplicaAllocationPreferences](https://github.com/kubernetes/federation/blob/{{page.githubbranch}}/apis/federation/types.go)
>>>>>>> master
as an annotation with key `federation.kubernetes.io/job-preferences`
on the federated job.
@@ -16,7 +16,7 @@ replicas exist across the registered clusters.
* {% include federated-task-tutorial-prereqs.md %}
* You are also expected to have a basic
[working knowledge of Kubernetes](/docs/getting-started-guides/) in
[working knowledge of Kubernetes](/docs/setup/) in
general and [ReplicaSets](/docs/concepts/workloads/controllers/replicaset/) in particular.
{% endcapture %}
@@ -34,7 +34,7 @@ You can do that using [kubectl](/docs/user-guide/kubectl/) by running:
kubectl --context=federation-cluster create -f myrs.yaml
```
The '--context=federation-cluster' flag tells kubectl to submit the
The `--context=federation-cluster` flag tells kubectl to submit the
request to the Federation apiserver instead of sending it to a Kubernetes
cluster.
@@ -61,7 +61,7 @@ if you have 3 registered clusters and you create a federated ReplicaSet with
`spec.replicas = 9`, then each ReplicaSet in the 3 clusters will have
`spec.replicas=3`.
To modify the number of replicas in each cluster, you can specify
[FederatedReplicaSetPreference](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/federation/apis/federation/types.go)
[FederatedReplicaSetPreference](https://github.com/kubernetes/federation/blob/{{page.githubbranch}}/apis/federation/types.go)
as an annotation with key `federation.kubernetes.io/replica-set-preferences`
on the federated ReplicaSet.
+2 -2
View File
@@ -18,7 +18,7 @@ this for you). Other tutorials, for example
by Kelsey Hightower, are also available to help you.
You are also expected to have a basic
[working knowledge of Kubernetes](/docs/getting-started-guides/) in
[working knowledge of Kubernetes](/docs/setup/) in
general and [Secrets](/docs/concepts/configuration/secret/) in particular.
## Overview
@@ -42,7 +42,7 @@ You can do that using [kubectl](/docs/user-guide/kubectl/) by running:
kubectl --context=federation-cluster create -f mysecret.yaml
```
The '--context=federation-cluster' flag tells kubectl to submit the
The `--context=federation-cluster` flag tells kubectl to submit the
request to the Federation apiserver instead of sending it to a Kubernetes
cluster.
@@ -23,6 +23,12 @@ A few of the steps on this page require that the
in your cluster. But if you don't have Heapster running, you can do most
of the steps, and it won't be a problem if you skip the Heapster steps.
If you are running minikube, run the following command to enable heapster:
```shell
minikube addons enable heapster
```
To see whether the Heapster service is running, enter this command:
```shell
@@ -219,7 +225,7 @@ could use all of the CPU resources available on the Node where it is running.
* The Container is running in a namespace that has a default CPU limit, and the
Container is automatically assigned the default limit. Cluster administrators can use a
[LimitRange](https://kubernetes.io/docs/api-reference/v1.7/#limitrange-v1-core/)
[LimitRange](https://kubernetes.io/docs/api-reference/{{page.version}}/#limitrange-v1-core/)
to specify a default value for the CPU limit.
## Motivation for CPU requests and limits
@@ -22,6 +22,12 @@ A few of the steps on this page require that the
in your cluster. But if you don't have Heapster running, you can do most
of the steps, and it won't be a problem if you skip the Heapster steps.
If you are running minikube, run the following command to enable heapster:
```shell
minikube addons enable heapster
```
To see whether the Heapster service is running, enter this command:
```shell
@@ -118,12 +124,14 @@ Pod's 200 MiB limit.
}
```
Delete your Pod:
```shell
kubectl delete pod memory-demo --namespace=mem-example
```
## Exceed a Container's memory limit
A Container can exceed its memory request if the Node has memory available. But a Container
@@ -313,7 +321,7 @@ could use all of the memory available on the Node where it is running.
* The Container is running in a namespace that has a default memory limit, and the
Container is automatically assigned the default limit. Cluster administrators can use a
[LimitRange](https://kubernetes.io/docs/api-reference/v1.7/#limitrange-v1-core)
[LimitRange](https://kubernetes.io/docs/api-reference/{{page.version}}/#limitrange-v1-core)
to specify a default value for the memory limit.
## Motivation for memory requests and limits
@@ -364,4 +372,3 @@ kubectl delete namespace mem-example
{% include templates/task.md %}
@@ -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/v1.6/#describe) or [`kubectl get`](/docs/user-guide/kubectl/v1.6/#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
@@ -123,7 +123,7 @@ image.
{% include code.html language="yaml" file="http-liveness.yaml" ghlink="/docs/tasks/configure-pod-container/http-liveness.yaml" %}
In the configuration file, you can see that the Pod has a single Container.
The `livenessProbe` field specifies that the kubelet should perform a liveness
The `periodSeconds` field specifies that the kubelet should perform a liveness
probe every 3 seconds. The `initialDelaySeconds` field tells the kubelet that it
should wait 3 seconds before performing the first probe. To perform a probe, the
kubelet sends an HTTP GET request to the server that is running in the Container
@@ -252,7 +252,7 @@ you can use to more precisely control the behavior of liveness and readiness
checks:
* `initialDelaySeconds`: Number of seconds after the container has started
before liveness probes are initiated.
before liveness or readiness probes are initiated.
* `periodSeconds`: How often (in seconds) to perform the probe. Default to 10
seconds. Minimum value is 1.
* `timeoutSeconds`: Number of seconds after which the probe times out. Defaults
@@ -260,8 +260,9 @@ to 1 second. Minimum value is 1.
* `successThreshold`: Minimum consecutive successes for the probe to be
considered successful after having failed. Defaults to 1. Must be 1 for
liveness. Minimum value is 1.
* `failureThreshold`: Minimum consecutive failures for the probe to be
considered failed after having succeeded. Defaults to 3. Minimum value is 1.
* `failureThreshold`: When a Pod starts and the probe fails, Kubernetes will
try `failureThreshold` times before giving up. Giving up in case of liveness probe means restarting the Pod. In case of readiness probe the Pod will be marked Unready.
Defaults to 3. Minimum value is 1.
[HTTP probes](/docs/api-reference/{{page.version}}/#httpgetaction-v1-core)
have additional fields that can be set on `httpGet`:
@@ -275,7 +276,7 @@ set "Host" in httpHeaders instead.
in the range 1 to 65535.
For an HTTP probe, the kubelet sends an HTTP request to the specified path and
port to perform the check. The kubelet sends the probe to the containers IP address,
port to perform the check. The kubelet sends the probe to the pods IP address,
unless the address is overridden by the optional `host` field in `httpGet`. If
`scheme` field is set to `HTTPS`, the kubelet sends an HTTPS request skipping the
certificate verification. In most scenarios, you do not want to set the `host` field.
@@ -24,7 +24,7 @@ This page provides a series of usage examples demonstrating how to configure Pod
kubectl create configmap special-config --from-literal=special.how=very
```
1. Assign the `special.how` value defined in the ConfigMap to the `SPECIAL_LEVEL_KEY` environment variable in the Pod specification.
1. Assign the `special.how` value defined in the ConfigMap to the `SPECIAL_LEVEL_KEY` environment variable in the Pod specification.
```shell
kubectl edit pod dapi-test-pod
@@ -78,7 +78,7 @@ This page provides a series of usage examples demonstrating how to configure Pod
log_level: INFO
```
1. Define the environment variables in the Pod specification.
1. Define the environment variables in the Pod specification.
```yaml
apiVersion: v1
@@ -168,12 +168,12 @@ spec:
valueFrom:
configMapKeyRef:
name: special-config
key: special_level
key: SPECIAL_LEVEL
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special_type
key: SPECIAL_TYPE
restartPolicy: Never
```
@@ -272,7 +272,7 @@ very
### Project keys to specific paths and file permissions
You can project keys to specific paths and specific permissions on a per-file
basis. The [Secrets](/docs/concepts/configuration/secret#using-secrets-as-files-from-a-pod) user guide explains the syntax.
basis. The [Secrets](/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod) user guide explains the syntax.
### Mounted ConfigMaps are updated automatically
@@ -296,7 +296,7 @@ When a ConfigMap already being consumed in a volume is updated, projected keys a
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames {kubelet, 127.0.0.1} Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
```
1. ConfigMaps reside in a specific [namespace](/docs/user-guide/namespaces/). A ConfigMap can only be referenced by pods residing in the same namespace.
1. ConfigMaps reside in a specific [namespace](/docs/concepts/overview/working-with-objects/namespaces/). A ConfigMap can only be referenced by pods residing in the same namespace.
1. Kubelet doesn't support the use of ConfigMaps for pods not found on the API server.
This includes every pod created using kubectl or indirectly via a replication controller.
@@ -49,8 +49,8 @@ Verify that the nginx container is running:
The output shows that the nginx container is running:
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 43m
NAME READY STATUS RESTARTS AGE
init-demo 1/1 Running 0 1m
Get a shell into the nginx container running in the init-demo Pod:
@@ -34,7 +34,7 @@ Here is the configuration file for the Pod:
1. Create the Pod:
kubectl create -f projected-volume.yaml
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/projected-volume.yaml
1. Verify that the Pod's Container is running, and then watch for changes to
the Pod:
@@ -17,18 +17,18 @@ customized the behavior in your cluster, in which case this documentation may
not apply.
{: .note}
When you (a human) access the cluster (e.g. using `kubectl`), you are
When you (a human) access the cluster (for example, using `kubectl`), you are
authenticated by the apiserver as a particular User Account (currently this is
usually `admin`, unless your cluster administrator has customized your
cluster). Processes in containers inside pods can also contact the apiserver.
When they do, they are authenticated as a particular Service Account (e.g.
When they do, they are authenticated as a particular Service Account (for example,
`default`).
## Use the Default Service Account to access the API server.
When you create a pod, if you do not specify a service account, it is
automatically assigned the `default` service account in the same namespace.
If you get the raw json or yaml for a pod you have created (e.g. `kubectl get pods/podname -o yaml`),
If you get the raw json or yaml for a pod you have created (for example, `kubectl get pods/podname -o yaml`),
you can see the `spec.serviceAccountName` field has been
[automatically set](/docs/user-guide/working-with-resources/#resources-are-automatically-modified).
@@ -53,6 +53,7 @@ the Pod:
1. In your shell, go to `/data/redis`, and create a file:
root@redis:/data# cd /data/redis/
root@redis:/data/redis# echo Hello > test-file
1. In your shell, list the running processes:
@@ -15,7 +15,7 @@ spec:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
@@ -6,7 +6,6 @@ spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
@@ -15,19 +14,3 @@ spec:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
@@ -8,7 +8,7 @@ spec:
image: vish/stress
resources:
requests:
memory: 50Mi
memory: "50Mi"
limits:
memory: "100Mi"
args:
@@ -116,7 +116,7 @@ oir-demo-2 0/1 Pending 0 6m
Delete the Pod that you created for this exercise:
```shell
kubectl delete pod oir-demo
kubectl delete pod oir-demo-2
```
{% endcapture %}
@@ -4,8 +4,8 @@ metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: <your-private-image>
- name: private-reg-container
image: <your-private-image>
imagePullSecrets:
- name: regsecret
- name: regsecret
@@ -102,9 +102,12 @@ Here is a configuration file for a Pod that needs access to your secret data:
{% include code.html language="yaml" file="private-reg-pod.yaml" ghlink="/docs/tasks/configure-pod-container/private-reg-pod.yaml" %}
Copy the contents of `private-reg-pod.yaml` to your own file named
`my-private-reg-pod.yaml`. In your file, replace `<your-private-image>` with
the path to an image in a private repository.
Download the above file:
wget -O my-private-reg-pod.yaml https://k8s.io/docs/tasks/configure-pod-container/private-reg-pod.yaml
In file `my-private-reg-pod.yaml`, replace `<your-private-image>` with the
path to an image in a private repository.
Example Docker Hub private image:
@@ -127,7 +130,7 @@ Create a Pod that uses your Secret, and verify that the Pod is running:
* Learn more about [Secrets](/docs/concepts/configuration/secret/).
* Learn more about
[using a private registry](/docs/concepts/containers/images/#using-a-private-registry).
* See [kubectl create secret docker-registry](/docs/user-guide/kubectl/v1.6/#-em-secret-docker-registry-em-).
* See [kubectl create secret docker-registry](/docs/user-guide/kubectl/{{page.version}}/#-em-secret-docker-registry-em-).
* See [Secret](/docs/api-reference/{{page.version}}/#secret-v1-core)
* See the `imagePullSecrets` field of
[PodSpec](/docs/api-reference/{{page.version}}/#podspec-v1-core).
@@ -15,4 +15,5 @@ spec:
volumeMounts:
- name: sec-ctx-vol
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: false
@@ -3,12 +3,10 @@ apiVersion: v1
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
@@ -16,7 +14,7 @@ spec:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
@@ -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
```
@@ -376,10 +355,10 @@ status:
Learn about additional debugging tools, including:
* [Logging](/docs/user-guide/logging/overview)
* [Monitoring](/docs/user-guide/monitoring)
* [Getting into containers via `exec`](/docs/user-guide/getting-into-containers)
* [Logging](/docs/concepts/cluster-administration/logging/)
* [Monitoring](/docs/tasks/debug-application-cluster/resource-usage-monitoring/)
* [Getting into containers via `exec`](/docs/tasks/debug-application-cluster/get-shell-running-container/)
* [Connecting to containers via proxies](/docs/tasks/access-kubernetes-api/http-proxy-access-api/)
* [Connecting to containers via port forwarding](/docs/user-guide/connecting-to-applications-port-forward)
* [Connecting to containers via port forwarding](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)
@@ -111,5 +111,5 @@ Mitigations:
- Mitigates: Node shutdown
- Mitigates: Kubelet software fault
- Action: [Multiple independent clusters](/docs/admin/multi-cluster) (and avoid making risky changes to all clusters at once)
- Action: [Multiple independent clusters](/docs/concepts/cluster-administration/federation/) (and avoid making risky changes to all clusters at once)
- Mitigates: Everything listed above.
@@ -1,14 +1,13 @@
---
approvers:
- bprashanth
- janetkuo
- thockin
- bowei
title: Debug Services
---
An issue that comes up rather frequently for new installations of Kubernetes is
that `Services` are not working properly. You've run all your `Pods` and
`Deployments`, but you get no response when you try to access them.
that a `Service` is not working properly. You've run your `Deployment` and
created a `Service`, but you get no response when you try to access it.
This document will hopefully help you to figure out what's going wrong.
* TOC
@@ -45,30 +44,21 @@ OUTPUT
## Running commands in a Pod
For many steps here you will want to see what a `Pod` running in the cluster
sees. You can start a busybox `Pod` and run commands in it:
sees. The simplest way to do this is to run an interactive busybox `Pod`:
```shell
$ kubectl run -i --tty busybox --image=busybox --generator="run-pod/v1"
Waiting for pod default/busybox to be running, status is Pending, pod ready: false
Hit enter for command prompt
$ kubectl run -it --rm --restart=Never busybox --image=busybox sh
If you don't see a command prompt, try pressing enter.
/ #
```
If you already have a running `Pod`, run a command in it using:
If you already have a running `Pod` that you prefer to use, you can run a
command in it using:
```shell
$ kubectl exec <POD-NAME> -c <CONTAINER-NAME> -- <COMMAND>
```
or run an interactive shell with:
```shell
$ kubectl exec -ti <POD-NAME> -c <CONTAINER-NAME> sh
/ #
```
## Setup
For the purposes of this walk-through, let's run some `Pods`. Since you're
@@ -134,12 +124,6 @@ u@pod$ wget -qO- hostnames
wget: bad address 'hostname'
```
or:
```shell
u@pod$ echo $HOSTNAMES_SERVICE_HOST
```
So the first thing to check is whether that `Service` actually exists:
```shell
@@ -160,7 +144,7 @@ And read it back, just to be sure:
```shell
$ kubectl get svc hostnames
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hostnames 10.0.0.226 <none> 80/TCP 5s
hostnames 10.0.1.175 <none> 80/TCP 5s
```
As before, this is the same as if you had started the `Service` with YAML:
@@ -188,11 +172,10 @@ From a `Pod` in the same `Namespace`:
```shell
u@pod$ nslookup hostnames
Server: 10.0.0.10
Address: 10.0.0.10#53
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames
Address: 10.0.1.175
Name: hostnames
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
```
If this fails, perhaps your `Pod` and `Service` are in different
@@ -200,31 +183,31 @@ If this fails, perhaps your `Pod` and `Service` are in different
```shell
u@pod$ nslookup hostnames.default
Server: 10.0.0.10
Address: 10.0.0.10#53
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames.default
Address: 10.0.1.175
Name: hostnames.default
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
```
If this works, you'll need to ensure that `Pods` and `Services` run in the same
`Namespace`. If this still fails, try a fully-qualified name:
If this works, you'll need to adjust your app to use a cross-namespace name, or
run your app and `Service` in the same `Namespace`. If this still fails, try a
fully-qualified name:
```shell
u@pod$ nslookup hostnames.default.svc.cluster.local
Server: 10.0.0.10
Address: 10.0.0.10#53
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames.default.svc.cluster.local
Address: 10.0.1.175
Name: hostnames.default.svc.cluster.local
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
```
Note the suffix here: "default.svc.cluster.local". The "default" is the
`Namespace` we're operating in. The "svc" denotes that this is a `Service`.
The "cluster.local" is your cluster domain.
The "cluster.local" is your cluster domain, which COULD be different in your
own cluster.
You can also try this from a `Node` in the cluster (note: 10.0.0.10 is my DNS
`Service`):
`Service`, yours might be different):
```shell
u@node$ nslookup hostnames.default.svc.cluster.local 10.0.0.10
@@ -236,11 +219,30 @@ Address: 10.0.1.175
```
If you are able to do a fully-qualified name lookup but not a relative one, you
need to check that your `kubelet` is running with the right flags.
The `--cluster-dns` flag needs to point to your DNS `Service`'s IP and the
`--cluster-domain` flag needs to be your cluster's domain - we assumed
"cluster.local" in this document, but yours might be different, in which case
you should change that in all of the commands above.
need to check that your `/etc/resolv.conf` file is correct.
```shell
u@pod$ cat /etc/resolv.conf
nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local example.com
options ndots:5
```
The `nameserver` line must indicate your cluster's DNS `Service`. This is
passed into `kubelet` with the `--cluster-dns` flag.
The `search` line must include an appropriate suffix for you to find the
`Service` name. In this case it is looking for `Services` in the local
`Namespace` (`default.svc.cluster.local), `Services` in all `Namespaces`
(`svc.cluster.local`), and the cluster (`cluster.local`). Depending on your own
install you might have additional records after that (up to 6 total). The
cluster suffix is passed into `kubelet` with the `--cluster-domain` flag. We
assume that is "cluster.local" in this document, but yours might be different,
in which case you should change that in all of the commands above.
The `options` line must set `ndots` high enough that your DNS client library
considers search paths at all. Kubernetes sets this to 5 by default, which is
high enough to cover all of the DNS names it generates.
### Does any Service exist in DNS?
@@ -251,10 +253,10 @@ can take a step back and see what else is not working. The Kubernetes master
```shell
u@pod$ nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.0.0.1
Name: kubernetes.default
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
```
If this fails, you might need to go to the kube-proxy section of this doc, or
@@ -263,8 +265,9 @@ debugging your own `Service`, debug DNS.
## Does the Service work by IP?
The next thing to test is whether your `Service` works at all. From a
`Node` in your cluster, access the `Service`'s IP (from `kubectl get` above).
Assuming we can confirm that DNS works, the next thing to test is whether your
`Service` works at all. From a node in your cluster, access the `Service`'s
IP (from `kubectl get` above).
```shell
u@node$ curl 10.0.1.175:80
@@ -283,8 +286,8 @@ are a number of things that could be going wrong. Read on.
## Is the Service correct?
It might sound silly, but you should really double and triple check that your
`Service` is correct and matches your `Pods`. Read back your `Service` and
verify it:
`Service` is correct and matches your `Pod`'s port. Read back your `Service`
and verify it:
```shell
$ kubectl get service hostnames -o json
@@ -326,10 +329,10 @@ $ kubectl get service hostnames -o json
```
Is the port you are trying to access in `spec.ports[]`? Is the `targetPort`
correct for your `Pods`? If you meant it to be a numeric port, is it a number
(9376) or a string "9376"? If you meant it to be a named port, do your `Pods`
expose a port with the same name? Is the port's `protocol` the same as the
`Pod`'s?
correct for your `Pods` (many `Pods` choose to use a different port than the
`Service`)? If you meant it to be a numeric port, is it a number (9376) or a
string "9376"? If you meant it to be a named port, do your `Pods` expose a port
with the same name? Is the port's `protocol` the same as the `Pod`'s?
## Does the Service have any Endpoints?
@@ -360,16 +363,19 @@ NAME ENDPOINTS
hostnames 10.244.0.5:9376,10.244.0.6:9376,10.244.0.7:9376
```
This confirms that the control loop has found the correct `Pods` for your
`Service`. If the `hostnames` row is blank, you should check that the
This confirms that the endpoints controller has found the correct `Pods` for
your `Service`. If the `hostnames` row is blank, you should check that the
`spec.selector` field of your `Service` actually selects for `metadata.labels`
values on your `Pods`.
values on your `Pods`. A common mistake is to have a typo or other error, such
as the `Service` selecting for `run=hostnames`, but the `Deployment` specifying
`app=hostnames`.
## Are the Pods working?
At this point, we know that your `Service` exists and has selected your `Pods`.
Let's check that the `Pods` are actually working - we can bypass the `Service`
mechanism and go straight to the `Pods`.
mechanism and go straight to the `Pods`. Note that these commands use the `Pod`
port (9376), rather than the `Service` port (80).
```shell
u@pod$ wget -qO- 10.244.0.5:9376
@@ -388,6 +394,20 @@ this is not what happens (or whatever the correct behavior is for your own
`kubectl logs` to be useful or `kubectl exec` directly to your `Pods` and check
service from there.
Another thing to check is that your `Pods` are not crashing or being restarted.
Frequent restarts could lead to intermittent connectivity issues.
```shell
$ kubectl get pods -l app=hostnames
NAME READY STATUS RESTARTS AGE
hostnames-632524106-bbpiw 1/1 Running 0 2m
hostnames-632524106-ly40y 1/1 Running 0 2m
hostnames-632524106-tlaok 1/1 Running 0 2m
```
If the restart count is high, read more about how to [debug
pods](/docs/tasks/debug-application-cluster/debug-pod-replication-controller/#debugging-pods).
## Is the kube-proxy working?
If you get here, your `Service` is running, has `Endpoints`, and your `Pods`
@@ -426,6 +446,13 @@ I1027 22:14:54.040223 5063 proxier.go:294] Adding new service "kube-system/ku
If you see error messages about not being able to contact the master, you
should double-check your `Node` configuration and installation steps.
One of the possible reasons that `kube-proxy` cannot run correctly is that the
required `conntrack` binary cannot be found. This may happen on some Linux
systems, depending on how you are installing the cluster, for example, you are
installing Kubernetes from scratch. If this is the case, you need to manually
install the `conntrack` package (e.g. `sudo apt install conntrack` on Ubuntu)
and then retry.
### Is kube-proxy writing iptables rules?
One of the main responsibilities of `kube-proxy` is to write the `iptables`
@@ -449,6 +476,9 @@ example) - a "KUBE-PORTALS-CONTAINER" and a "KUBE-PORTALS-HOST". If you do
not see these, try restarting `kube-proxy` with the `-V` flag set to 4, and
then look at the logs again.
Almost nobody should be using the "userspace" mode any more, so we won't spend
more time on it here.
#### Iptables
```shell
@@ -500,69 +530,10 @@ Setting endpoints for default/hostnames:default to [10.244.0.5:9376 10.244.0.6:9
If you don't see those, try restarting `kube-proxy` with the `-V` flag set to 4, and
then look at the logs again.
Services provide load balancing across a set of pods. There are several common
problems that can make services not work properly. The following instructions
should help debug service problems.
First, verify that there are endpoints for the service. For every service
object, the apiserver makes an `endpoints` resource available.
You can view this resource with:
$ kubectl get endpoints ${SERVICE_NAME}
Make sure that the endpoints match up with the number of containers that you
expect to be a member of your service. For example, if your service is for an
nginx container with 3 replicas, you would expect to see three different IP
addresses in the service's endpoints.
### My service is missing endpoints
If you are missing endpoints, try listing pods using the labels that service
uses. Imagine that you have a service where the labels are:
...
spec:
- selector:
name: nginx
type: frontend
You can use:
$ kubectl get pods --selector=name=nginx,type=frontend
to list pods that match this selector. Verify that the list matches the pods
that you expect to provide your service.
If the list of pods matches expectations, but your endpoints are still empty,
it's possible that you don't have the right ports exposed. If your service has
a `containerPort` specified, but the pods that are selected don't have that
port listed, then they won't be added to the endpoints list.
Verify that the pod's `containerPort` matches up with the service's
`containerPort`.
### Network traffic is not forwarded
If you can connect to the service, but the connection is immediately dropped,
and there are endpoints in the endpoints list, it's likely that the proxy can't
contact your pods.
There are three things to check:
* Are your pods working correctly? Look for restart count, and
[debug pods](/docs/tasks/debug-application-cluster/debug-pod-replication-controller/#debugging-pods).
* Can you connect to your pods directly? Get the IP address for the pod, and
try to connect directly to that IP.
* Is your application serving on the port that you configured? Container
Engine doesn't do port remapping, so if your application serves on 8080,
the `containerPort` field needs to be 8080.
### A Pod cannot reach itself via Service IP
This mostly happens when `kube-proxy` is running in `iptables` mode and Pods
This can happen when the network is not properly configured for "hairpin"
traffic, usually when `kube-proxy` is running in `iptables` mode and Pods
are connected with bridge network. The `Kubelet` exposes a `hairpin-mode`
[flag](/docs/admin/kubelet/) that allows endpoints of a Service to loadbalance back to themselves
if they try to access their own Service VIP. The `hairpin-mode` flag must either be
@@ -44,7 +44,7 @@ You can debug individual Pods in a StatefulSet using the
{% capture whatsnext %}
Learn more about [debugging an init-container](/docs/tasks/troubleshoot/debug-init-containers/).
Learn more about [debugging an init-container](/docs/tasks/debug-application-cluster/debug-init-containers/).
{% endcapture %}
@@ -75,25 +75,36 @@ only the termination message:
{% raw %} kubectl get pod termination-demo -o go-template="{{range .status.containerStatuses}}{{.lastState.terminated.message}}{{end}}"{% endraw %}
```
## Setting the termination log file
## Customizing the termination message
By default Kubernetes retrieves termination messages from
`/dev/termination-log`. To change this to a different file,
specify a `terminationMessagePath` field for your Container.
Kubernetes retrieves termination messages from the termination message file
specified in the `terminationMessagePath` field of a Container, which as a default
value of `/dev/termination-log`. By customizing this field, you can tell Kubernetes
to use a different file. Kubernetes use the contents from the specified file to
populate the Container's status message on both success and failure.
For example, suppose your Container writes termination messages to
`/tmp/my-log`, and you want Kubernetes to retrieve those messages.
Set `terminationMessagePath` as shown here:
In the following example, the container writes termination messages to
`/tmp/my-log` for Kubernetes to retrieve:
apiVersion: v1
kind: Pod
metadata:
name: msg-path-demo
spec:
containers:
- name: msg-path-demo-container
image: debian
terminationMessagePath: "/tmp/my-log"
```yaml
apiVersion: v1
kind: Pod
metadata:
name: msg-path-demo
spec:
containers:
- name: msg-path-demo-container
image: debian
terminationMessagePath: "/tmp/my-log"
```
Moreover, users can set the `terminationMessagePolicy` field of a Container for
further customization. This field defaults to "`File`" which means the termination
messages are retrieved only from the termination message file. By setting the
`terminationMessagePolicy` to "`FallbackToLogsOnError`", you can tell Kubernetes
to use the last chunk of container log output if the termination message file
is empty and the container exited with an error. The log output is limited to
2048 bytes or 80 lines, whichever is smaller.
{% endcapture %}
@@ -38,9 +38,9 @@ of the potential inaccuracy.
## Deployment
### Google Container Engine
### Google Kubernetes Engine
In Google Container Engine (GKE), if cloud logging is enabled, event exporter
In Google Kubernetes Engine, if cloud logging is enabled, event exporter
is deployed by default to the clusters with master running version 1.7 and
higher. To prevent disturbing your workloads, event exporter does not have
resources set and is in the best effort QOS class, which means that it will
@@ -47,16 +47,10 @@ Get a shell to the running Container:
kubectl exec -it shell-demo -- /bin/bash
```
In your shell, list the running processes:
In your shell, list the root directory:
```shell
root@shell-demo:/# ps aux
```
In your shell, list the nginx processes:
```shell
root@shell-demo:/# ps aux | grep nginx
root@shell-demo:/# ls /
```
In your shell, experiment with other commands. Here are
@@ -67,10 +61,13 @@ root@shell-demo:/# ls /
root@shell-demo:/# cat /proc/mounts
root@shell-demo:/# cat /proc/1/maps
root@shell-demo:/# apt-get update
root@shell-demo:/# apt-get install tcpdump
root@shell-demo:/# apt-get install -y tcpdump
root@shell-demo:/# tcpdump
root@shell-demo:/# apt-get install lsof
root@shell-demo:/# apt-get install -y lsof
root@shell-demo:/# lsof
root@shell-demo:/# apt-get install -y procps
root@shell-demo:/# ps aux
root@shell-demo:/# ps aux | grep nginx
```
## Writing the root page for nginx
@@ -140,7 +137,7 @@ kubectl exec -it my-pod --container main-app -- /bin/bash
{% capture whatsnext %}
* [kubectl exec](/docs/user-guide/kubectl/v1.6/#exec)
* [kubectl exec](/docs/user-guide/kubectl/{{page.version}}/#exec)
{% endcapture %}
@@ -0,0 +1,60 @@
---
title: Developing and debugging services locally
---
{% capture overview %}
Kubernetes applications usually consist of multiple, separate services, each running in its own container. Developing and debugging these services on a remote Kubernetes cluster can be cumbersome, requiring you to [get a shell on a running container](https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/) and running your tools inside the remote shell.
`telepresence` is a tool to ease the process of developing and debugging services locally, while proxying the service to a remote Kubernetes cluster. Using `telepresence` allows you to use custom tools, such as a debugger and IDE, for a local service and provides the service full access to ConfigMap, secrets, and the services running on the remote cluster.
This document describes using `telepresence` to develop and debug services running on a remote cluster locally.
{% endcapture %}
{% capture prerequisites %}
* Kubernetes cluster is installed
* `kubectl` is configured to communicate with the cluster
* [Telepresence](https://www.telepresence.io/reference/install) is installed
{% endcapture %}
{% capture steps %}
## Getting a shell on a remote cluster
Open a terminal and run `telepresence` with no arguments to get a `telepresence` shell. This shell runs locally, giving you full access to your local filesystem.
The `telepresence` shell can be used in a variety of ways. For example, write a shell script on your laptop, and run it directly from the shell in real time. You can do this on a remote shell as well, but you might not be able to use your preferred code editor, and the script is deleted when the container is terminated.
Enter `exit` to quit and close the shell.
## Developing or debugging an existing service
When developing an application on Kubernetes, you typically program or debug a single service. The service might require access to other services for testing and debugging. One option is to use the continuous deployment pipeline, but even the fastest deployment pipeline introduces a delay in the program or debug cycle.
Use the `--swap-deployment` option to swap an existing deployment with the Telepresence proxy. Swapping allows you to run a service locally and connect to the remote Kubernetes cluster. The services in the remote cluster can now access the locally running instance.
To run telepresence with `--swap-deployment`, enter:
`telepresence --swap-deployment $DEPLOYMENT_NAME`
where $DEPLOYMENT_NAME is the name of your existing deployment.
Running this command spawns a shell. In the shell, start your service. You can then make edits to the source code locally, save, and see the changes take effect immediately. You can also run your service in a debugger, or any other local development tool.
{% endcapture %}
{% capture whatsnext %}
If you're interested in a hands-on tutorial, check out [this tutorial](https://cloud.google.com/community/tutorials/developing-services-with-k8s) that walks through locally developing the Guestbook application on Google Kubernetes Engine.
Telepresence has [numerous proxying options](https://www.telepresence.io/reference/methods), depending on your situation.
For further reading, visit the [Telepresence website](https://www.telepresence.io).
{% endcapture %}
{% include templates/task.md %}
@@ -14,7 +14,7 @@ This article describes how to set up a cluster to ingest logs into
them using [Kibana](https://www.elastic.co/products/kibana), as an alternative to
Stackdriver Logging when running on GCE. Note that Elasticsearch and Kibana
cannot be setup automatically in the Kubernetes cluster hosted on
Google Container Engine, you have to deploy it manually.
Google Kubernetes Engine, you have to deploy it manually.
To use Elasticsearch and Kibana for cluster logging, you should set the
following environment variable as shown below when creating your cluster with
@@ -22,9 +22,9 @@ and the instances are managed using a Kubernetes `DaemonSet`. The actual deploym
### Deploying to a new cluster
#### Google Container Engine
#### Google Kubernetes Engine
Stackdriver is the default logging solution for clusters deployed on Google Container Engine.
Stackdriver is the default logging solution for clusters deployed on Google Kubernetes Engine.
Stackdriver Logging is deployed to a new cluster by default unless you explicitly opt-out.
#### Other platforms
@@ -186,14 +186,14 @@ the messages from a particular pod.
The most important pieces of metadata are the resource type and log name.
The resource type of a container log is `container`, which is named
`GKE Containers` in the UI (even if the Kubernetes cluster is not on GKE).
`GKE Containers` in the UI (even if the Kubernetes cluster is not on Google Kubernetes Engine).
The log name is the name of the container, so that if you have a pod with
two containers, named `container_1` and `container_2` in the spec, their logs
will have log names `container_1` and `container_2` respectively.
System components have resource type `compute`, which is named
`GCE VM Instance` in the interface. Log names for system components are fixed.
For a GKE node, every log entry from a system component has one of the following
For a Google Kubernetes Engine node, every log entry from a system component has one of the following
log names:
* docker
@@ -32,7 +32,7 @@ kernel log now. It doesn't support log tools like journald.
* The kernel issue detection of node problem detector has assumption on kernel
log format, and now it only works on Ubuntu and Debian. However, it is easy to extend
it to [support other log format](/docs/admin/node-problem/#support-other-log-format).
it to [support other log format](/docs/tasks/debug-application-cluster/monitor-node-health/#support-other-log-format).
## Enable/Disable in GCE cluster
@@ -0,0 +1,20 @@
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
@@ -34,7 +34,7 @@ and command-line interfaces (CLIs), such as [`kubectl`](/docs/user-guide/kubectl
You may also find the Stack Overflow topics relevant:
* [Kubernetes](http://stackoverflow.com/questions/tagged/kubernetes)
* [Google Container Engine - GKE](http://stackoverflow.com/questions/tagged/google-container-engine)
* [Google Kubernetes Engine](http://stackoverflow.com/questions/tagged/google-container-engine)
## Help! My question isn't covered! I need help now!
@@ -67,7 +67,7 @@ these channels for localized support and info:
### Mailing List
The Kubernetes / Google Container Engine mailing list is [kubernetes-users@googlegroups.com](https://groups.google.com/forum/#!forum/kubernetes-users)
The Kubernetes / Google Kubernetes Engine mailing list is [kubernetes-users@googlegroups.com](https://groups.google.com/forum/#!forum/kubernetes-users)
### Bugs and Feature requests
+3 -3
View File
@@ -9,7 +9,7 @@ description: With kubectl plugins, you can extend the functionality of the kubec
{% include feature-state-alpha.md %}
This guide shows you how to install and write extensions for [kubectl](/docs/user-guide/kubectl). Usually called *plugins* or *binary extensions*, this feature allows you to extend the default set of commands available in `kubectl` by adding new subcommands to perform new tasks and extend the set of features available in the main distribution of `kubectl`.
This guide shows you how to install and write extensions for [kubectl](/docs/user-guide/kubectl/). Usually called *plugins* or *binary extensions*, this feature allows you to extend the default set of commands available in `kubectl` by adding new subcommands to perform new tasks and extend the set of features available in the main distribution of `kubectl`.
{% endcapture %}
@@ -66,7 +66,7 @@ You can write a plugin in any programming language or script that allows you to
A plugin does not necessarily need to have a binary component. It could rely entirely on operating system utilities
like `echo`, `sed`, or `grep`. Or it could rely on the `kubectl` binary.
The only strong requirement for a `kubectl` plugin is the `plugin.yaml` descriptor file. This file is responsible for declaring at least the minimum attributes required to register a plugin and must be located under one of the locations specified in the [Search order](#search-order) section.
The only strong requirement for a `kubectl` plugin is the `plugin.yaml` descriptor file. This file is responsible for declaring at least the minimum attributes required to register a plugin and must be located under one of the locations specified in the [Search order](#search-order) section.
### The plugin.yaml descriptor
@@ -107,7 +107,7 @@ For example, the directory structure for the `targaryen` plugin could look like
In most use cases, the binary or script file you write to support the plugin must have access to some contextual information provided by the plugin framework. For example, if you declared flags in the descriptor file, your plugin must have access to the user-provided flag values at runtime. The same is true for global flags. The plugin framework is responsible for doing that, so plugin writers don't need to worry about parsing arguments. This also ensures the best level of consistency between plugins and regular `kubectl` commands.
Plugins have access to runtime context attributes through environment variables. So to access the value provided through a flag, for example, just look for the value of the proper environment variable using the appropriate function call for your binary or script.
Plugins have access to runtime context attributes through environment variables. So to access the value provided through a flag, for example, just look for the value of the proper environment variable using the appropriate function call for your binary or script.
The supported environment variables are:
@@ -25,7 +25,7 @@ this for you). Other tutorials, for example
by Kelsey Hightower, are also available to help you.
You are also expected to have a basic
[working knowledge of Kubernetes](/docs/getting-started-guides/) in
[working knowledge of Kubernetes](/docs/setup/) in
general, and [Services](/docs/concepts/services-networking/service/) in particular.
## Overview
@@ -346,7 +346,7 @@ IP's in less time than that given appropriate configuration.
#### I cannot connect to my cluster federation API
Check that your
1. Client (typically kubectl) is correctly configured (including API endpoints and login credentials), and
1. Client (typically kubectl) is correctly configured (including API endpoints and login credentials).
2. Cluster Federation API server is running and network-reachable.
See the [federation admin guide](/docs/admin/federation/) to learn
@@ -356,7 +356,8 @@ how to bring up a cluster federation correctly (or have your cluster administrat
Check that:
1. Your clusters are correctly registered in the Cluster Federation API (`kubectl describe clusters`).
2. Your clusters are all 'Active'. This means that the cluster Federation system was able to connect and authenticate against the clusters' endpoints. If not, consult the logs of the federation-controller-manager pod to ascertain what the failure might be. (`kubectl --namespace=federation logs $(kubectl get pods --namespace=federation -l module=federation-controller-manager -o name`)
2. Your clusters are all 'Active'. This means that the cluster Federation system was able to connect and authenticate against the clusters' endpoints. If not, consult the logs of the federation-controller-manager pod to ascertain what the failure might be.
```kubectl --namespace=federation logs $(kubectl get pods --namespace=federation -l module=federation-controller-manager -o name)```
3. That the login credentials provided to the Cluster Federation API for the clusters have the correct authorization and quota to create services in the relevant namespace in the clusters. Again you should see associated error messages providing more detail in the above log file if this is not the case.
4. Whether any other error is preventing the service creation operation from succeeding (look for `service-controller` errors in the output of `kubectl logs federation-controller-manager --namespace federation`).
@@ -379,4 +380,4 @@ Check that:
## For more information
* [Federation proposal](https://git.k8s.io/community/contributors/design-proposals/federation/federation.md) details use cases that motivated this work.
* [Federation proposal](https://git.k8s.io/community/contributors/design-proposals/multicluster/federation.md) details use cases that motivated this work.
@@ -21,7 +21,7 @@ using `kubefed`.
## Prerequisites
This guide assumes that you have a running Kubernetes cluster. Please
see one of the [getting started](/docs/getting-started-guides/) guides
see one of the [getting started](/docs/setup/) guides
for installation instructions for your platform.
@@ -148,11 +148,11 @@ to program the DNS service that you are using. For example, if your
cluster is running on Google Compute Engine, you must enable the
Google Cloud DNS API for your project.
The machines in Google Container Engine (GKE) clusters are created
The machines in Google Kubernetes Engine clusters are created
without the Google Cloud DNS API scope by default. If you want to use a
GKE cluster as a Federation host, you must create it using the `gcloud`
Google Kubernetes Engine cluster as a Federation host, you must create it using the `gcloud`
command with the appropriate value in the `--scopes` field. You cannot
modify a GKE cluster directly to add this scope, but you can create a
modify a Google Kubernetes Engine cluster directly to add this scope, but you can create a
new node pool for your cluster and delete the old one. *Note that this
will cause pods in the cluster to be rescheduled.*
@@ -367,48 +367,45 @@ kubefed init fellowship \
```
For more information see
[Setting up CoreDNS as DNS provider for Cluster Federation](/docs/tutorials/federation/set-up-coredns-provider-federation/).
[Setting up CoreDNS as DNS provider for Cluster Federation](/docs/tasks/federation/set-up-coredns-provider-federation/).
## 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.
After you've deployed a federation control plane, you'll need to make that control plane aware of the clusters it should manage.
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.
To join clusters into the federation:
> 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/user-guide/identifiers/#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.
1. Change the context:
The following example command adds the cluster `gondor` to the
federation running on host cluster `rivendell`:
kubectl config use-context fellowship
```
kubefed join gondor --host-cluster-context=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:
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
The cluster name you supply to `kubefed join` must be a valid
[RFC 1035](https://www.ietf.org/rfc/rfc1035.txt) label and are
enumerated in the [Identifiers doc](/docs/user-guide/identifiers/#names).
enumerated in the [Identifiers doc](/docs/concepts/overview/working-with-objects/names/).
Furthermore, federation control plane requires credentials of the
joined clusters to operate on them. These credentials are obtained
@@ -487,5 +484,8 @@ federation control plane's etcd. You can delete the federation
namespace by running the following command:
```
$ kubectl delete ns federation-system
kubectl delete ns federation-system --context=rivendell
```
Note that `rivendell` is the host cluster name, replace that with the appropriate name in your configuration.
@@ -23,7 +23,7 @@ DNS provider for Cluster Federation.
* You need to have a running Kubernetes cluster (which is
referenced as host cluster). Please see one of the
[getting started](/docs/getting-started-guides/) guides for
[getting started](/docs/setup/) guides for
installation instructions for your platform.
* Support for `LoadBalancer` services in member clusters of federation is
mandatory to enable `CoreDNS` for service discovery across federated clusters.
@@ -57,7 +57,7 @@ The CoreDNS default configuration should be customized to suit the federation.
Shown below is the Values.yaml, which overrides the default
configuration parameters on the CoreDNS chart.
{% include code.html language="yaml" file="Values.yaml" ghlink="/docs/tutorials/federation/Values.yaml" %}
{% include code.html language="yaml" file="Values.yaml" ghlink="/docs/tasks/federation/Values.yaml" %}
The above configuration file needs some explanation:
@@ -12,7 +12,7 @@ resources using an external policy engine.
{% capture prerequisites %}
You need to have a running Kubernetes cluster (which is referenced as host
cluster). Please see one of the [getting started](/docs/getting-started-guides/)
cluster). Please see one of the [getting started](/docs/setup/)
guides for installation instructions for your platform.
{% endcapture %}
@@ -31,8 +31,7 @@ received from the external policy engine.
Shown below is an example ConfigMap for the Admission Controller:
{% include code.html language="yaml" file="scheduling-policy-admission.yaml"
ghlink="/docs/tutorials/federation/scheduling-policy-admission.yaml" %}
{% include code.html language="yaml" file="scheduling-policy-admission.yaml" ghlink="/docs/tasks/federation/scheduling-policy-admission.yaml" %}
The ConfigMap contains three files:
@@ -82,8 +81,7 @@ Create a Service in the host cluster to contact the external policy engine:
Shown below is an example Service for OPA.
{% include code.html language="yaml" file="policy-engine-service.yaml"
ghlink="/docs/tutorials/federation/policy-engine-service.yaml" %}
{% include code.html language="yaml" file="policy-engine-service.yaml" ghlink="/docs/tasks/federation/policy-engine-service.yaml" %}
Create a Deployment in the host cluster with the Federation control plane:
@@ -91,8 +89,7 @@ Create a Deployment in the host cluster with the Federation control plane:
Shown below is an example Deployment for OPA.
{% include code.html language="yaml" file="policy-engine-deployment.yaml"
ghlink="/docs/tutorials/federation/policy-engine-deployment.yaml" %}
{% include code.html language="yaml" file="policy-engine-deployment.yaml" ghlink="/docs/tasks/federation/policy-engine-deployment.yaml" %}
## Configuring placement policies via ConfigMaps
@@ -105,8 +102,7 @@ Create the namespace if it does not already exist:
Configure a sample policy to test the external policy engine:
{% include code.html language="yaml" file="policy.rego"
ghlink="/docs/tutorials/federation/policy.rego" %}
{% include code.html language="yaml" file="policy.rego" ghlink="/docs/tasks/federation/policy.rego" %}
Shown below is the command to create the sample policy:
@@ -129,8 +125,7 @@ Annotate one of the clusters to indicate that it is PCI certified.
Deploy a Federated ReplicaSet to test the placement policy.
{% include code.html language="yaml" file="replicaset-example-policy.yaml"
ghlink="/docs/tutorials/federation/replicaset-example-policy.yaml" %}
{% include code.html language="yaml" file="replicaset-example-policy.yaml" ghlink="/docs/tasks/federation/replicaset-example-policy.yaml" %}
Shown below is the command to deploy a ReplicaSet that *does* match the policy.
@@ -10,3 +10,4 @@ spec:
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
restartPolicy: OnFailure
@@ -5,7 +5,7 @@ title: Define a Command and Arguments for a Container
{% capture overview %}
This page shows how to define commands and arguments when you run a container
in a Kubernetes Pod.
in a {% glossary_tooltip term_id="pod" %}.
{% endcapture %}
@@ -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:
@@ -101,11 +101,11 @@ Here is a configuration file you can use to create a Pod:
`/etc/secret-volume`. In your shell, go to the directory where the secret data
is exposed:
root@secret-test-pod:/# cd /etc/secret-volume
root@secret-test-pod:/# cd /etc/secret-volume
1. In your shell, list the files in the `/etc/secret-volume` directory:
root@secret-test-pod:/etc/secret-volume# ls
root@secret-test-pod:/etc/secret-volume# ls
The output shows two files, one for each piece of secret data:
@@ -113,7 +113,7 @@ is exposed:
1. In your shell, display the contents of the `username` and `password` files:
root@secret-test-pod:/etc/secret-volume# cat username; echo; cat password; echo
root@secret-test-pod:/etc/secret-volume# cat username; echo; cat password; echo
The output is your username and password:
@@ -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:
@@ -8,12 +8,6 @@ This page shows how a Pod can use environment variables to expose information
about itself to Containers running in the Pod. Environment variables can expose
Pod fields and Container fields.
There are two ways to expose Pod and Container fields to a running Container:
environment variables and
[DownwardAPIVolumeFiles](/docs/resources-reference/{{page.version}}/#downwardapivolumefile-v1-core).
Together, these two ways of exposing Pod and Container fields are called the
*Downward API*.
{% endcapture %}
@@ -0,0 +1,37 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
containers:
- name: website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/app/config.json
readOnly: true
name: secret-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
- name: duplicate_key
value: FROM_ENV
- name: expansion
value: $(REPLACE_ME)
envFrom:
- configMapRef:
name: etcd-env-config
volumes:
- name: cache-volume
emptyDir: {}
- name: secret-volume
secret:
secretName: config-details
@@ -0,0 +1,30 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: 6379
- name: duplicate_key
value: FROM_ENV
- name: expansion
value: $(REPLACE_ME)
envFrom:
- configMapRef:
name: etcd-env-config
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/app/config.json
readOnly: true
name: secret-volume
volumes:
- name: cache-volume
emptyDir: {}
- name: secret-volume
secret:
secretName: config-details
@@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: etcd-env-config
data:
number_of_members: "1"
initial_cluster_state: new
initial_cluster_token: DUMMY_ETCD_INITIAL_CLUSTER_TOKEN
discovery_token: DUMMY_ETCD_DISCOVERY_TOKEN
discovery_url: http://etcd_discovery:2379
etcdctl_peers: http://etcd:2379
duplicate_key: FROM_CONFIG_MAP
REPLACE_ME: "a value"
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
ports:
volumes:
- name: cache-volume
emptyDir: {}
- containerPort: 80
@@ -0,0 +1,18 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
volumeMounts:
- mountPath: /cache
name: other-volume
volumes:
- name: other-volume
emptyDir: {}
@@ -0,0 +1,25 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
containers:
- name: website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,29 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
podpreset.admission.kubernetes.io/podpreset-proxy: "resource version"
spec:
containers:
- name: website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/proxy/configs
name: proxy-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
volumes:
- name: cache-volume
emptyDir: {}
- name: proxy-volume
emptyDir: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: nginx
ports:
- containerPort: 80
@@ -0,0 +1,17 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,14 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: proxy
spec:
selector:
matchLabels:
role: frontend
volumeMounts:
- mountPath: /etc/proxy/configs
name: proxy-volume
volumes:
- name: proxy-volume
emptyDir: {}

Some files were not shown because too many files have changed in this diff Show More