Convert site to Hugo (#8316)

This commit converts content and layout to use Hugo.
This commit is contained in:
Bjørn Erik Pedersen
2018-05-05 18:00:51 +02:00
committed by k8s-ci-robot
parent 7745f0e0c5
commit 7f3b633aa0
2327 changed files with 10928 additions and 171503 deletions
@@ -0,0 +1,5 @@
---
title: "Access Applications in a Cluster"
weight: 70
---
@@ -0,0 +1,335 @@
---
title: Accessing Clusters
---
{{< toc >}}
## Accessing the cluster API
### Accessing for the first time with kubectl
When accessing the Kubernetes API for the first time, we suggest using the
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/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:
```shell
$ kubectl config view
```
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
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 several ways to locate and authenticate:
- Run kubectl in proxy mode.
- Recommended approach.
- Uses stored apiserver location.
- Verifies identity of apiserver using self-signed cert. No MITM possible.
- Authenticates to apiserver.
- In future, may do intelligent client-side load-balancing and failover.
- Provide the location and credentials directly to the http client.
- Alternate approach.
- Works with some types of client code that are confused by using a proxy.
- Need to import a root cert into your browser to protect against MITM.
#### 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.
Run it like this:
```shell
$ kubectl proxy --port=8080 &
```
See [kubectl proxy](/docs/reference/generated/kubectl/kubectl-commands/#proxy) for more details.
Then you can explore the API with curl, wget, or a browser, replacing localhost
with [::1] for IPv6, like so:
```shell
$ curl http://localhost:8080/api/
{
"versions": [
"v1"
]
}
```
#### Without kubectl proxy (before v1.3.x)
It is possible to avoid using kubectl proxy by passing an authentication token
directly to the apiserver, like this:
```shell
$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
$ TOKEN=$(kubectl config view | grep token | cut -f 2 -d ":" | tr -d " ")
$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
{
"versions": [
"v1"
]
}
```
#### Without kubectl proxy (post v1.3.x)
In Kubernetes version 1.3 or later, `kubectl config view` no longer displays the token. Use `kubectl describe secret...` to get the token for the default service account, like this:
``` shell
$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
$ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t')
$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
```
The above examples use 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
with future high-availability support.
### Programmatic access to the API
Kubernetes officially supports [Go](#go-client) and [Python](#python-client)
client libraries.
#### Go client
* To get the library, run the following command: `go get k8s.io/client-go/<version number>/kubernetes`. See [https://github.com/kubernetes/client-go](https://github.com/kubernetes/client-go) to see which versions are supported.
* 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).
If the application is deployed as a Pod in the cluster, please refer to the [next section](#accessing-the-api-from-a-pod).
#### Python client
To use [Python client](https://github.com/kubernetes-client/python), run the following command: `pip install kubernetes`. See [Python Client Library page](https://github.com/kubernetes-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-client/python/tree/master/examples/example1.py).
#### Other languages
There are [client libraries](/docs/reference/client-libraries/) for accessing the API from other languages.
See documentation for other libraries for how they authenticate.
### Accessing the API from a Pod
When accessing the API from a pod, locating and authenticating
to the apiserver are somewhat different.
The recommended way to locate the apiserver within the pod is with
the `kubernetes.default.svc` DNS name, which resolves to a Service IP which in turn
will be routed to an apiserver.
The recommended way to authenticate to the apiserver is with a
[service account](/docs/tasks/configure-pod-container/configure-service-account/) credential. By kube-system, 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,
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.
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:
- run `kubectl proxy` in a sidecar container in the pod, or as a background
process within the 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.
- 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)
In each case, the credentials of the pod are used to communicate securely with the apiserver.
## Accessing services running on the cluster
The previous section was about connecting the Kubernetes API server. This section is about
connecting to other services running on Kubernetes cluster. In Kubernetes, the
[nodes](/docs/admin/node), [pods](/docs/user-guide/pods) and [services](/docs/user-guide/services) all have
their own IPs. In many cases, the node IPs, pod IPs, and some service IPs on a cluster will not be
routable, so they will not be reachable from a machine outside the cluster,
such as your desktop machine.
### Ways to connect
You have several options for connecting to nodes, pods and services from outside the cluster:
- 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/reference/generated/kubectl/kubectl-commands/#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 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.
- Does apiserver authentication and authorization prior to accessing the remote service.
Use this if the services are not secure enough to expose to the internet, or to gain
access to ports on the node IP, or for debugging.
- Proxies may cause problems for some web applications.
- 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/reference/generated/kubectl/kubectl-commands/#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.
### Discovering builtin services
Typically, there are several services which are started on a cluster by kube-system. Get a list of these
with the `kubectl cluster-info` command:
```shell
$ kubectl cluster-info
Kubernetes master is running at https://104.197.5.247
elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy
kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy
kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy
grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
```
This shows the proxy-verb URL for accessing each service.
For example, this cluster has cluster-level logging enabled (using Elasticsearch), which can be reached
at `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/` if suitable credentials are passed. Logging can also be reached through a kubectl proxy, for example at:
`http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`.
(See [above](#accessing-the-cluster-api) for how to pass credentials or use kubectl proxy.)
#### Manually constructing apiserver proxy URLs
As mentioned above, you use the `kubectl cluster-info` command to retrieve the service's proxy URL. To create proxy URLs that include service endpoints, suffixes, and parameters, you simply append to the service's proxy URL:
`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`service_name[:port_name]`*`/proxy`
If you haven't specified a name for your port, you don't have to specify *port_name* in the URL.
By default, the API server proxies to your service using http. To use https, prefix the service name with `https:`:
`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`https:service_name:[port_name]`*`/proxy`
The supported formats for the name segment of the URL are:
* `<service_name>` - proxies to the default or unnamed port using http
* `<service_name>:<port_name>` - proxies to the specified port using http
* `https:<service_name>:` - proxies to the default or unnamed port using https (note the trailing colon)
* `https:<service_name>:<port_name>` - proxies to the specified port using https
##### Examples
* To access the Elasticsearch service endpoint `_search?q=user:kimchy`, you would use: `http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy`
* To access the Elasticsearch cluster health information `_cluster/health?pretty=true`, you would use: `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true`
```json
{
"cluster_name" : "kubernetes_logging",
"status" : "yellow",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 5,
"active_shards" : 5,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 5
}
```
#### Using web browsers to access services running on the cluster
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,
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.
## Requesting redirects
The redirect capabilities have been deprecated and removed. Please use a proxy (see below) instead.
## So Many Proxies
There are several different proxies you may encounter when using Kubernetes:
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):
- 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
- client to proxy uses HTTPS (or http if apiserver so configured)
- 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):
- 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):
- 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:
- 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
- implementation varies by cloud provider.
Kubernetes users will typically not need to worry about anything other than the first two types. The cluster admin
will typically ensure that the latter types are setup correctly.
@@ -0,0 +1,150 @@
---
title: Communicate Between Containers in the Same Pod Using a Shared Volume
content_template: templates/task
---
{{% capture overview %}}
This page shows how to use a Volume to communicate between two Containers running
in the same Pod.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## Creating a Pod that runs two Containers
In this exercise, you create a Pod that runs two Containers. The two containers
share a Volume that they can use to communicate. Here is the configuration file
for the Pod:
{{< code file="two-container-pod.yaml" >}}
In the configuration file, you can see that the Pod has a Volume named
`shared-data`.
The first container listed in the configuration file runs an nginx server. The
mount path for the shared Volume is `/usr/share/nginx/html`.
The second container is based on the debian image, and has a mount path of
`/pod-data`. The second container runs the following command and then terminates.
echo Hello from the debian container > /pod-data/index.html
Notice that the second container writes the `index.html` file in the root
directory of the nginx server.
Create the Pod and the two Containers:
kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/two-container-pod.yaml
View information about the Pod and the Containers:
kubectl get pod two-containers --output=yaml
Here is a portion of the output:
apiVersion: v1
kind: Pod
metadata:
...
name: two-containers
namespace: default
...
spec:
...
containerStatuses:
- containerID: docker://c1d8abd1 ...
image: debian
...
lastState:
terminated:
...
name: debian-container
...
- containerID: docker://96c1ff2c5bb ...
image: nginx
...
name: nginx-container
...
state:
running:
...
You can see that the debian Container has terminated, and the nginx Container
is still running.
Get a shell to nginx Container:
kubectl exec -it two-containers -c nginx-container -- /bin/bash
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:
USER PID ... STAT START TIME COMMAND
root 1 ... Ss 21:12 0:00 nginx: master process nginx -g daemon off;
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:/# curl localhost
The output shows that nginx serves a web page written by the debian container:
Hello from the debian container
{{% /capture %}}
{{% capture discussion %}}
## Discussion
The primary reason that Pods can have multiple containers is to support
helper applications that assist a primary application. Typical examples of
helper applications are data pullers, data pushers, and proxies.
Helper and primary applications often need to communicate with each other.
Typically this is done through a shared filesystem, as shown in this exercise,
or through the loopback network interface, localhost. An example of this pattern is a
web server along with a helper program that polls a Git repository for new updates.
The Volume in this exercise provides a way for Containers to communicate during
the life of the Pod. If the Pod is deleted and recreated, any data stored in
the shared Volume is lost.
{{% /capture %}}
{{% capture whatsnext %}}
* Learn more about
[patterns for composite containers](http://blog.kubernetes.io/2015/06/the-distributed-system-toolkit-patterns.html).
* Learn about
[composite containers for modular architecture](http://www.slideshare.net/Docker/slideshare-burns).
* See
[Configuring a Pod to Use a Volume for Storage](/docs/tasks/configure-pod-container/configure-volume-storage/).
* See [Volume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volume-v1-core).
* See [Pod](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core).
{{% /capture %}}
@@ -0,0 +1,345 @@
---
title: Configure Access to Multiple Clusters
content_template: templates/task
---
{{% capture overview %}}
This page shows how to configure access to multiple clusters by using
configuration files. After your clusters, users, and contexts are defined in
one or more configuration files, you can quickly switch between clusters by using the
`kubectl config use-context` command.
{{< note >}}
**Note:** A file that is used to configure access to a cluster is sometimes called
a *kubeconfig file*. This is a generic way of referring to configuration files.
It does not mean that there is a file named `kubeconfig`.
{{< /note >}}
{{% /capture %}}
{{% capture prerequisites %}}
You need to have the [`kubectl`](/docs/tasks/tools/install-kubectl/) command-line tool installed.
{{% /capture %}}
{{% capture steps %}}
## Define clusters, users, and contexts
Suppose you have two clusters, one for development work and one for scratch work.
In the `development` cluster, your frontend developers work in a namespace called `frontend`,
and your storage developers work in a namespace called `storage`. In your `scratch` cluster,
developers work in the default namespace, or they create auxiliary namespaces as they
see fit. Access to the development cluster requires authentication by certificate. Access
to the scratch cluster requires authentication by username and password.
Create a directory named `config-exercise`. In your
`config-exercise` directory, create a file named `config-demo` with this content:
```shell
apiVersion: v1
kind: Config
preferences: {}
clusters:
- cluster:
name: development
- cluster:
name: scratch
users:
- name: developer
- name: experimenter
contexts:
- context:
name: dev-frontend
- context:
name: dev-storage
- context:
name: exp-scratch
```
A configuration file describes clusters, users, and contexts. Your `config-demo` file
has the framework to describe two clusters, two users, and three contexts.
Go to your `config-exercise` directory. Enter these commands to add cluster details to
your configuration file:
```shell
kubectl config --kubeconfig=config-demo set-cluster development --server=https://1.2.3.4 --certificate-authority=fake-ca-file
kubectl config --kubeconfig=config-demo set-cluster scratch --server=https://5.6.7.8 --insecure-skip-tls-verify
```
Add user details to your configuration file:
```shell
kubectl config --kubeconfig=config-demo set-credentials developer --client-certificate=fake-cert-file --client-key=fake-key-seefile
kubectl config --kubeconfig=config-demo set-credentials experimenter --username=exp --password=some-password
```
Add context details to your configuration file:
```shell
kubectl config --kubeconfig=config-demo set-context dev-frontend --cluster=development --namespace=frontend --user=developer
kubectl config --kubeconfig=config-demo set-context dev-storage --cluster=development --namespace=storage --user=developer
kubectl config --kubeconfig=config-demo set-context exp-scratch --cluster=scratch --namespace=default --user=experimenter
```
Open your `config-demo` file to see the added details. As an alternative to opening the
`config-demo` file, you can use the `config view` command.
```shell
kubectl config --kubeconfig=config-demo view
```
The output shows the two clusters, two users, and three contexts:
```shell
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
- cluster:
insecure-skip-tls-verify: true
server: https://5.6.7.8
name: scratch
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: scratch
namespace: default
user: experimenter
name: exp-scratch
current-context: ""
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
- name: experimenter
user:
password: some-password
username: exp
```
Each context is a triple (cluster, user, namespace). For example, the
`dev-frontend` context says, Use the credentials of the `developer`
user to access the `frontend` namespace of the `development` cluster.
Set the current context:
```shell
kubectl config --kubeconfig=config-demo use-context dev-frontend
```
Now whenever you enter a `kubectl` command, the action will apply to the cluster,
and namespace listed in the `dev-frontend` context. And the command will use
the credentials of the user listed in the `dev-frontend` context.
To see only the configuration information associated with
the current context, use the `--minify` flag.
```shell
kubectl config --kubeconfig=config-demo view --minify
```
The output shows configuration information associated with the `dev-frontend` context:
```shell
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
current-context: dev-frontend
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
```
Now suppose you want to work for a while in the scratch cluster.
Change the current context to `exp-scratch`:
```shell
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 `exp-scratch` context.
View configuration associated with the new current context, `exp-scratch`.
```shell
kubectl config --kubeconfig=config-demo view --minify
```
Finally, suppose you want to work for a while in the `storage` namespace of the
`development` cluster.
Change the current context to `dev-storage`:
```shell
kubectl config --kubeconfig=config-demo use-context dev-storage
```
View configuration associated with the new current context, `dev-storage`.
```shell
kubectl config --kubeconfig=config-demo view --minify
```
## Create a second configuration file
In your `config-exercise` directory, create a file named `config-demo-2` with this content:
```shell
apiVersion: v1
kind: Config
preferences: {}
contexts:
- context:
cluster: development
namespace: ramp
user: developer
name: dev-ramp-up
```
The preceding configuration file defines a new context named `dev-ramp-up`.
## Set the KUBECONFIG environment variable
See whether you have an environment variable named `KUBECONFIG`. If so, save the
current value of your `KUBECONFIG` environment variable, so you can restore it later.
For example, on Linux:
```shell
export KUBECONFIG_SAVED=$KUBECONFIG
```
The `KUBECONFIG` environment variable is a list of paths to configuration files. The list is
colon-delimited for Linux and Mac, and semicolon-delimited for Windows. If you have
a `KUBECONFIG` environment variable, familiarize yourself with the configuration files
in the list.
Temporarily append two paths to your `KUBECONFIG` environment variable. For example, on Linux:
```shell
export KUBECONFIG=$KUBECONFIG:config-demo:config-demo-2
```
In your `config-exercise` directory, enter this command:
```shell
kubectl config view
```
The output shows merged information from all the files listed in your `KUBECONFIG`
environment variable. In particular, notice that the merged information has the
`dev-ramp-up` context from the `config-demo-2` file and the three contexts from
the `config-demo` file:
```shell
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: ramp
user: developer
name: dev-ramp-up
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: scratch
namespace: default
user: experimenter
name: exp-scratch
```
For more information about how kubeconfig files are merged, see
[Organizing Cluster Access Using kubeconfig Files](/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
## Explore the $HOME/.kube directory
If you already have a cluster, and you can use `kubectl` to interact with
the cluster, then you probably have a file named `config` in the `$HOME/.kube`
directory.
Go to `$HOME/.kube`, and see what files are there. Typically, there is a file named
`config`. There might also be other configuration files in this directory. Briefly
familiarize yourself with the contents of these files.
## Append $HOME/.kube/config to your KUBECONFIG environment variable
If you have a `$HOME/.kube/config` file, and it's not already listed in your
`KUBECONFIG` environment variable, append it to your `KUBECONFIG` environment variable now.
For example, on Linux:
```shell
export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config
```
View configuration information merged from all the files that are now listed
in your `KUBECONFIG` environment variable. In your config-exercise directory, enter:
```shell
kubectl config view
```
## Clean up
Return your `KUBECONFIG` environment variable to its original value. For example, on Linux:
```shell
export KUBECONFIG=$KUBECONFIG_SAVED
```
{{% /capture %}}
{{% capture whatsnext %}}
* [Organizing Cluster Access Using kubeconfig Files](/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
* [kubectl config](/docs/reference/generated/kubectl/kubectl-commands/)
{{% /capture %}}
@@ -0,0 +1,99 @@
---
reviewers:
- bprashanth
- davidopp
title: Configure Your Cloud Provider's Firewalls
---
Many cloud providers (e.g. Google Compute Engine) define firewalls that help prevent inadvertent
exposure to the internet. When exposing a service to the external world, you may need to open up
one or more ports in these firewalls to serve traffic. This document describes this process, as
well as any provider specific details that may be necessary.
### Restrict Access For LoadBalancer Service
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 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.
```yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
ports:
- port: 8765
targetPort: 9376
selector:
app: example
type: LoadBalancer
loadBalancerSourceRanges:
- 10.0.0.0/8
```
In the following example, a load balancer will be created that is only accessible to clients with IP addresses from 130.211.204.1 and 130.211.204.2.
```yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
ports:
- port: 8765
targetPort: 9376
selector:
app: example
type: LoadBalancer
loadBalancerSourceRanges:
- 130.211.204.1/32
- 130.211.204.2/32
```
### Google Compute Engine
When using a Service with `spec.type: LoadBalancer`, the firewall will be
opened automatically. When using `spec.type: NodePort`, however, the firewall
is *not* opened by default.
Google Compute Engine firewalls are documented [elsewhere](https://cloud.google.com/compute/docs/networking#firewalls_1).
You can add a firewall with the `gcloud` command line tool:
```shell
gcloud compute firewall-rules create my-rule --allow=tcp:<port>
```
**Note**
There is one important security note when using firewalls on Google Compute Engine:
as of Kubernetes v1.0.0, GCE firewalls are defined per-vm, rather than per-ip
address. This means that when you open a firewall for a service's ports,
anything that serves on that port on that VM's host IP address may potentially
serve traffic. Note that this is not a problem for other Kubernetes services,
as they listen on IP addresses that are different than the host node's external
IP address.
Consider:
* You create a Service with an external load balancer (IP Address 1.2.3.4)
and port 80
* You open the firewall for port 80 for all nodes in your cluster, so that
the external Service actually can deliver packets to your Service
* You start an nginx server, running on port 80 on the host virtual machine
(IP Address 2.3.4.5). This nginx is also exposed to the internet on
the VM's external IP address.
Consequently, please be careful when opening firewalls in Google Compute Engine
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.
### Other cloud providers
Coming soon.
@@ -0,0 +1,205 @@
---
title: Connect a Front End to a Back End Using a Service
content_template: templates/tutorial
---
{{% capture overview %}}
This task shows how to create a frontend and a backend
microservice. The backend microservice is a hello greeter. The
frontend and backend are connected using a Kubernetes Service object.
{{% /capture %}}
{{% capture objectives %}}
* Create and run a microservice using a Deployment object.
* Route traffic to the backend using a frontend.
* Use a Service object to connect the frontend application to the
backend application.
{{% /capture %}}
{{% capture prerequisites %}}
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
* This task uses
[Services with external load balancers](/docs/tasks/access-application-cluster/create-external-load-balancer/), which
require a supported environment. If your environment does not
support this, you can use a Service of type
[NodePort](/docs/concepts/services-networking/service/#type-nodeport) instead.
{{% /capture %}}
{{% capture lessoncontent %}}
### Creating the backend using a Deployment
The backend is a simple hello greeter microservice. Here is the configuration
file for the backend Deployment:
{{< code file="hello.yaml" >}}
Create the backend Deployment:
```
kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/hello.yaml
```
View information about the backend Deployment:
```
kubectl describe deployment hello
```
The output is similar to this:
```
Name: hello
Namespace: default
CreationTimestamp: Mon, 24 Oct 2016 14:21:02 -0700
Labels: app=hello
tier=backend
track=stable
Annotations: deployment.kubernetes.io/revision=1
Selector: app=hello,tier=backend,track=stable
Replicas: 7 desired | 7 updated | 7 total | 7 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=hello
tier=backend
track=stable
Containers:
hello:
Image: "gcr.io/google-samples/hello-go-gke:1.0"
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: hello-3621623197 (7/7 replicas created)
Events:
...
```
### Creating the backend Service object
The key to connecting a frontend to a backend is the backend
Service. A Service creates a persistent IP address and DNS name entry
so that the backend microservice can always be reached. A Service uses
selector labels to find the Pods that it routes traffic to.
First, explore the Service configuration file:
{{< code file="hello-service.yaml" >}}
In the configuration file, you can see that the Service routes traffic to Pods
that have the labels `app: hello` and `tier: backend`.
Create the `hello` Service:
```
kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/hello-service.yaml
```
At this point, you have a backend Deployment running, and you have a
Service that can route traffic to it.
### Creating the frontend
Now that you have your backend, you can create a frontend that connects to the backend.
The frontend connects to the backend worker Pods by using the DNS name
given to the backend Service. The DNS name is "hello", which is the value
of the `name` field in the preceding Service configuration file.
The Pods in the frontend Deployment run an nginx image that is configured
to find the hello backend Service. Here is the nginx configuration file:
{{< code file="frontend/frontend.conf" >}}
Similar to the backend, the frontend has a Deployment and a Service. The
configuration for the Service has `type: LoadBalancer`, which means that
the Service uses the default load balancer of your cloud provider.
{{< code file="frontend.yaml" >}}
Create the frontend Deployment and Service:
```
kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/frontend.yaml
```
The output verifies that both resources were created:
```
deployment "frontend" created
service "frontend" created
```
**Note**: The nginx configuration is baked into the
[container image](/docs/tasks/access-application-cluster/frontend/Dockerfile).
A better way to do this would be to use a
[ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/), so
that you can change the configuration more easily.
### Interact with the frontend Service
Once youve created a Service of type LoadBalancer, you can use this
command to find the external IP:
```
kubectl get service frontend
```
The external IP field may take some time to populate. If this is the
case, the external IP is listed as `<pending>`.
```
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend 10.51.252.116 <pending> 80/TCP 10s
```
Repeat the same command again until it shows an external IP address:
```
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m
```
### Send traffic through the frontend
The frontend and backends are now connected. You can hit the endpoint
by using the curl command on the external IP of your frontend Service.
```
curl http://<EXTERNAL-IP>
```
The output shows the message generated by the backend:
```
{"message":"Hello"}
```
{{% /capture %}}
{{% capture whatsnext %}}
* Learn more about [Services](/docs/concepts/services-networking/service/)
* Learn more about [ConfigMaps](/docs/tasks/configure-pod-container/configure-pod-configmap/)
{{% /capture %}}
@@ -0,0 +1,219 @@
---
title: Create an External Load Balancer
content_template: templates/task
---
{{% capture overview %}}
This page shows how to create an External Load Balancer.
When creating a service, you have the option of automatically creating a
cloud network load balancer. This provides an externally-accessible IP address
that sends traffic to the correct port on your cluster nodes
_provided your cluster runs in a supported environment and is configured with
the correct cloud load balancer provider package_.
For information on provisioning and using an Ingress resource that can give
services externally-reachable URLs, load balance the traffic, terminate SSL etc.,
please check the [Ingress](/docs/concepts/services-networking/ingress/)
documentation.
{{% /capture %}}
{{% capture prerequisites %}}
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## Configuration file
To create an external load balancer, add the following line to your
[service configuration file](/docs/concepts/services-networking/service/#type-loadbalancer):
```json
"type": "LoadBalancer"
```
Your configuration file might look like:
```json
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "example-service"
},
"spec": {
"ports": [{
"port": 8765,
"targetPort": 9376
}],
"selector": {
"app": "example"
},
"type": "LoadBalancer"
}
}
```
## Using kubectl
You can alternatively create the service with the `kubectl expose` command and
its `--type=LoadBalancer` flag:
```bash
kubectl expose rc example --port=8765 --target-port=9376 \
--name=example-service --type=LoadBalancer
```
This command creates a new service using the same selectors as the referenced
resource (in the case of the example above, a replication controller named
`example`).
For more information, including optional flags, refer to the
[`kubectl expose` reference](/docs/reference/generated/kubectl/kubectl-commands/#expose).
## Finding your IP address
You can find the IP address created for your service by getting the service
information through `kubectl`:
```bash
kubectl describe services example-service
```
which should produce output like this:
```bash
Name: example-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=example
Type: LoadBalancer
IP: 10.67.252.103
LoadBalancer Ingress: 123.45.678.9
Port: <unnamed> 80/TCP
NodePort: <unnamed> 32445/TCP
Endpoints: 10.64.0.4:80,10.64.1.5:80,10.64.2.4:80
Session Affinity: None
Events: <none>
```
The IP address is listed next to `LoadBalancer Ingress`.
{{< note >}}
**Note**: If you are running your service on Minikube, you can find the assigned IP address and port with:
{{< /note >}}
```bash
minikube service example-service --url
```
## Preserving the client source IP
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/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
options: "Cluster" (default) and "Local". "Cluster" obscures the client source
IP and may cause a second hop to another node, but should have good overall
load-spreading. "Local" preserves the client source IP and avoids a second hop
for LoadBalancer and NodePort type services, but risks potentially imbalanced
traffic spreading.
* `service.spec.healthCheckNodePort` - specifies the healthcheck nodePort
(numeric port number) for the service. If not specified, healthCheckNodePort is
created by the service API backend with the allocated nodePort. It will use the
user-specified nodePort value if specified by the client. It only has an
effect when type is set to "LoadBalancer" and externalTrafficPolicy is set
to "Local".
This feature can be activated by setting `externalTrafficPolicy` to "Local" in the
Service Configuration file.
```json
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "example-service"
},
"spec": {
"ports": [{
"port": 8765,
"targetPort": 9376
}],
"selector": {
"app": "example"
},
"type": "LoadBalancer",
"externalTrafficPolicy": "Local"
}
}
```
### Feature availability
| k8s version | Feature support |
| :---------: |:-----------:|
| 1.7+ | Supports the full API fields |
| 1.5 - 1.6 | Supports Beta Annotations |
| <1.5 | Unsupported |
Below you could find the deprecated Beta annotations used to enable this feature
prior to its stable version. Newer Kubernetes versions may stop supporting these
after v1.7. Please update existing applications to use the fields directly.
* `service.beta.kubernetes.io/external-traffic` annotation <-> `service.spec.externalTrafficPolicy` field
* `service.beta.kubernetes.io/healthcheck-nodeport` annotation <-> `service.spec.healthCheckNodePort` field
`service.beta.kubernetes.io/external-traffic` annotation has a different set of values
compared to the `service.spec.externalTrafficPolicy` field. The values match as follows:
* "OnlyLocal" for annotation <-> "Local" for field
* "Global" for annotation <-> "Cluster" for field
**Note that this feature is not currently implemented for all cloudproviders/environments.**
Known issues:
* AWS: [kubernetes/kubernetes#35758](https://github.com/kubernetes/kubernetes/issues/35758)
* Weave-Net: [weaveworks/weave/#2924](https://github.com/weaveworks/weave/issues/2924)
{{% /capture %}}
{{% capture discussion %}}
## External Load Balancer Providers
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 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
GCE/AWS load balancers do not provide weights for their target pools. This was not an issue with the old LB
kube-proxy rules which would correctly balance across all endpoints.
With the new functionality, the external traffic will not be equally load balanced across pods, but rather
equally balanced at the node level (because GCE/AWS and other external LB implementations do not have the ability
for specifying the weight per node, they balance equally across all target nodes, disregarding the number of
pods on each node).
We can, however, state that for NumServicePods << NumNodes or NumServicePods >> NumNodes, a fairly close-to-equal
distribution will be seen, even without weights.
Once the external load balancers provide weights, this functionality can be added to the LB programming path.
*Future Work: No support for weights is provided for the 1.4 release, but may be added at a future date*
Internal pod to pod traffic should behave similar to ClusterIP services, with equal probability across all pods.
{{% /capture %}}
@@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
selector:
app: hello
tier: frontend
ports:
- protocol: "TCP"
port: 80
targetPort: 80
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: hello
tier: frontend
track: stable
replicas: 1
template:
metadata:
labels:
app: hello
tier: frontend
track: stable
spec:
containers:
- name: nginx
image: "gcr.io/google-samples/hello-frontend:1.0"
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
@@ -0,0 +1,4 @@
FROM nginx:1.9.14
RUN rm /etc/nginx/conf.d/default.conf
COPY frontend.conf /etc/nginx/conf.d
@@ -0,0 +1,11 @@
upstream hello {
server hello;
}
server {
listen 80;
location / {
proxy_pass http://hello;
}
}
@@ -0,0 +1,12 @@
kind: Service
apiVersion: v1
metadata:
name: hello
spec:
selector:
app: hello
tier: backend
ports:
- protocol: TCP
port: 80
targetPort: http
@@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
selector:
matchLabels:
app: hello
tier: backend
track: stable
replicas: 7
template:
metadata:
labels:
app: hello
tier: backend
track: stable
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-go-gke:1.0"
ports:
- name: http
containerPort: 80
@@ -0,0 +1,4 @@
FROM alpine:3.1
MAINTAINER Carter Morgan <askcarter@google.com>
COPY hello /usr/bin/
CMD ["/usr/bin/hello"]
@@ -0,0 +1,7 @@
Build hello go binary first
go build -tags netgo -ldflags "-extldflags '-lm -lstdc++ -static'" .
Then build docker image
docker build -t hello .
@@ -0,0 +1,74 @@
package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"github.com/braintree/manners"
"github.com/GoogleCloudPlatform/kubernetes-workshops/bundles/kubernetes-101/workshop/app/handlers"
"github.com/GoogleCloudPlatform/kubernetes-workshops/bundles/kubernetes-101/workshop/app/health"
)
const version = "1.0.0"
func main() {
var (
httpAddr = flag.String("http", "0.0.0.0:80", "HTTP service address.")
healthAddr = flag.String("health", "0.0.0.0:81", "Health service address.")
)
flag.Parse()
log.Println("Starting server...")
log.Printf("Health service listening on %s", *healthAddr)
log.Printf("HTTP service listening on %s", *httpAddr)
errChan := make(chan error, 10)
hmux := http.NewServeMux()
hmux.HandleFunc("/healthz", health.HealthzHandler)
hmux.HandleFunc("/readiness", health.ReadinessHandler)
hmux.HandleFunc("/healthz/status", health.HealthzStatusHandler)
hmux.HandleFunc("/readiness/status", health.ReadinessStatusHandler)
healthServer := manners.NewServer()
healthServer.Addr = *healthAddr
healthServer.Handler = handlers.LoggingHandler(hmux)
go func() {
errChan <- healthServer.ListenAndServe()
}()
mux := http.NewServeMux()
mux.HandleFunc("/", handlers.HelloHandler)
mux.Handle("/secure", handlers.JWTAuthHandler(handlers.HelloHandler))
mux.Handle("/version", handlers.VersionHandler(version))
httpServer := manners.NewServer()
httpServer.Addr = *httpAddr
httpServer.Handler = handlers.LoggingHandler(mux)
go func() {
errChan <- httpServer.ListenAndServe()
}()
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
for {
select {
case err := <-errChan:
if err != nil {
log.Fatal(err)
}
case s := <-signalChan:
log.Println(fmt.Sprintf("Captured %v. Exiting...", s))
health.SetReadinessStatus(http.StatusServiceUnavailable)
httpServer.BlockingClose()
os.Exit(0)
}
}
}
@@ -0,0 +1,123 @@
---
title: List All Container Images Running in a Cluster
content_template: templates/task
---
{{% capture overview %}}
This page shows how to use kubectl to list all of the Container images
for Pods running in a cluster.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
In this exercise you will use kubectl to fetch all of the Pods
running in a cluster, and format the output to pull out the list
of Containers for each.
## List all Containers in all namespaces
- Fetch all Pods in all namespaces using `kubectl get pods --all-namespaces`
- Format the output to include only the list of Container image names
using `-o jsonpath={..image}`. This will recursively parse out the
`image` field from the returned json.
- See the [jsonpath reference](/docs/user-guide/jsonpath/)
for further information on how to use jsonpath.
- Format the output using standard tools: `tr`, `sort`, `uniq`
- Use `tr` to replace spaces with newlines
- Use `sort` to sort the results
- Use `uniq` to aggregate image counts
```sh
kubectl get pods --all-namespaces -o jsonpath="{..image}" |\
tr -s '[[:space:]]' '\n' |\
sort |\
uniq -c
```
The above command will recursively return all fields named `image`
for all items returned.
As an alternative, it is possible to use the absolute path to the image
field within the Pod. This ensures the correct field is retrieved
even when the field name is repeated,
e.g. many fields are called `name` within a given item:
```sh
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}"
```
The jsonpath is interpreted as follows:
- `.items[*]`: for each returned value
- `.spec`: get the spec
- `.containers[*]`: for each container
- `.image`: get the image
**Note:** When fetching a single Pod by name, e.g. `kubectl get pod nginx`,
the `.items[*]` portion of the path should be omitted because a single
Pod is returned instead of a list of items.
## List Containers by Pod
The formatting can be controlled further by using the `range` operation to
iterate over elements individually.
```sh
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
sort
```
## List Containers filtering by Pod label
To target only Pods matching a specific label, use the -l flag. The
following matches only Pods with labels matching `app=nginx`.
```sh
kubectl get pods --all-namespaces -o=jsonpath="{..image}" -l app=nginx
```
## List Containers filtering by Pod namespace
To target only pods in a specific namespace, use the namespace flag. The
following matches only Pods in the `kube-system` namespace.
```sh
kubectl get pods --namespace kube-system -o jsonpath="{..image}"
```
## List Containers using a go-template instead of jsonpath
As an alternative to jsonpath, Kubectl supports using [go-templates](https://golang.org/pkg/text/template/)
for formatting the output:
```sh
kubectl get pods --all-namespaces -o go-template --template="{{range .items}}{{range .spec.containers}}{{.image}} {{end}}{{end}}"
```
{{% /capture %}}
{{% capture discussion %}}
{{% /capture %}}
{{% capture whatsnext %}}
### Reference
* [Jsonpath](/docs/user-guide/jsonpath/) reference guide
* [Go template](https://golang.org/pkg/text/template/) reference guide
{{% /capture %}}
@@ -0,0 +1,119 @@
---
title: Provide Load-Balanced Access to an Application in a Cluster
content_template: templates/tutorial
---
{{% capture overview %}}
This page shows how to create a Kubernetes Service object that provides
load-balanced access to an application running in a cluster.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture objectives %}}
* Run two instances of a Hello World application
* Create a Service object
* Use the Service object to access the running application
{{% /capture %}}
{{% capture lessoncontent %}}
## Creating a Service for an application running in two pods
1. Run a Hello World application in your cluster:
kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080
1. List the pods that are running the Hello World application:
kubectl get pods --selector="run=load-balancer-example"
The output is similar to this:
NAME READY STATUS RESTARTS AGE
hello-world-2189936611-8fyp0 1/1 Running 0 6m
hello-world-2189936611-9isq8 1/1 Running 0 6m
1. List the replica set for the two Hello World pods:
kubectl get replicasets --selector="run=load-balancer-example"
The output is similar to this:
NAME DESIRED CURRENT AGE
hello-world-2189936611 2 2 12m
1. Create a Service object that exposes the replica set:
kubectl expose rs <your-replica-set-name> --type="LoadBalancer" --name="example-service"
where `<your-replica-set-name>` is the name of your replica set.
1. Display the IP addresses for your service:
kubectl get services example-service
The output shows the internal IP address and the external IP address of
your service. If the external IP address shows as `<pending>`, repeat the
command.
Note: If you are using Minikube, you don't get an external IP address. The
external IP address remains in the pending state.
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
example-service 10.0.0.160 <pending> 8080/TCP 40s
1. Use your Service object to access the Hello World application:
curl <your-external-ip-address>:8080
where `<your-external-ip-address>` is the external IP address of your
service.
The output is a hello message from the application:
Hello Kubernetes!
Note: If you are using Minikube, enter these commands:
kubectl cluster-info
kubectl describe services example-service
The output displays the IP address of your Minikube node and the NodePort
value for your service. Then enter this command to access the Hello World
application:
curl <minikube-node-ip-address>:<service-node-port>
where `<minikube-node-ip-address>` us the IP address of your Minikube node,
and `<service-node-port>` is the NodePort value for your service.
## Using a service configuration file
As an alternative to using `kubectl expose`, you can use a
[service configuration file](/docs/concepts/services-networking/service/)
to create a Service.
{{% /capture %}}
{{% capture whatsnext %}}
Learn more about
[connecting applications with services](/docs/concepts/services-networking/connect-applications-service/).
{{% /capture %}}
@@ -0,0 +1,141 @@
---
title: Use Port Forwarding to Access Applications in a Cluster
content_template: templates/task
---
{{% capture overview %}}
This page shows how to use `kubectl port-forward` to connect to a Redis
server running in a Kubernetes cluster. This type of connection can be useful
for database debugging.
{{% /capture %}}
{{% capture prerequisites %}}
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
* Install [redis-cli](http://redis.io/topics/rediscli).
{{% /capture %}}
{{% capture steps %}}
## Creating Redis deployment and service
1. Create a Redis deployment:
kubectl create -f https://k8s.io/docs/tutorials/stateless-application/guestbook/redis-master-deployment.yaml
The output of a successful command verifies that the deployment was created:
deployment "redis-master" created
When the pod is ready, you can get:
kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-master-765d459796-258hz 1/1 Running 0 50s
kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
redis-master 1 1 1 1 55s
kubectl get rs
NAME DESIRED CURRENT READY AGE
redis-master-765d459796 1 1 1 1m
2. Create a Redis service:
kubectl create -f https://k8s.io/docs/tutorials/stateless-application/guestbook/redis-master-service.yaml
The output of a successful command verifies that the service was created:
service "redis-master" created
Check the service created:
kubectl get svc | grep redis
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-master ClusterIP 10.0.0.213 <none> 6379/TCP 27s
3. Verify that the Redis server is running in the pod and listening on port 6379:
kubectl get pods redis-master-765d459796-258hz --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
The output displays the port:
6379
## Forward a local port to a port on the pod
1. `kubectl port-forward` allows using resource name, such as a service name, to select a matching pod to port forward to since Kubernetes v1.10.
kubectl port-forward redis-master-765d459796-258hz 6379:6379
which is the same as
kubectl port-forward pods/redis-master-765d459796-258hz 6379:6379
or
kubectl port-forward deployment/redis-master 6379:6379
or
kubectl port-forward rs/redis-master 6379:6379
or
kubectl port-forward svc/redis-master 6379:6379
Any of the above commands works. The output is similar to this:
I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:6379 -> 6379
I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:6379 -> 6379
2. Start the Redis command line interface:
redis-cli
3. At the Redis command line prompt, enter the `ping` command:
127.0.0.1:6379>ping
A successful ping request returns PONG.
{{% /capture %}}
{{% capture discussion %}}
## Discussion
Connections made to local port 6379 are forwarded to port 6379 of the pod that
is running the Redis server. With this connection in place you can use your
local workstation to debug the database that is running in the pod.
{{< warning >}}
**Warning**: Due to known limitations, port forward today only works for TCP protocol.
The support to UDP protocol is being tracked in
[issue 47862](https://github.com/kubernetes/kubernetes/issues/47862).
{{< /warning >}}
{{% /capture %}}
{{% capture whatsnext %}}
Learn more about [kubectl port-forward](/docs/reference/generated/kubectl/kubectl-commands/#port-forward).
{{% /capture %}}
@@ -0,0 +1,33 @@
apiVersion: v1
kind: Pod
metadata:
labels:
name: redis
redis-sentinel: "true"
role: master
name: redis-master
spec:
containers:
- name: master
image: k8s.gcr.io/redis:v1
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
resources:
limits:
cpu: "0.1"
volumeMounts:
- mountPath: /redis-master-data
name: data
- name: sentinel
image: kubernetes/redis:v1
env:
- name: SENTINEL
value: "true"
ports:
- containerPort: 26379
volumes:
- name: data
emptyDir: {}
@@ -0,0 +1,150 @@
---
title: Use a Service to Access an Application in a Cluster
content_template: templates/tutorial
---
{{% capture overview %}}
This page shows how to create a Kubernetes Service object that external
clients can use to access an application running in a cluster. The Service
provides load balancing for an application that has two running instances.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture objectives %}}
* Run two instances of a Hello World application.
* Create a Service object that exposes a node port.
* Use the Service object to access the running application.
{{% /capture %}}
{{% capture lessoncontent %}}
## Creating a service for an application running in two pods
1. Run a Hello World application in your cluster:
kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080
The preceding command creates a
[Deployment](/docs/concepts/workloads/controllers/deployment/)
object and an associated
[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/)
object. The ReplicaSet has two
[Pods](/docs/concepts/workloads/pods/pod/),
each of which runs the Hello World application.
1. Display information about the Deployment:
kubectl get deployments hello-world
kubectl describe deployments hello-world
1. Display information about your ReplicaSet objects:
kubectl get replicasets
kubectl describe replicasets
1. Create a Service object that exposes the deployment:
kubectl expose deployment hello-world --type=NodePort --name=example-service
1. Display information about the Service:
kubectl describe services example-service
The output is similar to this:
Name: example-service
Namespace: default
Labels: run=load-balancer-example
Annotations: <none>
Selector: run=load-balancer-example
Type: NodePort
IP: 10.32.0.16
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 31496/TCP
Endpoints: 10.200.1.4:8080,10.200.2.5:8080
Session Affinity: None
Events: <none>
Make a note of the NodePort value for the service. For example,
in the preceding output, the NodePort value is 31496.
1. List the pods that are running the Hello World application:
kubectl get pods --selector="run=load-balancer-example" --output=wide
The output is similar to this:
NAME READY STATUS ... IP NODE
hello-world-2895499144-bsbk5 1/1 Running ... 10.200.1.4 worker1
hello-world-2895499144-m1pwt 1/1 Running ... 10.200.2.5 worker2
1. Get the public IP address of one of your nodes that is running
a Hello World pod. How you get this address depends on how you set
up your cluster. For example, if you are using Minikube, you can
see the node address by running `kubectl cluster-info`. If you are
using Google Compute Engine instances, you can use the
`gcloud compute instances list` command to see the public addresses of your
nodes. For more information about this command, see the [GCE documentation](https://cloud.google.com/sdk/gcloud/reference/compute/instances/list).
1. On your chosen node, create a firewall rule that allows TCP traffic
on your node port. For example, if your Service has a NodePort value of
31568, create a firewall rule that allows TCP traffic on port 31568. Different
cloud providers offer different ways of configuring firewall rules. See [the
GCE documentation on firewall rules](https://cloud.google.com/compute/docs/vpc/firewalls),
for example.
1. Use the node address and node port to access the Hello World application:
curl http://<public-node-ip>:<node-port>
where `<public-node-ip>` is the public IP address of your node,
and `<node-port>` is the NodePort value for your service.
The response to a successful request is a hello message:
Hello Kubernetes!
## Using a service configuration file
As an alternative to using `kubectl expose`, you can use a
[service configuration file](/docs/concepts/services-networking/service/)
to create a Service.
{{% /capture %}}
{{% capture cleanup %}}
To delete the Service, enter this command:
kubectl delete services example-service
To delete the Deployment, the ReplicaSet, and the Pods that are running
the Hello World application, enter this command:
kubectl delete deployment hello-world
{{% /capture %}}
{{% capture whatsnext %}}
Learn more about
[connecting applications with services](/docs/concepts/services-networking/connect-applications-service/).
{{% /capture %}}
@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
name: two-containers
spec:
restartPolicy: Never
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: debian-container
image: debian
volumeMounts:
- name: shared-data
mountPath: /pod-data
command: ["/bin/sh"]
args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]
@@ -0,0 +1,170 @@
---
reviewers:
- bryk
- mikedanese
- rf232
title: Web UI (Dashboard)
---
Dashboard is a web-based Kubernetes user interface. You can use Dashboard to deploy containerized applications to a Kubernetes cluster, troubleshoot your containerized application, and manage the cluster itself along with its attendant resources. You can use Dashboard to get an overview of applications running on your cluster, as well as for creating or modifying individual Kubernetes resources (such as Deployments, Jobs, DaemonSets, etc). For example, you can scale a Deployment, initiate a rolling update, restart a pod or deploy new applications using a deploy wizard.
Dashboard also provides information on the state of Kubernetes resources in your cluster, and on any errors that may have occurred.
![Kubernetes Dashboard UI](/images/docs/ui-dashboard.png)
{{< toc >}}
## Deploying the Dashboard UI
The Dashboard UI is not deployed by default. To deploy it, run the following command:
```
kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
```
## Accessing the Dashboard UI
There are multiple ways you can access the Dashboard UI; either by using the kubectl command-line interface, or by accessing the Kubernetes master apiserver using your web browser.
### Command line proxy
You can access Dashboard using the kubectl command-line tool by running the following command:
```
kubectl proxy
```
Kubectl will handle authentication with apiserver and make Dashboard available at http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/.
The UI can _only_ be accessed from the machine where the command is executed. See `kubectl proxy --help` for more options.
### Master server
You may access the UI directly via the Kubernetes master apiserver. Open a browser and navigate to ``https://<master-ip>:<apiserver-port>/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/``, where `<kubernetes-master>` is IP address or domain name of the Kubernetes
master.
Please note, this works only if the apiserver is set up to allow authentication with username and password. This is not currently the case with some setup tools (e.g., `kubeadm`). Refer to the [authentication admin documentation](/docs/admin/authentication/) for information on how to configure authentication manually.
If the username and password are configured but unknown to you, then use `kubectl config view` to find it.
## Welcome view
When you access Dashboard on an empty cluster, you'll see the welcome page. This page contains a link to this document as well as a button to deploy your first application. In addition, you can view which system applications are running by default in the `kube-system` [namespace](/docs/tasks/administer-cluster/namespaces/) of your cluster, for example the Dashboard itself.
![Kubernetes Dashboard welcome page](/images/docs/ui-dashboard-zerostate.png)
## Deploying containerized applications
Dashboard lets you create and deploy a containerized application as a Deployment and optional Service with a simple wizard. You can either manually specify application details, or upload a YAML or JSON file containing application configuration.
To access the deploy wizard from the Welcome page, click the respective button. To access the wizard at a later point in time, click the **CREATE** button in the upper right corner of any page.
![Deploy wizard](/images/docs/ui-dashboard-deploy-simple.png)
### Specifying application details
The deploy wizard expects that you provide the following information:
- **App name** (mandatory): Name for your application. A [label](/docs/concepts/overview/working-with-objects/labels/) with the name will be added to the Deployment and Service, if any, that will be deployed.
The application name must be unique within the selected Kubernetes [namespace](/docs/tasks/administer-cluster/namespaces/). It must start with a lowercase character, and end with a lowercase character or a number, and contain only lowercase letters, numbers and dashes (-). It is limited to 24 characters. Leading and trailing spaces are ignored.
- **Container image** (mandatory): The URL of a public Docker [container image](/docs/concepts/containers/images/) on any registry, or a private image (commonly hosted on the Google Container Registry or Docker Hub). The container image specification must end with a colon.
- **Number of pods** (mandatory): The target number of Pods you want your application to be deployed in. The value must be a positive integer.
A [Deployment](/docs/concepts/workloads/controllers/deployment/) will be created to maintain the desired number of Pods across your cluster.
- **Service** (optional): For some parts of your application (e.g. frontends) you may want to expose a [Service](/docs/concepts/services-networking/service/) onto an external, maybe public IP address outside of your cluster (external Service). For external Services, you may need to open up one or more ports to do so. Find more details [here](/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/).
Other Services that are only visible from inside the cluster are called internal Services.
Irrespective of the Service type, if you choose to create a Service and your container listens on a port (incoming), you need to specify two ports. The Service will be created mapping the port (incoming) to the target port seen by the container. This Service will route to your deployed Pods. Supported protocols are TCP and UDP. The internal DNS name for this Service will be the value you specified as application name above.
If needed, you can expand the **Advanced options** section where you can specify more settings:
- **Description**: The text you enter here will be added as an [annotation](/docs/concepts/overview/working-with-objects/annotations/) to the Deployment and displayed in the application's details.
- **Labels**: Default [labels](/docs/concepts/overview/working-with-objects/labels/) to be used for your application are application name and version. You can specify additional labels to be applied to the Deployment, Service (if any), and Pods, such as release, environment, tier, partition, and release track.
Example:
```conf
release=1.0
tier=frontend
environment=pod
track=stable
```
- **Namespace**: Kubernetes supports multiple virtual clusters backed by the same physical cluster. These virtual clusters are called [namespaces](/docs/tasks/administer-cluster/namespaces/). They let you partition resources into logically named groups.
Dashboard offers all available namespaces in a dropdown list, and allows you to create a new namespace. The namespace name may contain a maximum of 63 alphanumeric characters and dashes (-) but can not contain capital letters.
Namespace names should not consist of only numbers. If the name is set as a number, such as 10, the pod will be put in the default namespace.
In case the creation of the namespace is successful, it is selected by default. If the creation fails, the first namespace is selected.
- **Image Pull Secret**: In case the specified Docker container image is private, it may require [pull secret](/docs/concepts/configuration/secret/) credentials.
Dashboard offers all available secrets in a dropdown list, and allows you to create a new secret. The secret name must follow the DNS domain name syntax, e.g. `new.image-pull.secret`. The content of a secret must be base64-encoded and specified in a [`.dockercfg`](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) file. The secret name may consist of a maximum of 253 characters.
In case the creation of the image pull secret is successful, it is selected by default. If the creation fails, no secret is applied.
- **CPU requirement (cores)** and **Memory requirement (MiB)**: You can specify the minimum [resource limits](/docs/tasks/configure-pod-container/limit-range/) for the container. By default, Pods run with unbounded CPU and memory limits.
- **Run command** and **Run command arguments**: By default, your containers run the specified Docker image's default [entrypoint command](/docs/user-guide/containers/#containers-and-commands). You can use the command options and arguments to override the default.
- **Run as privileged**: This setting determines whether processes in [privileged containers](/docs/user-guide/pods/#privileged-mode-for-pod-containers) are equivalent to processes running as root on the host. Privileged containers can make use of capabilities like manipulating the network stack and accessing devices.
- **Environment variables**: Kubernetes exposes Services through [environment variables](/docs/tasks/inject-data-application/environment-variable-expose-pod-information/). You can compose environment variable or pass arguments to your commands using the values of environment variables. They can be used in applications to find a Service. Values can reference other variables using the `$(VAR_NAME)` syntax.
### Uploading a YAML or JSON file
Kubernetes supports declarative configuration. In this style, all configuration is stored in YAML or JSON configuration files using the Kubernetes [API](/docs/concepts/overview/kubernetes-api/) resource schemas.
As an alternative to specifying application details in the deploy wizard, you can define your application in YAML or JSON files, and upload the files using Dashboard:
![Deploy wizard file upload](/images/docs/ui-dashboard-deploy-file.png)
## Using Dashboard
Following sections describe views of the Kubernetes Dashboard UI; what they provide and how can they be used.
### Navigation
When there are Kubernetes objects defined in the cluster, Dashboard shows them in the initial view. By default only objects from the _default_ namespace are shown and this can be changed using the namespace selector located in the navigation menu.
Dashboard shows most Kubernetes object kinds and groups them in a few menu categories.
#### Admin
View for cluster and namespace administrators. It lists Nodes, Namespaces and Persistent Volumes and has detail views for them. Node list view contains CPU and memory usage metrics aggregated across all Nodes. The details view shows the metrics for a Node, its specification, status, allocated resources, events and pods running on the node.
![Node detail view](/images/docs/ui-dashboard-node.png)
#### Workloads
Entry point view that shows all applications running in the selected namespace. The view lists applications by workload kind (e.g., Deployments, Replica Sets, Stateful Sets, etc.) and each workload kind can be viewed separately. The lists summarize actionable information about the workloads, such as the number of ready pods for a Replica Set or current memory usage for a Pod.
![Workloads view](/images/docs/ui-dashboard-workloadview.png)
Detail views for workloads show status and specification information and surface relationships between objects. For example, Pods that Replica Set is controlling or New Replica Sets and Horizontal Pod Autoscalers for Deployments.
![Deployment detail view](/images/docs/ui-dashboard-deployment-detail.png)
#### Services and discovery
Services and discovery view shows Kubernetes resources that allow for exposing services to external world and discovering them within a cluster. For that reason, Service and Ingress views show Pods targeted by them, internal endpoints for cluster connections and external endpoints for external users.
![Service list partial view](/images/docs/ui-dashboard-service-list.png)
#### Storage
Storage view shows Persistent Volume Claim resources which are used by applications for storing data.
#### Config
Config view shows all Kubernetes resources that are used for live configuration of applications running in clusters. This is now Config Maps and Secrets. The view allows for editing and managing config objects and displays secrets hidden by default.
![Secret detail view](/images/docs/ui-dashboard-secret-detail.png)
#### Logs viewer
Pod lists and detail pages link to logs viewer that is built into Dashboard. The viewer allows for drilling down logs from containers belonging to a single Pod.
![Logs viewer](/images/docs/ui-dashboard-logs-view.png)
## More information
For more information, see the
[Kubernetes Dashboard project page](https://github.com/kubernetes/dashboard).