Syntax highlighting
This commit is contained in:
@@ -104,11 +104,11 @@ system:serviceaccount:<namespace>:default
|
||||
|
||||
For example, if you wanted to grant the default service account in the kube-system full privilege to the API, you would add this line to your policy file:
|
||||
|
||||
{% highlight json %}
|
||||
```json
|
||||
|
||||
{"user":"system:serviceaccount:kube-system:default"}
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
The apiserver will need to be restarted to pickup the new policy lines.
|
||||
|
||||
@@ -117,13 +117,13 @@ The apiserver will need to be restarted to pickup the new policy lines.
|
||||
Other implementations can be developed fairly easily.
|
||||
The APIserver calls the Authorizer interface:
|
||||
|
||||
{% highlight go %}
|
||||
```go
|
||||
|
||||
type Authorizer interface {
|
||||
Authorize(a Attributes) error
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
to determine whether or not to allow each API action.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ To prevent memory leaks or other resource issues in [cluster addons](https://rel
|
||||
|
||||
For example:
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
containers:
|
||||
- image: gcr.io/google_containers/heapster:v0.15.0
|
||||
name: heapster
|
||||
@@ -48,7 +48,7 @@ containers:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 200Mi
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
These limits, however, are based on data collected from addons running on 4-node clusters (see [#10335](http://issue.k8s.io/10335#issuecomment-117861225)). The addons consume a lot more resources when running on large deployment clusters (see [#5880](http://issue.k8s.io/5880#issuecomment-113984085)). So, if a large cluster is deployed without adjusting these values, the addons may continuously get killed because they keep hitting the limits.
|
||||
|
||||
|
||||
@@ -46,19 +46,19 @@ Get its usage by running `cluster/gce/upgrade.sh -h`.
|
||||
|
||||
For example, to upgrade just your master to a specific version (v1.0.2):
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
cluster/gce/upgrade.sh -M v1.0.2
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Alternatively, to upgrade your entire cluster to the latest stable release:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
cluster/gce/upgrade.sh release/stable
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
### Other platforms
|
||||
|
||||
@@ -122,11 +122,11 @@ If you want more control over the upgrading process, you may use the following w
|
||||
|
||||
Mark the node to be rebooted as unschedulable:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
kubectl replace nodes $NODENAME --patch='{"apiVersion": "v1", "spec": {"unschedulable": true}}'
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
This keeps new pods from landing on the node while you are trying to get them off.
|
||||
|
||||
@@ -134,11 +134,11 @@ Get the pods off the machine, via any of the following strategies:
|
||||
* Wait for finite-duration pods to complete.
|
||||
* Delete pods with:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
kubectl delete pods $PODNAME
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
For pods with a replication controller, the pod will eventually be replaced by a new pod which will be scheduled to a new node. Additionally, if the pod is part of a service, then clients will automatically be redirected to the new pod.
|
||||
|
||||
@@ -148,11 +148,11 @@ Perform maintenance work on the node.
|
||||
|
||||
Make the node schedulable again:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
kubectl replace nodes $NODENAME --patch='{"apiVersion": "v1", "spec": {"unschedulable": false}}'
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
If you deleted the node's VM instance and created a new one, then a new schedulable node resource will
|
||||
be created automatically when you create a new VM instance (if you're using a cloud provider that supports
|
||||
@@ -192,12 +192,12 @@ for changes to this variable to take effect.
|
||||
|
||||
You can use the `kube-version-change` utility to convert config files between different API versions.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ hack/build-go.sh cmd/kube-version-change
|
||||
$ _output/local/go/bin/kube-version-change -i myPod.v1beta3.yaml -o myPod.v1.yaml
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@ The first thing to debug in your cluster is if your nodes are all registered cor
|
||||
|
||||
Run
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
kubectl get nodes
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
And verify that all of the nodes you expect to see are present and that they are all in the `Ready` state.
|
||||
|
||||
|
||||
@@ -41,11 +41,11 @@ To test whether `etcd` is running correctly, you can try writing a value to a
|
||||
test key. On your master VM (or somewhere with firewalls configured such that
|
||||
you can talk to your cluster's etcd), try:
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
curl -fs -X PUT "http://${host}:${port}/v2/keys/_test"
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,9 +85,9 @@ a simple cluster set up, using etcd's built in discovery to build our cluster.
|
||||
|
||||
First, hit the etcd discovery service to create a new token:
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
curl https://discovery.etcd.io/new?size=3
|
||||
curl https://discovery.etcd.io/new?size=3
|
||||
|
||||
```
|
||||
|
||||
@@ -103,15 +103,15 @@ for `${NODE_IP}` on each machine.
|
||||
|
||||
#### Validating your cluster
|
||||
|
||||
Once you copy this into all three nodes, you should have a clustered etcd set up. You can validate with
|
||||
Once you copy this into all three nodes, you should have a clustered etcd set up. You can validate with
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
etcdctl member list
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
and
|
||||
and
|
||||
|
||||
```shell
|
||||
|
||||
@@ -141,9 +141,9 @@ Once you have replicated etcd set up correctly, we will also install the apiserv
|
||||
|
||||
## Replicated API Servers
|
||||
|
||||
Once you have replicated etcd set up correctly, we will also install the apiserver using the kubelet.
|
||||
Once you have replicated etcd set up correctly, we will also install the apiserver using the kubelet.
|
||||
|
||||
### Installing configuration files
|
||||
### Installing configuration files
|
||||
|
||||
First you need to create the initial log file, so that Docker mounts a file instead of a directory:
|
||||
|
||||
@@ -193,10 +193,10 @@ In the future, we expect to more tightly integrate this lease-locking into the s
|
||||
instances of these actors, in case a machine dies. To achieve this, we are going to use a lease-lock in etcd to perform
|
||||
master election. On each of the three apiserver nodes, we run a small utility application named `podmaster`. It's job is to implement a master
|
||||
election protocol using etcd "compare and swap". If the apiserver node wins the election, it starts the master component it is managing (e.g. the scheduler), if it
|
||||
loses the election, it ensures that any master components running on the node (e.g. the scheduler) are stopped.
|
||||
loses the election, it ensures that any master components running on the node (e.g. the scheduler) are stopped.
|
||||
|
||||
In the future, we expect to more tightly integrate this lease-locking into the scheduler and controller-manager binaries directly, as described in the [high availability design proposal](../proposals/high-availability)
|
||||
|
||||
|
||||
### Installing configuration files
|
||||
|
||||
First, create empty log files on each node, so that Docker will mount the files not make new directories:
|
||||
|
||||
@@ -40,7 +40,7 @@ This example will work in a custom namespace to demonstrate the concepts involve
|
||||
|
||||
Let's create a new namespace called limit-example:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/limitrange/namespace.yaml
|
||||
namespace "limit-example" created
|
||||
@@ -49,22 +49,22 @@ NAME LABELS STATUS AGE
|
||||
default <none> Active 5m
|
||||
limit-example <none> Active 53s
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Step 2: Apply a limit to the namespace
|
||||
|
||||
Let's create a simple limit in our namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/limitrange/limits.yaml --namespace=limit-example
|
||||
limitrange "mylimits" created
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Let's describe the limits that we have imposed in our namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl describe limits mylimits --namespace=limit-example
|
||||
Name: mylimits
|
||||
@@ -76,7 +76,7 @@ Pod memory 6Mi 1Gi - - -
|
||||
Container cpu 100m 2 200m 300m -
|
||||
Container memory 3Mi 1Gi 100Mi 200Mi -
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
In this scenario, we have said the following:
|
||||
|
||||
@@ -104,7 +104,7 @@ of creation explaining why.
|
||||
Let's first spin up a replication controller that creates a single container pod to demonstrate
|
||||
how default values are applied to each pod.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=limit-example
|
||||
replicationcontroller "nginx" created
|
||||
@@ -113,9 +113,9 @@ NAME READY STATUS RESTARTS AGE
|
||||
nginx-aq0mf 1/1 Running 0 35s
|
||||
$ kubectl get pods nginx-aq0mf --namespace=limit-example -o yaml | grep resources -C 8
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
|
||||
resourceVersion: "127"
|
||||
selfLink: /api/v1/namespaces/limit-example/pods/nginx-aq0mf
|
||||
@@ -135,30 +135,30 @@ spec:
|
||||
terminationMessagePath: /dev/termination-log
|
||||
volumeMounts:
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Note that our nginx container has picked up the namespace default cpu and memory resource *limits* and *requests*.
|
||||
|
||||
Let's create a pod that exceeds our allowed limits by having it have a container that requests 3 cpu cores.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/limitrange/invalid-pod.yaml --namespace=limit-example
|
||||
Error from server: error when creating "docs/admin/limitrange/invalid-pod.yaml": Pod "invalid-pod" is forbidden: [Maximum cpu usage per Pod is 2, but limit is 3., Maximum cpu usage per Container is 2, but limit is 3.]
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Let's create a pod that falls within the allowed limit boundaries.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/limitrange/valid-pod.yaml --namespace=limit-example
|
||||
pod "valid-pod" created
|
||||
$ kubectl get pods valid-pod --namespace=limit-example -o yaml | grep -C 6 resources
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
|
||||
uid: 162a12aa-7157-11e5-9921-286ed488f785
|
||||
spec:
|
||||
@@ -174,7 +174,7 @@ spec:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Note that this pod specifies explicit resource *limits* and *requests* so it did not pick up the namespace
|
||||
default values.
|
||||
@@ -196,7 +196,7 @@ $ kubelet --cpu-cfs-quota=true ...
|
||||
|
||||
To remove the resources used by this example, you can just delete the limit-example namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl delete namespace limit-example
|
||||
namespace "limit-example" deleted
|
||||
@@ -204,7 +204,7 @@ $ kubectl get namespaces
|
||||
NAME LABELS STATUS AGE
|
||||
default <none> Active 20m
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ This example will work in a custom namespace to demonstrate the concepts involve
|
||||
|
||||
Let's create a new namespace called limit-example:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/limitrange/namespace.yaml
|
||||
namespace "limit-example" created
|
||||
@@ -49,22 +49,22 @@ NAME LABELS STATUS AGE
|
||||
default <none> Active 5m
|
||||
limit-example <none> Active 53s
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Step 2: Apply a limit to the namespace
|
||||
|
||||
Let's create a simple limit in our namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/limitrange/limits.yaml --namespace=limit-example
|
||||
limitrange "mylimits" created
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Let's describe the limits that we have imposed in our namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl describe limits mylimits --namespace=limit-example
|
||||
Name: mylimits
|
||||
@@ -76,7 +76,7 @@ Pod memory 6Mi 1Gi - - -
|
||||
Container cpu 100m 2 200m 300m -
|
||||
Container memory 3Mi 1Gi 100Mi 200Mi -
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
In this scenario, we have said the following:
|
||||
|
||||
@@ -104,7 +104,7 @@ of creation explaining why.
|
||||
Let's first spin up a replication controller that creates a single container pod to demonstrate
|
||||
how default values are applied to each pod.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=limit-example
|
||||
replicationcontroller "nginx" created
|
||||
@@ -113,9 +113,9 @@ NAME READY STATUS RESTARTS AGE
|
||||
nginx-aq0mf 1/1 Running 0 35s
|
||||
$ kubectl get pods nginx-aq0mf --namespace=limit-example -o yaml | grep resources -C 8
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
|
||||
resourceVersion: "127"
|
||||
selfLink: /api/v1/namespaces/limit-example/pods/nginx-aq0mf
|
||||
@@ -135,30 +135,30 @@ spec:
|
||||
terminationMessagePath: /dev/termination-log
|
||||
volumeMounts:
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Note that our nginx container has picked up the namespace default cpu and memory resource *limits* and *requests*.
|
||||
|
||||
Let's create a pod that exceeds our allowed limits by having it have a container that requests 3 cpu cores.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/limitrange/invalid-pod.yaml --namespace=limit-example
|
||||
Error from server: error when creating "docs/admin/limitrange/invalid-pod.yaml": Pod "invalid-pod" is forbidden: [Maximum cpu usage per Pod is 2, but limit is 3., Maximum cpu usage per Container is 2, but limit is 3.]
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Let's create a pod that falls within the allowed limit boundaries.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/limitrange/valid-pod.yaml --namespace=limit-example
|
||||
pod "valid-pod" created
|
||||
$ kubectl get pods valid-pod --namespace=limit-example -o yaml | grep -C 6 resources
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
|
||||
uid: 162a12aa-7157-11e5-9921-286ed488f785
|
||||
spec:
|
||||
@@ -174,7 +174,7 @@ spec:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Note that this pod specifies explicit resource *limits* and *requests* so it did not pick up the namespace
|
||||
default values.
|
||||
@@ -196,7 +196,7 @@ $ kubelet --cpu-cfs-quota=true ...
|
||||
|
||||
To remove the resources used by this example, you can just delete the limit-example namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl delete namespace limit-example
|
||||
namespace "limit-example" deleted
|
||||
@@ -204,7 +204,7 @@ $ kubectl get namespaces
|
||||
NAME LABELS STATUS AGE
|
||||
default <none> Active 20m
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
|
||||
@@ -45,14 +45,14 @@ Look [here](namespaces/) for an in depth example of namespaces.
|
||||
|
||||
You can list the current namespaces in a cluster using:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS STATUS
|
||||
default <none> Active
|
||||
kube-system <none> Active
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Kubernetes starts with two initial namespaces:
|
||||
* `default` The default namespace for objects with no other namespace
|
||||
@@ -60,15 +60,15 @@ Kubernetes starts with two initial namespaces:
|
||||
|
||||
You can also get the summary of a specific namespace using:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get namespaces <name>
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Or you can get detailed information with:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl describe namespaces <name>
|
||||
Name: default
|
||||
@@ -82,7 +82,7 @@ Resource Limits
|
||||
---- -------- --- --- ---
|
||||
Container cpu - - 100m
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Note that these details show both resource quota (if present) as well as resource limit ranges.
|
||||
|
||||
@@ -104,14 +104,14 @@ See the [design doc](../design/namespaces.html#phases) for more details.
|
||||
|
||||
To create a new namespace, first create a new YAML file called `my-namespace.yaml` with the contents:
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: <insert-namespace-name-here>
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Note that the name of your namespace must be a DNS compatible label.
|
||||
|
||||
@@ -119,11 +119,11 @@ More information on the `finalizers` field can be found in the namespace [design
|
||||
|
||||
Then run:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f ./my-namespace.yaml
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
### Working in namespaces
|
||||
|
||||
@@ -134,11 +134,11 @@ and [Setting the namespace preference](/{{page.version}}/docs/user-guide/namespa
|
||||
|
||||
You can delete a namespace with
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl delete namespaces <insert-some-namespace-name>
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
**WARNING, this deletes _everything_ under the namespace!**
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ services, and replication controllers used by the cluster.
|
||||
|
||||
Assuming you have a fresh cluster, you can introspect the available namespace's by doing the following:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS
|
||||
default <none>
|
||||
default <none>
|
||||
|
||||
```
|
||||
|
||||
@@ -54,7 +54,7 @@ Use the file [`namespace-dev.json`](namespace-dev.json) which describes a develo
|
||||
|
||||
Use the file [`namespace-dev.json`](namespace-dev.json) which describes a development namespace:
|
||||
|
||||
<!-- BEGIN MUNGE: EXAMPLE namespace-dev.json -->
|
||||
<!-- BEGIN MUNGE: EXAMPLE namespace-dev.json -->
|
||||
|
||||
```json
|
||||
|
||||
@@ -65,32 +65,32 @@ Use the file [`namespace-dev.json`](namespace-dev.json) which describes a develo
|
||||
"name": "development",
|
||||
"labels": {
|
||||
"name": "development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
[Download example](namespace-dev.json)
|
||||
<!-- END MUNGE: EXAMPLE namespace-dev.json -->
|
||||
<!-- END MUNGE: EXAMPLE namespace-dev.json -->
|
||||
|
||||
Create the development namespace using kubectl.
|
||||
Create the development namespace using kubectl.
|
||||
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/namespaces/namespace-dev.json
|
||||
$ kubectl create -f docs/admin/namespaces/namespace-dev.json
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
And then lets create the production namespace using kubectl.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/namespaces/namespace-prod.json
|
||||
|
||||
```
|
||||
|
||||
To be sure things are right, let's list all of the namespaces in our cluster.
|
||||
To be sure things are right, let's list all of the namespaces in our cluster.
|
||||
|
||||
```shell
|
||||
|
||||
@@ -103,7 +103,7 @@ To demonstrate this, let's spin up a simple replication controller and pod in th
|
||||
```
|
||||
|
||||
|
||||
### Step Three: Create pods in each namespace
|
||||
### Step Three: Create pods in each namespace
|
||||
|
||||
A Kubernetes namespace provides the scope for pods, services, and replication controllers in the cluster.
|
||||
|
||||
@@ -128,31 +128,31 @@ users:
|
||||
name: lithe-cocoa-92103_kubernetes
|
||||
current-context: lithe-cocoa-92103_kubernetes
|
||||
kind: Config
|
||||
preferences: {}
|
||||
preferences: {}
|
||||
users:
|
||||
- name: lithe-cocoa-92103_kubernetes
|
||||
user:
|
||||
client-certificate-data: REDACTED
|
||||
client-certificate-data: REDACTED
|
||||
client-key-data: REDACTED
|
||||
token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
|
||||
- name: lithe-cocoa-92103_kubernetes-basic-auth
|
||||
- name: lithe-cocoa-92103_kubernetes-basic-auth
|
||||
user:
|
||||
password: h5M0FtUUIflBSdI7
|
||||
username: admin
|
||||
|
||||
```
|
||||
|
||||
The next step is to define a context for the kubectl client to work in each namespace. The value of "cluster" and "user" fields are copied from the current context.
|
||||
The next step is to define a context for the kubectl client to work in each namespace. The value of "cluster" and "user" fields are copied from the current context.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl config set-context dev --namespace=development --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes
|
||||
$ kubectl config set-context prod --namespace=production --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
The above commands provided two request contexts you can alternate against depending on what namespace you
|
||||
wish to work against.
|
||||
wish to work against.
|
||||
|
||||
Let's switch to operate in the development namespace.
|
||||
|
||||
@@ -187,19 +187,19 @@ users:
|
||||
- context:
|
||||
cluster: lithe-cocoa-92103_kubernetes
|
||||
user: lithe-cocoa-92103_kubernetes
|
||||
name: lithe-cocoa-92103_kubernetes
|
||||
name: lithe-cocoa-92103_kubernetes
|
||||
- context:
|
||||
cluster: lithe-cocoa-92103_kubernetes
|
||||
namespace: production
|
||||
user: lithe-cocoa-92103_kubernetes
|
||||
name: prod
|
||||
current-context: dev
|
||||
current-context: dev
|
||||
kind: Config
|
||||
preferences: {}
|
||||
preferences: {}
|
||||
users:
|
||||
- name: lithe-cocoa-92103_kubernetes
|
||||
user:
|
||||
client-certificate-data: REDACTED
|
||||
client-certificate-data: REDACTED
|
||||
client-key-data: REDACTED
|
||||
token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
|
||||
- name: lithe-cocoa-92103_kubernetes-basic-auth
|
||||
@@ -208,29 +208,29 @@ $ kubectl get pods
|
||||
username: admin
|
||||
|
||||
```
|
||||
|
||||
|
||||
At this point, all requests we make to the Kubernetes cluster from the command line are scoped to the development namespace.
|
||||
|
||||
Let's create some content.
|
||||
|
||||
```shell
|
||||
|
||||
|
||||
$ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2
|
||||
|
||||
|
||||
```
|
||||
|
||||
We have just created a replication controller whose replica size is 2 that is running the pod called snowflake with a basic container that just serves the hostname.
|
||||
|
||||
|
||||
```shell
|
||||
|
||||
$ kubectl get rc
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
snowflake snowflake kubernetes/serve_hostname run=snowflake 2
|
||||
|
||||
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
snowflake-8w0qn 1/1 Running 0 22s
|
||||
snowflake-jrpzb 1/1 Running 0 22s
|
||||
snowflake-jrpzb 1/1 Running 0 22s
|
||||
|
||||
```
|
||||
|
||||
@@ -244,7 +244,7 @@ cattle-i9ojn 1/1 Running 0 12s
|
||||
|
||||
```
|
||||
|
||||
The production namespace should be empty.
|
||||
The production namespace should be empty.
|
||||
|
||||
```shell
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ services, and replication controllers used by the cluster.
|
||||
|
||||
Assuming you have a fresh cluster, you can introspect the available namespace's by doing the following:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS
|
||||
default <none>
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
### Step Two: Create new namespaces
|
||||
|
||||
@@ -55,7 +55,7 @@ Use the file [`namespace-dev.json`](namespace-dev.json) which describes a develo
|
||||
|
||||
<!-- BEGIN MUNGE: EXAMPLE namespace-dev.json -->
|
||||
|
||||
{% highlight json %}
|
||||
```json
|
||||
|
||||
{
|
||||
"kind": "Namespace",
|
||||
@@ -68,30 +68,30 @@ Use the file [`namespace-dev.json`](namespace-dev.json) which describes a develo
|
||||
}
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
[Download example](namespace-dev.json)
|
||||
<!-- END MUNGE: EXAMPLE namespace-dev.json -->
|
||||
|
||||
Create the development namespace using kubectl.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/namespaces/namespace-dev.json
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
And then lets create the production namespace using kubectl.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/namespaces/namespace-prod.json
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
To be sure things are right, let's list all of the namespaces in our cluster.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS STATUS
|
||||
@@ -99,7 +99,7 @@ default <none> Active
|
||||
development name=development Active
|
||||
production name=production Active
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
|
||||
### Step Three: Create pods in each namespace
|
||||
@@ -112,7 +112,7 @@ To demonstrate this, let's spin up a simple replication controller and pod in th
|
||||
|
||||
We first check what is the current context:
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
@@ -139,37 +139,37 @@ users:
|
||||
password: h5M0FtUUIflBSdI7
|
||||
username: admin
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
The next step is to define a context for the kubectl client to work in each namespace. The value of "cluster" and "user" fields are copied from the current context.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl config set-context dev --namespace=development --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes
|
||||
$ kubectl config set-context prod --namespace=production --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
The above commands provided two request contexts you can alternate against depending on what namespace you
|
||||
wish to work against.
|
||||
|
||||
Let's switch to operate in the development namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl config use-context dev
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
You can verify your current context by doing the following:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl config view
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
@@ -206,21 +206,21 @@ users:
|
||||
password: h5M0FtUUIflBSdI7
|
||||
username: admin
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
At this point, all requests we make to the Kubernetes cluster from the command line are scoped to the development namespace.
|
||||
|
||||
Let's create some content.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
We have just created a replication controller whose replica size is 2 that is running the pod called snowflake with a basic container that just serves the hostname.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get rc
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
@@ -231,21 +231,21 @@ NAME READY STATUS RESTARTS AGE
|
||||
snowflake-8w0qn 1/1 Running 0 22s
|
||||
snowflake-jrpzb 1/1 Running 0 22s
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
And this is great, developers are able to do what they want, and they do not have to worry about affecting content in the production namespace.
|
||||
|
||||
Let's switch to the production namespace and show how resources in one namespace are hidden from the other.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl config use-context prod
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
The production namespace should be empty.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get rc
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
@@ -253,11 +253,11 @@ CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Production likes to run cattle, so let's create some cattle pods.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl run cattle --image=kubernetes/serve_hostname --replicas=5
|
||||
|
||||
@@ -273,7 +273,7 @@ cattle-qj3yv 1/1 Running 0 12s
|
||||
cattle-yc7vn 1/1 Running 0 12s
|
||||
cattle-zz7ea 1/1 Running 0 12s
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
At this point, it should be clear that the resources users create in one namespace are hidden from the other namespace.
|
||||
|
||||
|
||||
@@ -107,11 +107,11 @@ on that subnet, and is passed to docker's `--bridge` flag.
|
||||
|
||||
We start Docker with:
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false"
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
This bridge is created by Kubelet (controlled by the `--configure-cbr0=true`
|
||||
flag) according to the `Node`'s `spec.podCIDR`.
|
||||
@@ -126,20 +126,20 @@ masquerade (aka SNAT - to make it seem as if packets came from the `Node`
|
||||
itself) traffic that is bound for IPs outside the GCE project network
|
||||
(10.0.0.0/8).
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
iptables -t nat -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Lastly we enable IP forwarding in the kernel (so the kernel will process
|
||||
packets for bridged containers):
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
sysctl net.ipv4.ip_forward=1
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
The result of all this is that all `Pods` can reach each other and can egress
|
||||
traffic to the internet.
|
||||
|
||||
@@ -56,7 +56,7 @@ node recently (currently 40 seconds).
|
||||
Node condition is represented as a json object. For example,
|
||||
the following conditions mean the node is in sane state:
|
||||
|
||||
{% highlight json %}
|
||||
```json
|
||||
|
||||
"conditions": [
|
||||
{
|
||||
@@ -65,7 +65,7 @@ the following conditions mean the node is in sane state:
|
||||
},
|
||||
]
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
If the Status of the Ready condition
|
||||
is Unknown or False for more than five minutes, then all of the Pods on the node are terminated by the Node Controller.
|
||||
@@ -90,7 +90,7 @@ Kubernetes creates a node, it is really just creating an object that represents
|
||||
After creation, Kubernetes will check whether the node is valid or not.
|
||||
For example, if you try to create a node from the following content:
|
||||
|
||||
{% highlight json %}
|
||||
```json
|
||||
|
||||
{
|
||||
"kind": "Node",
|
||||
@@ -103,7 +103,7 @@ For example, if you try to create a node from the following content:
|
||||
}
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Kubernetes will create a Node object internally (the representation), and
|
||||
validate the node by health checking based on the `metadata.name` field: we
|
||||
@@ -164,11 +164,11 @@ node, but will not affect any existing pods on the node. This is useful as a
|
||||
preparatory step before a node reboot, etc. For example, to mark a node
|
||||
unschedulable, run this command:
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
kubectl replace nodes 10.1.2.3 --patch='{"apiVersion": "v1", "unschedulable": true}'
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Note that pods which are created by a daemonSet controller bypass the Kubernetes scheduler,
|
||||
and do not respect the unschedulable attribute on a node. The assumption is that daemons belong on
|
||||
@@ -189,7 +189,7 @@ processes not in containers.
|
||||
If you want to explicitly reserve resources for non-Pod processes, you can create a placeholder
|
||||
pod. Use the following template:
|
||||
|
||||
{% highlight yaml %}
|
||||
```yaml
|
||||
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -204,7 +204,7 @@ spec:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Set the `cpu` and `memory` values to the amount of resources you want to reserve.
|
||||
Place the file in the manifest directory (`--config=DIR` flag of kubelet). Do this
|
||||
|
||||
@@ -86,7 +86,7 @@ supply of Pod IPs.
|
||||
|
||||
Kubectl supports creating, updating, and viewing quotas:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl namespace myspace
|
||||
$ cat <<EOF > quota.json
|
||||
@@ -123,7 +123,7 @@ replicationcontrollers 5 20
|
||||
resourcequotas 1 1
|
||||
services 3 5
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Quota and Cluster Capacity
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ This example will work in a custom namespace to demonstrate the concepts involve
|
||||
|
||||
Let's create a new namespace called quota-example:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/resourcequota/namespace.yaml
|
||||
namespace "quota-example" created
|
||||
@@ -22,7 +22,7 @@ NAME LABELS STATUS AGE
|
||||
default <none> Active 2m
|
||||
quota-example <none> Active 39s
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Step 2: Apply a quota to the namespace
|
||||
|
||||
@@ -37,12 +37,12 @@ checks the total resource *requests*, not resource *limits* of all containers/po
|
||||
|
||||
Let's create a simple quota in our namespace:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/resourcequota/quota.yaml --namespace=quota-example
|
||||
resourcequota "quota" created
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Once your quota is applied to a namespace, the system will restrict any creation of content
|
||||
in the namespace until the quota usage has been calculated. This should happen quickly.
|
||||
@@ -50,7 +50,7 @@ in the namespace until the quota usage has been calculated. This should happen
|
||||
You can describe your current quota usage to see what resources are being consumed in your
|
||||
namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl describe quota quota --namespace=quota-example
|
||||
Name: quota
|
||||
@@ -66,7 +66,7 @@ resourcequotas 1 1
|
||||
secrets 1 10
|
||||
services 0 5
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Step 3: Applying default resource requests and limits
|
||||
|
||||
@@ -77,25 +77,25 @@ cpu and memory by creating an nginx container.
|
||||
|
||||
To demonstrate, lets create a replication controller that runs nginx:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=quota-example
|
||||
replicationcontroller "nginx" created
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Now let's look at the pods that were created.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
What happened? I have no pods! Let's describe the replication controller to get a view of what is happening.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
kubectl describe rc nginx --namespace=quota-example
|
||||
Name: nginx
|
||||
@@ -110,14 +110,14 @@ Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Reason Message
|
||||
42s 11s 3 {replication-controller } FailedCreate Error creating: Pod "nginx-" is forbidden: Must make a non-zero request for memory since it is tracked by quota.
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
The Kubernetes API server is rejecting the replication controllers requests to create a pod because our pods
|
||||
do not specify any memory usage *request*.
|
||||
|
||||
So let's set some default values for the amount of cpu and memory a pod can consume:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/resourcequota/limits.yaml --namespace=quota-example
|
||||
limitrange "limits" created
|
||||
@@ -129,7 +129,7 @@ Type Resource Min Max Request Limit Limit/Request
|
||||
Container memory - - 256Mi 512Mi -
|
||||
Container cpu - - 100m 200m -
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Now any time a pod is created in this namespace, if it has not specified any resource request/limit, the default
|
||||
amount of cpu and memory per container will be applied, and the request will be used as part of admission control.
|
||||
@@ -137,17 +137,17 @@ amount of cpu and memory per container will be applied, and the request will be
|
||||
Now that we have applied default resource *request* for our namespace, our replication controller should be able to
|
||||
create its pods.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-fca65 1/1 Running 0 1m
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
And if we print out our quota usage in the namespace:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl describe quota quota --namespace=quota-example
|
||||
Name: quota
|
||||
@@ -163,7 +163,7 @@ resourcequotas 1 1
|
||||
secrets 1 10
|
||||
services 0 5
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
You can now see the pod that was created is consuming explicit amounts of resources (specified by resource *request*),
|
||||
and the usage is being tracked by the Kubernetes system properly.
|
||||
|
||||
@@ -13,7 +13,7 @@ This example will work in a custom namespace to demonstrate the concepts involve
|
||||
|
||||
Let's create a new namespace called quota-example:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/resourcequota/namespace.yaml
|
||||
namespace "quota-example" created
|
||||
@@ -22,7 +22,7 @@ NAME LABELS STATUS AGE
|
||||
default <none> Active 2m
|
||||
quota-example <none> Active 39s
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Step 2: Apply a quota to the namespace
|
||||
|
||||
@@ -37,12 +37,12 @@ checks the total resource *requests*, not resource *limits* of all containers/po
|
||||
|
||||
Let's create a simple quota in our namespace:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/resourcequota/quota.yaml --namespace=quota-example
|
||||
resourcequota "quota" created
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Once your quota is applied to a namespace, the system will restrict any creation of content
|
||||
in the namespace until the quota usage has been calculated. This should happen quickly.
|
||||
@@ -50,7 +50,7 @@ in the namespace until the quota usage has been calculated. This should happen
|
||||
You can describe your current quota usage to see what resources are being consumed in your
|
||||
namespace.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl describe quota quota --namespace=quota-example
|
||||
Name: quota
|
||||
@@ -66,7 +66,7 @@ resourcequotas 1 1
|
||||
secrets 1 10
|
||||
services 0 5
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Step 3: Applying default resource requests and limits
|
||||
|
||||
@@ -77,25 +77,25 @@ cpu and memory by creating an nginx container.
|
||||
|
||||
To demonstrate, lets create a replication controller that runs nginx:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=quota-example
|
||||
replicationcontroller "nginx" created
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Now let's look at the pods that were created.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
What happened? I have no pods! Let's describe the replication controller to get a view of what is happening.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
kubectl describe rc nginx --namespace=quota-example
|
||||
Name: nginx
|
||||
@@ -110,14 +110,14 @@ Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Reason Message
|
||||
42s 11s 3 {replication-controller } FailedCreate Error creating: Pod "nginx-" is forbidden: Must make a non-zero request for memory since it is tracked by quota.
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
The Kubernetes API server is rejecting the replication controllers requests to create a pod because our pods
|
||||
do not specify any memory usage *request*.
|
||||
|
||||
So let's set some default values for the amount of cpu and memory a pod can consume:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl create -f docs/admin/resourcequota/limits.yaml --namespace=quota-example
|
||||
limitrange "limits" created
|
||||
@@ -129,7 +129,7 @@ Type Resource Min Max Request Limit Limit/Request
|
||||
Container memory - - 256Mi 512Mi -
|
||||
Container cpu - - 100m 200m -
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Now any time a pod is created in this namespace, if it has not specified any resource request/limit, the default
|
||||
amount of cpu and memory per container will be applied, and the request will be used as part of admission control.
|
||||
@@ -137,17 +137,17 @@ amount of cpu and memory per container will be applied, and the request will be
|
||||
Now that we have applied default resource *request* for our namespace, our replication controller should be able to
|
||||
create its pods.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-fca65 1/1 Running 0 1m
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
And if we print out our quota usage in the namespace:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
|
||||
$ kubectl describe quota quota --namespace=quota-example
|
||||
Name: quota
|
||||
@@ -163,7 +163,7 @@ resourcequotas 1 1
|
||||
secrets 1 10
|
||||
services 0 5
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
You can now see the pod that was created is consuming explicit amounts of resources (specified by resource *request*),
|
||||
and the usage is being tracked by the Kubernetes system properly.
|
||||
|
||||
+14
-12
@@ -13,10 +13,10 @@ The **salt-minion** service runs on the kubernetes-master and each kubernetes-no
|
||||
|
||||
Each salt-minion service is configured to interact with the **salt-master** service hosted on the kubernetes-master via the **master.conf** file [(except on GCE)](#standalone-salt-configuration-on-gce).
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[root@kubernetes-master] $ cat /etc/salt/minion.d/master.conf
|
||||
master: kubernetes-master
|
||||
{% endhighlight %}
|
||||
master: kubernetes-master
|
||||
```
|
||||
|
||||
The salt-master is contacted by each salt-minion and depending upon the machine information presented, the salt-master will provision the machine as either a kubernetes-master or kubernetes-node with all the required capabilities needed to run Kubernetes.
|
||||
|
||||
@@ -34,11 +34,11 @@ All remaining sections that refer to master/minion setups should be ignored for
|
||||
|
||||
Security is not enabled on the salt-master, and the salt-master is configured to auto-accept incoming requests from minions. It is not recommended to use this security configuration in production environments without deeper study. (In some environments this isn't as bad as it might sound if the salt master port isn't externally accessible and you trust everyone on your network.)
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[root@kubernetes-master] $ cat /etc/salt/master.d/auto-accept.conf
|
||||
open_mode: True
|
||||
auto_accept: True
|
||||
{% endhighlight %}
|
||||
auto_accept: True
|
||||
```
|
||||
|
||||
## Salt minion configuration
|
||||
|
||||
@@ -46,14 +46,14 @@ Each minion in the salt cluster has an associated configuration that instructs t
|
||||
|
||||
An example file is presented below using the Vagrant based environment.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[root@kubernetes-master] $ cat /etc/salt/minion.d/grains.conf
|
||||
grains:
|
||||
etcd_servers: $MASTER_IP
|
||||
cloud_provider: vagrant
|
||||
roles:
|
||||
- kubernetes-master
|
||||
{% endhighlight %}
|
||||
- kubernetes-master
|
||||
```
|
||||
|
||||
Each hosting environment has a slightly different grains.conf file that is used to build conditional logic where required in the Salt files.
|
||||
|
||||
@@ -77,13 +77,15 @@ These keys may be leveraged by the Salt sls files to branch behavior.
|
||||
|
||||
In addition, a cluster may be running a Debian based operating system or Red Hat based operating system (Centos, Fedora, RHEL, etc.). As a result, it's important to sometimes distinguish behavior based on operating system using if branches like the following.
|
||||
|
||||
{% highlight jinja %}
|
||||
```liquid
|
||||
{% raw %}
|
||||
{% if grains['os_family'] == 'RedHat' %}
|
||||
// something specific to a RedHat environment (Centos, Fedora, RHEL) where you may use yum, systemd, etc.
|
||||
{% else %}
|
||||
// something specific to Debian environment (apt-get, initd)
|
||||
{% endif %}
|
||||
{% endhighlight %}
|
||||
{% endif %}
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ account. To create additional API tokens for a service account, create a secret
|
||||
of type `ServiceAccountToken` with an annotation referencing the service
|
||||
account, and the controller will update it with a generated token:
|
||||
|
||||
{% highlight json %}
|
||||
```json
|
||||
|
||||
secret.json:
|
||||
{
|
||||
@@ -76,22 +76,22 @@ secret.json:
|
||||
"type": "kubernetes.io/service-account-token"
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
kubectl create -f ./secret.json
|
||||
kubectl describe secret mysecretname
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
#### To delete/invalidate a service account token
|
||||
|
||||
{% highlight sh %}
|
||||
```shell
|
||||
|
||||
kubectl delete secret mysecretname
|
||||
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
### Service Account Controller
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@ For example, this is how to start a simple web server as a static pod:
|
||||
|
||||
1. Choose a node where we want to run the static pod. In this example, it's `my-minion1`.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[joe@host ~] $ ssh my-minion1
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
2. Choose a directory, say `/etc/kubelet.d` and place a web server pod definition there, e.g. `/etc/kubernetes.d/static-web.yaml`:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[root@my-minion1 ~] $ mkdir /etc/kubernetes.d/
|
||||
[root@my-minion1 ~] $ cat <<EOF >/etc/kubernetes.d/static-web.yaml
|
||||
apiVersion: v1
|
||||
@@ -44,7 +44,7 @@ For example, this is how to start a simple web server as a static pod:
|
||||
containerPort: 80
|
||||
protocol: tcp
|
||||
EOF
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
2. Configure your kubelet daemon on the node to use this directory by running it with `--config=/etc/kubelet.d/` argument. On Fedora Fedora 21 with Kubernetes 0.17 edit `/etc/kubernetes/kubelet` to include this line:
|
||||
|
||||
@@ -56,9 +56,9 @@ For example, this is how to start a simple web server as a static pod:
|
||||
|
||||
3. Restart kubelet. On Fedora 21, this is:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[root@my-minion1 ~] $ systemctl restart kubelet
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Pods created via HTTP
|
||||
|
||||
@@ -68,50 +68,50 @@ Kubelet periodically downloads a file specified by `--manifest-url=<URL>` argume
|
||||
|
||||
When kubelet starts, it automatically starts all pods defined in directory specified in `--config=` or `--manifest-url=` arguments, i.e. our static-web. (It may take some time to pull nginx image, be patient'|):
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[joe@my-minion1 ~] $ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
|
||||
f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-minion1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
If we look at our Kubernetes API server (running on host `my-master`), we see that a new mirror-pod was created there too:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[joe@host ~] $ ssh my-master
|
||||
[joe@my-master ~] $ kubectl get pods
|
||||
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED MESSAGE
|
||||
static-web-my-minion1 172.17.0.3 my-minion1/192.168.100.71 role=myrole Running 11 minutes
|
||||
web nginx Running 11 minutes
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Labels from the static pod are propagated into the mirror-pod and can be used as usual for filtering.
|
||||
|
||||
Notice we cannot delete the pod with the API server (e.g. via [`kubectl`](../user-guide/kubectl/kubectl) command), kubelet simply won't remove it.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[joe@my-master ~] $ kubectl delete pod static-web-my-minion1
|
||||
pods/static-web-my-minion1
|
||||
[joe@my-master ~] $ kubectl get pods
|
||||
POD IP CONTAINER(S) IMAGE(S) HOST ...
|
||||
static-web-my-minion1 172.17.0.3 my-minion1/192.168.100.71 ...
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
Back to our `my-minion1` host, we can try to stop the container manually and see, that kubelet automatically restarts it in a while:
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[joe@host ~] $ ssh my-minion1
|
||||
[joe@my-minion1 ~] $ docker stop f6d05272b57e
|
||||
[joe@my-minion1 ~] $ sleep 20
|
||||
[joe@my-minion1 ~] $ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED ...
|
||||
5b920cbaf8b1 nginx:latest "nginx -g 'daemon of 2 seconds ago ...
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
## Dynamic addition and removal of static pods
|
||||
|
||||
Running kubelet periodically scans the configured directory (`/etc/kubelet.d` in our example) for changes and adds/removes pods as files appear/disappear in this directory.
|
||||
|
||||
{% highlight console %}
|
||||
```shell
|
||||
[joe@my-minion1 ~] $ mv /etc/kubernetes.d/static-web.yaml /tmp
|
||||
[joe@my-minion1 ~] $ sleep 20
|
||||
[joe@my-minion1 ~] $ docker ps
|
||||
@@ -121,7 +121,7 @@ Running kubelet periodically scans the configured directory (`/etc/kubelet.d` in
|
||||
[joe@my-minion1 ~] $ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED ...
|
||||
e7a62e3427f1 nginx:latest "nginx -g 'daemon of 27 seconds ago
|
||||
{% endhighlight %}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user