Merge pull request #588 from kubernetes/master
Rebasing 1.3 with all the churn in the 1.2 docs.pull/611/head
commit
94aaca027b
21
404.md
21
404.md
|
|
@ -6,7 +6,7 @@ permalink: /404.html
|
|||
<script language="JavaScript">
|
||||
$( document ).ready(function() {
|
||||
var oldURLs=["/README.md","/README.html",".html",".md","/v1.1/","/v1.0/"];
|
||||
var fwdDirs=["examples/","cluster/"];
|
||||
var fwdDirs=["examples/","cluster/","docs/devel","docs/design"];
|
||||
var doRedirect = false;
|
||||
var notHere = false;
|
||||
var forwardingURL=window.location.href;
|
||||
|
|
@ -15,16 +15,31 @@ $( document ).ready(function() {
|
|||
notHere = true;
|
||||
window.location.replace("http://kubernetes.io/kubernetes/third_party/swagger-ui/");
|
||||
}
|
||||
if (forwardingURL.indexOf("docs/design") > -1)
|
||||
if (forwardingURL.indexOf("resource-quota") > -1)
|
||||
{
|
||||
notHere = true;
|
||||
window.location.replace("https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/design");
|
||||
window.location.replace("http://kubernetes.io/docs/admin/resourcequota/");
|
||||
}
|
||||
if (forwardingURL.indexOf("horizontal-pod-autoscaler") > -1)
|
||||
{
|
||||
notHere = true;
|
||||
window.location.replace("http://kubernetes.io/docs/user-guide/horizontal-pod-autoscaling/");
|
||||
}
|
||||
if (forwardingURL.indexOf("docs/roadmap") > -1)
|
||||
{
|
||||
notHere = true;
|
||||
window.location.replace("https://github.com/kubernetes/kubernetes/milestones/");
|
||||
}
|
||||
if (forwardingURL.indexOf("api-ref/") > -1)
|
||||
{
|
||||
notHere = true;
|
||||
window.location.replace("http://kubernetes.io/docs/api/");
|
||||
}
|
||||
if (forwardingURL.indexOf("docs/user-guide/overview") > -1)
|
||||
{
|
||||
notHere = true;
|
||||
window.location.replace("http://kubernetes.io/docs/whatisk8s/");
|
||||
}
|
||||
for (i=0;i<fwdDirs.length;i++) {
|
||||
if (forwardingURL.indexOf(fwdDirs[i]) > -1)
|
||||
{
|
||||
|
|
|
|||
11
README.md
11
README.md
|
|
@ -133,6 +133,17 @@ The current version of the website is served out of the `master` branch.
|
|||
|
||||
All versions of the site that relate to past and future versions will be named after their Kubernetes release number. For example, [the old branch for the 1.1 docs is called `release-1.1`](https://github.com/kubernetes/kubernetes.github.io/tree/release-1.1).
|
||||
|
||||
Changes in the "docsv2" branch (where we are testing a revamp of the docs) are automatically staged here:
|
||||
http://k8sdocs.github.io/docs/tutorials/
|
||||
|
||||
Changes in the "release-1.1" branch (for k8s v1.1 docs) are automatically staged here:
|
||||
http://kubernetes-v1-1.github.io/
|
||||
|
||||
Changes in the "release-1.3" branch (for k8s v1.3 docs) are automatically staged here:
|
||||
http://kubernetes-v1-3.github.io/
|
||||
|
||||
Editing of these branches will kick off a build using Travis CI that auto-updates these URLs; you can monitor the build progress at [https://travis-ci.org/kubernetes/kubernetes.github.io](https://travis-ci.org/kubernetes/kubernetes.github.io).
|
||||
|
||||
## Thank you!
|
||||
|
||||
Kubernetes thrives on community participation and we really appreciate your
|
||||
|
|
|
|||
300
_data/guides.yml
300
_data/guides.yml
|
|
@ -8,22 +8,121 @@ toc:
|
|||
section:
|
||||
- title: What is Kubernetes?
|
||||
path: /docs/whatisk8s/
|
||||
- title: Downloading Kubernetes
|
||||
- title: Downloading or Building Kubernetes
|
||||
path: /docs/getting-started-guides/binary_release/
|
||||
- title: Hello World Walkthrough
|
||||
path: /docs/hellonode/
|
||||
- title: Kubernetes 101
|
||||
path: /docs/user-guide/walkthrough/
|
||||
- title: Kubernetes 201
|
||||
path: /docs/user-guide/walkthrough/k8s201/
|
||||
- title: Online Training Course
|
||||
path: https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615
|
||||
|
||||
- title: Accessing the Cluster
|
||||
section:
|
||||
- title: Installing and Setting up kubectl
|
||||
path: /docs/user-guide/prereqs/
|
||||
- title: Accessing Clusters
|
||||
path: /docs/user-guide/accessing-the-cluster/
|
||||
- title: Sharing Cluster Access with kubeconfig
|
||||
path: /docs/user-guide/sharing-clusters/
|
||||
- title: Authenticating Across Clusters with kubeconfig
|
||||
path: /docs/user-guide/kubeconfig-file/
|
||||
|
||||
- title: User Guide
|
||||
path: /docs/user-guide/
|
||||
|
||||
- title: Admin Guide
|
||||
path: /docs/admin/
|
||||
- title: Web UI (Dashboard)
|
||||
path: /docs/user-guide/ui/
|
||||
|
||||
- title: Running Kubernetes
|
||||
- title: Workload Deployment and Management
|
||||
section:
|
||||
- title: Launching, Exposing, and Killing Applications
|
||||
path: /docs/user-guide/quick-start/
|
||||
- title: Deploying Applications
|
||||
path: /docs/user-guide/deploying-applications/
|
||||
- title: Managing Resources
|
||||
path: /docs/user-guide/managing-deployments/
|
||||
- title: Replication Controller Operations
|
||||
path: /docs/user-guide/replication-controller/operations/
|
||||
- title: Resizing a Replication Controller
|
||||
path: /docs/user-guide/resizing-a-replication-controller/
|
||||
- title: Rolling Updates
|
||||
path: /docs/user-guide/rolling-updates/
|
||||
- title: Rolling Update Demo
|
||||
path: /docs/user-guide/update-demo/
|
||||
- title: Secrets Walkthrough
|
||||
path: /docs/user-guide/secrets/walkthrough/
|
||||
- title: Using ConfigMap
|
||||
path: /docs/user-guide/configmap/
|
||||
- title: Horizontal Pod Autoscaling
|
||||
path: /docs/user-guide/horizontal-pod-autoscaling/walkthrough/
|
||||
- title: Best Practices for Configuration
|
||||
path: /docs/user-guide/config-best-practices/
|
||||
- title: Using kubectl to Manage Resources
|
||||
path: /docs/user-guide/working-with-resources/
|
||||
|
||||
- title: Service Discovery and Load Balancing
|
||||
section:
|
||||
- title: Connecting Applications with Services
|
||||
path: /docs/user-guide/connecting-applications/
|
||||
- title: Service Operations
|
||||
path: /docs/user-guide/services/operations/
|
||||
- title: Creating an External Load Balancer
|
||||
path: /docs/user-guide/load-balancer/
|
||||
- title: Configuring Your Cloud Provider's Firewalls
|
||||
path: /docs/user-guide/services-firewalls/
|
||||
|
||||
- title: Containers and Pods
|
||||
section:
|
||||
- title: Running Your First Containers
|
||||
path: /docs/user-guide/simple-nginx/
|
||||
- title: Creating Single-Container Pods
|
||||
path: /docs/user-guide/pods/single-container/
|
||||
- title: Creating Multi-Container Pods
|
||||
path: /docs/user-guide/pods/multi-container/
|
||||
- title: Configuring Containers
|
||||
path: /docs/user-guide/configuring-containers/
|
||||
- title: Working with Containers in Production
|
||||
path: /docs/user-guide/production-pods/
|
||||
- title: Commands and Capabilities
|
||||
path: /docs/user-guide/containers/
|
||||
- title: Using Environment Variables
|
||||
path: /docs/user-guide/environment-guide/
|
||||
- title: Managing Compute Resources
|
||||
path: /docs/user-guide/compute-resources/
|
||||
- title: The Lifecycle of a Pod
|
||||
path: /docs/user-guide/pod-states/
|
||||
- title: Checking Pod Health
|
||||
path: /docs/user-guide/liveness/
|
||||
- title: Container Lifecycle Hooks
|
||||
path: /docs/user-guide/container-environment/
|
||||
- title: Assigning Pods to Nodes
|
||||
path: /docs/user-guide/node-selection/
|
||||
- title: Using the Downward API to Convey Pod Properties
|
||||
path: /docs/user-guide/downward-api/
|
||||
- title: Downward API Volumes
|
||||
path: /docs/user-guide/downward-api/volume
|
||||
- title: Persistent Volumes Walkthrough
|
||||
path: /docs/user-guide/persistent-volumes/walkthrough/
|
||||
|
||||
- title: Monitoring, Logging, and Debugging Containers
|
||||
section:
|
||||
- title: Resource Usage Monitoring
|
||||
path: /docs/user-guide/monitoring/
|
||||
- title: Logging
|
||||
path: /docs/getting-started-guides/logging/
|
||||
- title: Logging with Elasticsearch and Kibana
|
||||
path: /docs/getting-started-guides/logging-elasticsearch/
|
||||
- title: Elasticsearch/Kibana Logging Demo
|
||||
path: /docs/user-guide/logging-demo
|
||||
- title: Running Commands in a Container with kubectl exec
|
||||
path: /docs/user-guide/getting-into-containers/
|
||||
- title: Connect with Proxies
|
||||
path: /docs/user-guide/connecting-to-applications-proxy/
|
||||
- title: Connect with Port Forwarding
|
||||
path: /docs/user-guide/connecting-to-applications-port-forward/
|
||||
- title: Using Explorer to Examine the Runtime Environment
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/explorer
|
||||
|
||||
- title: Creating a Cluster
|
||||
section:
|
||||
- title: Picking the Right Solution
|
||||
path: /docs/getting-started-guides/
|
||||
|
|
@ -31,10 +130,10 @@ toc:
|
|||
section:
|
||||
- title: Running Kubernetes Locally via Docker
|
||||
path: /docs/getting-started-guides/docker/
|
||||
- title: Running Kubernetes Locally via Vagrant
|
||||
path: /docs/getting-started-guides/vagrant/
|
||||
- title: Running Kubernetes Locally with No VM
|
||||
path: /docs/getting-started-guides/locally/
|
||||
- title: Running Kubernetes Locally with Vagrant
|
||||
path: /docs/getting-started-guides/vagrant/
|
||||
- title: Running Kubernetes on Turn-key Cloud Solutions
|
||||
section:
|
||||
- title: Running Kubernetes on Google Container Engine
|
||||
|
|
@ -45,21 +144,31 @@ toc:
|
|||
path: /docs/getting-started-guides/aws/
|
||||
- title: Running Kubernetes on Azure
|
||||
path: /docs/getting-started-guides/coreos/azure/
|
||||
- title: Running Kubernetes on CenturyLink Cloud
|
||||
path: /docs/getting-started-guides/clc/
|
||||
- title: Portable Multi-Node Clusters
|
||||
section:
|
||||
- title: Installing a Kubernetes Master Node via Docker
|
||||
path: /docs/getting-started-guides/docker-multinode/master/
|
||||
- title: Adding a Kubernetes Worker Node via Docker
|
||||
path: /docs/getting-started-guides/docker-multinode/worker/
|
||||
- title: Deploying DNS
|
||||
path: /docs/getting-started-guides/docker-multinode/deployDNS/
|
||||
- title: Running Kubernetes on Custom Solutions
|
||||
section:
|
||||
- title: Getting Started From Scratch
|
||||
- title: Creating a Custom Cluster from Scratch
|
||||
path: /docs/getting-started-guides/scratch/
|
||||
- title: Custom Cloud Solutions
|
||||
section:
|
||||
- title: AWS or GCE on CoreOS
|
||||
- title: CoreOS on AWS or GCE
|
||||
path: /docs/getting-started-guides/coreos/
|
||||
- title: AWS or Joyent on Ubuntu
|
||||
- title: Ubuntu on AWS or Joyent
|
||||
path: /docs/getting-started-guides/juju/
|
||||
- title: Rackspace on CoreOS
|
||||
- title: CoreOS on Rackspace
|
||||
path: /docs/getting-started-guides/rackspace/
|
||||
- title: On-Premise VMs
|
||||
section:
|
||||
- title: Vagrant or VMware
|
||||
- title: CoreOS on Vagrant
|
||||
path: /docs/getting-started-guides/coreos/
|
||||
- title: Cloudstack
|
||||
path: /docs/getting-started-guides/cloudstack/
|
||||
|
|
@ -69,13 +178,13 @@ toc:
|
|||
path: /docs/getting-started-guides/juju/
|
||||
- title: DCOS
|
||||
path: /docs/getting-started-guides/dcos/
|
||||
- title: libvirt on CoreOS
|
||||
- title: CoreOS on libvirt
|
||||
path: /docs/getting-started-guides/libvirt-coreos/
|
||||
- title: oVirt
|
||||
path: /docs/getting-started-guides/ovirt/
|
||||
- title: libvirt or KVM
|
||||
path: /docs/getting-started-guides/fedora/flannel_multi_node_cluster/
|
||||
- title: Multinode Cluster on CoreOS
|
||||
- title: OpenStack Heat
|
||||
path: /docs/getting-started-guides/openstack-heat/
|
||||
- title: CoreOS on Multinode Cluster
|
||||
path: /docs/getting-started-guides/coreos/coreos_multinode_cluster/
|
||||
- title: Fedora With Calico Networking
|
||||
path: /docs/getting-started-guides/fedora/fedora-calico/
|
||||
|
|
@ -99,161 +208,60 @@ toc:
|
|||
path: /docs/getting-started-guides/fedora/fedora_manual_config/
|
||||
- title: Fedora (Multi Node)
|
||||
path: /docs/getting-started-guides/fedora/flannel_multi_node_cluster/
|
||||
- title: Centos
|
||||
- title: CentOS
|
||||
path: /docs/getting-started-guides/centos/centos_manual_config/
|
||||
- title: Ubuntu
|
||||
path: /docs/getting-started-guides/ubuntu/
|
||||
- title: Docker (Multi-Node)
|
||||
path: /docs/getting-started-guides/docker-multinode/
|
||||
- title: CoreOS with Calico
|
||||
path: /docs/getting-started-guides/coreos/bare_metal_calico/
|
||||
- title: Ubuntu Nodes with Calico
|
||||
path: /docs/getting-started-guides/ubuntu-calico/
|
||||
- title: Building Large Clusters
|
||||
path: /docs/admin/cluster-large/
|
||||
- title: Running in Multiple Zones
|
||||
path: /docs/admin/multiple-zones/
|
||||
- title: Building High-Availability Clusters
|
||||
path: /docs/admin/high-availability/
|
||||
|
||||
- title: Administering Clusters
|
||||
section:
|
||||
- title: Admin Guide
|
||||
path: /docs/admin/
|
||||
- title: Cluster Management Guide
|
||||
path: /docs/admin/cluster-management/
|
||||
- title: Cluster Management Tools
|
||||
- title: Sharing a Cluster with Namespaces
|
||||
path: /docs/admin/namespaces/
|
||||
- title: Namespaces Walkthrough
|
||||
path: /docs/admin/namespaces/walkthrough/
|
||||
- title: Setting Pod CPU and Memory Limits
|
||||
path: /docs/admin/limitrange/
|
||||
- title: Understanding Resource Quotas
|
||||
path: /docs/admin/resourcequota/
|
||||
- title: Applying Resource Quotas and Limits
|
||||
path: /docs/admin/resourcequota/walkthrough/
|
||||
- title: Kubernetes Components
|
||||
path: /docs/admin/cluster-components/
|
||||
- title: Configuring Kubernetes Use of etcd
|
||||
path: /docs/admin/etcd/
|
||||
- title: Using Multiple Clusters
|
||||
path: /docs/admin/multi-cluster/
|
||||
- title: Using Large Clusters
|
||||
path: /docs/admin/cluster-large/
|
||||
- title: Building High-Availability Clusters
|
||||
path: /docs/admin/high-availability/
|
||||
- title: Accessing Clusters
|
||||
path: /docs/user-guide/accessing-the-cluster/
|
||||
- title: Sharing a Cluster
|
||||
path: /docs/admin/namespaces/
|
||||
- title: Changing Cluster Size
|
||||
path: https://github.com/kubernetes/kubernetes/wiki/User-FAQ#how-do-i-change-the-size-of-my-cluster/
|
||||
- title: Creating a Custom Cluster from Scratch
|
||||
path: /docs/getting-started-guides/scratch/
|
||||
- title: Authenticating Across Clusters with kubeconfig
|
||||
path: /docs/user-guide/kubeconfig-file/
|
||||
- title: Replication Controller Operations
|
||||
path: /docs/user-guide/replication-controller/operations/
|
||||
- title: Resizing a Replication Controller
|
||||
path: /docs/user-guide/resizing-a-replication-controller/
|
||||
- title: Service Operations
|
||||
path: /docs/user-guide/services/operations/
|
||||
|
||||
- title: Using Nodes, Pods, and Containers
|
||||
section:
|
||||
- title: The Container Environment
|
||||
path: /docs/user-guide/container-environment/
|
||||
- title: Running Your First Containers
|
||||
path: /docs/user-guide/simple-nginx/
|
||||
- title: Working with Containers
|
||||
path: /docs/user-guide/production-pods/
|
||||
- title: Overriding Default Container Behavior
|
||||
path: /docs/user-guide/containers/
|
||||
- title: Running Commands in a Container with kubectl exec
|
||||
path: /docs/user-guide/getting-into-containers/
|
||||
- title: The Lifecycle of a Pod
|
||||
path: /docs/user-guide/pod-states/
|
||||
- title: Creating Single-Container Pods
|
||||
path: /docs/user-guide/pods/single-container/
|
||||
- title: Creating Multi-Container Pods
|
||||
path: /docs/user-guide/pods/multi-container/
|
||||
- title: Pod Templates
|
||||
path: /docs/user-guide/pod-templates/
|
||||
- title: Assigning Pods to Nodes
|
||||
path: /docs/user-guide/node-selection/
|
||||
- title: Creating Pods with the Downward API
|
||||
path: /docs/user-guide/downward-api/
|
||||
- title: Updating Live Pods
|
||||
path: /docs/user-guide/update-demo/
|
||||
- title: Static Pods
|
||||
path: /docs/admin/static-pods/
|
||||
- title: Installing a Kubernetes Master Node via Docker
|
||||
path: /docs/getting-started-guides/docker-multinode/master/
|
||||
- title: Adding a Kubernetes Worker Node via Docker
|
||||
path: /docs/getting-started-guides/docker-multinode/worker/
|
||||
|
||||
- title: Networking
|
||||
section:
|
||||
- title: Configuring Multiple Schedulers
|
||||
path: /docs/admin/multiple-schedulers/
|
||||
- title: Networking in Kubernetes
|
||||
path: /docs/admin/networking/
|
||||
- title: Creating an External Load Balancer
|
||||
path: /docs/user-guide/load-balancer/
|
||||
- title: Using DNS Pods and Services
|
||||
path: /docs/admin/dns/
|
||||
- title: Setting Up and Configuring DNS
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/cluster-dns
|
||||
- title: Deploying DNS
|
||||
path: /docs/getting-started-guides/docker-multinode/deployDNS/
|
||||
- title: Connecting Applications
|
||||
path: /docs/user-guide/connecting-applications/
|
||||
- title: Creating Servers with External IPs
|
||||
path: https://github.com/kubernetes/kubernetes/blob/release-1.2/examples/simple-nginx.md
|
||||
- title: Connect with Proxies
|
||||
path: /docs/user-guide/connecting-to-applications-proxy/
|
||||
- title: Connect with Port Forwarding
|
||||
path: /docs/user-guide/connecting-to-applications-port-forward/
|
||||
- title: Configuring Your Cloud Provider's Firewalls
|
||||
path: /docs/user-guide/services-firewalls/
|
||||
- title: Master <-> Node Communication
|
||||
path: /docs/admin/master-node-communication/
|
||||
- title: Network Plugins
|
||||
path: /docs/admin/network-plugins/
|
||||
|
||||
- title: Configuring Kubernetes
|
||||
section:
|
||||
- title: Using Configuration Files
|
||||
path: /docs/user-guide/simple-yaml/
|
||||
- title: Best Practices for Configuration
|
||||
path: /docs/user-guide/config-best-practices/
|
||||
- title: Configuring Containers
|
||||
path: /docs/user-guide/configuring-containers/
|
||||
- title: Using ConfigMap
|
||||
path: /docs/user-guide/configmap/
|
||||
- title: Sharing Cluster Access with kubeconfig
|
||||
path: /docs/user-guide/sharing-clusters/
|
||||
- title: Using Environment Variables
|
||||
path: /docs/user-guide/environment-guide/
|
||||
- title: Managing Compute Resources
|
||||
path: /docs/user-guide/compute-resources/
|
||||
- title: Using kubectl to Manage Resources
|
||||
path: /docs/user-guide/working-with-resources/
|
||||
- title: Applying Resource Quotas and Limits
|
||||
path: /docs/admin/resourcequota/
|
||||
- title: Setting Pod CPU and Memory Limits
|
||||
path: /docs/admin/limitrange/
|
||||
- title: Static Pods
|
||||
path: /docs/admin/static-pods/
|
||||
- title: Configuring Garbage Collection
|
||||
path: /docs/admin/garbage-collection/
|
||||
- title: Configuring Kubernetes with Salt
|
||||
path: /docs/admin/salt/
|
||||
- title: Configuring Kubernetes Use of etcd
|
||||
path: /docs/admin/etcd/
|
||||
|
||||
- title: Application Management and Deployment
|
||||
section:
|
||||
- title: "Managing Applications: Prerequisites"
|
||||
path: /docs/user-guide/prereqs/
|
||||
- title: Managing Deployments
|
||||
path: /docs/user-guide/managing-deployments/
|
||||
- title: Deploying Applications
|
||||
path: /docs/user-guide/deploying-applications/
|
||||
- title: Updating Applications with Rolling Updates
|
||||
path: /docs/user-guide/rolling-updates/
|
||||
- title: Launching, Exposing, and Killing Applications
|
||||
path: /docs/user-guide/quick-start/
|
||||
|
||||
- title: Testing and Monitoring
|
||||
section:
|
||||
- title: Testing a Kubernetes Cluster
|
||||
path: /docs/getting-started-guides/docker-multinode/testing/
|
||||
- title: Simulating Large Test Loads
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/k8petstore
|
||||
- title: Checking Pod Health
|
||||
path: /docs/user-guide/liveness/
|
||||
- title: Using Explorer to Examine the Runtime Environment
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/explorer
|
||||
- title: Resource Usage Monitoring
|
||||
path: /docs/user-guide/monitoring/
|
||||
- title: Logging
|
||||
path: /docs/getting-started-guides/logging/
|
||||
- title: Logging with Elasticsearch and Kibana
|
||||
path: /docs/getting-started-guides/logging-elasticsearch/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ toc:
|
|||
path: /docs/api-reference/v1/operations/
|
||||
- title: Kubernetes API Definitions
|
||||
path: /docs/api-reference/v1/definitions/
|
||||
- title: Kubernetes API Swagger Spec
|
||||
path: /kubernetes/third_party/swagger-ui/
|
||||
|
||||
- title: Extensions API
|
||||
section:
|
||||
|
|
@ -52,6 +54,8 @@ toc:
|
|||
path: /docs/user-guide/kubectl-overview/
|
||||
- title: kubectl for Docker Users
|
||||
path: /docs/user-guide/docker-cli-to-kubectl/
|
||||
- title: kubectl Usage Conventions
|
||||
path: /docs/user-guide/kubectl-conventions/
|
||||
- title: JSONpath Support
|
||||
path: /docs/user-guide/jsonpath/
|
||||
- title: kubectl Cheat Sheet
|
||||
|
|
@ -80,7 +84,7 @@ toc:
|
|||
path: /docs/user-guide/kubectl/kubectl_config_set-cluster/
|
||||
- title: kubectl config set-context
|
||||
path: /docs/user-guide/kubectl/kubectl_config_set-context/
|
||||
- title: kubectl set-credentials
|
||||
- title: kubectl config set-credentials
|
||||
path: /docs/user-guide/kubectl/kubectl_config_set-credentials/
|
||||
- title: kubectl config set
|
||||
path: /docs/user-guide/kubectl/kubectl_config_set/
|
||||
|
|
@ -163,20 +167,18 @@ toc:
|
|||
- title: kubectl stop
|
||||
path: /docs/user-guide/kubectl/kubectl_stop/
|
||||
|
||||
- title: kube-apiserver CLI
|
||||
path: /docs/admin/kube-apiserver/
|
||||
|
||||
- title: kube-proxy CLI
|
||||
path: /docs/admin/kube-proxy/
|
||||
|
||||
- title: kube-scheduler CLI
|
||||
path: /docs/admin/kube-scheduler/
|
||||
|
||||
- title: kubelet CLI
|
||||
path: /docs/admin/kubelet/
|
||||
|
||||
- title: kube-controller-manager CLI
|
||||
path: /docs/admin/kube-controller-manager/
|
||||
- title: Kubernetes Components
|
||||
section:
|
||||
- title: kube-apiserver
|
||||
path: /docs/admin/kube-apiserver/
|
||||
- title: kube-proxy
|
||||
path: /docs/admin/kube-proxy/
|
||||
- title: kube-scheduler
|
||||
path: /docs/admin/kube-scheduler/
|
||||
- title: kubelet
|
||||
path: /docs/admin/kubelet/
|
||||
- title: kube-controller-manager
|
||||
path: /docs/admin/kube-controller-manager/
|
||||
|
||||
- title: Glossary
|
||||
section:
|
||||
|
|
@ -215,11 +217,13 @@ toc:
|
|||
- title: Ingress Resources
|
||||
path: /docs/user-guide/ingress/
|
||||
- title: Horizontal Pod Autoscaling
|
||||
path: /docs/user-guide/horizontal-pod-autoscaler/
|
||||
path: /docs/user-guide/horizontal-pod-autoscaling/
|
||||
- title: Jobs
|
||||
path: /docs/user-guide/jobs/
|
||||
- title: Resource Quotas
|
||||
path: /docs/admin/resource-quota/
|
||||
- title: Replica Sets
|
||||
path: /docs/user-guide/replicasets/
|
||||
|
||||
- title: Kubernetes Design Docs
|
||||
section:
|
||||
|
|
|
|||
|
|
@ -4,59 +4,76 @@ toc:
|
|||
- title: Samples
|
||||
path: /docs/samples/
|
||||
|
||||
- title: Clustered Application Samples
|
||||
- title: Storage / Database / KV
|
||||
section:
|
||||
- title: Apache Cassandra Database
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/cassandra
|
||||
- title: Apache Spark
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/spark
|
||||
- title: Apache Storm
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/storm
|
||||
- title: Distributed Task Queue
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/celery-rabbitmq
|
||||
- title: Ceph
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/rbd/
|
||||
- title: CephFS
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/cephfs/
|
||||
- title: GlusterFS
|
||||
path: /https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/glusterfs/
|
||||
- title: Hazelcast
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/hazelcast
|
||||
- title: Meteor Applications
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/meteor/
|
||||
- title: iSCSI
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/iscsi/
|
||||
- title: MySQL Galera
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/mysql-galera
|
||||
- title: NFS
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/nfs/
|
||||
- title: Redis
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/redis/
|
||||
- title: RethinkDB
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/rethinkdb/
|
||||
- title: Elasticsearch/Kibana Logging Demonstration
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/logging-demo/
|
||||
- title: Vitess
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/vitess/
|
||||
|
||||
- title: Big Data
|
||||
section:
|
||||
- title: Apache Spark
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/spark
|
||||
- title: Apache Storm
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/storm
|
||||
|
||||
- title: Messaging / Queueing
|
||||
section:
|
||||
- title: Celery + RabbitMQ
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/celery-rabbitmq
|
||||
- title: Hazelcast
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/hazelcast
|
||||
|
||||
- title: Miscellaneous
|
||||
section:
|
||||
- title: Meteor Applications
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/meteor/
|
||||
- title: Elasticsearch
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/elasticsearch/
|
||||
- title: OpenShift Origin
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/openshift-origin/
|
||||
- title: Ceph
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/rbd/
|
||||
- title: MEAN stack on Google Cloud Platform
|
||||
path: /docs/getting-started-guides/meanstack/
|
||||
- title: Selenium
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/selenium/
|
||||
|
||||
- title: Persistent Volume Samples
|
||||
- title: Monitoring and Logging
|
||||
section:
|
||||
- title: WordPress on a Kubernetes Persistent Volume
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/mysql-wordpress-pd/
|
||||
- title: GlusterFS
|
||||
path: /https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/glusterfs/
|
||||
- title: iSCSI
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/iscsi/
|
||||
- title: NFS
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/nfs/
|
||||
- title: Downward API Volumes
|
||||
path: /docs/user-guide/downward-api/volume
|
||||
- title: Elasticsearch/Kibana Logging Demonstration
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/logging-demo/
|
||||
- title: NewRelic
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/newrelic
|
||||
|
||||
- title: Multi-tier Application Samples
|
||||
- title: Multi-tier Applications
|
||||
section:
|
||||
- title: Guestbook - Go Server
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/guestbook-go/
|
||||
- title: GuestBook - PHP Server
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/guestbook/
|
||||
- title: MySQL - Phabricator Server
|
||||
- title: MEAN stack on Google Cloud Platform
|
||||
path: /docs/getting-started-guides/meanstack/
|
||||
- title: MySQL + Wordpress
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/mysql-wordpress-pd/
|
||||
- title: MySQL + Phabricator Server
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/phabricator/
|
||||
|
||||
- title: Elasticsearch/Kibana Logging Demo
|
||||
path: https://github.com/kubernetes/kubernetes.github.io/tree/master/docs/user-guide/logging-demo
|
||||
|
||||
- title: ConfigMap Example
|
||||
path: https://github.com/kubernetes/kubernetes.github.io/tree/master/docs/user-guide/configmap
|
||||
- title: Nodejs + Mongo
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/nodesjs-mongodb
|
||||
- title: Petstore
|
||||
path: https://github.com/kubernetes/kubernetes/tree/release-1.2/examples/k8spetstore/
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ toc:
|
|||
section:
|
||||
- title: Debugging Pods and Replication Controllers
|
||||
path: /docs/user-guide/debugging-pods-and-replication-controllers/
|
||||
- title: Web Interface
|
||||
path: /docs/user-guide/ui/
|
||||
- title: Application Introspection and Debugging
|
||||
path: /docs/user-guide/introspection-and-debugging/
|
||||
- title: Retrieving Logs
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
{% capture samplecode %}{% include_relative {{include.file}} %}{% endcapture %}
|
||||
{% if include.k8slink %}{% capture ghlink %}https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}{{include.k8slink}}{% endcapture %}{% endif %}
|
||||
{% if include.ghlink %}{% capture ghlink %}https://github.com/kubernetes/kubernetes.github.io/blob/master{{include.ghlink}}{% endcapture %}{% endif %}
|
||||
{% if include.k8slink %}{% capture ghlink %}https://raw.githubusercontent.com/kubernetes/kubernetes/blob/{{page.githubbranch}}{{include.k8slink}}{% endcapture %}{% endif %}
|
||||
{% if include.ghlink %}{% capture ghlink %}https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/{{page.docsbranch}}{{include.ghlink}}{% endcapture %}{% endif %}
|
||||
{% capture mysample %}
|
||||
```{{include.language}}
|
||||
{{ samplecode | raw | strip }}
|
||||
```
|
||||
{: id="{{include.file | handleize}}"}
|
||||
{% endcapture %}
|
||||
<table class="includecode"><thead><tr><th>{% if ghlink %}<a href="{{ghlink}}">{% endif %}<code>{{include.file}}</code></a></th></tr></thead>
|
||||
<table class="includecode"><thead><tr><th>{% if ghlink %}<a href="{{ghlink}}" download="{{include.file}}">{% endif %}<code>{{include.file}}</code></a><img src="/images/copycode.svg" style="max-height:24px" onClick="copyCode('{{include.file | handleize}}')" title="Copy {{include.file}} to clipboard"></th></tr></thead>
|
||||
<tr><td>{{ mysample | markdownify }}</td></tr></table>
|
||||
|
|
@ -2,14 +2,17 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="http://kubernetes.io{{page.url}}" />
|
||||
<link rel="shortcut icon" type="image/png" href="/images/favicon.png">
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto+Mono' type='text/css'>
|
||||
<link rel="stylesheet" href="/css/styles.css"/>
|
||||
<link rel="stylesheet" href="/css/jquery-ui.min.css">
|
||||
<link rel="stylesheet" href="/css/jquery-ui.min.css">
|
||||
<link rel="stylesheet" href="/css/sweetalert.css">
|
||||
<script src="/js/jquery-2.2.0.min.js"></script>
|
||||
<script src="/js/jquery-ui.min.js"></script>
|
||||
<script src="/js/jquery-ui.min.js"></script>
|
||||
<script src="/js/script.js"></script>
|
||||
<script src="/js/sweetalert.min.js"></script>
|
||||
<title>Kubernetes - {{ title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -61,4 +64,4 @@
|
|||
<div class="clear" style="clear: both"></div>
|
||||
</main>
|
||||
</nav>
|
||||
</header>
|
||||
</header>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
{% if concept %}<!-- check for this before going any further; if not present, skip to else at bottom -->
|
||||
|
||||
# Overview of {{concept}}s
|
||||
|
||||
{% if what_is %}
|
||||
|
||||
### What is a {{ concept }}?
|
||||
|
||||
{{ what_is }}
|
||||
|
||||
{% else %}
|
||||
|
||||
### ERROR: You must define a "what_is" block
|
||||
{: style="color:red" }
|
||||
|
||||
This template requires that you explain what this concept is. This explanation will
|
||||
be displayed under the heading, **What is a {{ concept }}?**
|
||||
|
||||
To get rid of this message and take advantage of this template, define the `what_is`
|
||||
variable and populate it with content.
|
||||
|
||||
```liquid
|
||||
{% raw %}{% capture what_is %}{% endraw %}
|
||||
A {{ concept }} does x and y and z...(etc, etc, text goes on)
|
||||
{% raw %}{% endcapture %}{% endraw %}
|
||||
```
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if when_to_use %}
|
||||
|
||||
### When to use {{ concept }}s
|
||||
|
||||
{{ when_to_use }}
|
||||
|
||||
{% else %}
|
||||
|
||||
### ERROR: You must define a "when_to_use" block
|
||||
{: style="color:red" }
|
||||
|
||||
This template requires that you explain when to use this object. This explanation will
|
||||
be displayed under the heading, **When to use {{ concept }}s**
|
||||
|
||||
To get rid of this message and take advantage of this template, define the `when_to_use`
|
||||
variable and populate it with content.
|
||||
|
||||
```liquid
|
||||
{% raw %}{% capture when_to_use %}{% endraw %}
|
||||
You should use {{ concept }} when...
|
||||
{% raw %}{% endcapture %}{% endraw %}
|
||||
```
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if when_not_to_use %}
|
||||
|
||||
### When not to use {{ concept }}s (alternatives)
|
||||
|
||||
{{ when_not_to_use }}
|
||||
|
||||
{% else %}
|
||||
|
||||
### ERROR: You must define a "when_not_to_use" block
|
||||
{: style="color:red" }
|
||||
|
||||
This template requires that you explain when not to use this object. This explanation will
|
||||
be displayed under the heading, **When not to use {{ concept }}s (alternatives)**
|
||||
|
||||
To get rid of this message and take advantage of this template, define the `when_not_to_use`
|
||||
block and populate it with content.
|
||||
|
||||
```liquid
|
||||
{% raw %}{% capture when_not_to_use %}{% endraw %}
|
||||
You should not use {{ concept }} if...
|
||||
{% raw %}{% endcapture %}{% endraw %}
|
||||
```
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if status %}
|
||||
|
||||
### {{ concept }} status
|
||||
|
||||
{{ status }}
|
||||
|
||||
{% else %}
|
||||
|
||||
### ERROR: You must define a "status" block
|
||||
{: style="color:red" }
|
||||
|
||||
This template requires that you explain the current status of support for this object.
|
||||
This explanation will be displayed under the heading, **{{ concept }} status**.
|
||||
|
||||
To get rid of this message and take advantage of this template, define the `status`
|
||||
block and populate it with content.
|
||||
|
||||
```liquid
|
||||
{% raw %}{% capture status %}{% endraw %}
|
||||
The current status of {{ concept }}s is...
|
||||
{% raw %}{% endcapture %}{% endraw %}
|
||||
```
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if required_fields %}
|
||||
|
||||
### {{ concept }} spec
|
||||
|
||||
#### Required Fields
|
||||
|
||||
{{ required_fields }}
|
||||
|
||||
{% else %}
|
||||
|
||||
### ERROR: You must define a "required_fields" block
|
||||
{: style="color:red" }
|
||||
|
||||
This template requires that you provide a Markdown list of required fields for this
|
||||
object. This list will be displayed under the heading **Required Fields**.
|
||||
|
||||
To get rid of this message and take advantage of this template, define the `required_fields`
|
||||
block and populate it with content.
|
||||
|
||||
```liquid
|
||||
{% raw %}{% capture required_fields %}
|
||||
* `kind`: Always `Pod`.
|
||||
* `apiVersion`: Currently `v1`.
|
||||
* `metadata`: An object containing:
|
||||
* `name`: Required if `generateName` is not specified. The name of this pod.
|
||||
It must be an
|
||||
[RFC1035](https://www.ietf.org/rfc/rfc1035.txt) compatible value and be
|
||||
unique within the namespace.
|
||||
{% endcapture %}{% endraw %}
|
||||
```
|
||||
|
||||
**Note**: You can also define a `common_fields` block that will go under a heading
|
||||
directly underneath **Required Fields** called **Common Fields**, but it is
|
||||
not required.
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if common_fields %}
|
||||
|
||||
#### Common Fields
|
||||
|
||||
{{ common_fields }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
<!-- continuing the "if concept" if/then: -->
|
||||
|
||||
{% else %}
|
||||
|
||||
### ERROR: You must define a "concept" variable
|
||||
{: style="color:red" }
|
||||
|
||||
This template requires a variable called `concept` that is simply the name of the
|
||||
concept for which you are giving an overview. This will be displayed in the
|
||||
headings for the document.
|
||||
|
||||
To get rid of this message and take advantage of this template, define `concept`:
|
||||
|
||||
```liquid
|
||||
{% raw %}{% assign concept="Replication Controller" %}{% endraw %}
|
||||
```
|
||||
|
||||
Complete this task, then we'll walk you through preparing the rest of the document.
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
{% if page.cards %}<!-- check for this before going any further; if not present, skip to else at bottom -->
|
||||
<style>
|
||||
h2, h3, h4 {
|
||||
border-bottom: 0px !important;
|
||||
font-size: 22px !important;
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
.colContainer {
|
||||
padding-top:2px;
|
||||
padding-left: 2px;
|
||||
overflow: auto;
|
||||
}
|
||||
#samples a {
|
||||
color: #000;
|
||||
}
|
||||
.col3rd {
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 30px;
|
||||
margin-bottom: 30px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.col3rd h3, .col2nd h3 {
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
.col3rd .button, .col2nd .button {
|
||||
margin-top: 20px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.col3rd p, .col2nd p {
|
||||
margin-left: 2px;
|
||||
}
|
||||
.col2nd {
|
||||
display: block;
|
||||
width: 400px;
|
||||
float: left;
|
||||
margin-right: 30px;
|
||||
margin-bottom: 30px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.shadowbox {
|
||||
width: 250px;
|
||||
display: inline;
|
||||
float: left;
|
||||
text-transform: none;
|
||||
font-weight: bold;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
line-height: 24px;
|
||||
position: relative;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 2px rgba(0,0,0,.24),0 0 2px rgba(0,0,0,.12);
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
transition: all .3s;
|
||||
padding: 16px;
|
||||
margin: 0 16px 16px 0;
|
||||
text-decoration: none;
|
||||
letter-spacing: .01em;
|
||||
height: 220px;
|
||||
}
|
||||
.shadowbox img {
|
||||
min-width: 100px;
|
||||
max-width: 100px;
|
||||
max-height: 50px;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="colContainer">
|
||||
{% for card in page.cards %}{% if card.title %}
|
||||
<div class="col3rd shadowbox">
|
||||
<h3>{{card.title}}</h3>
|
||||
<p>{% if card.image %}<img src="{{card.image}}">{% endif %}{{card.description}}</p>
|
||||
</div>
|
||||
{% endif %}{% endfor %}
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
|
||||
### ERROR: You must define "cards" front-matter YAML
|
||||
{: style="color:red" }
|
||||
|
||||
This template requires that you insert YAML at the top of your document
|
||||
that defines the "cards" you'd like to display on the page. The cards will
|
||||
render in clickable boxes.
|
||||
|
||||
To get rid of this message and take advantage of this template, define `cards`:
|
||||
|
||||
```yaml
|
||||
---
|
||||
cards:
|
||||
- progression: no
|
||||
- card:
|
||||
title: Mean Stack
|
||||
image: /docs/meanstack/image_0.png
|
||||
description: Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Guestbook + Redis
|
||||
image: /images/docs/redis.svg
|
||||
description: Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Cloud Native Cassandra
|
||||
image: /images/docs/cassandra.svg
|
||||
description: Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: WordPress + MySQL
|
||||
image: /images/docs/wordpress.svg
|
||||
description: Lorem ipsum dolor it verberum.
|
||||
---
|
||||
```
|
||||
|
||||
**Note:** If `progression` is set to `yes` then a "Start Here!" icon will be
|
||||
placed on the first card and arrows suggesting linear reading will be overlayed
|
||||
between the other cards, telling the reader that they should explore the content
|
||||
in a certain order.
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -181,7 +181,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonsetlist">v1beta1.DaemonSetList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonsetlist">v1beta1.DaemonSetList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -321,7 +321,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deploymentlist">v1beta1.DeploymentList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deploymentlist">v1beta1.DeploymentList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -461,7 +461,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscalerlist">v1beta1.HorizontalPodAutoscalerList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscalerlist">v1beta1.HorizontalPodAutoscalerList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -601,7 +601,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingresslist">v1beta1.IngressList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingresslist">v1beta1.IngressList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -741,7 +741,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_joblist">v1beta1.JobList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_joblist">v1beta1.JobList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -889,7 +889,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonsetlist">v1beta1.DaemonSetList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonsetlist">v1beta1.DaemonSetList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1037,7 +1037,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1119,7 +1119,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1153,7 +1153,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1285,7 +1285,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1367,7 +1367,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1409,7 +1409,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1491,7 +1491,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1533,7 +1533,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1615,7 +1615,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1657,7 +1657,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1745,7 +1745,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1787,7 +1787,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_daemonset">v1beta1.DaemonSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1935,7 +1935,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deploymentlist">v1beta1.DeploymentList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deploymentlist">v1beta1.DeploymentList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -2083,7 +2083,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -2165,7 +2165,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -2199,7 +2199,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -2331,7 +2331,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -2413,7 +2413,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -2455,7 +2455,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -2537,7 +2537,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -2579,7 +2579,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -2661,7 +2661,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -2703,7 +2703,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -2791,7 +2791,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deploymentrollback">v1beta1.DeploymentRollback</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deploymentrollback">v1beta1.DeploymentRollback</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -2833,7 +2833,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deploymentrollback">v1beta1.DeploymentRollback</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deploymentrollback">v1beta1.DeploymentRollback</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -2949,7 +2949,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -3031,7 +3031,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -3073,7 +3073,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -3155,7 +3155,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -3197,7 +3197,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -3285,7 +3285,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -3327,7 +3327,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_deployment">v1beta1.Deployment</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -3475,7 +3475,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscalerlist">v1beta1.HorizontalPodAutoscalerList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscalerlist">v1beta1.HorizontalPodAutoscalerList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -3623,7 +3623,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -3705,7 +3705,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -3739,7 +3739,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -3871,7 +3871,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -3953,7 +3953,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -3995,7 +3995,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -4077,7 +4077,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -4119,7 +4119,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -4201,7 +4201,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -4243,7 +4243,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -4331,7 +4331,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -4373,7 +4373,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_horizontalpodautoscaler">v1beta1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -4521,7 +4521,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingresslist">v1beta1.IngressList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingresslist">v1beta1.IngressList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -4669,7 +4669,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -4751,7 +4751,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -4785,7 +4785,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -4917,7 +4917,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -4999,7 +4999,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -5041,7 +5041,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -5123,7 +5123,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -5165,7 +5165,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -5247,7 +5247,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -5289,7 +5289,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -5377,7 +5377,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -5419,7 +5419,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_ingress">v1beta1.Ingress</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -5567,7 +5567,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_joblist">v1beta1.JobList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_joblist">v1beta1.JobList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -5715,7 +5715,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -5797,7 +5797,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -5831,7 +5831,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -5963,7 +5963,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -6045,7 +6045,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -6087,7 +6087,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -6169,7 +6169,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -6211,7 +6211,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -6293,7 +6293,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -6335,7 +6335,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -6423,7 +6423,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -6465,7 +6465,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_job">v1beta1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -6613,7 +6613,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicasetlist">v1beta1.ReplicaSetList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicasetlist">v1beta1.ReplicaSetList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -6761,7 +6761,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -6843,7 +6843,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -6877,7 +6877,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7009,7 +7009,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7091,7 +7091,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -7133,7 +7133,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7215,7 +7215,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -7257,7 +7257,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7339,7 +7339,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -7381,7 +7381,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7503,7 +7503,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7585,7 +7585,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -7627,7 +7627,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7709,7 +7709,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -7751,7 +7751,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7839,7 +7839,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -7881,7 +7881,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicaset">v1beta1.ReplicaSet</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -7997,7 +7997,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -8079,7 +8079,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -8121,7 +8121,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -8203,7 +8203,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -8245,7 +8245,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_scale">v1beta1.Scale</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -8391,7 +8391,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1beta1_replicasetlist">v1beta1.ReplicaSetList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1beta1_replicasetlist">v1beta1.ReplicaSetList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -8531,7 +8531,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -8668,7 +8668,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -8805,7 +8805,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -8942,7 +8942,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -9079,7 +9079,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -9224,7 +9224,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -9377,7 +9377,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -9522,7 +9522,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -9675,7 +9675,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -9820,7 +9820,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -9973,7 +9973,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -10118,7 +10118,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -10271,7 +10271,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -10416,7 +10416,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -10569,7 +10569,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -10714,7 +10714,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -10867,7 +10867,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -11004,7 +11004,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -512,7 +512,7 @@ section
|
|||
background-color: $light-grey
|
||||
border-left: 3px solid $blue
|
||||
padding: 7.5px 10px 7.5px 18px
|
||||
margin-left: -21px
|
||||
margin-left: -3px
|
||||
color: $blue
|
||||
|
||||
.open-toc
|
||||
|
|
@ -526,10 +526,13 @@ section
|
|||
overflow-y: auto
|
||||
|
||||
.pi-accordion
|
||||
margin-left: -20px
|
||||
& > .container:first-child > .item:first-child > .title:first-child
|
||||
padding-left: 0
|
||||
font-size: 1.5em
|
||||
font-weight: 700
|
||||
|
||||
.container
|
||||
padding-left: 20px
|
||||
& > .container:first-child > .item.yah:first-child > .title:first-child
|
||||
margin-left: -20px !important
|
||||
|
||||
.item
|
||||
overflow: hidden
|
||||
|
|
@ -546,7 +549,6 @@ section
|
|||
|
||||
a.item > .title
|
||||
color: black
|
||||
padding-left: 0
|
||||
|
||||
&:hover
|
||||
color: $blue
|
||||
|
|
@ -689,11 +691,10 @@ dd
|
|||
#docsContent
|
||||
position: relative
|
||||
float: right
|
||||
//width: calc(100% - 400px)
|
||||
width: 100%
|
||||
|
||||
$toc-margin: 15px
|
||||
$header-clearance: 40px
|
||||
$header-clearance: $header-height + 20px
|
||||
|
||||
* + h2, * + h3, * + h4, * + h5, * + h6
|
||||
margin-top: 30px
|
||||
|
|
@ -705,12 +706,12 @@ dd
|
|||
padding-bottom: 10px
|
||||
border-bottom: 1px solid #cccccc
|
||||
|
||||
// Make sure anchor links aren't hidden by the header
|
||||
&:before
|
||||
content: ''
|
||||
display: block
|
||||
height: 100px
|
||||
margin-top: -100px
|
||||
background-color: red
|
||||
content: " "
|
||||
margin-top: -$header-clearance
|
||||
height: $header-clearance
|
||||
visibility: hidden
|
||||
|
||||
h1
|
||||
|
|
@ -845,9 +846,9 @@ dd
|
|||
white-space: nowrap
|
||||
text-indent: 50px
|
||||
overflow: hidden
|
||||
background: $blue url(/images/pencil.png) no-repeat
|
||||
background-position: 1px 1px
|
||||
background-size: auto
|
||||
background: $blue url(/images/icon-pencil.svg) no-repeat
|
||||
background-position: 12px 10px
|
||||
background-size: 29px 29px
|
||||
|
||||
#markdown-toc
|
||||
margin-bottom: 20px
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ $video-section-height: 550px
|
|||
|
||||
#encyclopedia
|
||||
padding: 50px 50px 20px 20px
|
||||
clear: both
|
||||
|
||||
#docsToc
|
||||
position: relative
|
||||
|
|
@ -88,6 +89,11 @@ $video-section-height: 550px
|
|||
main
|
||||
max-width: $main-max-width
|
||||
|
||||
#home
|
||||
section, header, footer
|
||||
main
|
||||
max-width: 1000px
|
||||
|
||||
#oceanNodes
|
||||
main
|
||||
position: relative
|
||||
|
|
@ -95,7 +101,7 @@ $video-section-height: 550px
|
|||
|
||||
&:nth-child(1)
|
||||
max-width: 1000px
|
||||
padding-right: 500px
|
||||
padding-right: 475px
|
||||
|
||||
h3, p
|
||||
text-align: left
|
||||
|
|
@ -105,6 +111,9 @@ $video-section-height: 550px
|
|||
max-width: 48%
|
||||
transform: translateY(-50%)
|
||||
|
||||
img
|
||||
max-width: 425px
|
||||
|
||||
//.content
|
||||
// width: 50%
|
||||
|
||||
|
|
@ -170,30 +179,6 @@ $video-section-height: 550px
|
|||
div:last-child
|
||||
float: right
|
||||
|
||||
//.social
|
||||
// position: relative
|
||||
// margin: 20px 0
|
||||
//
|
||||
// a
|
||||
// float: left
|
||||
//
|
||||
// a + a
|
||||
// margin-left: 10px
|
||||
//
|
||||
// label
|
||||
// float: right
|
||||
// width: auto
|
||||
// display: inline-block
|
||||
// height: 50px
|
||||
// line-height: 50px
|
||||
// font-weight: 100
|
||||
// white-space: nowrap
|
||||
//
|
||||
// input
|
||||
// margin-left: 8px
|
||||
// max-width: none
|
||||
|
||||
|
||||
#search, #wishField
|
||||
background-color: transparent
|
||||
padding: 10px
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ title: Community
|
|||
<img src="/images/community_logos/core_os_logo.png">
|
||||
<img src="/images/community_logos/puppet_logo.png">
|
||||
<img src="/images/community_logos/sysdig_logo.png">
|
||||
<img src="/images/community_logos/deis_logo.png">
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,934 @@
|
|||
body.stop-scrolling {
|
||||
height: 100%;
|
||||
overflow: hidden; }
|
||||
|
||||
.sweet-overlay {
|
||||
background-color: black;
|
||||
/* IE8 */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
|
||||
/* IE8 */
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
z-index: 10000; }
|
||||
|
||||
.sweet-alert {
|
||||
background-color: white;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
width: 478px;
|
||||
padding: 17px;
|
||||
border-radius: 5px;
|
||||
text-align: left;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -256px;
|
||||
margin-top: -200px;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
z-index: 99999; }
|
||||
@media all and (max-width: 540px) {
|
||||
.sweet-alert {
|
||||
width: auto;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
left: 15px;
|
||||
right: 15px; } }
|
||||
.sweet-alert h2 {
|
||||
color: #575757;
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
position: relative;
|
||||
margin: 25px 0;
|
||||
padding: 0;
|
||||
line-height: 40px;
|
||||
display: block; }
|
||||
.sweet-alert p {
|
||||
color: #797979;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
font-weight: 300;
|
||||
position: relative;
|
||||
text-align: inherit;
|
||||
float: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-left: 10px !important;
|
||||
font-family: courier,monospace;
|
||||
line-height: normal; }
|
||||
.sweet-alert fieldset {
|
||||
border: none;
|
||||
position: relative; }
|
||||
.sweet-alert .sa-error-container {
|
||||
background-color: #f1f1f1;
|
||||
margin-left: -17px;
|
||||
margin-right: -17px;
|
||||
overflow: hidden;
|
||||
padding: 0 10px;
|
||||
max-height: 0;
|
||||
webkit-transition: padding 0.15s, max-height 0.15s;
|
||||
transition: padding 0.15s, max-height 0.15s; }
|
||||
.sweet-alert .sa-error-container.show {
|
||||
padding: 10px 0;
|
||||
max-height: 100px;
|
||||
webkit-transition: padding 0.2s, max-height 0.2s;
|
||||
transition: padding 0.25s, max-height 0.25s; }
|
||||
.sweet-alert .sa-error-container .icon {
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background-color: #ea7d7d;
|
||||
color: white;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
margin-right: 3px; }
|
||||
.sweet-alert .sa-error-container p {
|
||||
display: inline-block; }
|
||||
.sweet-alert .sa-input-error {
|
||||
position: absolute;
|
||||
top: 29px;
|
||||
right: 26px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.5);
|
||||
transform: scale(0.5);
|
||||
-webkit-transform-origin: 50% 50%;
|
||||
transform-origin: 50% 50%;
|
||||
-webkit-transition: all 0.1s;
|
||||
transition: all 0.1s; }
|
||||
.sweet-alert .sa-input-error::before, .sweet-alert .sa-input-error::after {
|
||||
content: "";
|
||||
width: 20px;
|
||||
height: 6px;
|
||||
background-color: #f06e57;
|
||||
border-radius: 3px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -4px;
|
||||
left: 50%;
|
||||
margin-left: -9px; }
|
||||
.sweet-alert .sa-input-error::before {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg); }
|
||||
.sweet-alert .sa-input-error::after {
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg); }
|
||||
.sweet-alert .sa-input-error.show {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1); }
|
||||
.sweet-alert input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #d7d7d7;
|
||||
height: 43px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 17px;
|
||||
font-size: 18px;
|
||||
box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.06);
|
||||
padding: 0 12px;
|
||||
display: none;
|
||||
-webkit-transition: all 0.3s;
|
||||
transition: all 0.3s; }
|
||||
.sweet-alert input:focus {
|
||||
outline: none;
|
||||
box-shadow: 0px 0px 3px #c4e6f5;
|
||||
border: 1px solid #b4dbed; }
|
||||
.sweet-alert input:focus::-moz-placeholder {
|
||||
transition: opacity 0.3s 0.03s ease;
|
||||
opacity: 0.5; }
|
||||
.sweet-alert input:focus:-ms-input-placeholder {
|
||||
transition: opacity 0.3s 0.03s ease;
|
||||
opacity: 0.5; }
|
||||
.sweet-alert input:focus::-webkit-input-placeholder {
|
||||
transition: opacity 0.3s 0.03s ease;
|
||||
opacity: 0.5; }
|
||||
.sweet-alert input::-moz-placeholder {
|
||||
color: #bdbdbd; }
|
||||
.sweet-alert input:-ms-input-placeholder {
|
||||
color: #bdbdbd; }
|
||||
.sweet-alert input::-webkit-input-placeholder {
|
||||
color: #bdbdbd; }
|
||||
.sweet-alert.show-input input {
|
||||
display: block; }
|
||||
.sweet-alert .sa-confirm-button-container {
|
||||
display: inline-block;
|
||||
position: relative; }
|
||||
.sweet-alert .la-ball-fall {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -27px;
|
||||
margin-top: 4px;
|
||||
opacity: 0;
|
||||
visibility: hidden; }
|
||||
.sweet-alert button {
|
||||
background-color: #8CD4F5;
|
||||
color: white;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 5px;
|
||||
padding: 10px 32px;
|
||||
margin: 26px 5px 0 5px;
|
||||
cursor: pointer; }
|
||||
.sweet-alert button:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05); }
|
||||
.sweet-alert button:hover {
|
||||
background-color: #7ecff4; }
|
||||
.sweet-alert button:active {
|
||||
background-color: #5dc2f1; }
|
||||
.sweet-alert button.cancel {
|
||||
background-color: #C1C1C1; }
|
||||
.sweet-alert button.cancel:hover {
|
||||
background-color: #b9b9b9; }
|
||||
.sweet-alert button.cancel:active {
|
||||
background-color: #a8a8a8; }
|
||||
.sweet-alert button.cancel:focus {
|
||||
box-shadow: rgba(197, 205, 211, 0.8) 0px 0px 2px, rgba(0, 0, 0, 0.0470588) 0px 0px 0px 1px inset !important; }
|
||||
.sweet-alert button[disabled] {
|
||||
opacity: .6;
|
||||
cursor: default; }
|
||||
.sweet-alert button.confirm[disabled] {
|
||||
color: transparent; }
|
||||
.sweet-alert button.confirm[disabled] ~ .la-ball-fall {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition-delay: 0s; }
|
||||
.sweet-alert button::-moz-focus-inner {
|
||||
border: 0; }
|
||||
.sweet-alert[data-has-cancel-button=false] button {
|
||||
box-shadow: none !important; }
|
||||
.sweet-alert[data-has-confirm-button=false][data-has-cancel-button=false] {
|
||||
padding-bottom: 40px; }
|
||||
.sweet-alert .sa-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: 4px solid gray;
|
||||
-webkit-border-radius: 40px;
|
||||
border-radius: 40px;
|
||||
border-radius: 50%;
|
||||
margin: 20px auto;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
box-sizing: content-box; }
|
||||
.sweet-alert .sa-icon.sa-error {
|
||||
border-color: #F27474; }
|
||||
.sweet-alert .sa-icon.sa-error .sa-x-mark {
|
||||
position: relative;
|
||||
display: block; }
|
||||
.sweet-alert .sa-icon.sa-error .sa-line {
|
||||
position: absolute;
|
||||
height: 5px;
|
||||
width: 47px;
|
||||
background-color: #F27474;
|
||||
display: block;
|
||||
top: 37px;
|
||||
border-radius: 2px; }
|
||||
.sweet-alert .sa-icon.sa-error .sa-line.sa-left {
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
left: 17px; }
|
||||
.sweet-alert .sa-icon.sa-error .sa-line.sa-right {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
right: 16px; }
|
||||
.sweet-alert .sa-icon.sa-warning {
|
||||
border-color: #F8BB86; }
|
||||
.sweet-alert .sa-icon.sa-warning .sa-body {
|
||||
position: absolute;
|
||||
width: 5px;
|
||||
height: 47px;
|
||||
left: 50%;
|
||||
top: 10px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
margin-left: -2px;
|
||||
background-color: #F8BB86; }
|
||||
.sweet-alert .sa-icon.sa-warning .sa-dot {
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
margin-left: -3px;
|
||||
left: 50%;
|
||||
bottom: 10px;
|
||||
background-color: #F8BB86; }
|
||||
.sweet-alert .sa-icon.sa-info {
|
||||
border-color: #C9DAE1; }
|
||||
.sweet-alert .sa-icon.sa-info::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 5px;
|
||||
height: 29px;
|
||||
left: 50%;
|
||||
bottom: 17px;
|
||||
border-radius: 2px;
|
||||
margin-left: -2px;
|
||||
background-color: #C9DAE1; }
|
||||
.sweet-alert .sa-icon.sa-info::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
margin-left: -3px;
|
||||
top: 19px;
|
||||
background-color: #C9DAE1; }
|
||||
.sweet-alert .sa-icon.sa-success {
|
||||
border-color: #A5DC86; }
|
||||
.sweet-alert .sa-icon.sa-success::before, .sweet-alert .sa-icon.sa-success::after {
|
||||
content: '';
|
||||
-webkit-border-radius: 40px;
|
||||
border-radius: 40px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
height: 120px;
|
||||
background: white;
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg); }
|
||||
.sweet-alert .sa-icon.sa-success::before {
|
||||
-webkit-border-radius: 120px 0 0 120px;
|
||||
border-radius: 120px 0 0 120px;
|
||||
top: -7px;
|
||||
left: -33px;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform-origin: 60px 60px;
|
||||
transform-origin: 60px 60px; }
|
||||
.sweet-alert .sa-icon.sa-success::after {
|
||||
-webkit-border-radius: 0 120px 120px 0;
|
||||
border-radius: 0 120px 120px 0;
|
||||
top: -11px;
|
||||
left: 30px;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform-origin: 0px 60px;
|
||||
transform-origin: 0px 60px; }
|
||||
.sweet-alert .sa-icon.sa-success .sa-placeholder {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: 4px solid rgba(165, 220, 134, 0.2);
|
||||
-webkit-border-radius: 40px;
|
||||
border-radius: 40px;
|
||||
border-radius: 50%;
|
||||
box-sizing: content-box;
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
z-index: 2; }
|
||||
.sweet-alert .sa-icon.sa-success .sa-fix {
|
||||
width: 5px;
|
||||
height: 90px;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
left: 28px;
|
||||
top: 8px;
|
||||
z-index: 1;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg); }
|
||||
.sweet-alert .sa-icon.sa-success .sa-line {
|
||||
height: 5px;
|
||||
background-color: #A5DC86;
|
||||
display: block;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
z-index: 2; }
|
||||
.sweet-alert .sa-icon.sa-success .sa-line.sa-tip {
|
||||
width: 25px;
|
||||
left: 14px;
|
||||
top: 46px;
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg); }
|
||||
.sweet-alert .sa-icon.sa-success .sa-line.sa-long {
|
||||
width: 47px;
|
||||
right: 8px;
|
||||
top: 38px;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg); }
|
||||
.sweet-alert .sa-icon.sa-custom {
|
||||
background-size: contain;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat; }
|
||||
|
||||
/*
|
||||
* Animations
|
||||
*/
|
||||
@-webkit-keyframes showSweetAlert {
|
||||
0% {
|
||||
transform: scale(0.7);
|
||||
-webkit-transform: scale(0.7); }
|
||||
45% {
|
||||
transform: scale(1.05);
|
||||
-webkit-transform: scale(1.05); }
|
||||
80% {
|
||||
transform: scale(0.95);
|
||||
-webkit-transform: scale(0.95); }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); } }
|
||||
|
||||
@keyframes showSweetAlert {
|
||||
0% {
|
||||
transform: scale(0.7);
|
||||
-webkit-transform: scale(0.7); }
|
||||
45% {
|
||||
transform: scale(1.05);
|
||||
-webkit-transform: scale(1.05); }
|
||||
80% {
|
||||
transform: scale(0.95);
|
||||
-webkit-transform: scale(0.95); }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); } }
|
||||
|
||||
@-webkit-keyframes hideSweetAlert {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); }
|
||||
100% {
|
||||
transform: scale(0.5);
|
||||
-webkit-transform: scale(0.5); } }
|
||||
|
||||
@keyframes hideSweetAlert {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); }
|
||||
100% {
|
||||
transform: scale(0.5);
|
||||
-webkit-transform: scale(0.5); } }
|
||||
|
||||
@-webkit-keyframes slideFromTop {
|
||||
0% {
|
||||
top: 0%; }
|
||||
100% {
|
||||
top: 50%; } }
|
||||
|
||||
@keyframes slideFromTop {
|
||||
0% {
|
||||
top: 0%; }
|
||||
100% {
|
||||
top: 50%; } }
|
||||
|
||||
@-webkit-keyframes slideToTop {
|
||||
0% {
|
||||
top: 50%; }
|
||||
100% {
|
||||
top: 0%; } }
|
||||
|
||||
@keyframes slideToTop {
|
||||
0% {
|
||||
top: 50%; }
|
||||
100% {
|
||||
top: 0%; } }
|
||||
|
||||
@-webkit-keyframes slideFromBottom {
|
||||
0% {
|
||||
top: 70%; }
|
||||
100% {
|
||||
top: 50%; } }
|
||||
|
||||
@keyframes slideFromBottom {
|
||||
0% {
|
||||
top: 70%; }
|
||||
100% {
|
||||
top: 50%; } }
|
||||
|
||||
@-webkit-keyframes slideToBottom {
|
||||
0% {
|
||||
top: 50%; }
|
||||
100% {
|
||||
top: 70%; } }
|
||||
|
||||
@keyframes slideToBottom {
|
||||
0% {
|
||||
top: 50%; }
|
||||
100% {
|
||||
top: 70%; } }
|
||||
|
||||
.showSweetAlert[data-animation=pop] {
|
||||
-webkit-animation: showSweetAlert 0.3s;
|
||||
animation: showSweetAlert 0.3s; }
|
||||
|
||||
.showSweetAlert[data-animation=none] {
|
||||
-webkit-animation: none;
|
||||
animation: none; }
|
||||
|
||||
.showSweetAlert[data-animation=slide-from-top] {
|
||||
-webkit-animation: slideFromTop 0.3s;
|
||||
animation: slideFromTop 0.3s; }
|
||||
|
||||
.showSweetAlert[data-animation=slide-from-bottom] {
|
||||
-webkit-animation: slideFromBottom 0.3s;
|
||||
animation: slideFromBottom 0.3s; }
|
||||
|
||||
.hideSweetAlert[data-animation=pop] {
|
||||
-webkit-animation: hideSweetAlert 0.2s;
|
||||
animation: hideSweetAlert 0.2s; }
|
||||
|
||||
.hideSweetAlert[data-animation=none] {
|
||||
-webkit-animation: none;
|
||||
animation: none; }
|
||||
|
||||
.hideSweetAlert[data-animation=slide-from-top] {
|
||||
-webkit-animation: slideToTop 0.4s;
|
||||
animation: slideToTop 0.4s; }
|
||||
|
||||
.hideSweetAlert[data-animation=slide-from-bottom] {
|
||||
-webkit-animation: slideToBottom 0.3s;
|
||||
animation: slideToBottom 0.3s; }
|
||||
|
||||
@-webkit-keyframes animateSuccessTip {
|
||||
0% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px; }
|
||||
54% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px; }
|
||||
70% {
|
||||
width: 50px;
|
||||
left: -8px;
|
||||
top: 37px; }
|
||||
84% {
|
||||
width: 17px;
|
||||
left: 21px;
|
||||
top: 48px; }
|
||||
100% {
|
||||
width: 25px;
|
||||
left: 14px;
|
||||
top: 45px; } }
|
||||
|
||||
@keyframes animateSuccessTip {
|
||||
0% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px; }
|
||||
54% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px; }
|
||||
70% {
|
||||
width: 50px;
|
||||
left: -8px;
|
||||
top: 37px; }
|
||||
84% {
|
||||
width: 17px;
|
||||
left: 21px;
|
||||
top: 48px; }
|
||||
100% {
|
||||
width: 25px;
|
||||
left: 14px;
|
||||
top: 45px; } }
|
||||
|
||||
@-webkit-keyframes animateSuccessLong {
|
||||
0% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px; }
|
||||
65% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px; }
|
||||
84% {
|
||||
width: 55px;
|
||||
right: 0px;
|
||||
top: 35px; }
|
||||
100% {
|
||||
width: 47px;
|
||||
right: 8px;
|
||||
top: 38px; } }
|
||||
|
||||
@keyframes animateSuccessLong {
|
||||
0% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px; }
|
||||
65% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px; }
|
||||
84% {
|
||||
width: 55px;
|
||||
right: 0px;
|
||||
top: 35px; }
|
||||
100% {
|
||||
width: 47px;
|
||||
right: 8px;
|
||||
top: 38px; } }
|
||||
|
||||
@-webkit-keyframes rotatePlaceholder {
|
||||
0% {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg); }
|
||||
5% {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg); }
|
||||
12% {
|
||||
transform: rotate(-405deg);
|
||||
-webkit-transform: rotate(-405deg); }
|
||||
100% {
|
||||
transform: rotate(-405deg);
|
||||
-webkit-transform: rotate(-405deg); } }
|
||||
|
||||
@keyframes rotatePlaceholder {
|
||||
0% {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg); }
|
||||
5% {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg); }
|
||||
12% {
|
||||
transform: rotate(-405deg);
|
||||
-webkit-transform: rotate(-405deg); }
|
||||
100% {
|
||||
transform: rotate(-405deg);
|
||||
-webkit-transform: rotate(-405deg); } }
|
||||
|
||||
.animateSuccessTip {
|
||||
-webkit-animation: animateSuccessTip 0.75s;
|
||||
animation: animateSuccessTip 0.75s; }
|
||||
|
||||
.animateSuccessLong {
|
||||
-webkit-animation: animateSuccessLong 0.75s;
|
||||
animation: animateSuccessLong 0.75s; }
|
||||
|
||||
.sa-icon.sa-success.animate::after {
|
||||
-webkit-animation: rotatePlaceholder 4.25s ease-in;
|
||||
animation: rotatePlaceholder 4.25s ease-in; }
|
||||
|
||||
@-webkit-keyframes animateErrorIcon {
|
||||
0% {
|
||||
transform: rotateX(100deg);
|
||||
-webkit-transform: rotateX(100deg);
|
||||
opacity: 0; }
|
||||
100% {
|
||||
transform: rotateX(0deg);
|
||||
-webkit-transform: rotateX(0deg);
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes animateErrorIcon {
|
||||
0% {
|
||||
transform: rotateX(100deg);
|
||||
-webkit-transform: rotateX(100deg);
|
||||
opacity: 0; }
|
||||
100% {
|
||||
transform: rotateX(0deg);
|
||||
-webkit-transform: rotateX(0deg);
|
||||
opacity: 1; } }
|
||||
|
||||
.animateErrorIcon {
|
||||
-webkit-animation: animateErrorIcon 0.5s;
|
||||
animation: animateErrorIcon 0.5s; }
|
||||
|
||||
@-webkit-keyframes animateXMark {
|
||||
0% {
|
||||
transform: scale(0.4);
|
||||
-webkit-transform: scale(0.4);
|
||||
margin-top: 26px;
|
||||
opacity: 0; }
|
||||
50% {
|
||||
transform: scale(0.4);
|
||||
-webkit-transform: scale(0.4);
|
||||
margin-top: 26px;
|
||||
opacity: 0; }
|
||||
80% {
|
||||
transform: scale(1.15);
|
||||
-webkit-transform: scale(1.15);
|
||||
margin-top: -6px; }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
margin-top: 0;
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes animateXMark {
|
||||
0% {
|
||||
transform: scale(0.4);
|
||||
-webkit-transform: scale(0.4);
|
||||
margin-top: 26px;
|
||||
opacity: 0; }
|
||||
50% {
|
||||
transform: scale(0.4);
|
||||
-webkit-transform: scale(0.4);
|
||||
margin-top: 26px;
|
||||
opacity: 0; }
|
||||
80% {
|
||||
transform: scale(1.15);
|
||||
-webkit-transform: scale(1.15);
|
||||
margin-top: -6px; }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
margin-top: 0;
|
||||
opacity: 1; } }
|
||||
|
||||
.animateXMark {
|
||||
-webkit-animation: animateXMark 0.5s;
|
||||
animation: animateXMark 0.5s; }
|
||||
|
||||
@-webkit-keyframes pulseWarning {
|
||||
0% {
|
||||
border-color: #F8D486; }
|
||||
100% {
|
||||
border-color: #F8BB86; } }
|
||||
|
||||
@keyframes pulseWarning {
|
||||
0% {
|
||||
border-color: #F8D486; }
|
||||
100% {
|
||||
border-color: #F8BB86; } }
|
||||
|
||||
.pulseWarning {
|
||||
-webkit-animation: pulseWarning 0.75s infinite alternate;
|
||||
animation: pulseWarning 0.75s infinite alternate; }
|
||||
|
||||
@-webkit-keyframes pulseWarningIns {
|
||||
0% {
|
||||
background-color: #F8D486; }
|
||||
100% {
|
||||
background-color: #F8BB86; } }
|
||||
|
||||
@keyframes pulseWarningIns {
|
||||
0% {
|
||||
background-color: #F8D486; }
|
||||
100% {
|
||||
background-color: #F8BB86; } }
|
||||
|
||||
.pulseWarningIns {
|
||||
-webkit-animation: pulseWarningIns 0.75s infinite alternate;
|
||||
animation: pulseWarningIns 0.75s infinite alternate; }
|
||||
|
||||
@-webkit-keyframes rotate-loading {
|
||||
0% {
|
||||
transform: rotate(0deg); }
|
||||
100% {
|
||||
transform: rotate(360deg); } }
|
||||
|
||||
@keyframes rotate-loading {
|
||||
0% {
|
||||
transform: rotate(0deg); }
|
||||
100% {
|
||||
transform: rotate(360deg); } }
|
||||
|
||||
/* Internet Explorer 9 has some special quirks that are fixed here */
|
||||
/* The icons are not animated. */
|
||||
/* This file is automatically merged into sweet-alert.min.js through Gulp */
|
||||
/* Error icon */
|
||||
.sweet-alert .sa-icon.sa-error .sa-line.sa-left {
|
||||
-ms-transform: rotate(45deg) \9; }
|
||||
|
||||
.sweet-alert .sa-icon.sa-error .sa-line.sa-right {
|
||||
-ms-transform: rotate(-45deg) \9; }
|
||||
|
||||
/* Success icon */
|
||||
.sweet-alert .sa-icon.sa-success {
|
||||
border-color: transparent\9; }
|
||||
|
||||
.sweet-alert .sa-icon.sa-success .sa-line.sa-tip {
|
||||
-ms-transform: rotate(45deg) \9; }
|
||||
|
||||
.sweet-alert .sa-icon.sa-success .sa-line.sa-long {
|
||||
-ms-transform: rotate(-45deg) \9; }
|
||||
|
||||
/*!
|
||||
* Load Awesome v1.1.0 (http://github.danielcardoso.net/load-awesome/)
|
||||
* Copyright 2015 Daniel Cardoso <@DanielCardoso>
|
||||
* Licensed under MIT
|
||||
*/
|
||||
.la-ball-fall,
|
||||
.la-ball-fall > div {
|
||||
position: relative;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box; }
|
||||
|
||||
.la-ball-fall {
|
||||
display: block;
|
||||
font-size: 0;
|
||||
color: #fff; }
|
||||
|
||||
.la-ball-fall.la-dark {
|
||||
color: #333; }
|
||||
|
||||
.la-ball-fall > div {
|
||||
display: inline-block;
|
||||
float: none;
|
||||
background-color: currentColor;
|
||||
border: 0 solid currentColor; }
|
||||
|
||||
.la-ball-fall {
|
||||
width: 54px;
|
||||
height: 18px; }
|
||||
|
||||
.la-ball-fall > div {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin: 4px;
|
||||
border-radius: 100%;
|
||||
opacity: 0;
|
||||
-webkit-animation: ball-fall 1s ease-in-out infinite;
|
||||
-moz-animation: ball-fall 1s ease-in-out infinite;
|
||||
-o-animation: ball-fall 1s ease-in-out infinite;
|
||||
animation: ball-fall 1s ease-in-out infinite; }
|
||||
|
||||
.la-ball-fall > div:nth-child(1) {
|
||||
-webkit-animation-delay: -200ms;
|
||||
-moz-animation-delay: -200ms;
|
||||
-o-animation-delay: -200ms;
|
||||
animation-delay: -200ms; }
|
||||
|
||||
.la-ball-fall > div:nth-child(2) {
|
||||
-webkit-animation-delay: -100ms;
|
||||
-moz-animation-delay: -100ms;
|
||||
-o-animation-delay: -100ms;
|
||||
animation-delay: -100ms; }
|
||||
|
||||
.la-ball-fall > div:nth-child(3) {
|
||||
-webkit-animation-delay: 0ms;
|
||||
-moz-animation-delay: 0ms;
|
||||
-o-animation-delay: 0ms;
|
||||
animation-delay: 0ms; }
|
||||
|
||||
.la-ball-fall.la-sm {
|
||||
width: 26px;
|
||||
height: 8px; }
|
||||
|
||||
.la-ball-fall.la-sm > div {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
margin: 2px; }
|
||||
|
||||
.la-ball-fall.la-2x {
|
||||
width: 108px;
|
||||
height: 36px; }
|
||||
|
||||
.la-ball-fall.la-2x > div {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 8px; }
|
||||
|
||||
.la-ball-fall.la-3x {
|
||||
width: 162px;
|
||||
height: 54px; }
|
||||
|
||||
.la-ball-fall.la-3x > div {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 12px; }
|
||||
|
||||
/*
|
||||
* Animation
|
||||
*/
|
||||
@-webkit-keyframes ball-fall {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-145%);
|
||||
transform: translateY(-145%); }
|
||||
10% {
|
||||
opacity: .5; }
|
||||
20% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
80% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
90% {
|
||||
opacity: .5; }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(145%);
|
||||
transform: translateY(145%); } }
|
||||
|
||||
@-moz-keyframes ball-fall {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-moz-transform: translateY(-145%);
|
||||
transform: translateY(-145%); }
|
||||
10% {
|
||||
opacity: .5; }
|
||||
20% {
|
||||
opacity: 1;
|
||||
-moz-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
80% {
|
||||
opacity: 1;
|
||||
-moz-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
90% {
|
||||
opacity: .5; }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-moz-transform: translateY(145%);
|
||||
transform: translateY(145%); } }
|
||||
|
||||
@-o-keyframes ball-fall {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-o-transform: translateY(-145%);
|
||||
transform: translateY(-145%); }
|
||||
10% {
|
||||
opacity: .5; }
|
||||
20% {
|
||||
opacity: 1;
|
||||
-o-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
80% {
|
||||
opacity: 1;
|
||||
-o-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
90% {
|
||||
opacity: .5; }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-o-transform: translateY(145%);
|
||||
transform: translateY(145%); } }
|
||||
|
||||
@keyframes ball-fall {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-145%);
|
||||
-moz-transform: translateY(-145%);
|
||||
-o-transform: translateY(-145%);
|
||||
transform: translateY(-145%); }
|
||||
10% {
|
||||
opacity: .5; }
|
||||
20% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-moz-transform: translateY(0);
|
||||
-o-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
80% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-moz-transform: translateY(0);
|
||||
-o-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
90% {
|
||||
opacity: .5; }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(145%);
|
||||
-moz-transform: translateY(145%);
|
||||
-o-transform: translateY(145%);
|
||||
transform: translateY(145%); } }
|
||||
|
|
@ -17,20 +17,23 @@ there is one of these running on a single kubernetes-master node.
|
|||
|
||||
By default the Kubernetes APIserver serves HTTP on 2 ports:
|
||||
|
||||
1. Localhost Port
|
||||
- serves HTTP
|
||||
- default is port 8080, change with `--insecure-port` flag.
|
||||
- defaults IP is localhost, change with `--insecure-bind-address` flag.
|
||||
- no authentication or authorization checks in HTTP
|
||||
- protected by need to have host access
|
||||
2. Secure Port
|
||||
- default is port 6443, change with `--secure-port` flag.
|
||||
- default IP is first non-localhost network interface, change with `--bind-address` flag.
|
||||
- serves HTTPS. Set cert with `--tls-cert-file` and key with `--tls-private-key-file` flag.
|
||||
- uses token-file or client-certificate based [authentication](/docs/admin/authentication).
|
||||
- uses policy-based [authorization](/docs/admin/authorization).
|
||||
3. Removed: ReadOnly Port
|
||||
- For security reasons, this had to be removed. Use the [service account](/docs/user-guide/service-accounts) feature instead.
|
||||
1. `Localhost Port`:
|
||||
|
||||
- serves HTTP
|
||||
- default is port 8080, change with `--insecure-port` flag.
|
||||
- defaults IP is localhost, change with `--insecure-bind-address` flag.
|
||||
- no authentication or authorization checks in HTTP
|
||||
- protected by need to have host access
|
||||
2. `Secure Port`:
|
||||
|
||||
- default is port 6443, change with `--secure-port` flag.
|
||||
- default IP is first non-localhost network interface, change with `--bind-address` flag.
|
||||
- serves HTTPS. Set cert with `--tls-cert-file` and key with `--tls-private-key-file` flag.
|
||||
- uses token-file or client-certificate based [authentication](/docs/admin/authentication).
|
||||
- uses policy-based [authorization](/docs/admin/authorization).
|
||||
3. Removed: `ReadOnly Port`
|
||||
|
||||
- For security reasons, this had to be removed. Use the [service account](/docs/user-guide/service-accounts) feature instead.
|
||||
|
||||
## Proxies and Firewall rules
|
||||
|
||||
|
|
@ -39,35 +42,31 @@ on the same machine as the apiserver process. The proxy serves HTTPS protected
|
|||
by Basic Auth on port 443, and proxies to the apiserver on localhost:8080. In
|
||||
these configurations the secure port is typically set to 6443.
|
||||
|
||||
A firewall rule is typically configured to allow external HTTPS access to port 443.
|
||||
A firewall rule is typically configured to allow external HTTPS access to port
|
||||
443.
|
||||
|
||||
The above are defaults and reflect how Kubernetes is deployed to Google Compute Engine using
|
||||
kube-up.sh. Other cloud providers may vary.
|
||||
The above are defaults and reflect how Kubernetes is deployed to Google Compute
|
||||
Engine using `kube-up.sh.` Other cloud providers may vary.
|
||||
|
||||
## Use Cases vs IP:Ports
|
||||
|
||||
There are three differently configured serving ports because there are a
|
||||
variety of uses cases:
|
||||
There are differently configured serving ports to serve a variety of uses cases:
|
||||
|
||||
1. Clients outside of a Kubernetes cluster, such as human running `kubectl`
|
||||
on desktop machine. Currently, accesses the Localhost Port via a proxy (nginx)
|
||||
running on the `kubernetes-master` machine. The proxy can use cert-based authentication
|
||||
or token-based authentication.
|
||||
on a desktop machine. Currently, accesses the Localhost Port via a proxy (nginx)
|
||||
running on the `kubernetes-master` machine. The proxy can use cert-based
|
||||
authentication or token-based authentication.
|
||||
2. Processes running in Containers on Kubernetes that need to read from
|
||||
the apiserver. Currently, these can use a [service account](/docs/user-guide/service-accounts).
|
||||
the apiserver. Currently, these can use a [service account](/docs/user-guide/service-accounts).
|
||||
3. Scheduler and Controller-manager processes, which need to do read-write
|
||||
API operations, using service accounts to avoid the need to be co-located.
|
||||
API operations, using service accounts to avoid the need to be co-located.
|
||||
4. Kubelets, which need to do read-write API operations and are necessarily
|
||||
on different machines than the apiserver. Kubelet uses the Secure Port
|
||||
to get their pods, to find the services that a pod can see, and to
|
||||
write events. Credentials are distributed to kubelets at cluster
|
||||
setup time. Kubelet and kube-proxy can use cert-based authentication or token-based
|
||||
authentication.
|
||||
on different machines than the apiserver. Kubelet uses the Secure Port
|
||||
to get their pods, to find the services that a pod can see, and to
|
||||
write events. Credentials are distributed to kubelets at cluster
|
||||
setup time. Kubelet and kube-proxy can use cert-based authentication or
|
||||
token-based authentication.
|
||||
|
||||
## Expected changes
|
||||
|
||||
- Policy will limit the actions kubelets can do via the authed port.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,13 @@ namespace. In order to enforce integrity of that process, we strongly recommend
|
|||
|
||||
Yes.
|
||||
|
||||
For Kubernetes 1.0, we strongly recommend running the following set of admission control plug-ins (order matters):
|
||||
For Kubernetes >= 1.2.0, we strongly recommend running the following set of admission control plug-ins (order matters):
|
||||
|
||||
```shell
|
||||
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota
|
||||
```
|
||||
|
||||
For Kubernetes >= 1.0.0, we strongly recommend running the following set of admission control plug-ins (order matters):
|
||||
|
||||
```shell
|
||||
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ When using token authentication from an http client the apiserver expects an `Au
|
|||
header with a value of `Bearer SOMETOKEN`.
|
||||
|
||||
**OpenID Connect ID Token** is enabled by passing the following options to the apiserver:
|
||||
|
||||
- `--oidc-issuer-url` (required) tells the apiserver where to connect to the OpenID provider. Only HTTPS scheme will be accepted.
|
||||
- `--oidc-client-id` (required) is used by apiserver to verify the audience of the token.
|
||||
A valid [ID token](http://openid.net/specs/openid-connect-core-1_0.html#IDToken) MUST have this
|
||||
|
|
@ -59,38 +60,47 @@ with a value of `Basic BASE64ENCODED(USER:PASSWORD)`.
|
|||
|
||||
**Keystone authentication** is enabled by passing the `--experimental-keystone-url=<AuthURL>`
|
||||
option to the apiserver during startup. The plugin is implemented in
|
||||
`plugin/pkg/auth/authenticator/request/keystone/keystone.go`.
|
||||
`plugin/pkg/auth/authenticator/password/keystone/keystone.go`.
|
||||
|
||||
For details on how to use keystone to manage projects and users, refer to the
|
||||
[Keystone documentation](http://docs.openstack.org/developer/keystone/). Please note that
|
||||
this plugin is still experimental which means it is subject to changes.
|
||||
|
||||
Please refer to the [discussion](https://github.com/kubernetes/kubernetes/pull/11798#issuecomment-129655212)
|
||||
and the [blueprint](https://github.com/kubernetes/kubernetes/issues/11626) for more details
|
||||
and the [blueprint](https://github.com/kubernetes/kubernetes/issues/11626) for more details.
|
||||
|
||||
## Plugin Development
|
||||
|
||||
We plan for the Kubernetes API server to issue tokens
|
||||
after the user has been (re)authenticated by a *bedrock* authentication
|
||||
provider external to Kubernetes. We plan to make it easy to develop modules
|
||||
that interface between Kubernetes and a bedrock authentication provider (e.g.
|
||||
github.com, google.com, enterprise directory, kerberos, etc.)
|
||||
We plan for the Kubernetes API server to issue tokens after the user has been
|
||||
(re)authenticated by a *bedrock* authentication provider external to Kubernetes.
|
||||
We also plan to make it easy to develop modules that interface between
|
||||
Kubernetes and a bedrock authentication provider (e.g. github.com, google.com,
|
||||
enterprise directory, kerberos, etc.)
|
||||
|
||||
## APPENDIX
|
||||
|
||||
### Creating Certificates
|
||||
|
||||
When using client certificate authentication, you can generate certificates manually or
|
||||
using an existing deployment script.
|
||||
When using client certificate authentication, you can generate certificates
|
||||
using an existing deployment script or manually through `easyrsa` or `openssl.``
|
||||
|
||||
**Deployment script** is implemented at
|
||||
`cluster/saltbase/salt/generate-cert/make-ca-cert.sh`.
|
||||
Execute this script with two parameters. First is the IP address of apiserver, the second is
|
||||
a list of subject alternate names in the form `IP:<ip-address> or DNS:<dns-name>`.
|
||||
The script will generate three files:ca.crt, server.crt and server.key.
|
||||
Finally, add these parameters
|
||||
`--client-ca-file=/srv/kubernetes/ca.crt`
|
||||
`--tls-cert-file=/srv/kubernetes/server.cert`
|
||||
`--tls-private-key-file=/srv/kubernetes/server.key`
|
||||
into apiserver start parameters.
|
||||
#### Using an Existing Deployment Script
|
||||
|
||||
**Using an existing deployment script** is implemented at
|
||||
`cluster/saltbase/salt/generate-cert/make-ca-cert.sh`.
|
||||
|
||||
Execute this script with two parameters. The first is the IP address
|
||||
of apiserver. The second is a list of subject alternate names in the form `IP:<ip-address> or DNS:<dns-name>`.
|
||||
|
||||
The script will generate three files: `ca.crt`, `server.crt`, and `server.key`.
|
||||
|
||||
Finally, add the following parameters into apiserver start parameters:
|
||||
|
||||
- `--client-ca-file=/srv/kubernetes/ca.crt`
|
||||
- `--tls-cert-file=/srv/kubernetes/server.cert`
|
||||
- `--tls-private-key-file=/srv/kubernetes/server.key`
|
||||
|
||||
#### easyrsa
|
||||
|
||||
**easyrsa** can be used to manually generate certificates for your cluster.
|
||||
|
||||
|
|
@ -107,29 +117,34 @@ into apiserver start parameters.
|
|||
(build-server-full [filename]: Generate a keypair and sign locally for a client or server)
|
||||
|
||||
./easyrsa --subject-alt-name="IP:${MASTER_IP}" build-server-full kubernetes-master nopass
|
||||
1. Copy `pki/ca.crt` `pki/issued/kubernetes-master.crt`
|
||||
`pki/private/kubernetes-master.key` to your directory.
|
||||
1. Remember fill the parameters
|
||||
`--client-ca-file=/yourdirectory/ca.crt`
|
||||
`--tls-cert-file=/yourdirectory/server.cert`
|
||||
`--tls-private-key-file=/yourdirectory/server.key`
|
||||
and add these into apiserver start parameters.
|
||||
1. Copy `pki/ca.crt`, `pki/issued/kubernetes-master.crt`, and `pki/private/kubernetes-master.key` to your directory.
|
||||
1. Fill in and add the following parameters into the apiserver start parameters:
|
||||
|
||||
--client-ca-file=/yourdirectory/ca.crt
|
||||
--tls-cert-file=/yourdirectory/server.cert
|
||||
--tls-private-key-file=/yourdirectory/server.key
|
||||
|
||||
#### openssl
|
||||
|
||||
**openssl** can also be use to manually generate certificates for your cluster.
|
||||
|
||||
1. Generate a ca.key with 2048bit
|
||||
`openssl genrsa -out ca.key 2048`
|
||||
1. According to the ca.key generate a ca.crt. (-days set the certificate effective time).
|
||||
`openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt`
|
||||
1. Generate a ca.key with 2048bit:
|
||||
|
||||
openssl genrsa -out ca.key 2048
|
||||
1. According to the ca.key generate a ca.crt (use -days to set the certificate effective time):
|
||||
|
||||
openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt
|
||||
1. Generate a server.key with 2048bit
|
||||
`openssl genrsa -out server.key 2048`
|
||||
1. According to the server.key generate a server.csr.
|
||||
`openssl req -new -key server.key -subj "/CN=${MASTER_IP}" -out server.csr`
|
||||
1. According to the ca.key, ca.crt and server.csr generate the server.crt.
|
||||
`openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
|
||||
-days 10000`
|
||||
|
||||
openssl genrsa -out server.key 2048
|
||||
1. According to the server.key generate a server.csr:
|
||||
|
||||
openssl req -new -key server.key -subj "/CN=${MASTER_IP}" -out server.csr
|
||||
1. According to the ca.key, ca.crt and server.csr generate the server.crt:
|
||||
|
||||
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 10000
|
||||
1. View the certificate.
|
||||
`openssl x509 -noout -text -in ./server.crt`
|
||||
Finally, do not forget fill the same parameters and add parameters into apiserver start parameters.
|
||||
|
||||
openssl x509 -noout -text -in ./server.crt
|
||||
|
||||
Finally, do not forget to fill out and add the same parameters into the apiserver start parameters.
|
||||
|
|
|
|||
|
|
@ -13,31 +13,35 @@ policies. An API call must be allowed by some policy in order to proceed.
|
|||
|
||||
The following implementations are available, and are selected by flag:
|
||||
|
||||
- `--authorization-mode=AlwaysDeny`
|
||||
- `--authorization-mode=AlwaysAllow`
|
||||
- `--authorization-mode=ABAC`
|
||||
- `--authorization-mode=Webhook`
|
||||
|
||||
`AlwaysDeny` blocks all requests (used in tests).
|
||||
`AlwaysAllow` allows all requests; use if you don't need authorization.
|
||||
`ABAC` allows for user-configured authorization policy. ABAC stands for Attribute-Based Access Control.
|
||||
`Webhook` allows for authorization to be driven by a remote service using REST.
|
||||
- `--authorization-mode=AlwaysDeny` blocks all requests (used in tests).
|
||||
- `--authorization-mode=AlwaysAllow` allows all requests; use if you don't
|
||||
need authorization.
|
||||
- `--authorization-mode=ABAC`allows for user-configured authorization policy.
|
||||
ABAC stands for
|
||||
Attribute-Based Access Control.
|
||||
- `--authorization-mode=Webhook` allows for authorization to be driven by a
|
||||
remote service using REST.
|
||||
|
||||
## ABAC Mode
|
||||
|
||||
### Request Attributes
|
||||
|
||||
A request has the following attributes that can be considered for authorization:
|
||||
|
||||
- user (the user-string which a user was authenticated as).
|
||||
- group (the list of group names the authenticated user is a member of).
|
||||
- whether the request is for an API resource.
|
||||
- the request path.
|
||||
- allows authorizing access to miscellaneous endpoints like `/api` or `/healthz` (see [kubectl](#kubectl)).
|
||||
- allows authorizing access to miscellaneous endpoints like `/api` or
|
||||
`/healthz` (see [kubectl](#kubectl)).
|
||||
- the request verb.
|
||||
- API verbs like `get`, `list`, `create`, `update`, `watch`, `delete`, and `deletecollection` are used for API requests
|
||||
- HTTP verbs like `get`, `post`, `put`, and `delete` are used for non-API requests
|
||||
- API verbs like `get`, `list`, `create`, `update`, `watch`, `delete`, and
|
||||
`deletecollection` are used for API requests
|
||||
- HTTP verbs like `get`, `post`, `put`, and `delete` are used for non-API
|
||||
requests
|
||||
- what resource is being accessed (for API requests only)
|
||||
- the namespace of the object being accessed (for namespaced API requests only)
|
||||
- the namespace of the object being accessed (for namespaced API requests
|
||||
only)
|
||||
- the API group being accessed (for API requests only)
|
||||
|
||||
We anticipate adding more attributes to allow finer grained access control and
|
||||
|
|
@ -47,33 +51,33 @@ to assist in policy management.
|
|||
|
||||
For mode `ABAC`, also specify `--authorization-policy-file=SOME_FILENAME`.
|
||||
|
||||
The file format is [one JSON object per line](http://jsonlines.org/). There should be no enclosing list or map, just
|
||||
one map per line.
|
||||
The file format is [one JSON object per line](http://jsonlines.org/). There
|
||||
should be no enclosing list or map, just one map per line.
|
||||
|
||||
Each line is a "policy object". A policy object is a map with the following
|
||||
properties:
|
||||
|
||||
Each line is a "policy object". A policy object is a map with the following properties:
|
||||
- Versioning properties:
|
||||
- `apiVersion`, type string; valid values are "abac.authorization.kubernetes.io/v1beta1". Allows versioning and conversion of the policy format.
|
||||
- `kind`, type string: valid values are "Policy". Allows versioning and conversion of the policy format.
|
||||
|
||||
- `spec` property set to a map with the following properties:
|
||||
- Subject-matching properties:
|
||||
- `user`, type string; the user-string from `--token-auth-file`. If you specify `user`, it must match the username of the authenticated user. `*` matches all requests.
|
||||
- `group`, type string; if you specify `group`, it must match one of the groups of the authenticated user. `*` matches all requests.
|
||||
|
||||
- `readonly`, type boolean, when true, means that the policy only applies to get, list, and watch operations.
|
||||
|
||||
- Resource-matching properties:
|
||||
- `apiGroup`, type string; an API group, such as `extensions`. `*` matches all API groups.
|
||||
- `namespace`, type string; a namespace string. `*` matches all resource requests.
|
||||
- `resource`, type string; a resource, such as `pods`. `*` matches all resource requests.
|
||||
|
||||
- Non-resource-matching properties:
|
||||
- `nonResourcePath`, type string; matches the non-resource request paths (like `/version` and `/apis`). `*` matches all non-resource requests. `/foo/*` matches `/foo/` and all of its subpaths.
|
||||
|
||||
An unset property is the same as a property set to the zero value for its type (e.g. empty string, 0, false).
|
||||
However, unset should be preferred for readability.
|
||||
An unset property is the same as a property set to the zero value for its type
|
||||
(e.g. empty string, 0, false). However, unset should be preferred for
|
||||
readability.
|
||||
|
||||
In the future, policies may be expressed in a JSON format, and managed via a REST interface.
|
||||
In the future, policies may be expressed in a JSON format, and managed via a
|
||||
REST interface.
|
||||
|
||||
### Authorization Algorithm
|
||||
|
||||
|
|
@ -84,23 +88,32 @@ are set to the zero value of its type (e.g. empty string, 0, false).
|
|||
|
||||
A property set to "*" will match any value of the corresponding attribute.
|
||||
|
||||
The tuple of attributes is checked for a match against every policy in the policy file.
|
||||
If at least one line matches the request attributes, then the request is authorized (but may fail later validation).
|
||||
The tuple of attributes is checked for a match against every policy in the
|
||||
policy file. If at least one line matches the request attributes, then the
|
||||
request is authorized (but may fail later validation).
|
||||
|
||||
To permit any user to do something, write a policy with the user property set to "*".
|
||||
To permit a user to do anything, write a policy with the apiGroup, namespace, resource, and nonResourcePath properties set to "*".
|
||||
To permit any user to do something, write a policy with the user property set to
|
||||
"*".
|
||||
|
||||
To permit a user to do anything, write a policy with the apiGroup, namespace,
|
||||
resource, and nonResourcePath properties set to "*".
|
||||
|
||||
### Kubectl
|
||||
|
||||
Kubectl uses the `/api` and `/apis` endpoints of api-server to negotiate client/server versions. To validate objects sent to the API by create/update operations, kubectl queries certain swagger resources. For API version `v1` those would be `/swaggerapi/api/v1` & `/swaggerapi/experimental/v1`.
|
||||
Kubectl uses the `/api` and `/apis` endpoints of api-server to negotiate
|
||||
client/server versions. To validate objects sent to the API by create/update
|
||||
operations, kubectl queries certain swagger resources. For API version `v1`
|
||||
those would be `/swaggerapi/api/v1` & `/swaggerapi/experimental/v1`.
|
||||
|
||||
When using ABAC authorization, those special resources have to be explicitly exposed via the `nonResourcePath` property in a policy (see [examples](#examples) below):
|
||||
When using ABAC authorization, those special resources have to be explicitly
|
||||
exposed via the `nonResourcePath` property in a policy (see [examples](#examples) below):
|
||||
|
||||
* `/api`, `/api/*`, `/apis`, and `/apis/*` for API version negotiation.
|
||||
* `/version` for retrieving the server version via `kubectl version`.
|
||||
* `/swaggerapi/*` for create/update operations.
|
||||
|
||||
To inspect the HTTP calls involved in a specific kubectl operation you can turn up the verbosity:
|
||||
To inspect the HTTP calls involved in a specific kubectl operation you can turn
|
||||
up the verbosity:
|
||||
|
||||
kubectl --v=8 version
|
||||
|
||||
|
|
@ -116,18 +129,22 @@ To inspect the HTTP calls involved in a specific kubectl operation you can turn
|
|||
|
||||
### A quick note on service accounts
|
||||
|
||||
A service account automatically generates a user. The user's name is generated according to the naming convention:
|
||||
A service account automatically generates a user. The user's name is generated
|
||||
according to the naming convention:
|
||||
|
||||
```shell
|
||||
system:serviceaccount:<namespace>:<serviceaccountname>
|
||||
```
|
||||
Creating a new namespace also causes a new service account to be created, of this form:*
|
||||
Creating a new namespace also causes a new service account to be created, of
|
||||
this form:*
|
||||
|
||||
```shell
|
||||
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:
|
||||
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:
|
||||
|
||||
```json
|
||||
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}
|
||||
|
|
@ -137,13 +154,17 @@ The apiserver will need to be restarted to pickup the new policy lines.
|
|||
|
||||
## Webhook Mode
|
||||
|
||||
When specified, mode `Webhook` causes Kubernetes to query an outside REST service when determining user privileges.
|
||||
When specified, mode `Webhook` causes Kubernetes to query an outside REST
|
||||
service when determining user privileges.
|
||||
|
||||
### Configuration File Format
|
||||
|
||||
Mode `Webhook` requires a file for HTTP configuration, specify by the `--authorization-webhook-config-file=SOME_FILENAME` flag.
|
||||
Mode `Webhook` requires a file for HTTP configuration, specify by the
|
||||
`--authorization-webhook-config-file=SOME_FILENAME` flag.
|
||||
|
||||
The configuration file uses the [kubeconfig](/docs/user-guide/kubeconfig-file/) file format. Within the file "users" refers to the API Server webhook and "clusters" refers to the remote service.
|
||||
The configuration file uses the [kubeconfig](/docs/user-guide/kubeconfig-file/)
|
||||
file format. Within the file "users" refers to the API Server webhook and
|
||||
"clusters" refers to the remote service.
|
||||
|
||||
A configuration example which uses HTTPS client auth:
|
||||
|
||||
|
|
@ -173,9 +194,17 @@ contexts:
|
|||
|
||||
### Request Payloads
|
||||
|
||||
When faced with an authorization decision, the API Server POSTs a JSON serialized api.authorization.v1beta1.SubjectAccessReview object describing the action. This object contains fields describing the user attempting to make the request, and either details about the resource being accessed or requests attributes.
|
||||
When faced with an authorization decision, the API Server POSTs a JSON
|
||||
serialized api.authorization.v1beta1.SubjectAccessReview object describing the
|
||||
action. This object contains fields describing the user attempting to make the
|
||||
request, and either details about the resource being accessed or requests
|
||||
attributes.
|
||||
|
||||
Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/api/) as other Kubernetes API objects. Implementers should be aware of loser compatibility promises for beta objects and check the "apiVersion" field of the request to ensure correct deserialization. Additionally, the API Server must enable the `authorization.k8s.io/v1beta1` API extensions group (`--runtime-config=authorization.k8s.io/v1beta1=true`).
|
||||
Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/api/)
|
||||
as other Kubernetes API objects. Implementers should be aware of loser
|
||||
compatibility promises for beta objects and check the "apiVersion" field of the
|
||||
request to ensure correct deserialization. Additionally, the API Server must
|
||||
enable the `authorization.k8s.io/v1beta1` API extensions group (`--runtime-config=authorization.k8s.io/v1beta1=true`).
|
||||
|
||||
An example request body:
|
||||
|
||||
|
|
@ -199,7 +228,9 @@ An example request body:
|
|||
}
|
||||
```
|
||||
|
||||
The remote service is expected to fill the SubjectAccessReviewStatus field of the request and respond to either allow or disallow access. The response body's "spec" field is ignored and may be omitted. A permissive response would return:
|
||||
The remote service is expected to fill the SubjectAccessReviewStatus field of
|
||||
the request and respond to either allow or disallow access. The response body's
|
||||
"spec" field is ignored and may be omitted. A permissive response would return:
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -244,9 +275,15 @@ Access to non-resource paths are sent as:
|
|||
}
|
||||
```
|
||||
|
||||
Non-resource paths include: `/api`, `/apis`, `/metrics`, `/resetMetrics`, `/logs`, `/debug`, `/healthz`, `/swagger-ui/`, `/swaggerapi/`, `/ui`, and `/version.` Clients require access to `/api`, `/api/*/`, `/apis/`, `/apis/*`, `/apis/*/*`, and `/version` to discover what resources and versions are present on the server. Access to other non-resource paths can be disallowed without restricting access to the REST api.
|
||||
Non-resource paths include: `/api`, `/apis`, `/metrics`, `/resetMetrics`,
|
||||
`/logs`, `/debug`, `/healthz`, `/swagger-ui/`, `/swaggerapi/`, `/ui`, and
|
||||
`/version.` Clients require access to `/api`, `/api/*/`, `/apis/`, `/apis/*`,
|
||||
`/apis/*/*`, and `/version` to discover what resources and versions are present
|
||||
on the server. Access to other non-resource paths can be disallowed without
|
||||
restricting access to the REST api.
|
||||
|
||||
For further documentation refer to the authorization.v1beta1 API objects and plugin/pkg/auth/authorizer/webhook/webhook.go.
|
||||
For further documentation refer to the authorization.v1beta1 API objects and
|
||||
plugin/pkg/auth/authorizer/webhook/webhook.go.
|
||||
|
||||
## Plugin Development
|
||||
|
||||
|
|
@ -267,5 +304,5 @@ Authorization plugin code goes in `pkg/auth/authorizer/$MODULENAME`.
|
|||
An authorization module can be completely implemented in go, or can call out
|
||||
to a remote authorization service. Authorization modules can implement
|
||||
their own caching to reduce the cost of repeated authorization calls with the
|
||||
same or similar arguments. Developers should then consider the interaction between
|
||||
caching and revocation of permissions.
|
||||
same or similar arguments. Developers should then consider the interaction
|
||||
between caching and revocation of permissions.
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ Addon objects are created in the "kube-system" namespace.
|
|||
#### DNS
|
||||
|
||||
While the other addons are not strictly required, all Kubernetes
|
||||
clusters should have [cluster DNS](dns.md), as many examples rely on it.
|
||||
clusters should have [cluster DNS](/docs/admin/dns/), as many examples rely on it.
|
||||
|
||||
Cluster DNS is a DNS server, in addition to the other DNS server(s) in your
|
||||
environment, which serves DNS records for Kubernetes services.
|
||||
|
|
@ -88,15 +88,15 @@ about containers in a central database, and provides a UI for browsing that data
|
|||
|
||||
#### Cluster-level Logging
|
||||
|
||||
[Container Logging](/docs/user-guide/monitoring.md) saves container logs
|
||||
[Container Logging](/docs/user-guide/monitoring) saves container logs
|
||||
to a central log store with search/browsing interface. There are two
|
||||
implementations:
|
||||
|
||||
* [Cluster-level logging to Google Cloud Logging](
|
||||
docs/user-guide/logging/#cluster-level-logging-to-google-cloud-logging)
|
||||
/docs/user-guide/logging/#cluster-level-logging-to-google-cloud-logging)
|
||||
|
||||
* [Cluster-level Logging with Elasticsearch and Kibana](
|
||||
docs/user-guide/logging/#cluster-level-logging-with-elasticsearch-and-kibana)
|
||||
/docs/getting-started-guides/logging-elasticsearch/)
|
||||
|
||||
## Node components
|
||||
|
||||
|
|
@ -138,4 +138,3 @@ running.
|
|||
### fluentd
|
||||
|
||||
`fluentd` is a daemon which helps provide [cluster-level logging](#cluster-level-logging).
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@ To avoid running into cluster addon resource issues, when creating a cluster wit
|
|||
* [FluentD with ElasticSearch Plugin](http://releases.k8s.io/{{page.githubbranch}}/cluster/saltbase/salt/fluentd-es/fluentd-es.yaml)
|
||||
* [FluentD with GCP Plugin](http://releases.k8s.io/{{page.githubbranch}}/cluster/saltbase/salt/fluentd-gcp/fluentd-gcp.yaml)
|
||||
|
||||
Heapster's resource limits are set dynamically based on the initial size of your cluster (see [#16185](http://issue.k8s.io/16185) and [#21258](http://issue.k8s.io/21258)). If you find that Heapster is running
|
||||
Heapster's resource limits are set dynamically based on the initial size of your cluster (see [#16185](http://issue.k8s.io/16185)
|
||||
and [#22940](http://issue.k8s.io/22940)). If you find that Heapster is running
|
||||
out of resources, you should adjust the formulas that compute heapster memory request (see those PRs for details).
|
||||
|
||||
For directions on how to detect if addon containers are hitting resource limits, see the [Troubleshooting section of Compute Resources](/docs/user-guide/compute-resources/#troubleshooting).
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ The steps involved are as follows:
|
|||
* [Setting up master-elected Kubernetes scheduler and controller-manager daemons](#master-elected-components)
|
||||
|
||||
Here's what the system should look like when it's finished:
|
||||

|
||||
|
||||
Ready? Let's get started.
|
||||

|
||||
|
||||
## Initial set-up
|
||||
|
||||
|
|
@ -55,11 +54,11 @@ choices. For example, on systemd-based systems (e.g. RHEL, CentOS), you can run
|
|||
If you are extending from a standard Kubernetes installation, the `kubelet` binary should already be present on your system. You can run
|
||||
`which kubelet` to determine if the binary is in fact installed. If it is not installed,
|
||||
you should install the [kubelet binary](https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubelet), the
|
||||
[kubelet init file](http://releases.k8s.io/{{page.githubbranch}}/cluster/saltbase/salt/kubelet/initd) and [high-availability/default-kubelet](/docs/admin/high-availability/default-kubelet)
|
||||
[kubelet init file](http://releases.k8s.io/{{page.githubbranch}}/cluster/saltbase/salt/kubelet/initd) and [default-kubelet](/docs/admin/high-availability/default-kubelet)
|
||||
scripts.
|
||||
|
||||
If you are using monit, you should also install the monit daemon (`apt-get install monit`) and the [high-availability/monit-kubelet](/docs/admin/high-availability/monit-kubelet) and
|
||||
[high-availability/monit-docker](/docs/admin/high-availability/monit-docker) configs.
|
||||
If you are using monit, you should also install the monit daemon (`apt-get install monit`) and the [monit-kubelet](/docs/admin/high-availability/monit-kubelet) and
|
||||
[monit-docker](/docs/admin/high-availability/monit-docker) configs.
|
||||
|
||||
On systemd systems you `systemctl enable kubelet` and `systemctl enable docker`.
|
||||
|
||||
|
|
@ -79,7 +78,7 @@ size of the cluster from three to five nodes. If that is still insufficient, yo
|
|||
### Clustering etcd
|
||||
|
||||
The full details of clustering etcd are beyond the scope of this document, lots of details are given on the
|
||||
[etcd clustering page](https://github.com/coreos/etcd/blob/master/Documentation/clustering.md). This example walks through
|
||||
[etcd clustering page](https://github.com/coreos/etcd/blob/master/Documentation/op-guide/clustering.md). This example walks through
|
||||
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:
|
||||
|
|
@ -94,7 +93,7 @@ The kubelet on each node actively monitors the contents of that directory, and i
|
|||
server from the definition of the pod specified in `etcd.yaml`.
|
||||
|
||||
Note that in `etcd.yaml` you should substitute the token URL you got above for `${DISCOVERY_TOKEN}` on all three machines,
|
||||
and you should substitute a different name (e.g. `node-1`) for ${NODE_NAME} and the correct IP address
|
||||
and you should substitute a different name (e.g. `node-1`) for `${NODE_NAME}` and the correct IP address
|
||||
for `${NODE_IP}` on each machine.
|
||||
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ project](/docs/admin/salt).
|
|||
|
||||
## Multi-tenant support
|
||||
|
||||
* **Resource Quota** ([resource-quota.md](/docs/admin/resource-quota))
|
||||
* **Resource Quota** ([resourcequota/](/docs/admin/resourcequota/))
|
||||
|
||||
## Security
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ may be too small to be useful, but big enough for the waste to be costly over th
|
|||
the cluster operator may want to set limits that a pod must consume at least 20% of the memory and cpu of their
|
||||
average node size in order to provide for more uniform scheduling and to limit waste.
|
||||
|
||||
This example demonstrates how limits can be applied to a Kubernetes namespace to control
|
||||
This example demonstrates how limits can be applied to a Kubernetes [namespace](/docs/admin/namespaces/walkthrough/) to control
|
||||
min/max resource limits per pod. In addition, this example demonstrates how you can
|
||||
apply default resource limits to pods in the absence of an end-user specified value.
|
||||
|
||||
|
|
@ -41,12 +41,17 @@ This example will work in a custom namespace to demonstrate the concepts involve
|
|||
Let's create a new namespace called limit-example:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/limitrange/namespace.yaml
|
||||
namespace "limit-example" created
|
||||
$ kubectl create namespace limit-example
|
||||
namespace "limit-example" created
|
||||
```
|
||||
|
||||
Note that `kubectl` commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands:
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS STATUS AGE
|
||||
default <none> Active 5m
|
||||
limit-example <none> Active 53s
|
||||
NAME STATUS AGE
|
||||
default Active 51s
|
||||
limit-example Active 45s
|
||||
```
|
||||
|
||||
## Step 2: Apply a limit to the namespace
|
||||
|
|
@ -95,36 +100,45 @@ were previously created in a namespace.
|
|||
If a resource (cpu or memory) is being restricted by a limit, the user will get an error at time
|
||||
of creation explaining why.
|
||||
|
||||
Let's first spin up a replication controller that creates a single container pod to demonstrate
|
||||
Let's first spin up a [Deployment](/docs/user-guide/deployments) that creates a single container Pod to demonstrate
|
||||
how default values are applied to each pod.
|
||||
|
||||
```shell
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=limit-example
|
||||
replicationcontroller "nginx" created
|
||||
$ kubectl get pods --namespace=limit-example
|
||||
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
|
||||
deployment "nginx" created
|
||||
```
|
||||
|
||||
```yaml
|
||||
resourceVersion: "127"
|
||||
selfLink: /api/v1/namespaces/limit-example/pods/nginx-aq0mf
|
||||
uid: 51be42a7-7156-11e5-9921-286ed488f785
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
resources:
|
||||
limits:
|
||||
cpu: 300m
|
||||
memory: 200Mi
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 100Mi
|
||||
terminationMessagePath: /dev/termination-log
|
||||
volumeMounts:
|
||||
Note that `kubectl run` creates a Deployment named "nginx" on Kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead.
|
||||
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/kubectl_run/) for more details.
|
||||
The Deployment manages 1 replica of single container Pod. Let's take a look at the Pod it manages. First, find the name of the Pod:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=limit-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-2040093540-s8vzu 1/1 Running 0 11s
|
||||
```
|
||||
|
||||
Let's print this Pod with yaml output format (using `-o yaml` flag), and then `grep` the `resources` field. Note that your pod name will be different.
|
||||
|
||||
``` shell
|
||||
$ kubectl get pods nginx-2040093540-s8vzu --namespace=limit-example -o yaml | grep resources -C 8
|
||||
resourceVersion: "57"
|
||||
selfLink: /api/v1/namespaces/limit-example/pods/nginx-2040093540-ivimu
|
||||
uid: 67b20741-f53b-11e5-b066-64510658e388
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
resources:
|
||||
limits:
|
||||
cpu: 300m
|
||||
memory: 200Mi
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 100Mi
|
||||
terminationMessagePath: /dev/termination-log
|
||||
volumeMounts:
|
||||
```
|
||||
|
||||
Note that our nginx container has picked up the namespace default cpu and memory resource *limits* and *requests*.
|
||||
|
|
@ -141,37 +155,39 @@ Let's create a pod that falls within the allowed limit boundaries.
|
|||
```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
|
||||
```
|
||||
|
||||
```yaml
|
||||
uid: 162a12aa-7157-11e5-9921-286ed488f785
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/google_containers/serve_hostname
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: kubernetes-serve-hostname
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
Now look at the Pod's resources field:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods valid-pod --namespace=limit-example -o yaml | grep -C 6 resources
|
||||
uid: 3b1bfd7a-f53c-11e5-b066-64510658e388
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/google_containers/serve_hostname
|
||||
imagePullPolicy: Always
|
||||
name: kubernetes-serve-hostname
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
```
|
||||
|
||||
Note that this pod specifies explicit resource *limits* and *requests* so it did not pick up the namespace
|
||||
default values.
|
||||
|
||||
Note: The *limits* for CPU resource are not enforced in the default Kubernetes setup on the physical node
|
||||
Note: The *limits* for CPU resource are enforced in the default Kubernetes setup on the physical node
|
||||
that runs the container unless the administrator deploys the kubelet with the folllowing flag:
|
||||
|
||||
```shell
|
||||
$ kubelet --help
|
||||
Usage of kubelet
|
||||
....
|
||||
--cpu-cfs-quota[=false]: Enable CPU CFS quota enforcement for containers that specify CPU limits
|
||||
$ kubelet --cpu-cfs-quota=true ...
|
||||
--cpu-cfs-quota[=true]: Enable CPU CFS quota enforcement for containers that specify CPU limits
|
||||
$ kubelet --cpu-cfs-quota=false ...
|
||||
```
|
||||
|
||||
## Step 4: Cleanup
|
||||
|
|
@ -182,8 +198,8 @@ To remove the resources used by this example, you can just delete the limit-exam
|
|||
$ kubectl delete namespace limit-example
|
||||
namespace "limit-example" deleted
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS STATUS AGE
|
||||
default <none> Active 20m
|
||||
NAME STATUS AGE
|
||||
default Active 12m
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
|
@ -191,4 +207,4 @@ default <none> Active 20m
|
|||
Cluster operators that want to restrict the amount of resources a single container or pod may consume
|
||||
are able to define allowable ranges per Kubernetes namespace. In the absence of any explicit assignments,
|
||||
the Kubernetes system is able to apply default resource *limits* and *requests* if desired in order to
|
||||
constrain the amount of resource a pod consumes on a node.
|
||||
constrain the amount of resource a pod consumes on a node.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
---
|
||||
---
|
||||
|
||||
Kubernetes ships with a default scheduler that is described [here](/docs/admin/kube-scheduler/).
|
||||
If the default scheduler does not suit your needs you can implement your own scheduler.
|
||||
Not just that, you can even run multiple schedulers simultaneously alongside the default
|
||||
scheduler and instruct Kubernetes what scheduler to use for each of your pods. Let's
|
||||
learn how to run multiple schedulers in Kubernetes with an example.
|
||||
|
||||
A detailed description of how to implement a scheduler is outside the scope of this
|
||||
document. Please refer to the kube-scheduler implementation in
|
||||
[plugin/pkg/scheduler](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/plugin/pkg/scheduler)
|
||||
in the Kubernetes source directory for a canonical example.
|
||||
|
||||
### 1. Package the scheduler
|
||||
|
||||
Package your scheduler binary into a container image. For the purposes of this example,
|
||||
let's just use the default scheduler (kube-scheduler) as our second scheduler as well.
|
||||
Clone the [Kubernetes source code from Github](https://github.com/kubernetes/kubernetes)
|
||||
and build the source.
|
||||
|
||||
```shell
|
||||
git clone https://github.com/kubernetes/kubernetes.git
|
||||
cd kubernetes
|
||||
hack/build-go.sh
|
||||
```
|
||||
|
||||
Create a container image containing the kube-scheduler binary. Here is the `Dockerfile`
|
||||
to build the image:
|
||||
|
||||
```docker
|
||||
FROM busybox
|
||||
ADD _output/local/go/bin/kube-scheduler /usr/local/bin/kube-scheduler
|
||||
```
|
||||
|
||||
Save the file as `Dockerfile`, build the image and push it to a registry. This example
|
||||
pushes the image to
|
||||
[Google Container Registry (GCR)](https://cloud.google.com/container-registry/).
|
||||
For more details, please read the GCR
|
||||
[documentation](https://cloud.google.com/container-registry/docs/).
|
||||
|
||||
```shell
|
||||
docker build -t my-kube-scheduler:1.0 .
|
||||
gcloud docker push gcr.io/my-gcp-project/my-kube-scheduler:1.0
|
||||
```
|
||||
|
||||
### 2. Define a Kubernetes Deployment for the scheduler
|
||||
|
||||
Now that we have our scheduler in a container image, we can just create a pod
|
||||
config for it and run it in our Kubernetes cluster. But instead of creating a pod
|
||||
directly in the cluster, let's use a [Deployment](/docs/user-guide/deployments/)
|
||||
for this example. A [Deployment](/docs/user-guide/deployments/) manages a
|
||||
[Replica Set](/docs/user-guide/replicasets/) which in turn manages the pods,
|
||||
thereby making the scheduler resilient to failures. Here is the deployment
|
||||
config. Save it as `my-scheduler.yaml`:
|
||||
|
||||
{% include code.html language="yaml" file="multiple-schedulers/my-scheduler.yaml" ghlink="/docs/admin/multiple-schedulers/my-scheduler.yaml" %}
|
||||
|
||||
An important thing to note here is that the name of the scheduler specified as an
|
||||
argument to the scheduler command in the container spec should be unique. This is the name that is matched against the value of the optional `scheduler.alpha.kubernetes.io/name` annotation on pods, to determine whether this scheduler is responsible for scheduling a particular pod.
|
||||
|
||||
Please see the
|
||||
[kube-scheduler documentation](/docs/admin/kube-scheduler/) for
|
||||
detailed description of other command line arguments.
|
||||
|
||||
### 3. Run the second scheduler in the cluster
|
||||
|
||||
In order to run your scheduler in a Kubernetes cluster, just create the deployment
|
||||
specified in the config above in a Kubernetes cluster:
|
||||
|
||||
```shell
|
||||
kubectl create -f my-scheduler.yaml
|
||||
```
|
||||
|
||||
Verify that the scheduler pod is running:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=kube-system
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
....
|
||||
my-scheduler-lnf4s-4744f 1/1 Running 0 2m
|
||||
...
|
||||
```
|
||||
|
||||
You should see a "Running" my-scheduler pod, in addition to the default kube-scheduler
|
||||
pod in this list.
|
||||
|
||||
### 4. Specify schedulers for pods
|
||||
|
||||
Now that our second scheduler is running, let's create some pods, and direct them to be scheduled by either the default scheduler or the one we just deployed. In order to schedule a given pod using a specific scheduler, we specify the name of the
|
||||
scheduler as an annotation in that pod spec. Let's look at three examples.
|
||||
|
||||
|
||||
1. Pod spec without any scheduler annotation
|
||||
|
||||
{% include code.html language="yaml" file="multiple-schedulers/pod1.yaml" ghlink="/docs/admin/multiple-schedulers/pod1.yaml" %}
|
||||
|
||||
When no scheduler annotation is supplied, the pod is automatically scheduled using the
|
||||
default-scheduler.
|
||||
|
||||
Save this file as `pod1.yaml` and submit it to the Kubernetes cluster.
|
||||
|
||||
```shell
|
||||
kubectl create -f pod1.yaml
|
||||
```
|
||||
2. Pod spec with `default-scheduler` annotation
|
||||
|
||||
{% include code.html language="yaml" file="multiple-schedulers/pod2.yaml" ghlink="/docs/admin/multiple-schedulers/pod2.yaml" %}
|
||||
|
||||
A scheduler is specified by supplying the scheduler name as a value to the annotation
|
||||
with key `scheduler.alpha.kubernetes.io/name`. In this case, we supply the name of the
|
||||
default scheduler which is `default-scheduler`.
|
||||
|
||||
Save this file as `pod2.yaml` and submit it to the Kubernetes cluster.
|
||||
|
||||
```shell
|
||||
kubectl create -f pod2.yaml
|
||||
```
|
||||
3. Pod spec with `my-scheduler` annotation
|
||||
|
||||
{% include code.html language="yaml" file="multiple-schedulers/pod3.yaml" ghlink="/docs/admin/multiple-schedulers/pod3.yaml" %}
|
||||
|
||||
In this case, we specify that this pod should be scheduled using the scheduler that we
|
||||
deployed - `my-scheduler`. Note that the value of the annotation with key
|
||||
`scheduler.alpha.kubernetes.io/name` should match the name supplied to the scheduler
|
||||
command as an argument in the deployment config for the scheduler.
|
||||
|
||||
Save this file as `pod3.yaml` and submit it to the Kubernetes cluster.
|
||||
|
||||
```shell
|
||||
kubectl create -f pod3.yaml
|
||||
```
|
||||
|
||||
Verify that all three pods are running.
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
### Verifying that the pods were scheduled using the desired schedulers
|
||||
|
||||
In order to make it easier to work through these examples, we did not verify that the
|
||||
pods were actually scheduled using the desired schedulers. We can verify that by
|
||||
changing the order of pod and deployment config submissions above. If we submit all the
|
||||
pod configs to a Kubernetes cluster before submitting the scheduler deployment config,
|
||||
we see that the pod `annotation-second-scheduler` remains in "Pending" state forever
|
||||
while the other two pods get scheduled. Once we submit the scheduler deployment config
|
||||
and our new scheduler starts running, the `annotation-second-scheduler` pod gets
|
||||
scheduled as well.
|
||||
|
||||
Alternatively, one could just look at the "Scheduled" entries in the event logs to
|
||||
verify that the pods were scheduled by the desired schedulers.
|
||||
|
||||
```shell
|
||||
kubectl get events
|
||||
```
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
component: scheduler
|
||||
tier: control-plane
|
||||
name: my-scheduler
|
||||
namespace: kube-system
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
component: scheduler
|
||||
tier: control-plane
|
||||
version: second
|
||||
spec:
|
||||
containers:
|
||||
- command: [/usr/local/bin/kube-scheduler, --address=0.0.0.0,
|
||||
--scheduler-name=my-scheduler]
|
||||
image: gcr.io/my-gcp-project/my-kube-scheduler:1.0
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 10251
|
||||
initialDelaySeconds: 15
|
||||
name: kube-second-scheduler
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 10251
|
||||
resources:
|
||||
requests:
|
||||
cpu: '0.1'
|
||||
securityContext:
|
||||
privileged: false
|
||||
volumeMounts: []
|
||||
hostNetwork: false
|
||||
hostPID: false
|
||||
volumes: []
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: no-annotation
|
||||
labels:
|
||||
name: multischeduler-example
|
||||
spec:
|
||||
containers:
|
||||
- name: pod-with-no-annotation-container
|
||||
image: gcr.io/google_containers/pause:2.0
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: annotation-default-scheduler
|
||||
annotations:
|
||||
scheduler.alpha.kubernetes.io/name: default-scheduler
|
||||
labels:
|
||||
name: multischeduler-example
|
||||
spec:
|
||||
containers:
|
||||
- name: pod-with-default-annotation-container
|
||||
image: gcr.io/google_containers/pause:2.0
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: annotation-second-scheduler
|
||||
annotations:
|
||||
scheduler.alpha.kubernetes.io/name: my-scheduler
|
||||
labels:
|
||||
name: multischeduler-example
|
||||
spec:
|
||||
containers:
|
||||
- name: pod-with-second-annotation-container
|
||||
image: gcr.io/google_containers/pause:2.0
|
||||
|
|
@ -0,0 +1,313 @@
|
|||
---
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
Kubernetes 1.2 adds support for running a single cluster in multiple failure zones
|
||||
(GCE calls them simply "zones", AWS calls them "availability zones", here we'll refer to them as "zones").
|
||||
This is a lightweight version of a broader effort for federating multiple
|
||||
Kubernetes clusters together (sometimes referred to by the affectionate
|
||||
nickname ["Ubernetes"](https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/federation.md).
|
||||
Full federation will allow combining separate
|
||||
Kubernetes clusters running in different regions or clouds. However, many
|
||||
users simply want to run a more available Kubernetes cluster in multiple zones
|
||||
of their cloud provider, and this is what the multizone support in 1.2 allows
|
||||
(we nickname this "Ubernetes Lite").
|
||||
|
||||
Multizone support is deliberately limited: a single Kubernetes cluster can run
|
||||
in multiple zones, but only within the same region (and cloud provider). Only
|
||||
GCE and AWS are currently supported automatically (though it is easy to
|
||||
add similar support for other clouds or even bare metal, by simply arranging
|
||||
for the appropriate labels to be added to nodes and volumes).
|
||||
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## Functionality
|
||||
|
||||
When nodes are started, the kubelet automatically adds labels to them with
|
||||
zone information.
|
||||
|
||||
Kubernetes will automatically spread the pods in a replication controller
|
||||
or service across nodes in a single-zone cluster (to reduce the impact of
|
||||
failures.) With multiple-zone clusters, this spreading behaviour is
|
||||
extended across zones (to reduce the impact of zone failures.) (This is
|
||||
achieved via `SelectorSpreadPriority`). This is a best-effort
|
||||
placement, and so if the zones in your cluster are heterogenous
|
||||
(e.g. different numbers of nodes, different types of nodes, or
|
||||
different pod resource requirements), this might prevent perfectly
|
||||
even spreading of your pods across zones. If desired, you can use
|
||||
homogenous zones (same number and types of nodes) to reduce the
|
||||
probability of unequal spreading.
|
||||
|
||||
When persistent volumes are created, the `PersistentVolumeLabel`
|
||||
admission controller automatically adds zone labels to them. The scheduler (via the
|
||||
`VolumeZonePredicate` predicate) will then ensure that pods that claim a
|
||||
given volume are only placed into the same zone as that volume, as volumes
|
||||
cannot be attached across zones.
|
||||
|
||||
## Limitations
|
||||
|
||||
There are some important limitations of the multizone support:
|
||||
|
||||
* We assume that the different zones are located close to each other in the
|
||||
network, so we don't perform any zone-aware routing. In particular, traffic
|
||||
that goes via services might cross zones (even if pods in some pods backing that service
|
||||
exist in the same zone as the client), and this may incur additional latency and cost.
|
||||
|
||||
* Volume zone-affinity will only work with a `PersistentVolume`, and will not
|
||||
work if you directly specify an EBS volume in the pod spec (for example).
|
||||
|
||||
* Clusters cannot span clouds or regions (this functionality will require full
|
||||
federation support).
|
||||
|
||||
* Although your nodes are in multiple zones, kube-up currently builds
|
||||
a single master node by default. While services are highly
|
||||
available and can tolerate the loss of a zone, the control plane is
|
||||
located in a single zone. Users that want a highly available control
|
||||
plane should follow the [high availability](/docs/admin/high-availability) instructions.
|
||||
|
||||
|
||||
## Walkthough
|
||||
|
||||
We're now going to walk through setting up and using a multi-zone
|
||||
cluster on both GCE & AWS. To do so, you bring up a full cluster
|
||||
(specifying `MULTIZONE=1`), and then you add nodes in additional zones
|
||||
by running `kube-up` again (specifying `KUBE_USE_EXISTING_MASTER=true`).
|
||||
|
||||
### Bringing up your cluster
|
||||
|
||||
Create the cluster as normal, but pass MULTIZONE to tell the cluster to manage multiple zones; creating nodes in us-central1-a.
|
||||
|
||||
GCE:
|
||||
|
||||
```shell
|
||||
curl -sS https://get.k8s.io | MULTIZONE=1 KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-a NUM_NODES=3 bash
|
||||
```
|
||||
|
||||
AWS:
|
||||
|
||||
```shell
|
||||
curl -sS https://get.k8s.io | MULTIZONE=1 KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a NUM_NODES=3 bash
|
||||
```
|
||||
|
||||
This step brings up a cluster as normal, still running in a single zone
|
||||
(but `MULTIZONE=1` has enabled multi-zone capabilities).
|
||||
|
||||
### Nodes are labeled
|
||||
|
||||
View the nodes; you can see that they are labeled with zone information.
|
||||
They are all in `us-central1-a` (GCE) or `us-west-2a` (AWS) so far. The
|
||||
labels are `failure-domain.beta.kubernetes.io/region` for the region,
|
||||
and `failure-domain.beta.kubernetes.io/zone` for the zone:
|
||||
|
||||
```shell
|
||||
> kubectl get nodes --show-labels
|
||||
|
||||
|
||||
NAME STATUS AGE LABELS
|
||||
kubernetes-master Ready,SchedulingDisabled 6m beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
|
||||
kubernetes-minion-87j9 Ready 6m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
|
||||
kubernetes-minion-9vlv Ready 6m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
kubernetes-minion-a12q Ready 6m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
|
||||
```
|
||||
|
||||
### Add more nodes in a second zone
|
||||
|
||||
Let's add another set of nodes to the existing cluster, reusing the
|
||||
existing master, running in a different zone (us-central1-b or us-west-2b).
|
||||
We run kube-up again, but by specifying `KUBE_USE_EXISTING_MASTER=1`
|
||||
kube-up will not create a new master, but will reuse one that was previously
|
||||
created instead.
|
||||
|
||||
GCE:
|
||||
|
||||
```shell
|
||||
KUBE_USE_EXISTING_MASTER=true MULTIZONE=1 KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-b NUM_NODES=3 kubernetes/cluster/kube-up.sh
|
||||
```
|
||||
|
||||
On AWS we also need to specify the network CIDR for the additional
|
||||
subnet, along with the master internal IP address:
|
||||
|
||||
```shell
|
||||
KUBE_USE_EXISTING_MASTER=true MULTIZONE=1 KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2b NUM_NODES=3 KUBE_SUBNET_CIDR=172.20.1.0/24 MASTER_INTERNAL_IP=172.20.0.9 kubernetes/cluster/kube-up.sh
|
||||
```
|
||||
|
||||
|
||||
View the nodes again; 3 more nodes should have launched and be tagged
|
||||
in us-central1-b:
|
||||
|
||||
```shell
|
||||
> kubectl get nodes --show-labels
|
||||
|
||||
NAME STATUS AGE LABELS
|
||||
kubernetes-master Ready,SchedulingDisabled 16m beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
|
||||
kubernetes-minion-281d Ready 2m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
|
||||
kubernetes-minion-87j9 Ready 16m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
|
||||
kubernetes-minion-9vlv Ready 16m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
kubernetes-minion-a12q Ready 17m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
|
||||
kubernetes-minion-pp2f Ready 2m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-pp2f
|
||||
kubernetes-minion-wf8i Ready 2m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-wf8i
|
||||
```
|
||||
|
||||
### Volume affinity
|
||||
|
||||
Create a volume (only PersistentVolumes are supported for zone
|
||||
affinity), using the new dynamic volume creation:
|
||||
|
||||
```json
|
||||
kubectl create -f - <<EOF
|
||||
{
|
||||
"kind": "PersistentVolumeClaim",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "claim1",
|
||||
"annotations": {
|
||||
"volume.alpha.kubernetes.io/storage-class": "foo"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
],
|
||||
"resources": {
|
||||
"requests": {
|
||||
"storage": "5Gi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
The PV is also labeled with the zone & region it was created in. For
|
||||
version 1.2, dynamic persistent volumes are always created in the zone
|
||||
of the cluster master (here us-centaral1-a / us-west-2a); this will
|
||||
be improved in a future version (issue [#23330](https://github.com/kubernetes/kubernetes/issues/23330).)
|
||||
|
||||
```shell
|
||||
> kubectl get pv --show-labels
|
||||
NAME CAPACITY ACCESSMODES STATUS CLAIM REASON AGE LABELS
|
||||
pv-gce-mj4gm 5Gi RWO Bound default/claim1 46s failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a
|
||||
```
|
||||
|
||||
So now we will create a pod that uses the persistent volume claim.
|
||||
Because GCE PDs / AWS EBS volumes cannot be attached across zones,
|
||||
this means that this pod can only be created in the same zone as the volume:
|
||||
|
||||
```yaml
|
||||
kubectl create -f - <<EOF
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mypod
|
||||
spec:
|
||||
containers:
|
||||
- name: myfrontend
|
||||
image: nginx
|
||||
volumeMounts:
|
||||
- mountPath: "/var/www/html"
|
||||
name: mypd
|
||||
volumes:
|
||||
- name: mypd
|
||||
persistentVolumeClaim:
|
||||
claimName: claim1
|
||||
EOF
|
||||
```
|
||||
|
||||
Note that the pod was automatically created in the same zone as the volume, as
|
||||
cross-zone attachments are not generally permitted by cloud providers:
|
||||
|
||||
```shell
|
||||
> kubectl describe pod mypod | grep Node
|
||||
Node: kubernetes-minion-9vlv/10.240.0.5
|
||||
> kubectl get node kubernetes-minion-9vlv --show-labels
|
||||
NAME STATUS AGE LABELS
|
||||
kubernetes-minion-9vlv Ready 22m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
```
|
||||
|
||||
### Pods are spread across zones
|
||||
|
||||
Pods in a replication controller or service are automatically spread
|
||||
across zones. First, let's launch more nodes in a third zone:
|
||||
|
||||
GCE:
|
||||
|
||||
```shell
|
||||
KUBE_USE_EXISTING_MASTER=true MULTIZONE=1 KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-f NUM_NODES=3 kubernetes/cluster/kube-up.sh
|
||||
```
|
||||
|
||||
AWS:
|
||||
|
||||
```shell
|
||||
KUBE_USE_EXISTING_MASTER=true MULTIZONE=1 KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2c NUM_NODES=3 KUBE_SUBNET_CIDR=172.20.2.0/24 MASTER_INTERNAL_IP=172.20.0.9 kubernetes/cluster/kube-up.sh
|
||||
```
|
||||
|
||||
Verify that you now have nodes in 3 zones:
|
||||
|
||||
```shell
|
||||
kubectl get nodes --show-labels
|
||||
```
|
||||
|
||||
Create the guestbook-go example, which includes an RC of size 3, running a simple web app:
|
||||
|
||||
```shell
|
||||
find kubernetes/examples/guestbook-go/ -name '*.json' | xargs -I {} kubectl create -f {}
|
||||
```
|
||||
|
||||
The pods should be spread across all 3 zones:
|
||||
|
||||
```shell
|
||||
> kubectl describe pod -l app=guestbook | grep Node
|
||||
Node: kubernetes-minion-9vlv/10.240.0.5
|
||||
Node: kubernetes-minion-281d/10.240.0.8
|
||||
Node: kubernetes-minion-olsh/10.240.0.11
|
||||
|
||||
> kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels
|
||||
NAME STATUS AGE LABELS
|
||||
kubernetes-minion-9vlv Ready 34m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
kubernetes-minion-281d Ready 20m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
|
||||
kubernetes-minion-olsh Ready 3m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-f,kubernetes.io/hostname=kubernetes-minion-olsh
|
||||
```
|
||||
|
||||
|
||||
Load-balancers span all zones in a cluster; the guestbook-go example
|
||||
includes an example load-balanced service:
|
||||
|
||||
```shell
|
||||
> kubectl describe service guestbook | grep LoadBalancer.Ingress
|
||||
LoadBalancer Ingress: 130.211.126.21
|
||||
|
||||
> ip=130.211.126.21
|
||||
|
||||
> curl -s http://${ip}:3000/env | grep HOSTNAME
|
||||
"HOSTNAME": "guestbook-44sep",
|
||||
|
||||
> (for i in `seq 20`; do curl -s http://${ip}:3000/env | grep HOSTNAME; done) | sort | uniq
|
||||
"HOSTNAME": "guestbook-44sep",
|
||||
"HOSTNAME": "guestbook-hum5n",
|
||||
"HOSTNAME": "guestbook-ppm40",
|
||||
```
|
||||
|
||||
The load balancer correctly targets all the pods, even though they are in multiple zones.
|
||||
|
||||
### Shutting down the cluster
|
||||
|
||||
When you're done, clean up:
|
||||
|
||||
GCE:
|
||||
|
||||
```shell
|
||||
KUBERNETES_PROVIDER=gce KUBE_USE_EXISTING_MASTER=true KUBE_GCE_ZONE=us-central1-f kubernetes/cluster/kube-down.sh
|
||||
KUBERNETES_PROVIDER=gce KUBE_USE_EXISTING_MASTER=true KUBE_GCE_ZONE=us-central1-b kubernetes/cluster/kube-down.sh
|
||||
KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-a kubernetes/cluster/kube-down.sh
|
||||
```
|
||||
|
||||
AWS:
|
||||
|
||||
```shell
|
||||
KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2c kubernetes/cluster/kube-down.sh
|
||||
KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2b kubernetes/cluster/kube-down.sh
|
||||
KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a kubernetes/cluster/kube-down.sh
|
||||
```
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
---
|
||||
---
|
||||
|
||||
A Namespace is a mechanism to partition resources created by users into
|
||||
a logically named group.
|
||||
|
||||
## Motivation
|
||||
|
||||
A single cluster should be able to satisfy the needs of multiple users or groups of users (henceforth a 'user community').
|
||||
|
||||
Each user community wants to be able to work in isolation from other communities.
|
||||
|
||||
Each user community has its own:
|
||||
|
||||
1. resources (pods, services, replication controllers, etc.)
|
||||
2. policies (who can or cannot perform actions in their community)
|
||||
3. constraints (this community is allowed this much quota, etc.)
|
||||
|
||||
A cluster operator may create a Namespace for each unique user community.
|
||||
|
||||
The Namespace provides a unique scope for:
|
||||
|
||||
1. named resources (to avoid basic naming collisions)
|
||||
2. delegated management authority to trusted users
|
||||
3. ability to limit community resource consumption
|
||||
|
||||
## Use cases
|
||||
|
||||
1. As a cluster operator, I want to support multiple user communities on a single cluster.
|
||||
2. As a cluster operator, I want to delegate authority to partitions of the cluster to trusted users
|
||||
in those communities.
|
||||
3. As a cluster operator, I want to limit the amount of resources each community can consume in order
|
||||
to limit the impact to other communities using the cluster.
|
||||
4. As a cluster user, I want to interact with resources that are pertinent to my user community in
|
||||
isolation of what other user communities are doing on the cluster.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Look [here](/docs/admin/namespaces/) for an in depth example of namespaces.
|
||||
|
||||
### Viewing namespaces
|
||||
|
||||
You can list the current namespaces in a cluster using:
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS STATUS
|
||||
default <none> Active
|
||||
kube-system <none> Active
|
||||
```
|
||||
|
||||
Kubernetes starts with two initial namespaces:
|
||||
* `default` The default namespace for objects with no other namespace
|
||||
* `kube-system` The namespace for objects created by the Kubernetes system
|
||||
|
||||
You can also get the summary of a specific namespace using:
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces <name>
|
||||
```
|
||||
|
||||
Or you can get detailed information with:
|
||||
|
||||
```shell
|
||||
$ kubectl describe namespaces <name>
|
||||
Name: default
|
||||
Labels: <none>
|
||||
Status: Active
|
||||
|
||||
No resource quota.
|
||||
|
||||
Resource Limits
|
||||
Type Resource Min Max Default
|
||||
---- -------- --- --- ---
|
||||
Container cpu - - 100m
|
||||
```
|
||||
|
||||
Note that these details show both resource quota (if present) as well as resource limit ranges.
|
||||
|
||||
Resource quota tracks aggregate usage of resources in the *Namespace* and allows cluster operators
|
||||
to define *Hard* resource usage limits that a *Namespace* may consume.
|
||||
|
||||
A limit range defines min/max constraints on the amount of resources a single entity can consume in
|
||||
a *Namespace*.
|
||||
|
||||
See [Admission control: Limit Range](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/admission_control_limit_range.md)
|
||||
|
||||
A namespace can be in one of two phases:
|
||||
* `Active` the namespace is in use
|
||||
* `Terminating` the namespace is being deleted, and can not be used for new objects
|
||||
|
||||
See the [design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md#phases) for more details.
|
||||
|
||||
### Creating a new namespace
|
||||
|
||||
To create a new namespace, first create a new YAML file called `my-namespace.yaml` with the contents:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: <insert-namespace-name-here>
|
||||
```
|
||||
|
||||
Note that the name of your namespace must be a DNS compatible label.
|
||||
|
||||
More information on the `finalizers` field can be found in the namespace [design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md#finalizers).
|
||||
|
||||
Then run:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f ./my-namespace.yaml
|
||||
```
|
||||
|
||||
### Working in namespaces
|
||||
|
||||
See [Setting the namespace for a request](/docs/user-guide/namespaces/#setting-the-namespace-for-a-request)
|
||||
and [Setting the namespace preference](/docs/user-guide/namespaces/#setting-the-namespace-preference).
|
||||
|
||||
### Deleting a namespace
|
||||
|
||||
You can delete a namespace with
|
||||
|
||||
```shell
|
||||
$ kubectl delete namespaces <insert-some-namespace-name>
|
||||
```
|
||||
|
||||
**WARNING, this deletes _everything_ under the namespace!**
|
||||
|
||||
This delete is asynchronous, so for a time you will see the namespace in the `Terminating` state.
|
||||
|
||||
## Namespaces and DNS
|
||||
|
||||
When you create a [Service](/docs/user-guide/services), it creates a corresponding [DNS entry](/docs/admin/dns).
|
||||
This entry is of the form `<service-name>.<namespace-name>.svc.cluster.local`, which means
|
||||
that if a container just uses `<service-name>` it will resolve to the service which
|
||||
is local to a namespace. This is useful for using the same configuration across
|
||||
multiple namespaces such as Development, Staging and Production. If you want to reach
|
||||
across namespaces, you need to use the fully qualified domain name (FQDN).
|
||||
|
||||
## Design
|
||||
|
||||
Details of the design of namespaces in Kubernetes, including a [detailed example](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md#example-openshift-origin-managing-a-kubernetes-namespace)
|
||||
can be found in the [namespaces design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md)
|
||||
|
|
@ -1,234 +1,140 @@
|
|||
---
|
||||
---
|
||||
|
||||
Kubernetes _namespaces_ help different projects, teams, or customers to share a Kubernetes cluster.
|
||||
A Namespace is a mechanism to partition resources created by users into
|
||||
a logically named group.
|
||||
|
||||
It does this by providing the following:
|
||||
## Motivation
|
||||
|
||||
1. A scope for [Names](/docs/user-guide/identifiers).
|
||||
2. A mechanism to attach authorization and policy to a subsection of the cluster.
|
||||
A single cluster should be able to satisfy the needs of multiple users or groups of users (henceforth a 'user community').
|
||||
|
||||
Use of multiple namespaces is optional.
|
||||
Each user community wants to be able to work in isolation from other communities.
|
||||
|
||||
This example demonstrates how to use Kubernetes namespaces to subdivide your cluster.
|
||||
Each user community has its own:
|
||||
|
||||
### Step Zero: Prerequisites
|
||||
1. resources (pods, services, replication controllers, etc.)
|
||||
2. policies (who can or cannot perform actions in their community)
|
||||
3. constraints (this community is allowed this much quota, etc.)
|
||||
|
||||
This example assumes the following:
|
||||
A cluster operator may create a Namespace for each unique user community.
|
||||
|
||||
1. You have an [existing Kubernetes cluster](/docs/getting-started-guides/).
|
||||
2. You have a basic understanding of Kubernetes _[pods](/docs/user-guide/pods)_, _[services](/docs/user-guide/services)_, and _[replication controllers](/docs/user-guide/replication-controller)_.
|
||||
The Namespace provides a unique scope for:
|
||||
|
||||
### Step One: Understand the default namespace
|
||||
1. named resources (to avoid basic naming collisions)
|
||||
2. delegated management authority to trusted users
|
||||
3. ability to limit community resource consumption
|
||||
|
||||
By default, a Kubernetes cluster will instantiate a default namespace when provisioning the cluster to hold the default set of pods,
|
||||
services, and replication controllers used by the cluster.
|
||||
## Use cases
|
||||
|
||||
Assuming you have a fresh cluster, you can introspect the available namespace's by doing the following:
|
||||
1. As a cluster operator, I want to support multiple user communities on a single cluster.
|
||||
2. As a cluster operator, I want to delegate authority to partitions of the cluster to trusted users
|
||||
in those communities.
|
||||
3. As a cluster operator, I want to limit the amount of resources each community can consume in order
|
||||
to limit the impact to other communities using the cluster.
|
||||
4. As a cluster user, I want to interact with resources that are pertinent to my user community in
|
||||
isolation of what other user communities are doing on the cluster.
|
||||
|
||||
## Viewing namespaces
|
||||
|
||||
You can list the current namespaces in a cluster using:
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS
|
||||
default <none>
|
||||
NAME LABELS STATUS
|
||||
default <none> Active
|
||||
kube-system <none> Active
|
||||
```
|
||||
|
||||
### Step Two: Create new namespaces
|
||||
Kubernetes starts with two initial namespaces:
|
||||
* `default` The default namespace for objects with no other namespace
|
||||
* `kube-system` The namespace for objects created by the Kubernetes system
|
||||
|
||||
For this exercise, we will create two additional Kubernetes namespaces to hold our content.
|
||||
|
||||
Let's imagine a scenario where an organization is using a shared Kubernetes cluster for development and production use cases.
|
||||
|
||||
The development team would like to maintain a space in the cluster where they can get a view on the list of pods, services, and replication controllers
|
||||
they use to build and run their application. In this space, Kubernetes resources come and go, and the restrictions on who can or cannot modify resources
|
||||
are relaxed to enable agile development.
|
||||
|
||||
The operations team would like to maintain a space in the cluster where they can enforce strict procedures on who can or cannot manipulate the set of
|
||||
pods, services, and replication controllers that run the production site.
|
||||
|
||||
One pattern this organization could follow is to partition the Kubernetes cluster into two namespaces: development and production.
|
||||
|
||||
Let's create two new namespaces to hold our work.
|
||||
|
||||
Use the file [`namespace-dev.json`](/docs/admin/namespaces/namespace-dev.json) which describes a development namespace:
|
||||
|
||||
{% include code.html language="json" file="namespace-dev.json" ghlink="/docs/admin/namespaces/namespace-dev.json" %}
|
||||
|
||||
Create the development namespace using kubectl.
|
||||
You can also get the summary of a specific namespace using:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/namespaces/namespace-dev.json
|
||||
$ kubectl get namespaces <name>
|
||||
```
|
||||
|
||||
And then lets create the production namespace using kubectl.
|
||||
Or you can get detailed information with:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/namespaces/namespace-prod.json
|
||||
$ kubectl describe namespaces <name>
|
||||
Name: default
|
||||
Labels: <none>
|
||||
Status: Active
|
||||
|
||||
No resource quota.
|
||||
|
||||
Resource Limits
|
||||
Type Resource Min Max Default
|
||||
---- -------- --- --- ---
|
||||
Container cpu - - 100m
|
||||
```
|
||||
|
||||
To be sure things are right, let's list all of the namespaces in our cluster.
|
||||
Note that these details show both resource quota (if present) as well as resource limit ranges.
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS STATUS
|
||||
default <none> Active
|
||||
development name=development Active
|
||||
production name=production Active
|
||||
```
|
||||
Resource quota tracks aggregate usage of resources in the *Namespace* and allows cluster operators
|
||||
to define *Hard* resource usage limits that a *Namespace* may consume.
|
||||
|
||||
### Step Three: Create pods in each namespace
|
||||
A limit range defines min/max constraints on the amount of resources a single entity can consume in
|
||||
a *Namespace*.
|
||||
|
||||
A Kubernetes namespace provides the scope for pods, services, and replication controllers in the cluster.
|
||||
See [Admission control: Limit Range](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/admission_control_limit_range.md)
|
||||
|
||||
Users interacting with one namespace do not see the content in another namespace.
|
||||
A namespace can be in one of two phases:
|
||||
* `Active` the namespace is in use
|
||||
* `Terminating` the namespace is being deleted, and can not be used for new objects
|
||||
|
||||
To demonstrate this, let's spin up a simple replication controller and pod in the development namespace.
|
||||
See the [design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md#phases) for more details.
|
||||
|
||||
We first check what is the current context:
|
||||
## Creating a new namespace
|
||||
|
||||
To create a new namespace, first create a new YAML file called `my-namespace.yaml` with the contents:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: REDACTED
|
||||
server: https://130.211.122.180
|
||||
name: lithe-cocoa-92103_kubernetes
|
||||
contexts:
|
||||
- context:
|
||||
cluster: lithe-cocoa-92103_kubernetes
|
||||
user: lithe-cocoa-92103_kubernetes
|
||||
name: lithe-cocoa-92103_kubernetes
|
||||
current-context: lithe-cocoa-92103_kubernetes
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: lithe-cocoa-92103_kubernetes
|
||||
user:
|
||||
client-certificate-data: REDACTED
|
||||
client-key-data: REDACTED
|
||||
token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
|
||||
- name: lithe-cocoa-92103_kubernetes-basic-auth
|
||||
user:
|
||||
password: h5M0FtUUIflBSdI7
|
||||
username: admin
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: <insert-namespace-name-here>
|
||||
```
|
||||
|
||||
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.
|
||||
Note that the name of your namespace must be a DNS compatible label.
|
||||
|
||||
More information on the `finalizers` field can be found in the namespace [design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md#finalizers).
|
||||
|
||||
Then run:
|
||||
|
||||
```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
|
||||
$ kubectl create -f ./my-namespace.yaml
|
||||
```
|
||||
|
||||
The above commands provided two request contexts you can alternate against depending on what namespace you
|
||||
wish to work against.
|
||||
## Working in namespaces
|
||||
|
||||
Let's switch to operate in the development namespace.
|
||||
See [Setting the namespace for a request](/docs/user-guide/namespaces/#setting-the-namespace-for-a-request)
|
||||
and [Setting the namespace preference](/docs/user-guide/namespaces/#setting-the-namespace-preference).
|
||||
|
||||
## Deleting a namespace
|
||||
|
||||
You can delete a namespace with
|
||||
|
||||
```shell
|
||||
$ kubectl config use-context dev
|
||||
$ kubectl delete namespaces <insert-some-namespace-name>
|
||||
```
|
||||
|
||||
You can verify your current context by doing the following:
|
||||
**WARNING, this deletes _everything_ under the namespace!**
|
||||
|
||||
```shell
|
||||
$ kubectl config view
|
||||
```
|
||||
This delete is asynchronous, so for a time you will see the namespace in the `Terminating` state.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: REDACTED
|
||||
server: https://130.211.122.180
|
||||
name: lithe-cocoa-92103_kubernetes
|
||||
contexts:
|
||||
- context:
|
||||
cluster: lithe-cocoa-92103_kubernetes
|
||||
namespace: development
|
||||
user: lithe-cocoa-92103_kubernetes
|
||||
name: dev
|
||||
- context:
|
||||
cluster: lithe-cocoa-92103_kubernetes
|
||||
user: 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
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: lithe-cocoa-92103_kubernetes
|
||||
user:
|
||||
client-certificate-data: REDACTED
|
||||
client-key-data: REDACTED
|
||||
token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
|
||||
- name: lithe-cocoa-92103_kubernetes-basic-auth
|
||||
user:
|
||||
password: h5M0FtUUIflBSdI7
|
||||
username: admin
|
||||
```
|
||||
## Namespaces and DNS
|
||||
|
||||
At this point, all requests we make to the Kubernetes cluster from the command line are scoped to the development namespace.
|
||||
When you create a [Service](/docs/user-guide/services), it creates a corresponding [DNS entry](/docs/admin/dns).
|
||||
This entry is of the form `<service-name>.<namespace-name>.svc.cluster.local`, which means
|
||||
that if a container just uses `<service-name>` it will resolve to the service which
|
||||
is local to a namespace. This is useful for using the same configuration across
|
||||
multiple namespaces such as Development, Staging and Production. If you want to reach
|
||||
across namespaces, you need to use the fully qualified domain name (FQDN).
|
||||
|
||||
Let's create some content.
|
||||
## Design
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
```shell
|
||||
$ kubectl config use-context prod
|
||||
```
|
||||
|
||||
The production namespace should be empty.
|
||||
|
||||
```shell
|
||||
$ kubectl get rc
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
```
|
||||
|
||||
Production likes to run cattle, so let's create some cattle pods.
|
||||
|
||||
```shell
|
||||
$ kubectl run cattle --image=kubernetes/serve_hostname --replicas=5
|
||||
|
||||
$ kubectl get rc
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
cattle cattle kubernetes/serve_hostname run=cattle 5
|
||||
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
cattle-97rva 1/1 Running 0 12s
|
||||
cattle-i9ojn 1/1 Running 0 12s
|
||||
cattle-qj3yv 1/1 Running 0 12s
|
||||
cattle-yc7vn 1/1 Running 0 12s
|
||||
cattle-zz7ea 1/1 Running 0 12s
|
||||
```
|
||||
|
||||
At this point, it should be clear that the resources users create in one namespace are hidden from the other namespace.
|
||||
|
||||
As the policy support in Kubernetes evolves, we will extend this scenario to show how you can provide different
|
||||
authorization rules for each namespace.
|
||||
Details of the design of namespaces in Kubernetes, including a [detailed example](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md#example-openshift-origin-managing-a-kubernetes-namespace)
|
||||
can be found in the [namespaces design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
---
|
||||
---
|
||||
|
||||
Kubernetes _namespaces_ help different projects, teams, or customers to share a Kubernetes cluster.
|
||||
|
||||
It does this by providing the following:
|
||||
|
||||
1. A scope for [Names](/docs/user-guide/identifiers/).
|
||||
2. A mechanism to attach authorization and policy to a subsection of the cluster.
|
||||
|
||||
Use of multiple namespaces is optional.
|
||||
|
||||
This example demonstrates how to use Kubernetes namespaces to subdivide your cluster.
|
||||
|
||||
### Step Zero: Prerequisites
|
||||
|
||||
This example assumes the following:
|
||||
|
||||
1. You have an [existing Kubernetes cluster](/docs/getting-started-guides/).
|
||||
2. You have a basic understanding of Kubernetes _[Pods](/docs/user-guide/pods/)_, _[Services](/docs/user-guide/services/)_, and _[Deployments](/docs/user-guide/deployments/)_.
|
||||
|
||||
### Step One: Understand the default namespace
|
||||
|
||||
By default, a Kubernetes cluster will instantiate a default namespace when provisioning the cluster to hold the default set of Pods,
|
||||
Services, and Deployments used by the cluster.
|
||||
|
||||
Assuming you have a fresh cluster, you can introspect the available namespace's by doing the following:
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces
|
||||
NAME STATUS AGE
|
||||
default Active 13m
|
||||
```
|
||||
|
||||
### Step Two: Create new namespaces
|
||||
|
||||
For this exercise, we will create two additional Kubernetes namespaces to hold our content.
|
||||
|
||||
Let's imagine a scenario where an organization is using a shared Kubernetes cluster for development and production use cases.
|
||||
|
||||
The development team would like to maintain a space in the cluster where they can get a view on the list of Pods, Services, and Deployments
|
||||
they use to build and run their application. In this space, Kubernetes resources come and go, and the restrictions on who can or cannot modify resources
|
||||
are relaxed to enable agile development.
|
||||
|
||||
The operations team would like to maintain a space in the cluster where they can enforce strict procedures on who can or cannot manipulate the set of
|
||||
Pods, Services, and Deployments that run the production site.
|
||||
|
||||
One pattern this organization could follow is to partition the Kubernetes cluster into two namespaces: development and production.
|
||||
|
||||
Let's create two new namespaces to hold our work.
|
||||
|
||||
Use the file [`namespace-dev.json`](/docs/admin/namespaces/namespace-dev.json) which describes a development namespace:
|
||||
|
||||
{% include code.html language="json" file="namespace-dev.json" ghlink="/docs/admin/namespaces/namespace-dev.json" %}
|
||||
|
||||
Create the development namespace using kubectl.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/namespaces/namespace-dev.json
|
||||
```
|
||||
|
||||
And then lets create the production namespace using kubectl.
|
||||
|
||||
```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.
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces --show-labels
|
||||
NAME STATUS AGE LABELS
|
||||
default Active 32m <none>
|
||||
development Active 29s name=development
|
||||
production Active 23s name=production
|
||||
```
|
||||
|
||||
### Step Three: Create pods in each namespace
|
||||
|
||||
A Kubernetes namespace provides the scope for Pods, Services, and Deployments in the cluster.
|
||||
|
||||
Users interacting with one namespace do not see the content in another namespace.
|
||||
|
||||
To demonstrate this, let's spin up a simple Deployment and Pods in the development namespace.
|
||||
|
||||
We first check what is the current context:
|
||||
|
||||
```shell
|
||||
$ kubectl config view
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: REDACTED
|
||||
server: https://130.211.122.180
|
||||
name: lithe-cocoa-92103_kubernetes
|
||||
contexts:
|
||||
- context:
|
||||
cluster: lithe-cocoa-92103_kubernetes
|
||||
user: lithe-cocoa-92103_kubernetes
|
||||
name: lithe-cocoa-92103_kubernetes
|
||||
current-context: lithe-cocoa-92103_kubernetes
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: lithe-cocoa-92103_kubernetes
|
||||
user:
|
||||
client-certificate-data: REDACTED
|
||||
client-key-data: REDACTED
|
||||
token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
|
||||
- name: lithe-cocoa-92103_kubernetes-basic-auth
|
||||
user:
|
||||
password: h5M0FtUUIflBSdI7
|
||||
username: admin
|
||||
|
||||
$ kubectl config current-context
|
||||
lithe-cocoa-92103_kubernetes
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
```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.
|
||||
|
||||
Let's switch to operate in the development namespace.
|
||||
|
||||
```shell
|
||||
$ kubectl config use-context dev
|
||||
```
|
||||
|
||||
You can verify your current context by doing the following:
|
||||
|
||||
```shell
|
||||
$ kubectl config current-context
|
||||
dev
|
||||
```
|
||||
|
||||
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 deployment whose replica size is 2 that is running the pod called snowflake with a basic container that just serves the hostname.
|
||||
Note that `kubectl run` creates deployments only on kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead.
|
||||
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/kubectl_run/) for more details.
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
snowflake 2 2 2 2 2m
|
||||
|
||||
$ kubectl get pods -l run=snowflake
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
snowflake-3968820950-9dgr8 1/1 Running 0 2m
|
||||
snowflake-3968820950-vgc4n 1/1 Running 0 2m
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
```shell
|
||||
$ kubectl config use-context prod
|
||||
```
|
||||
|
||||
The production namespace should be empty, and the following commands should return nothing.
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment
|
||||
$ kubectl get pods
|
||||
```
|
||||
|
||||
Production likes to run cattle, so let's create some cattle pods.
|
||||
|
||||
```shell
|
||||
$ kubectl run cattle --image=kubernetes/serve_hostname --replicas=5
|
||||
|
||||
$ kubectl get deployment
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
cattle 5 5 5 5 10s
|
||||
|
||||
kubectl get pods -l run=cattle
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
cattle-2263376956-41xy6 1/1 Running 0 34s
|
||||
cattle-2263376956-kw466 1/1 Running 0 34s
|
||||
cattle-2263376956-n4v97 1/1 Running 0 34s
|
||||
cattle-2263376956-p5p3i 1/1 Running 0 34s
|
||||
cattle-2263376956-sxpth 1/1 Running 0 34s
|
||||
```
|
||||
|
||||
At this point, it should be clear that the resources users create in one namespace are hidden from the other namespace.
|
||||
|
||||
As the policy support in Kubernetes evolves, we will extend this scenario to show how you can provide different
|
||||
authorization rules for each namespace.
|
||||
|
|
@ -154,6 +154,15 @@ Follow the "With Linux Bridge devices" section of [this very nice
|
|||
tutorial](http://blog.oddbit.com/2014/08/11/four-ways-to-connect-a-docker/) from
|
||||
Lars Kellogg-Stedman.
|
||||
|
||||
### Weave Net from Weaveworks
|
||||
|
||||
[Weave Net](https://www.weave.works/documentation/net-1-5-0-introducing-weave/) is a
|
||||
resilient and simple to use network for Kubernetes and its hosted applications.
|
||||
Weave Net runs as a [CNI plug-in](https://www.weave.works/documentation/net-1-5-0-cni-plugin/)
|
||||
or stand-alone. In either version, it doesn’t require any configuration or extra code
|
||||
to run, and in both cases, the network provides one IP address per pod - as is standard for Kubernetes.
|
||||
|
||||
|
||||
### Flannel
|
||||
|
||||
[Flannel](https://github.com/coreos/flannel#flannel) is a very simple overlay
|
||||
|
|
@ -167,10 +176,6 @@ people have reported success with Flannel and Kubernetes.
|
|||
complicated way to build an overlay network. This is endorsed by several of the
|
||||
"Big Shops" for networking.
|
||||
|
||||
### Weave
|
||||
|
||||
[Weave](https://github.com/zettio/weave) is yet another way to build an overlay
|
||||
network, primarily aiming at Docker integration.
|
||||
|
||||
### Calico
|
||||
|
||||
|
|
@ -179,7 +184,11 @@ IPs.
|
|||
|
||||
### Romana
|
||||
|
||||
[Romana](https://romana.io) is an open source software defined networking (SDN) solution that lets you deploy Kubernetes without an overlay network.
|
||||
[Romana](http://romana.io) is an open source software defined networking (SDN) solution that lets you deploy Kubernetes without an overlay network.
|
||||
|
||||
### Contiv
|
||||
|
||||
[Contiv](https://github.com/contiv/netplugin) provides configurable networking (native l3 using BGP, overlay using vxlan, classic l2, or Cisco-SDN/ACI) for various use cases. [Contiv](http://contiv.io) is all open sourced.
|
||||
|
||||
## Other reading
|
||||
|
||||
|
|
|
|||
|
|
@ -1,154 +0,0 @@
|
|||
---
|
||||
---
|
||||
|
||||
When several users or teams share a cluster with a fixed number of nodes,
|
||||
there is a concern that one team could use more than its fair share of resources.
|
||||
|
||||
Resource quotas are a tool for administrators to address this concern. Resource quotas
|
||||
work like this:
|
||||
|
||||
- Different teams work in different namespaces. Currently this is voluntary, but
|
||||
support for making this mandatory via ACLs is planned.
|
||||
- The administrator creates a Resource Quota for each namespace.
|
||||
- Users put compute resource requests on their pods. The sum of all resource requests across
|
||||
all pods in the same namespace must not exceed any hard resource limit in any Resource Quota
|
||||
document for the namespace. Note that we used to verify Resource Quota by taking the sum of
|
||||
resource limits of the pods, but this was altered to use resource requests. Backwards compatibility
|
||||
for those pods previously created is preserved because pods that only specify a resource limit have
|
||||
their resource requests defaulted to match their defined limits. The user is only charged for the
|
||||
resources they request in the Resource Quota versus their limits because the request is the minimum
|
||||
amount of resource guaranteed by the cluster during scheduling. For more information on over commit,
|
||||
see [compute-resources](/docs/user-guide/compute-resources).
|
||||
- If creating a pod would cause the namespace to exceed any of the limits specified in the
|
||||
the Resource Quota for that namespace, then the request will fail with HTTP status
|
||||
code `403 FORBIDDEN`.
|
||||
- If quota is enabled in a namespace and the user does not specify *requests* on the pod for each
|
||||
of the resources for which quota is enabled, then the POST of the pod will fail with HTTP
|
||||
status code `403 FORBIDDEN`. Hint: Use the LimitRange admission controller to force default
|
||||
values of *limits* (then resource *requests* would be equal to *limits* by default, see
|
||||
[admission controller](/docs/admin/admission-controllers)) before the quota is checked to avoid this problem.
|
||||
|
||||
Examples of policies that could be created using namespaces and quotas are:
|
||||
|
||||
- In a cluster with a capacity of 32 GiB RAM, and 16 cores, let team A use 20 Gib and 10 cores,
|
||||
let B use 10GiB and 4 cores, and hold 2GiB and 2 cores in reserve for future allocation.
|
||||
- Limit the "testing" namespace to using 1 core and 1GiB RAM. Let the "production" namespace
|
||||
use any amount.
|
||||
|
||||
In the case where the total capacity of the cluster is less than the sum of the quotas of the namespaces,
|
||||
there may be contention for resources. This is handled on a first-come-first-served basis.
|
||||
|
||||
Neither contention nor changes to quota will affect already-running pods.
|
||||
|
||||
## Enabling Resource Quota
|
||||
|
||||
Resource Quota support is enabled by default for many Kubernetes distributions. It is
|
||||
enabled when the apiserver `--admission-control=` flag has `ResourceQuota` as
|
||||
one of its arguments.
|
||||
|
||||
Resource Quota is enforced in a particular namespace when there is a
|
||||
`ResourceQuota` object in that namespace. There should be at most one
|
||||
`ResourceQuota` object in a namespace.
|
||||
|
||||
## Compute Resource Quota
|
||||
|
||||
The total sum of [compute resources](/docs/user-guide/compute-resources) requested by pods
|
||||
in a namespace can be limited. The following compute resource types are supported:
|
||||
|
||||
| ResourceName | Description |
|
||||
| ------------ | ----------- |
|
||||
| cpu | Total cpu requests of containers |
|
||||
| memory | Total memory requests of containers
|
||||
|
||||
For example, `cpu` quota sums up the `resources.requests.cpu` fields of every
|
||||
container of every pod in the namespace, and enforces a maximum on that sum.
|
||||
|
||||
## Object Count Quota
|
||||
|
||||
The number of objects of a given type can be restricted. The following types
|
||||
are supported:
|
||||
|
||||
| ResourceName | Description |
|
||||
| ------------ | ----------- |
|
||||
| pods | Total number of pods |
|
||||
| services | Total number of services |
|
||||
| replicationcontrollers | Total number of replication controllers |
|
||||
| resourcequotas | Total number of [resource quotas](/docs/admin/admission-controllers/#resourcequota) |
|
||||
| secrets | Total number of secrets |
|
||||
| persistentvolumeclaims | Total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) |
|
||||
|
||||
For example, `pods` quota counts and enforces a maximum on the number of `pods`
|
||||
created in a single namespace.
|
||||
|
||||
You might want to set a pods quota on a namespace
|
||||
to avoid the case where a user creates many small pods and exhausts the cluster's
|
||||
supply of Pod IPs.
|
||||
|
||||
## Viewing and Setting Quotas
|
||||
|
||||
Kubectl supports creating, updating, and viewing quotas:
|
||||
|
||||
```shell
|
||||
$ kubectl namespace myspace
|
||||
$ cat <<EOF > quota.json
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ResourceQuota",
|
||||
"metadata": {
|
||||
"name": "quota"
|
||||
},
|
||||
"spec": {
|
||||
"hard": {
|
||||
"memory": "1Gi",
|
||||
"cpu": "20",
|
||||
"pods": "10",
|
||||
"services": "5",
|
||||
"replicationcontrollers":"20",
|
||||
"resourcequotas":"1"
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
$ kubectl create -f ./quota.json
|
||||
$ kubectl get quota
|
||||
NAME
|
||||
quota
|
||||
$ kubectl describe quota quota
|
||||
Name: quota
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0m 20
|
||||
memory 0 1Gi
|
||||
pods 5 10
|
||||
replicationcontrollers 5 20
|
||||
resourcequotas 1 1
|
||||
services 3 5
|
||||
```
|
||||
|
||||
## Quota and Cluster Capacity
|
||||
|
||||
Resource Quota objects are independent of the Cluster Capacity. They are
|
||||
expressed in absolute units. So, if you add nodes to your cluster, this does *not*
|
||||
automatically give each namespace the ability to consume more resources.
|
||||
|
||||
Sometimes more complex policies may be desired, such as:
|
||||
|
||||
- proportionally divide total cluster resources among several teams.
|
||||
- allow each tenant to grow resource usage as needed, but have a generous
|
||||
limit to prevent accidental resource exhaustion.
|
||||
- detect demand from one namespace, add nodes, and increase quota.
|
||||
|
||||
Such policies could be implemented using ResourceQuota as a building-block, by
|
||||
writing a 'controller' which watches the quota usage and adjusts the quota
|
||||
hard limits of each namespace according to other signals.
|
||||
|
||||
Note that resource quota divides up aggregate cluster resources, but it creates no
|
||||
restrictions around nodes: pods from several namespaces may run on the same node.
|
||||
|
||||
## Example
|
||||
|
||||
See a [detailed example for how to use resource quota](/docs/admin/resourcequota/).
|
||||
|
||||
## Read More
|
||||
|
||||
See [ResourceQuota design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/admission_control_resource_quota.md) for more information.
|
||||
|
|
@ -1,156 +1,154 @@
|
|||
---
|
||||
---
|
||||
|
||||
This example demonstrates how [resource quota](/docs/admin/admission-controllers/#resourcequota) and
|
||||
[limitsranger](/docs/admin/admission-controllers/#limitranger) can be applied to a Kubernetes namespace.
|
||||
When several users or teams share a cluster with a fixed number of nodes,
|
||||
there is a concern that one team could use more than its fair share of resources.
|
||||
|
||||
Resource quotas are a tool for administrators to address this concern. Resource quotas
|
||||
work like this:
|
||||
|
||||
- Different teams work in different namespaces. Currently this is voluntary, but
|
||||
support for making this mandatory via ACLs is planned.
|
||||
- The administrator creates a Resource Quota for each namespace.
|
||||
- Users put compute resource requests on their pods. The sum of all resource requests across
|
||||
all pods in the same namespace must not exceed any hard resource limit in any Resource Quota
|
||||
document for the namespace. Note that we used to verify Resource Quota by taking the sum of
|
||||
resource limits of the pods, but this was altered to use resource requests. Backwards compatibility
|
||||
for those pods previously created is preserved because pods that only specify a resource limit have
|
||||
their resource requests defaulted to match their defined limits. The user is only charged for the
|
||||
resources they request in the Resource Quota versus their limits because the request is the minimum
|
||||
amount of resource guaranteed by the cluster during scheduling. For more information on over commit,
|
||||
see [compute-resources](/docs/user-guide/compute-resources).
|
||||
- If creating a pod would cause the namespace to exceed any of the limits specified in the
|
||||
the Resource Quota for that namespace, then the request will fail with HTTP status
|
||||
code `403 FORBIDDEN`.
|
||||
- If quota is enabled in a namespace and the user does not specify *requests* on the pod for each
|
||||
of the resources for which quota is enabled, then the POST of the pod will fail with HTTP
|
||||
status code `403 FORBIDDEN`. Hint: Use the LimitRange admission controller to force default
|
||||
values of *limits* (then resource *requests* would be equal to *limits* by default, see
|
||||
[admission controller](/docs/admin/admission-controllers)) before the quota is checked to avoid this problem.
|
||||
|
||||
Examples of policies that could be created using namespaces and quotas are:
|
||||
|
||||
- In a cluster with a capacity of 32 GiB RAM, and 16 cores, let team A use 20 Gib and 10 cores,
|
||||
let B use 10GiB and 4 cores, and hold 2GiB and 2 cores in reserve for future allocation.
|
||||
- Limit the "testing" namespace to using 1 core and 1GiB RAM. Let the "production" namespace
|
||||
use any amount.
|
||||
|
||||
In the case where the total capacity of the cluster is less than the sum of the quotas of the namespaces,
|
||||
there may be contention for resources. This is handled on a first-come-first-served basis.
|
||||
|
||||
Neither contention nor changes to quota will affect already-running pods.
|
||||
|
||||
## Enabling Resource Quota
|
||||
|
||||
Resource Quota support is enabled by default for many Kubernetes distributions. It is
|
||||
enabled when the apiserver `--admission-control=` flag has `ResourceQuota` as
|
||||
one of its arguments.
|
||||
|
||||
Resource Quota is enforced in a particular namespace when there is a
|
||||
`ResourceQuota` object in that namespace. There should be at most one
|
||||
`ResourceQuota` object in a namespace.
|
||||
|
||||
## Compute Resource Quota
|
||||
|
||||
The total sum of [compute resources](/docs/user-guide/compute-resources) requested by pods
|
||||
in a namespace can be limited. The following compute resource types are supported:
|
||||
|
||||
| ResourceName | Description |
|
||||
| ------------ | ----------- |
|
||||
| cpu | Total cpu requests of containers |
|
||||
| memory | Total memory requests of containers
|
||||
|
||||
For example, `cpu` quota sums up the `resources.requests.cpu` fields of every
|
||||
container of every pod in the namespace, and enforces a maximum on that sum.
|
||||
|
||||
## Object Count Quota
|
||||
|
||||
The number of objects of a given type can be restricted. The following types
|
||||
are supported:
|
||||
|
||||
| ResourceName | Description |
|
||||
| ------------ | ----------- |
|
||||
| pods | Total number of pods |
|
||||
| services | Total number of services |
|
||||
| replicationcontrollers | Total number of replication controllers |
|
||||
| resourcequotas | Total number of [resource quotas](/docs/admin/admission-controllers/#resourcequota) |
|
||||
| secrets | Total number of secrets |
|
||||
| persistentvolumeclaims | Total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) |
|
||||
|
||||
For example, `pods` quota counts and enforces a maximum on the number of `pods`
|
||||
created in a single namespace.
|
||||
|
||||
You might want to set a pods quota on a namespace
|
||||
to avoid the case where a user creates many small pods and exhausts the cluster's
|
||||
supply of Pod IPs.
|
||||
|
||||
## Viewing and Setting Quotas
|
||||
|
||||
Kubectl supports creating, updating, and viewing quotas:
|
||||
|
||||
```shell
|
||||
$ kubectl namespace myspace
|
||||
$ cat <<EOF > quota.json
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ResourceQuota",
|
||||
"metadata": {
|
||||
"name": "quota"
|
||||
},
|
||||
"spec": {
|
||||
"hard": {
|
||||
"memory": "1Gi",
|
||||
"cpu": "20",
|
||||
"pods": "10",
|
||||
"services": "5",
|
||||
"replicationcontrollers":"20",
|
||||
"resourcequotas":"1"
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
$ kubectl create -f ./quota.json
|
||||
$ kubectl get quota
|
||||
NAME
|
||||
quota
|
||||
$ kubectl describe quota quota
|
||||
Name: quota
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0m 20
|
||||
memory 0 1Gi
|
||||
pods 5 10
|
||||
replicationcontrollers 5 20
|
||||
resourcequotas 1 1
|
||||
services 3 5
|
||||
```
|
||||
|
||||
## Quota and Cluster Capacity
|
||||
|
||||
Resource Quota objects are independent of the Cluster Capacity. They are
|
||||
expressed in absolute units. So, if you add nodes to your cluster, this does *not*
|
||||
automatically give each namespace the ability to consume more resources.
|
||||
|
||||
Sometimes more complex policies may be desired, such as:
|
||||
|
||||
- proportionally divide total cluster resources among several teams.
|
||||
- allow each tenant to grow resource usage as needed, but have a generous
|
||||
limit to prevent accidental resource exhaustion.
|
||||
- detect demand from one namespace, add nodes, and increase quota.
|
||||
|
||||
Such policies could be implemented using ResourceQuota as a building-block, by
|
||||
writing a 'controller' which watches the quota usage and adjusts the quota
|
||||
hard limits of each namespace according to other signals.
|
||||
|
||||
Note that resource quota divides up aggregate cluster resources, but it creates no
|
||||
restrictions around nodes: pods from several namespaces may run on the same node.
|
||||
|
||||
## Example
|
||||
|
||||
See a [detailed example for how to use resource quota](/docs/admin/resourcequota/walkthrough/).
|
||||
|
||||
## Read More
|
||||
|
||||
See [ResourceQuota design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/admission_control_resource_quota.md) for more information.
|
||||
|
||||
This example assumes you have a functional Kubernetes setup.
|
||||
|
||||
## Step 1: Create a namespace
|
||||
|
||||
This example will work in a custom namespace to demonstrate the concepts involved.
|
||||
|
||||
Let's create a new namespace called quota-example:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/namespace.yaml
|
||||
namespace "quota-example" created
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS STATUS AGE
|
||||
default <none> Active 2m
|
||||
quota-example <none> Active 39s
|
||||
```
|
||||
|
||||
## Step 2: Apply a quota to the namespace
|
||||
|
||||
By default, a pod will run with unbounded CPU and memory requests/limits. This means that any pod in the
|
||||
system will be able to consume as much CPU and memory on the node that executes the pod.
|
||||
|
||||
Users may want to restrict how much of the cluster resources a given namespace may consume
|
||||
across all of its pods in order to manage cluster usage. To do this, a user applies a quota to
|
||||
a namespace. A quota lets the user set hard limits on the total amount of node resources (cpu, memory)
|
||||
and API resources (pods, services, etc.) that a namespace may consume. In term of resources, Kubernetes
|
||||
checks the total resource *requests*, not resource *limits* of all containers/pods in the namespace.
|
||||
|
||||
Let's create a simple quota in our namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/quota.yaml --namespace=quota-example
|
||||
resourcequota "quota" created
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
You can describe your current quota usage to see what resources are being consumed in your
|
||||
namespace.
|
||||
|
||||
```shell
|
||||
$ kubectl describe quota quota --namespace=quota-example
|
||||
Name: quota
|
||||
Namespace: quota-example
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0 20
|
||||
memory 0 1Gi
|
||||
persistentvolumeclaims 0 10
|
||||
pods 0 10
|
||||
replicationcontrollers 0 20
|
||||
resourcequotas 1 1
|
||||
secrets 1 10
|
||||
services 0 5
|
||||
```
|
||||
|
||||
## Step 3: Applying default resource requests and limits
|
||||
|
||||
Pod authors rarely specify resource requests and limits for their pods.
|
||||
|
||||
Since we applied a quota to our project, let's see what happens when an end-user creates a pod that has unbounded
|
||||
cpu and memory by creating an nginx container.
|
||||
|
||||
To demonstrate, lets create a replication controller that runs nginx:
|
||||
|
||||
```shell
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=quota-example
|
||||
replicationcontroller "nginx" created
|
||||
```
|
||||
|
||||
Now let's look at the pods that were created.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
```
|
||||
|
||||
What happened? I have no pods! Let's describe the replication controller to get a view of what is happening.
|
||||
|
||||
```shell
|
||||
kubectl describe rc nginx --namespace=quota-example
|
||||
Name: nginx
|
||||
Namespace: quota-example
|
||||
Image(s): nginx
|
||||
Selector: run=nginx
|
||||
Labels: run=nginx
|
||||
Replicas: 0 current / 1 desired
|
||||
Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed
|
||||
No volumes.
|
||||
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.
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/limits.yaml --namespace=quota-example
|
||||
limitrange "limits" created
|
||||
$ kubectl describe limits limits --namespace=quota-example
|
||||
Name: limits
|
||||
Namespace: quota-example
|
||||
Type Resource Min Max Request Limit Limit/Request
|
||||
---- -------- --- --- ------- ----- -------------
|
||||
Container memory - - 256Mi 512Mi -
|
||||
Container cpu - - 100m 200m -
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Now that we have applied default resource *request* for our namespace, our replication controller should be able to
|
||||
create its pods.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-fca65 1/1 Running 0 1m
|
||||
```
|
||||
|
||||
And if we print out our quota usage in the namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl describe quota quota --namespace=quota-example
|
||||
Name: quota
|
||||
Namespace: quota-example
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 100m 20
|
||||
memory 256Mi 1Gi
|
||||
persistentvolumeclaims 0 10
|
||||
pods 1 10
|
||||
replicationcontrollers 1 20
|
||||
resourcequotas 1 1
|
||||
secrets 1 10
|
||||
services 0 5
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Summary
|
||||
|
||||
Actions that consume node resources for cpu and memory can be subject to hard quota limits defined by the namespace quota. The resource consumption is measured by resource *request* in pod specification.
|
||||
|
||||
Any action that consumes those resources can be tweaked, or can pick up namespace level defaults to meet your end goal.
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
---
|
||||
---
|
||||
|
||||
This example demonstrates how [resource quota](/docs/admin/admission-controllers/#resourcequota) and
|
||||
[limitsranger](/docs/admin/admission-controllers/#limitranger) can be applied to a Kubernetes namespace.
|
||||
See [ResourceQuota design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/admission_control_resource_quota.md) for more information.
|
||||
|
||||
This example assumes you have a functional Kubernetes setup.
|
||||
|
||||
## Step 1: Create a namespace
|
||||
|
||||
This example will work in a custom namespace to demonstrate the concepts involved.
|
||||
|
||||
Let's create a new namespace called quota-example:
|
||||
|
||||
```shell
|
||||
$ kubectl create namespace quota-example
|
||||
namespace "quota-example" created
|
||||
```
|
||||
|
||||
Note that `kubectl` commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands:
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces
|
||||
NAME STATUS AGE
|
||||
default Active 50m
|
||||
quota-example Active 2s
|
||||
```
|
||||
|
||||
## Step 2: Apply a quota to the namespace
|
||||
|
||||
By default, a pod will run with unbounded CPU and memory requests/limits. This means that any pod in the
|
||||
system will be able to consume as much CPU and memory on the node that executes the pod.
|
||||
|
||||
Users may want to restrict how much of the cluster resources a given namespace may consume
|
||||
across all of its pods in order to manage cluster usage. To do this, a user applies a quota to
|
||||
a namespace. A quota lets the user set hard limits on the total amount of node resources (cpu, memory)
|
||||
and API resources (pods, services, etc.) that a namespace may consume. In term of resources, Kubernetes
|
||||
checks the total resource *requests*, not resource *limits* of all containers/pods in the namespace.
|
||||
|
||||
Let's create a simple quota in our namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/quota.yaml --namespace=quota-example
|
||||
resourcequota "quota" created
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
You can describe your current quota usage to see what resources are being consumed in your
|
||||
namespace.
|
||||
|
||||
```shell
|
||||
$ kubectl describe quota quota --namespace=quota-example
|
||||
Name: quota
|
||||
Namespace: quota-example
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0 20
|
||||
memory 0 1Gi
|
||||
persistentvolumeclaims 0 10
|
||||
pods 0 10
|
||||
replicationcontrollers 0 20
|
||||
resourcequotas 1 1
|
||||
secrets 1 10
|
||||
services 0 5
|
||||
```
|
||||
|
||||
## Step 3: Applying default resource requests and limits
|
||||
|
||||
Pod authors rarely specify resource requests and limits for their pods.
|
||||
|
||||
Since we applied a quota to our project, let's see what happens when an end-user creates a pod that has unbounded
|
||||
cpu and memory by creating an nginx container.
|
||||
|
||||
To demonstrate, lets create a Deployment that runs nginx:
|
||||
|
||||
```shell
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=quota-example
|
||||
deployment "nginx" created
|
||||
```
|
||||
|
||||
This creates a Deployment "nginx" with its underlying resource, a ReplicaSet, which handles the creation and deletion of Pod replicas. Now let's look at the pods that were created.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
```
|
||||
|
||||
What happened? I have no pods! Let's describe the ReplicaSet managed by the nginx Deployment to get a view of what is happening.
|
||||
Note that `kubectl describe rs` works only on kubernetes cluster >= v1.2. If you are running older versions, use `kubectl describe rc` instead.
|
||||
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/kubectl_run/) for more details.
|
||||
|
||||
```shell
|
||||
$ kubectl describe rs -l run=nginx --namespace=quota-example
|
||||
Name: nginx-2040093540
|
||||
Namespace: quota-example
|
||||
Image(s): nginx
|
||||
Selector: pod-template-hash=2040093540,run=nginx
|
||||
Labels: pod-template-hash=2040093540,run=nginx
|
||||
Replicas: 0 current / 1 desired
|
||||
Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed
|
||||
No volumes.
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
48s 26s 4 {replicaset-controller } Warning FailedCreate Error creating: pods "nginx-2040093540-" is forbidden: Failed quota: quota: must specify cpu,memory
|
||||
```
|
||||
|
||||
The Kubernetes API server is rejecting the ReplicaSet 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:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/limits.yaml --namespace=quota-example
|
||||
limitrange "limits" created
|
||||
$ kubectl describe limits limits --namespace=quota-example
|
||||
Name: limits
|
||||
Namespace: quota-example
|
||||
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
|
||||
---- -------- --- --- --------------- ------------- -----------------------
|
||||
Container cpu - - 100m 200m -
|
||||
Container memory - - 256Mi 512Mi -
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Now that we have applied default resource *request* for our namespace, our Deployment should be able to
|
||||
create its pods.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-2040093540-miohp 1/1 Running 0 5s
|
||||
```
|
||||
|
||||
And if we print out our quota usage in the namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl describe quota quota --namespace=quota-example
|
||||
Name: quota
|
||||
Namespace: quota-example
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 100m 20
|
||||
memory 256Mi 1Gi
|
||||
persistentvolumeclaims 0 10
|
||||
pods 1 10
|
||||
replicationcontrollers 1 20
|
||||
resourcequotas 1 1
|
||||
secrets 1 10
|
||||
services 0 5
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Summary
|
||||
|
||||
Actions that consume node resources for cpu and memory can be subject to hard quota limits defined by the namespace quota. The resource consumption is measured by resource *request* in pod specification.
|
||||
|
||||
Any action that consumes those resources can be tweaked, or can pick up namespace level defaults to meet your end goal.
|
||||
|
|
@ -184,7 +184,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscalerlist">v1.HorizontalPodAutoscalerList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscalerlist">v1.HorizontalPodAutoscalerList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -332,7 +332,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscalerlist">v1.HorizontalPodAutoscalerList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscalerlist">v1.HorizontalPodAutoscalerList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -480,7 +480,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -562,7 +562,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -596,7 +596,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -728,7 +728,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -810,7 +810,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -852,7 +852,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -934,7 +934,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -976,7 +976,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1058,7 +1058,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1100,7 +1100,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1188,7 +1188,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1230,7 +1230,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_horizontalpodautoscaler">v1.HorizontalPodAutoscaler</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1370,7 +1370,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1515,7 +1515,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1668,7 +1668,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_joblist">v1.JobList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_joblist">v1.JobList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -332,7 +332,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_joblist">v1.JobList</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_joblist">v1.JobList</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -480,7 +480,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -562,7 +562,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -596,7 +596,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_job">v1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -728,7 +728,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_job">v1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -810,7 +810,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -852,7 +852,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_job">v1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -934,7 +934,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_deleteoptions">v1.DeleteOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -976,7 +976,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_status">unversioned.Status</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_status">unversioned.Status</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1058,7 +1058,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_unversioned_patch">unversioned.Patch</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1100,7 +1100,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_job">v1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1188,7 +1188,7 @@
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -1230,7 +1230,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_v1_job">v1.Job</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_job">v1.Job</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1370,7 +1370,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1515,7 +1515,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1668,7 +1668,7 @@
|
|||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="definitions.html#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_json_watchevent">json.WatchEvent</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1714,4 +1714,4 @@ Last updated 2016-03-14 21:55:47 UTC
|
|||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ Primary system and API concepts are documented in the [User guide](/docs/user-gu
|
|||
|
||||
Overall API conventions are described in the [API conventions doc](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md).
|
||||
|
||||
Complete API details are documented via [Swagger](http://swagger.io/). The Kubernetes apiserver (aka "master") exports an API that can be used to retrieve the [Swagger spec](https://github.com/swagger-api/swagger-spec/tree/master/schemas/v1.2) for the Kubernetes API, by default at `/swaggerapi`, and a UI you can use to browse the API documentation at `/swagger-ui`. We also periodically update a [statically generated UI](http://kubernetes.io/third_party/swagger-ui/).
|
||||
|
||||
Remote access to the API is discussed in the [access doc](/docs/admin/accessing-the-api).
|
||||
|
||||
The Kubernetes API also serves as the foundation for the declarative configuration schema for the system. The [Kubectl](/docs/user-guide/kubectl/kubectl) command-line tool can be used to create, update, delete, and get API objects.
|
||||
|
|
@ -21,6 +19,12 @@ In our experience, any system that is successful needs to grow and change as new
|
|||
|
||||
What constitutes a compatible change and how to change the API are detailed by the [API change document](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api_changes.md).
|
||||
|
||||
## API Swagger definitions
|
||||
|
||||
Complete API details are documented using [Swagger v1.2](http://swagger.io/). The Kubernetes apiserver (aka "master") exposes an API that can be used to retrieve the Swagger Kubernetes API spec, by default at located at `/swaggerapi`, and a UI to browse the API documentation at `/swagger-ui`.
|
||||
|
||||
We also host a version of the [latest API documentation UI](http://kubernetes.io/kubernetes/third_party/swagger-ui/). This is updated with the latest release, so if you are using a different version of Kubernetes you will want to use the spec from your apiserver.
|
||||
|
||||
## API versioning
|
||||
|
||||
To make it easier to eliminate fields or restructure resource representations, Kubernetes supports
|
||||
|
|
|
|||
|
|
@ -0,0 +1,334 @@
|
|||
---
|
||||
---
|
||||
* TOC
|
||||
{: toc}
|
||||
|
||||
These scripts handle the creation, deletion and expansion of kubernetes clusters on CenturyLink Cloud.
|
||||
|
||||
You can accomplish all these tasks with a single command. We have made the Ansible playbooks used to perform these tasks available [here](https://github.com/CenturyLinkCloud/adm-kubernetes-on-clc/blob/master/ansible/README.md).
|
||||
|
||||
## Find Help
|
||||
|
||||
If you run into any problems or want help with anything, we are here to help. Reach out to use via any of the following ways:
|
||||
- Submit a github issue
|
||||
- Send an email to kubernetes AT ctl DOT io
|
||||
- Visit http://info.ctl.io/kubernetes
|
||||
|
||||
## Clusters of VMs or Physical Servers, your choice.
|
||||
|
||||
- We support Kubernetes clusters on both Virtual Machines or Physical Servers. If you want to use physical servers for the worker nodes (minions), simple use the --minion_type=bareMetal flag.
|
||||
- For more information on physical servers, visit: [https://www.ctl.io/bare-metal/](https://www.ctl.io/bare-metal/))
|
||||
- Physical serves are only available in the VA1 and GB3 data centers.
|
||||
- VMs are available in all 13 of our public cloud locations
|
||||
|
||||
## Requirements
|
||||
|
||||
The requirements to run this script are:
|
||||
- A linux administrative host (tested on ubuntu and OSX)
|
||||
- python 2 (tested on 2.7.11)
|
||||
- pip (installed with python as of 2.7.9)
|
||||
- git
|
||||
- A CenturyLink Cloud account with rights to create new hosts
|
||||
- An active VPN connection to the CenturyLink Cloud from your linux host
|
||||
|
||||
## Script Installation
|
||||
|
||||
After you have all the requirements met, please follow these instructions to install this script.
|
||||
|
||||
1) Clone this repository and cd into it.
|
||||
|
||||
```shell
|
||||
git clone https://github.com/CenturyLinkCloud/adm-kubernetes-on-clc
|
||||
```
|
||||
|
||||
2) Install all requirements, including
|
||||
* Ansible
|
||||
* CenturyLink Cloud SDK
|
||||
* Ansible Modules
|
||||
|
||||
```shell
|
||||
sudo pip install -r ansible/requirements.txt
|
||||
```
|
||||
|
||||
3) Create the credentials file from the template and use it to set your ENV variables
|
||||
|
||||
```shell
|
||||
cp ansible/credentials.sh.template ansible/credentials.sh
|
||||
vi ansible/credentials.sh
|
||||
source ansible/credentials.sh
|
||||
|
||||
```
|
||||
|
||||
4) Grant your machine access to the CenturyLink Cloud network by using a VM inside the network or [ configuring a VPN connection to the CenturyLink Cloud network.](https://www.ctl.io/knowledge-base/network/how-to-configure-client-vpn/)
|
||||
|
||||
|
||||
#### Script Installation Example: Ubuntu 14 Walkthrough
|
||||
|
||||
If you use an ubuntu 14, for your convenience we have provided a step by step
|
||||
guide to install the requirements and install the script.
|
||||
|
||||
```shell
|
||||
# system
|
||||
apt-get update
|
||||
apt-get install -y git python python-crypto
|
||||
curl -O https://bootstrap.pypa.io/get-pip.py
|
||||
python get-pip.py
|
||||
|
||||
# installing this repository
|
||||
mkdir -p ~home/k8s-on-clc
|
||||
cd ~home/k8s-on-clc
|
||||
git clone https://github.com/CenturyLinkCloud/adm-kubernetes-on-clc.git
|
||||
cd adm-kubernetes-on-clc/
|
||||
pip install -r requirements.txt
|
||||
|
||||
# getting started
|
||||
cd ansible
|
||||
cp credentials.sh.template credentials.sh; vi credentials.sh
|
||||
source credentials.sh
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Cluster Creation
|
||||
|
||||
To create a new Kubernetes cluster, simply run the kube-up.sh script. A complete
|
||||
list of script options and some examples are listed below.
|
||||
|
||||
```shell
|
||||
CLC_CLUSTER_NAME=[name of kubernetes cluster]
|
||||
cd ./adm-kubernetes-on-clc
|
||||
bash kube-up.sh -c="$CLC_CLUSTER_NAME"
|
||||
```
|
||||
|
||||
It takes about 15 minutes to create the cluster. Once the script completes, it
|
||||
will output some commands that will help you setup kubectl on your machine to
|
||||
point to the new cluster.
|
||||
|
||||
When the cluster creation is complete, the configuration files for it are stored
|
||||
locally on your administrative host, in the following directory
|
||||
|
||||
```shell
|
||||
> CLC_CLUSTER_HOME=$HOME/.clc_kube/$CLC_CLUSTER_NAME/
|
||||
```
|
||||
|
||||
|
||||
#### Cluster Creation: Script Options
|
||||
|
||||
```shell
|
||||
Usage: kube-up.sh [OPTIONS]
|
||||
Create servers in the CenturyLinkCloud environment and initialize a Kubernetes cluster
|
||||
Environment variables CLC_V2_API_USERNAME and CLC_V2_API_PASSWD must be set in
|
||||
order to access the CenturyLinkCloud API
|
||||
|
||||
All options (both short and long form) require arguments, and must include "="
|
||||
between option name and option value.
|
||||
|
||||
-h (--help) display this help and exit
|
||||
-c= (--clc_cluster_name=) set the name of the cluster, as used in CLC group names
|
||||
-t= (--minion_type=) standard -> VM (default), bareMetal -> physical]
|
||||
-d= (--datacenter=) VA1 (default)
|
||||
-m= (--minion_count=) number of kubernetes minion nodes
|
||||
-mem= (--vm_memory=) number of GB ram for each minion
|
||||
-cpu= (--vm_cpu=) number of virtual cps for each minion node
|
||||
-phyid= (--server_conf_id=) physical server configuration id, one of
|
||||
physical_server_20_core_conf_id
|
||||
physical_server_12_core_conf_id
|
||||
physical_server_4_core_conf_id (default)
|
||||
-etcd_separate_cluster=yes create a separate cluster of three etcd nodes,
|
||||
otherwise run etcd on the master node
|
||||
```
|
||||
|
||||
## Cluster Expansion
|
||||
|
||||
To expand an existing Kubernetes cluster, run the ```add-kube-node.sh```
|
||||
script. A complete list of script options and some examples are listed [[below]](####Cluster Expansion: Script Options).
|
||||
This script must be run from the same host that created the cluster (or a host
|
||||
that has the cluster artifact files stored in ```~/.clc_kube/$cluster_name```).
|
||||
|
||||
```shell
|
||||
cd ./adm-kubernetes-on-clc
|
||||
bash add-kube-node.sh -c="name_of_kubernetes_cluster" -m=2
|
||||
```
|
||||
|
||||
#### Cluster Expansion: Script Options
|
||||
|
||||
```shell
|
||||
Usage: add-kube-node.sh [OPTIONS]
|
||||
Create servers in the CenturyLinkCloud environment and add to an
|
||||
existing CLC kubernetes cluster
|
||||
|
||||
Environment variables CLC_V2_API_USERNAME and CLC_V2_API_PASSWD must be set in
|
||||
order to access the CenturyLinkCloud API
|
||||
|
||||
-h (--help) display this help and exit
|
||||
-c= (--clc_cluster_name=) set the name of the cluster, as used in CLC group names
|
||||
-m= (--minion_count=) number of kubernetes minion nodes to add
|
||||
|
||||
```
|
||||
|
||||
## Cluster Deletion
|
||||
|
||||
There are two ways to delete an existing cluster:
|
||||
|
||||
1) Use our python script:
|
||||
|
||||
```shell
|
||||
python delete_cluster.py --cluster=clc_cluster_name --datacenter=DC1
|
||||
|
||||
```
|
||||
|
||||
2) Use the CenturyLink Cloud UI. To delete a cluster, log into the CenturyLink
|
||||
Cloud control portal and delete the parent server group that contains the
|
||||
Kubernetes Cluster. We hope to add a scripted option to do this soon.
|
||||
|
||||
## Examples
|
||||
|
||||
Create a cluster with name of k8s_1, 1 master node and 3 worker minions (on physical machines), in VA1
|
||||
|
||||
```shell
|
||||
bash kube-up.sh --clc_cluster_name=k8s_1 --minion_type=bareMetal --minion_count=3 --datacenter=VA1
|
||||
```
|
||||
|
||||
Create a cluster with name of k8s_2, an ha etcd cluster on 3 VMs and 6 worker minions (on VMs), in VA1
|
||||
|
||||
```shell
|
||||
bash kube-up.sh --clc_cluster_name=k8s_2 --minion_type=standard --minion_count=6 --datacenter=VA1 --etcd_separate_cluster=yes
|
||||
```
|
||||
|
||||
Create a cluster with name of k8s_3, 1 master node, and 10 worker minions (on VMs) with higher mem/cpu, in UC1:
|
||||
|
||||
```shell
|
||||
bash kube-up.sh --clc_cluster_name=k8s_3 --minion_type=standard --minion_count=10 --datacenter=VA1 -mem=6 -cpu=4
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Cluster Features and Architecture
|
||||
|
||||
We configue the Kubernetes cluster with the following features:
|
||||
|
||||
* KubeDNS: DNS resolution and service discovery
|
||||
* Heapster/InfluxDB: For metric collection. Needed for Grafana and auto-scaling.
|
||||
* Grafana: Kubernetes/Docker metric dashboard
|
||||
* KubeUI: Simple web interface to view kubernetes state
|
||||
* Kube Dashboard: New web interface to interact with your cluster
|
||||
|
||||
We use the following to create the kubernetes cluster:
|
||||
|
||||
* Kubernetes 1.1.7
|
||||
* Unbuntu 14.04
|
||||
* Flannel 0.5.4
|
||||
* Docker 1.9.1-0~trusty
|
||||
* Etcd 2.2.2
|
||||
|
||||
## Optional add-ons
|
||||
|
||||
* Logging: We offer an integrated centralized logging ELK platform so that all
|
||||
Kubernetes and docker logs get sent to the ELK stack. To install the ELK stack
|
||||
and configure Kubernetes to send logs to it, follow [the log
|
||||
aggregation documentation](https://github.com/CenturyLinkCloud/adm-kubernetes-on-clc/blob/master/log_aggregration.md). Note: We don't install this by default as
|
||||
the footprint isn't trivial.
|
||||
|
||||
## Cluster management
|
||||
|
||||
The most widely used tool for managing a kubernetes cluster is the command-line
|
||||
utility ```kubectl```. If you do not already have a copy of this binary on your
|
||||
administrative machine, you may run the script ```install_kubectl.sh``` which will
|
||||
download it and install it in ```/usr/bin/local```.
|
||||
|
||||
The script requires that the environment variable ```CLC_CLUSTER_NAME``` be defined
|
||||
|
||||
```install_kubectl.sh``` also writes a configuration file which will embed the necessary
|
||||
authentication certificates for the particular cluster. The configuration file is
|
||||
written to the ```${CLC_CLUSTER_HOME}/kube``` directory
|
||||
|
||||
```shell
|
||||
export KUBECONFIG=${CLC_CLUSTER_HOME}/kube/config
|
||||
kubectl version
|
||||
kubectl cluster-info
|
||||
```
|
||||
|
||||
### Accessing the cluster programmatically
|
||||
|
||||
It's possible to use the locally-stored client certificates to access the api server. For example, you may want to use any of the [Kubernetes API client libraries](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/client-libraries.md) to program against your Kubernetes cluster in the programming language of your choice.
|
||||
|
||||
To demostrate how to use these locally stored certificates, we provide the folowing example of using ```curl``` to communicate to the master api server via https:
|
||||
|
||||
```shell
|
||||
curl \
|
||||
--cacert ${CLC_CLUSTER_HOME}/pki/ca.crt \
|
||||
--key ${CLC_CLUSTER_HOME}/pki/kubecfg.key \
|
||||
--cert ${CLC_CLUSTER_HOME}/pki/kubecfg.crt https://${MASTER_IP}:6443
|
||||
```
|
||||
|
||||
But please note, this *does not* work out of the box with the ```curl``` binary
|
||||
distributed with OSX.
|
||||
|
||||
### Accessing the cluster with a browser
|
||||
|
||||
We install two UIs on Kubernetes. The orginal KubeUI and [the newer kube
|
||||
dashboard](/docs/user-guide/ui/). When you create a cluster, the script should output URLs for these
|
||||
interfaces like this:
|
||||
|
||||
KubeUI is running at ```https://${MASTER_IP}:6443/api/v1/proxy/namespaces/kube-system/services/kube-ui```
|
||||
kubernetes-dashboard is running at ```https://${MASTER_IP}:6443/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard```
|
||||
|
||||
Note on Authentication to the UIs: The cluster is set up to use basic
|
||||
authentication for the user _admin_. Hitting the url at
|
||||
```https://${MASTER_IP}:6443``` will require accepting the self-signed certificate
|
||||
from the apiserver, and then presenting the admin password written to file at:
|
||||
|
||||
```> _${CLC_CLUSTER_HOME}/kube/admin_password.txt_```
|
||||
|
||||
|
||||
### Configuration files
|
||||
|
||||
Various configuration files are written into the home directory *CLC_CLUSTER_HOME* under
|
||||
```.clc_kube/${CLC_CLUSTER_NAME}``` in several subdirectories. You can use these files
|
||||
to access the cluster from machines other than where you created the cluster from.
|
||||
|
||||
* ```config/```: Ansible variable files containing parameters describing the master and minion hosts
|
||||
* ```hosts/```: hosts files listing access information for the ansible playbooks
|
||||
* ```kube/```: ```kubectl``` configuration files, and the basic-authentication password for admin access to the Kubernetes API
|
||||
* ```pki/```: public key infrastructure files enabling TLS communication in the cluster
|
||||
* ```ssh/```: SSH keys for root access to the hosts
|
||||
|
||||
|
||||
## ```kubectl``` usage examples
|
||||
|
||||
There are a great many features of _kubectl_. Here are a few examples
|
||||
|
||||
List existing nodes, pods, services and more, in all namespaces, or in just one:
|
||||
|
||||
```shell
|
||||
kubectl get nodes
|
||||
kubectl get --all-namespaces services
|
||||
kubectl get --namespace=kube-system replicationcontrollers
|
||||
```
|
||||
|
||||
The Kubernetes API server exposes services on web URLs, which are protected by requiring
|
||||
client certificates. If you run a kubectl proxy locally, ```kubectl``` will provide
|
||||
the necessary certificates and serve locally over http.
|
||||
|
||||
```shell
|
||||
kubectl proxy -p 8001
|
||||
```
|
||||
|
||||
Then, you can access urls like ```http://127.0.0.1:8001/api/v1/proxy/namespaces/kube-system/services/kube-ui/``` without the need for client certificates in your browser.
|
||||
|
||||
|
||||
## What Kubernetes features do not work on CenturyLink Cloud
|
||||
|
||||
These are the known items that don't work on CenturyLink cloud but do work on other cloud providers:
|
||||
|
||||
- At this time, there is no support services of the type [LoadBalancer](/docs/user-guide/load-balancer/). We are actively working on this and hope to publish the changes sometime around April 2016.
|
||||
|
||||
- At this time, there is no support for persistent storage volumes provided by
|
||||
CenturyLink Cloud. However, customers can bring their own persistent storage
|
||||
offering. We ourselves use Gluster.
|
||||
|
||||
|
||||
## Ansible Files
|
||||
|
||||
If you want more information about our Ansible files, please [read this file](https://github.com/CenturyLinkCloud/adm-kubernetes-on-clc/blob/master/ansible/README.md)
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ Check the tasks and templates in `roles/k8s` if you want to modify anything.
|
|||
|
||||
Once the playbook as finished, it will print out the IP of the Kubernetes master:
|
||||
|
||||
TASK: [k8s | debug msg='k8s master IP is {{ k8s_master.default_ip }}'] ********
|
||||
TASK: [k8s | debug msg='k8s master IP is {% raw %}{{ k8s_master.default_ip }}{% endraw %}'] ********
|
||||
|
||||
SSH to it using the key that was created and using the _core_ user and you can list the machines in your cluster:
|
||||
|
||||
|
|
@ -77,4 +77,4 @@ SSH to it using the key that was created and using the _core_ user and you can l
|
|||
MACHINE IP METADATA
|
||||
a017c422... <node #1 IP> role=node
|
||||
ad13bf84... <master IP> role=master
|
||||
e9af8293... <node #2 IP> role=node
|
||||
e9af8293... <node #2 IP> role=node
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ $ sed -e "s/{{ pillar\['dns_replicas'\] }}/${DNS_REPLICAS}/g;s/{{ pillar\['dns_d
|
|||
|
||||
# If the kube-system namespace isn't already created, create it
|
||||
$ kubectl get ns
|
||||
$ kubectl create -f ./kube-system.yaml
|
||||
$ kubectl create namespace kube-system
|
||||
|
||||
$ kubectl create -f ./skydns.yaml{% endraw %}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
---
|
||||
|
||||
_Note_:
|
||||
These instructions are somewhat significantly more advanced than the [single node](docker.md) instructions. If you are
|
||||
These instructions are somewhat significantly more advanced than the [single node](/docs/getting-started-guides/docker) instructions. If you are
|
||||
interested in just starting to explore Kubernetes, we recommend that you start there.
|
||||
|
||||
* TOC
|
||||
|
|
@ -35,7 +35,7 @@ it is still useful to use containers for deployment and management, so we create
|
|||
You can specify the version on every node before install:
|
||||
|
||||
```shell
|
||||
export K8S_VERSION=<your_k8s_version (e.g. 1.2.0-alpha.7)>
|
||||
export K8S_VERSION=<your_k8s_version (e.g. 1.2.0)>
|
||||
export ETCD_VERSION=<your_etcd_version (e.g. 2.2.1)>
|
||||
export FLANNEL_VERSION=<your_flannel_version (e.g. 0.5.5)>
|
||||
export FLANNEL_IFACE=<flannel_interface (defaults to eth0)>
|
||||
|
|
@ -3,13 +3,13 @@
|
|||
|
||||
We'll begin by setting up the master node. For the purposes of illustration, we'll assume that the IP of this machine
|
||||
is `${MASTER_IP}`. We'll need to run several versioned Kubernetes components, so we'll assume that the version we want
|
||||
to run is `${K8S_VERSION}`, which should hold a released version of Kubernetes >= "1.2.0-alpha.7"
|
||||
to run is `${K8S_VERSION}`, which should hold a released version of Kubernetes >= "1.2.1"
|
||||
|
||||
Enviroinment variables used:
|
||||
Environment variables used:
|
||||
|
||||
```shell
|
||||
export MASTER_IP=<the_master_ip_here>
|
||||
export K8S_VERSION=<your_k8s_version (e.g. 1.2.0-alpha.7)>
|
||||
export K8S_VERSION=<your_k8s_version (e.g. 1.2.1)>
|
||||
export ETCD_VERSION=<your_etcd_version (e.g. 2.2.1)>
|
||||
export FLANNEL_VERSION=<your_flannel_version (e.g. 0.5.5)>
|
||||
export FLANNEL_IFACE=<flannel_interface (defaults to eth0)>
|
||||
|
|
@ -114,6 +114,7 @@ sudo docker -H unix:///var/run/docker-bootstrap.sock run -d \
|
|||
--privileged \
|
||||
-v /dev/net:/dev/net \
|
||||
quay.io/coreos/flannel:${FLANNEL_VERSION} \
|
||||
/opt/bin/flanneld \
|
||||
--ip-masq=${FLANNEL_IPMASQ} \
|
||||
--iface=${FLANNEL_IFACE}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ if ( ! ps -ef | grep "/usr/bin/docker" | grep -v 'grep' &> /dev/null ); then
|
|||
fi
|
||||
|
||||
# Make sure k8s version env is properly set
|
||||
K8S_VERSION=${K8S_VERSION:-"1.2.0-alpha.7"}
|
||||
ETCD_VERSION=${ETCD_VERSION:-"2.2.1"}
|
||||
K8S_VERSION=${K8S_VERSION:-"1.2.2}
|
||||
ETCD_VERSION=${ETCD_VERSION:-"2.3.1"}
|
||||
FLANNEL_VERSION=${FLANNEL_VERSION:-"0.5.5"}
|
||||
FLANNEL_IPMASQ=${FLANNEL_IPMASQ:-"true"}
|
||||
FLANNEL_IFACE=${FLANNEL_IFACE:-"eth0"}
|
||||
|
|
@ -176,7 +176,7 @@ start_k8s(){
|
|||
;;
|
||||
centos)
|
||||
DOCKER_CONF="/etc/sysconfig/docker"
|
||||
echo "OPTIONS=\"\$OPTIONS --mtu=${FLANNEL_MTU} --bip=${FLANNEL_SUBNET}\"" | tee -a ${DOCKER_CONF}
|
||||
sed -i "/^OPTIONS=/ s|\( --mtu=.*\)\?'$| --mtu=${FLANNEL_MTU} --bip=${FLANNEL_SUBNET}'|" ${DOCKER_CONF}
|
||||
if ! command_exists ifconfig; then
|
||||
yum -y -q install net-tools
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ start_k8s() {
|
|||
case "${lsb_dist}" in
|
||||
centos)
|
||||
DOCKER_CONF="/etc/sysconfig/docker"
|
||||
echo "OPTIONS=\"\$OPTIONS --mtu=${FLANNEL_MTU} --bip=${FLANNEL_SUBNET}\"" | tee -a ${DOCKER_CONF}
|
||||
sed -i "/^OPTIONS=/ s|\( --mtu=.*\)\?'$| --mtu=${FLANNEL_MTU} --bip=${FLANNEL_SUBNET}'|" ${DOCKER_CONF}
|
||||
if ! command_exists ifconfig; then
|
||||
yum -y -q install net-tools
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -13,79 +13,98 @@ Here's a diagram of what the final result will look like:
|
|||
## Prerequisites
|
||||
|
||||
1. You need to have docker installed on one machine.
|
||||
2. Decide what Kubernetes version to use. Set the `${K8S_VERSION}` variable to
|
||||
a released version of Kubernetes >= "1.2.0-alpha.7"
|
||||
2. Decide what Kubernetes version to use. Set the `${K8S_VERSION}` variable to
|
||||
a released version of Kubernetes >= "v1.2.0". If you'd like to use the current stable version of Kubernetes, run the following:
|
||||
|
||||
```sh
|
||||
export K8S_VERSION=$(curl -sS https://storage.googleapis.com/kubernetes-release/release/stable.txt)
|
||||
```
|
||||
|
||||
and for the latest available version (including unstable releases):
|
||||
|
||||
```sh
|
||||
export K8S_VERSION=$(curl -sS https://storage.googleapis.com/kubernetes-release/release/latest.txt)
|
||||
```
|
||||
|
||||
### Run it
|
||||
|
||||
```shell
|
||||
docker run \
|
||||
export ARCH=amd64
|
||||
docker run -d \
|
||||
--volume=/:/rootfs:ro \
|
||||
--volume=/sys:/sys:ro \
|
||||
--volume=/sys:/sys:rw \
|
||||
--volume=/var/lib/docker/:/var/lib/docker:rw \
|
||||
--volume=/var/lib/kubelet/:/var/lib/kubelet:rw \
|
||||
--volume=/var/run:/var/run:rw \
|
||||
--net=host \
|
||||
--pid=host \
|
||||
--privileged=true \
|
||||
-d \
|
||||
gcr.io/google_containers/hyperkube-amd64:v${K8S_VERSION} \
|
||||
--privileged \
|
||||
gcr.io/google_containers/hyperkube-${ARCH}:${K8S_VERSION} \
|
||||
/hyperkube kubelet \
|
||||
--containerized \
|
||||
--hostname-override="127.0.0.1" \
|
||||
--address="0.0.0.0" \
|
||||
--hostname-override=127.0.0.1 \
|
||||
--api-servers=http://localhost:8080 \
|
||||
--config=/etc/kubernetes/manifests \
|
||||
--cluster-dns=10.0.0.10 \
|
||||
--cluster-domain=cluster.local \
|
||||
--allow-privileged=true --v=2
|
||||
--allow-privileged --v=2
|
||||
```
|
||||
|
||||
> Note that `--cluster-dns` and `--cluster-domain` is used to deploy dns, feel free to discard them if dns is not needed.
|
||||
|
||||
> If you would like to mount an external device as a volume, add `--volume=/dev:/dev` to the command above. It may however, cause some problems described in [#18230](https://github.com/kubernetes/kubernetes/issues/18230)
|
||||
|
||||
> Architectures other than `amd64` are experimental and sometimes unstable, but feel free to try them out! Valid values: `arm`, `arm64` and `ppc64le`. ARM is available with Kubernetes version `v1.3.0-alpha.2` and higher. ARM 64-bit and PowerPC 64 little-endian are available with `v1.3.0-alpha.3` and higher. Track progress on multi-arch support [here](https://github.com/kubernetes/kubernetes/issues/17981)
|
||||
|
||||
This actually runs the kubelet, which in turn runs a [pod](/docs/user-guide/pods/) that contains the other master components.
|
||||
|
||||
** **SECURITY WARNING** ** services exposed via Kubernetes using Hyperkube are available on the host node's public network interface / IP address. Because of this, this guide is not suitable for any host node/server that is directly internet accessible. Refer to [#21735](https://github.com/kubernetes/kubernetes/issues/21735) for addtional info.
|
||||
|
||||
### Download `kubectl`
|
||||
|
||||
At this point you should have a running Kubernetes cluster. You can test this
|
||||
by downloading the kubectl binary for `${K8S_VERSION}` (look at the URL in the
|
||||
following links) and make it available by editing your PATH environment
|
||||
variable.
|
||||
([OS X/amd64](http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0-alpha.7/bin/darwin/amd64/kubectl))
|
||||
([OS X/386](http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0-alpha.7/bin/darwin/386/kubectl))
|
||||
([linux/amd64](http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0-alpha.7/bin/linux/amd64/kubectl))
|
||||
([linux/386](http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0-alpha.7/bin/linux/386/kubectl))
|
||||
([linux/arm](http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0-alpha.7/bin/linux/arm/kubectl))
|
||||
At this point you should have a running Kubernetes cluster. You can test it out
|
||||
by downloading the kubectl binary for `${K8S_VERSION}` (in this example: `{{page.version}}.0`).
|
||||
|
||||
For example, OS X:
|
||||
|
||||
```shell
|
||||
$ wget http://storage.googleapis.com/kubernetes-release/release/v${K8S_VERSION}/bin/darwin/amd64/kubectl
|
||||
$ chmod 755 kubectl
|
||||
$ PATH=$PATH:`pwd`
|
||||
Downloads:
|
||||
|
||||
- `linux/amd64`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/linux/amd64/kubectl
|
||||
- `linux/386`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/linux/386/kubectl
|
||||
- `linux/arm`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/linux/arm/kubectl
|
||||
- `linux/arm64`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/linux/arm64/kubectl
|
||||
- `linux/ppc64le`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/linux/ppc64le/kubectl
|
||||
- `OS X/amd64`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/darwin/amd64/kubectl
|
||||
- `OS X/386`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/darwin/386/kubectl
|
||||
- `windows/amd64`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/windows/amd64/kubectl.exe
|
||||
- `windows/386`: http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/windows/386/kubectl.exe
|
||||
|
||||
The generic download path is:
|
||||
```
|
||||
http://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/${GOOS}/${GOARCH}/${K8S_BINARY}
|
||||
```
|
||||
|
||||
Linux:
|
||||
An example install with `linux/amd64`:
|
||||
|
||||
```shell
|
||||
$ wget http://storage.googleapis.com/kubernetes-release/release/v${K8S_VERSION}/bin/linux/amd64/kubectl
|
||||
$ chmod 755 kubectl
|
||||
$ PATH=$PATH:`pwd`
|
||||
```
|
||||
curl -sSL "http://storage.googleapis.com/kubernetes-release/release/{{page.version}}.0/bin/linux/amd64/kubectl" > /usr/bin/kubectl
|
||||
chmod +x /usr/bin/kubectl
|
||||
```
|
||||
|
||||
Create configuration:
|
||||
On OS X, to make the API server accessible locally, setup a ssh tunnel.
|
||||
|
||||
```shell
|
||||
$ kubectl config set-cluster test-doc --server=http://localhost:8080
|
||||
$ kubectl config set-context test-doc --cluster=test-doc
|
||||
$ kubectl config use-context test-doc
|
||||
docker-machine ssh `docker-machine active` -N -L 8080:localhost:8080
|
||||
```
|
||||
|
||||
For Max OS X users instead of `localhost` you will have to use IP address of your docker machine,
|
||||
which you can find by running `docker-machine env <machinename>` (see [documentation](https://docs.docker.com/machine/reference/env/)
|
||||
for details).
|
||||
Setting up a ssh tunnel is applicable to remote docker hosts as well.
|
||||
|
||||
(Optional) Create kubernetes cluster configuration:
|
||||
|
||||
```shell
|
||||
kubectl config set-cluster test-doc --server=http://localhost:8080
|
||||
kubectl config set-context test-doc --cluster=test-doc
|
||||
kubectl config use-context test-doc
|
||||
```
|
||||
|
||||
### Test it out
|
||||
|
||||
|
|
@ -98,8 +117,8 @@ kubectl get nodes
|
|||
This should print:
|
||||
|
||||
```shell
|
||||
NAME LABELS STATUS
|
||||
127.0.0.1 kubernetes.io/hostname=127.0.0.1 Ready
|
||||
NAME STATUS AGE
|
||||
127.0.0.1 Ready 1h
|
||||
```
|
||||
|
||||
### Run an application
|
||||
|
|
@ -108,7 +127,7 @@ NAME LABELS STATUS
|
|||
kubectl run nginx --image=nginx --port=80
|
||||
```
|
||||
|
||||
Now run `docker ps` you should see nginx running. You may need to wait a few minutes for the image to get pulled.
|
||||
Now run `docker ps` you should see nginx running. You may need to wait a few minutes for the image to get pulled.
|
||||
|
||||
### Expose it as a service
|
||||
|
||||
|
|
@ -116,66 +135,77 @@ Now run `docker ps` you should see nginx running. You may need to wait a few mi
|
|||
kubectl expose deployment nginx --port=80
|
||||
```
|
||||
|
||||
Run the following command to obtain the IP of this service we just created. There are two IPs, the first one is internal (CLUSTER_IP), and the second one is the external load-balanced IP (if a LoadBalancer is configured)
|
||||
Run the following command to obtain the cluster local IP of this service we just created:
|
||||
|
||||
```shell
|
||||
kubectl get svc nginx
|
||||
```
|
||||
```shell{% raw %}
|
||||
ip=$(kubectl get svc nginx --template={{.spec.clusterIP}})
|
||||
echo $ip
|
||||
{% endraw %}```
|
||||
|
||||
Alternatively, you can obtain only the first IP (CLUSTER_IP) by running:
|
||||
Hit the webserver with this IP:
|
||||
|
||||
```shell
|
||||
```shell{% raw %}
|
||||
kubectl get svc nginx --template={{.spec.clusterIP}}
|
||||
```
|
||||
{% endraw %}```
|
||||
|
||||
Hit the webserver with the first IP (CLUSTER_IP):
|
||||
On OS X, since docker is running inside a VM, run the following command instead:
|
||||
|
||||
```shell
|
||||
curl <insert-cluster-ip-here>
|
||||
docker-machine ssh `docker-machine active` curl $ip
|
||||
```
|
||||
|
||||
Note that you will need run this curl command on your boot2docker VM if you are running on OS X.
|
||||
|
||||
## Deploy a DNS
|
||||
|
||||
See [here](/docs/getting-started-guides/docker-multinode/deployDNS/) for instructions.
|
||||
|
||||
### A note on turning down your cluster
|
||||
### Turning down your cluster
|
||||
|
||||
Many of these containers run under the management of the `kubelet` binary, which attempts to keep containers running, even if they fail. So, in order to turn down
|
||||
the cluster, you need to first kill the kubelet container, and then any other containers.
|
||||
1. Delete all the containers including the kubelet:
|
||||
|
||||
You may use `docker kill $(docker ps -aq)`, note this removes _all_ containers running under Docker, so use with caution.
|
||||
Many of these containers run under the management of the `kubelet` binary, which attempts to keep containers running, even if they fail.
|
||||
So, in order to turn down the cluster, you need to first kill the kubelet container, and then any other containers.
|
||||
|
||||
You may use `docker rm -f $(docker ps -aq)`, note this removes _all_ containers running under Docker, so use with caution.
|
||||
|
||||
2. Cleanup the filesystem:
|
||||
|
||||
On OS X, first ssh into the docker VM:
|
||||
|
||||
```shell
|
||||
docker-machine ssh `docker-machine active`
|
||||
```
|
||||
|
||||
```shell
|
||||
sudo umount `cat /proc/mounts | grep /var/lib/kubelet | awk '{print $2}'`
|
||||
sudo rm -rf /var/lib/kubelet
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Node is in `NotReady` state
|
||||
|
||||
If you see your node as `NotReady` it's possible that your OS does not have memcg and swap enabled.
|
||||
If you see your node as `NotReady` it's possible that your OS does not have memcg enabled.
|
||||
|
||||
1. Your kernel should support memory and swap accounting. Ensure that the
|
||||
1. Your kernel should support memory accounting. Ensure that the
|
||||
following configs are turned on in your linux kernel:
|
||||
|
||||
```shell
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_MEMCG_SWAP_ENABLED=y
|
||||
CONFIG_MEMCG_KMEM=y
|
||||
```
|
||||
```shell
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_MEMCG=y
|
||||
```
|
||||
|
||||
2. Enable the memory and swap accounting in the kernel, at boot, as command line
|
||||
2. Enable the memory accounting in the kernel, at boot, as command line
|
||||
parameters as follows:
|
||||
|
||||
```shell
|
||||
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
|
||||
```
|
||||
```shell
|
||||
GRUB_CMDLINE_LINUX="cgroup_enable=memory=1"
|
||||
```
|
||||
|
||||
NOTE: The above is specifically for GRUB2.
|
||||
You can check the command line parameters passed to your kernel by looking at the
|
||||
output of /proc/cmdline:
|
||||
NOTE: The above is specifically for GRUB2.
|
||||
You can check the command line parameters passed to your kernel by looking at the
|
||||
output of /proc/cmdline:
|
||||
|
||||
```shell
|
||||
$ cat /proc/cmdline
|
||||
BOOT_IMAGE=/boot/vmlinuz-3.18.4-aufs root=/dev/sda5 ro cgroup_enable=memory swapaccount=1
|
||||
```
|
||||
```shell
|
||||
$ cat /proc/cmdline
|
||||
BOOT_IMAGE=/boot/vmlinuz-3.18.4-aufs root=/dev/sda5 ro cgroup_enable=memory=1
|
||||
```
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ But their size and availability is limited to that of a single machine.
|
|||
The local-machine solutions are:
|
||||
|
||||
- [Local Docker-based](/docs/getting-started-guides/docker) (recommended starting point)
|
||||
- [Vagrant](/docs/getting-started-guides/vagrant) (works on any platform with Vagrant: Linux, MacOS, or Windows.)
|
||||
- [No-VM local cluster](/docs/getting-started-guides/locally) (Linux only)
|
||||
- [Vagrant](/docs/getting-started-guides/vagrant)
|
||||
|
||||
|
||||
### Hosted Solutions
|
||||
|
|
@ -49,6 +49,7 @@ few commands, and have active community support.
|
|||
- [GCE](/docs/getting-started-guides/gce)
|
||||
- [AWS](/docs/getting-started-guides/aws)
|
||||
- [Azure](/docs/getting-started-guides/coreos/azure/)
|
||||
- [CenturyLink Cloud](/docs/getting-started-guides/clc)
|
||||
|
||||
### Custom Solutions
|
||||
|
||||
|
|
@ -82,6 +83,7 @@ These solutions are combinations of cloud provider and OS not covered by the abo
|
|||
- [Vmware](/docs/getting-started-guides/coreos) (uses CoreOS and flannel)
|
||||
- [libvirt-coreos.md](/docs/getting-started-guides/libvirt-coreos) (uses CoreOS)
|
||||
- [oVirt](/docs/getting-started-guides/ovirt)
|
||||
- [OpenStack Heat](/docs/getting-started-guides/openstack-heat) (uses CentOS and flannel)
|
||||
- [libvirt](/docs/getting-started-guides/fedora/flannel_multi_node_cluster) (uses Fedora and flannel)
|
||||
- [KVM](/docs/getting-started-guides/fedora/flannel_multi_node_cluster) (uses Fedora and flannel)
|
||||
|
||||
|
|
@ -112,11 +114,10 @@ Here are all the solutions mentioned above in table form.
|
|||
IaaS Provider | Config. Mgmt | OS | Networking | Docs | Conforms | Support Level
|
||||
-------------------- | ------------ | ------ | ---------- | --------------------------------------------- | ---------| ----------------------------
|
||||
GKE | | | GCE | [docs](https://cloud.google.com/container-engine) | ['œ“][3] | Commercial
|
||||
Vagrant | Saltstack | Fedora | flannel | [docs](/docs/getting-started-guides/vagrant) | ['œ“][2] | Project
|
||||
GCE | Saltstack | Debian | GCE | [docs](/docs/getting-started-guides/gce) | ['œ“][1] | Project
|
||||
Azure | CoreOS | CoreOS | Weave | [docs](/docs/getting-started-guides/coreos/azure/) | | Community ([@errordeveloper](https://github.com/errordeveloper), [@squillace](https://github.com/squillace), [@chanezon](https://github.com/chanezon), [@crossorigin](https://github.com/crossorigin))
|
||||
Docker Single Node | custom | N/A | local | [docs](/docs/getting-started-guides/docker) | | Project ([@brendandburns](https://github.com/brendandburns))
|
||||
Docker Multi Node | Flannel | N/A | local | [docs](/docs/getting-started-guides/docker-multinode) | | Project ([@brendandburns](https://github.com/brendandburns))
|
||||
Docker Multi Node | custom | N/A | flannel | [docs](/docs/getting-started-guides/docker-multinode) | | Project ([@brendandburns](https://github.com/brendandburns))
|
||||
Bare-metal | Ansible | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/fedora_ansible_config) | | Project
|
||||
Bare-metal | custom | Fedora | _none_ | [docs](/docs/getting-started-guides/fedora/fedora_manual_config) | | Project
|
||||
Bare-metal | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster) | | Community ([@aveshagarwal](https://github.com/aveshagarwal))
|
||||
|
|
@ -141,6 +142,7 @@ Bare-metal | custom | Ubuntu | Calico | [docs](/docs/gettin
|
|||
Bare-metal | custom | Ubuntu | flannel | [docs](/docs/getting-started-guides/ubuntu) | | Community ([@resouer](https://github.com/resouer), [@WIZARD-CXY](https://github.com/WIZARD-CXY))
|
||||
libvirt/KVM | CoreOS | CoreOS | libvirt/KVM | [docs](/docs/getting-started-guides/libvirt-coreos) | | Community ([@lhuard1A](https://github.com/lhuard1A))
|
||||
oVirt | | | | [docs](/docs/getting-started-guides/ovirt) | | Community ([@simon3z](https://github.com/simon3z))
|
||||
OpenStack Heat | Saltstack | CentOS | Neutron + flannel hostgw | [docs](/docs/getting-started-guides/openstack-heat) | | Community ([@FujitsuEnablingSoftwareTechnologyGmbH](https://github.com/FujitsuEnablingSoftwareTechnologyGmbH))
|
||||
Rackspace | CoreOS | CoreOS | flannel | [docs](/docs/getting-started-guides/rackspace) | | Community ([@doublerr](https://github.com/doublerr))
|
||||
any | any | any | any | [docs](/docs/getting-started-guides/scratch) | | Community ([@erictune](https://github.com/erictune))
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,15 @@
|
|||
|
||||
[Juju](https://jujucharms.com/docs/stable/about-juju) makes it easy to deploy
|
||||
Kubernetes by provisioning, installing and configuring all the systems in
|
||||
the cluster. Once deployed the cluster can easily scale up with one command
|
||||
the cluster. Once deployed the cluster can easily scale up with one command
|
||||
to increase the cluster size.
|
||||
|
||||
The Juju Kubernetes work is curated by a very small group of community members.
|
||||
Let us know how we are doing. If you find any problems please open an
|
||||
[issue at the kubernetes project](https://github.com/kubernetes/kubernetes/issues)
|
||||
and tag the issue with "juju" so we can find them.
|
||||
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
|
|
@ -13,48 +19,57 @@ to increase the cluster size.
|
|||
|
||||
> Note: If you're running kube-up, on Ubuntu - all of the dependencies
|
||||
> will be handled for you. You may safely skip to the section:
|
||||
> [Launch Kubernetes Cluster](#launch-kubernetes-cluster)
|
||||
> [Launch a Kubernetes Cluster](#launch-a-kubernetes-cluster)
|
||||
|
||||
### On Ubuntu
|
||||
|
||||
[Install the Juju client](https://jujucharms.com/get-started) on your
|
||||
local Ubuntu system:
|
||||
[Install the Juju client](https://jujucharms.com/get-started)
|
||||
|
||||
> This documentation focuses on the Juju 2.0 release which will be
|
||||
> promoted to stable during the April 2016 release cycle.
|
||||
|
||||
To paraphrase, on your local Ubuntu system:
|
||||
|
||||
```shell
|
||||
sudo add-apt-repository ppa:juju/stable
|
||||
sudo add-apt-repository ppa:juju/devel
|
||||
sudo apt-get update
|
||||
sudo apt-get install juju-core juju-quickstart
|
||||
sudo apt-get install juju2
|
||||
```
|
||||
|
||||
If you are using another distro/platform - please consult the
|
||||
[getting started guide](https://jujucharms.com/get-started) to install the
|
||||
Juju dependencies for your platform.
|
||||
|
||||
### With Docker
|
||||
|
||||
If you are not using Ubuntu or prefer the isolation of Docker, you may
|
||||
run the following:
|
||||
|
||||
```shell
|
||||
mkdir ~/.juju
|
||||
sudo docker run -v ~/.juju:/home/ubuntu/.juju -ti jujusolutions/jujubox:latest
|
||||
```
|
||||
|
||||
At this point from either path you will have access to the `juju
|
||||
quickstart` command.
|
||||
|
||||
To set up the credentials for your chosen cloud run:
|
||||
> While this is a common target, the charmbox flavors of images are
|
||||
> unofficial, and should be treated as experimental. If you encounter any issues
|
||||
> turning up the Kubernetes cluster with charmbox, please file a bug on the
|
||||
> [charmbox issue tracker](https://github.com/juju-solutions/charmbox/issues).
|
||||
|
||||
```shell
|
||||
juju quickstart --constraints="mem=3.75G" -i
|
||||
mkdir ~/.juju2
|
||||
sudo docker run -v ~/.juju2:/home/ubuntu/.local/share/juju -ti jujusolutions/charmbox:devel
|
||||
```
|
||||
|
||||
> The `constraints` flag is optional, it changes the size of virtual machines
|
||||
> that Juju will generate when it requests a new machine. Larger machines
|
||||
> will run faster but cost more money than smaller machines.
|
||||
### Configure Juju to point a cloud
|
||||
|
||||
Follow the dialogue and choose `save` and `use`. Quickstart will now
|
||||
bootstrap the juju root node and setup the juju web based user
|
||||
interface.
|
||||
At this point you have access to the Juju client. Before you can deploy a
|
||||
cluster you have to configure the credentials for the Juju cloud provider.
|
||||
|
||||
Juju [supports a wide variety of public clouds](#Cloud-compatibility) to set
|
||||
up the credentials for your chosen cloud see the
|
||||
[cloud setup page](https://jujucharms.com/docs/devel/getting-started#2.-choose-a-cloud).
|
||||
|
||||
## Launch Kubernetes cluster
|
||||
After configuration is complete test your setup with a `juju bootstrap`
|
||||
command:
|
||||
`juju bootstrap $cloudname $cloudtype` you are ready to launch the
|
||||
Kubernetes cluster.
|
||||
|
||||
## Launch a Kubernetes cluster
|
||||
|
||||
You will need to export the `KUBERNETES_PROVIDER` environment variable before
|
||||
bringing up the cluster.
|
||||
|
|
@ -64,44 +79,50 @@ export KUBERNETES_PROVIDER=juju
|
|||
cluster/kube-up.sh
|
||||
```
|
||||
|
||||
If this is your first time running the `kube-up.sh` script, it will install
|
||||
the required dependencies to get started with Juju, additionally it will
|
||||
launch a curses based configuration utility allowing you to select your cloud
|
||||
provider and enter the proper access credentials.
|
||||
|
||||
Next it will deploy the kubernetes master, etcd, 2 nodes with flannel based
|
||||
Software Defined Networking (SDN) so containers on different hosts can
|
||||
communicate with each other.
|
||||
If this is your first time running the `kube-up.sh` script, it will attempt to
|
||||
install the required dependencies to get started with Juju.
|
||||
|
||||
Next it will deploy two nodes of Kubernetes, 1 unit of etcd, and network
|
||||
the units so containers on different hosts can communicate with each other.
|
||||
|
||||
## Exploring the cluster
|
||||
|
||||
The `juju status` command provides information about each unit in the cluster:
|
||||
|
||||
```shell
|
||||
$ juju status --format=oneline
|
||||
- docker/0: 52.4.92.78 (started)
|
||||
- flannel-docker/0: 52.4.92.78 (started)
|
||||
- kubernetes/0: 52.4.92.78 (started)
|
||||
- docker/1: 52.6.104.142 (started)
|
||||
- flannel-docker/1: 52.6.104.142 (started)
|
||||
- kubernetes/1: 52.6.104.142 (started)
|
||||
- etcd/0: 52.5.216.210 (started) 4001/tcp
|
||||
- juju-gui/0: 52.5.205.174 (started) 80/tcp, 443/tcp
|
||||
- kubernetes-master/0: 52.6.19.238 (started) 8080/tcp
|
||||
```
|
||||
$ juju status
|
||||
|
||||
You can use `juju ssh` to access any of the units:
|
||||
... (omitted for brevity)
|
||||
|
||||
```shell
|
||||
juju ssh kubernetes-master/0
|
||||
[Units]
|
||||
ID WORKLOAD-STATE AGENT-STATE VERSION MACHINE PORTS PUBLIC-ADDRESS MESSAGE
|
||||
etcd/0 active idle 2.0-beta2 1 54.146.50.29 Etcd leader running
|
||||
kubernetes/0 active idle 2.0-beta2 2 6443/tcp,8088/tcp 54.205.204.227 Kubernetes follower running
|
||||
kubernetes/1 active idle 2.0-beta2 3 6443/tcp,8088/tcp 54.145.57.114 Kubernetes leader running
|
||||
|
||||
... (omitted for brevity)
|
||||
```
|
||||
|
||||
## Run some containers!
|
||||
|
||||
`kubectl` is available on the Kubernetes master node. We'll ssh in to
|
||||
launch some containers, but one could use `kubectl` locally by setting
|
||||
`KUBERNETES_MASTER` to point at the ip address of "kubernetes-master/0".
|
||||
The `kubectl` file, the TLS certificates along with the configuration are
|
||||
all available on the Kubernetes leader unit. Fetch the kubectl package so you
|
||||
can run commands on the new Kuberntetes cluster.
|
||||
|
||||
Use the `juju status` command to figure out which Kubernetes unit is the leader
|
||||
and copy the file from the leader:
|
||||
|
||||
```shell
|
||||
juju scp kubernetes/1:kubectl_package.tar.gz .
|
||||
tar xvfz kubectl_package.tar.gz
|
||||
kubectl --kubeconfig config get pods
|
||||
```
|
||||
|
||||
If you are not on a Linux amd64 host system, you will need to find or build a
|
||||
kubectl binary package for your architecture.
|
||||
|
||||
Put the config file in the home directory so you don't have to specify it on
|
||||
the command line each time. The default location is `${HOME}/.kube/config`.
|
||||
|
||||
No pods will be available before starting a container:
|
||||
|
||||
|
|
@ -139,21 +160,20 @@ We'll follow the aws-coreos example. Create a pod manifest: `pod.json`
|
|||
}
|
||||
```
|
||||
|
||||
Create the pod with kubectl:
|
||||
Create the pod with kubectl:
|
||||
|
||||
```shell
|
||||
kubectl create -f pod.json
|
||||
```
|
||||
|
||||
Get info on the pod:
|
||||
Get info on the pod:
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
To test the hello app, we need to locate which node is hosting
|
||||
the container. Better tooling for using Juju to introspect container
|
||||
is in the works but we can use `juju run` and `juju status` to find
|
||||
the container. We can use `juju run` and `juju status` commands to find
|
||||
our hello app.
|
||||
|
||||
Exit out of our ssh session and run:
|
||||
|
|
@ -166,7 +186,8 @@ CONTAINER IDIMAGE COMMAND CREATED STATUS PORTS NAMES
|
|||
02beb61339d8quay.io/kelseyhightower/hello:latest /hello About an hour ago Up About an hourk8s_hello....
|
||||
```
|
||||
|
||||
We see "kubernetes/1" has our container, we can open port 80:
|
||||
We see "kubernetes/1" has our container, expose the kubernetes charm and open
|
||||
port 80:
|
||||
|
||||
```shell
|
||||
juju run --unit kubernetes/1 "open-port 80"
|
||||
|
|
@ -175,55 +196,65 @@ sudo apt-get install curl
|
|||
curl $(juju status --format=oneline kubernetes/1 | cut -d' ' -f3)
|
||||
```
|
||||
|
||||
Finally delete the pod:
|
||||
Finally delete the pod:
|
||||
|
||||
```shell
|
||||
juju ssh kubernetes-master/0
|
||||
juju ssh kubernetes/0
|
||||
kubectl delete pods hello
|
||||
```
|
||||
## Scale up cluster
|
||||
|
||||
Want larger Kubernetes nodes? It is easy to request different sizes of cloud
|
||||
resources from Juju by using **constraints**. You can increase the amount of
|
||||
CPU or memory (RAM) in any of the systems requested by Juju. This allows you
|
||||
to fine tune th Kubernetes cluster to fit your workload. Use flags on the
|
||||
bootstrap command or as a separate `juju constraints` command. Look to the
|
||||
[Juju documentation for machine constraints](https://jujucharms.com/docs/devel/charms-constraints)
|
||||
details.
|
||||
|
||||
## Scale out cluster
|
||||
|
||||
We can add node units like so:
|
||||
Need more clusters? Juju makes it easy to add units of a charm:
|
||||
|
||||
```shell
|
||||
juju add-unit docker # creates unit docker/2, kubernetes/2, docker-flannel/2
|
||||
juju add-unit kubernetes
|
||||
```
|
||||
|
||||
## Launch the "k8petstore" example app
|
||||
|
||||
The [k8petstore example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/k8petstore/) is available as a
|
||||
[juju action](https://jujucharms.com/docs/devel/actions).
|
||||
Or multiple units at one time:
|
||||
|
||||
```shell
|
||||
juju action do kubernetes-master/0
|
||||
juju add-unit -n3 kubernetes
|
||||
```
|
||||
|
||||
> Note: this example includes curl statements to exercise the app, which
|
||||
> automatically generates "petstore" transactions written to redis, and allows
|
||||
> you to visualize the throughput in your browser.
|
||||
|
||||
## Tear down cluster
|
||||
|
||||
We recommend that you use the `kube-down.sh` command when you are done using
|
||||
the cluster, as it properly brings down the cloud and removes some of the
|
||||
build directories.
|
||||
|
||||
```shell
|
||||
./kube-down.sh
|
||||
```
|
||||
|
||||
or destroy your current Juju environment (using the `juju env` command):
|
||||
Alternately if you want stop the servers you can destroy your current Juju
|
||||
environment. Use the `juju env` command to get the current environment name:
|
||||
|
||||
```shell
|
||||
juju destroy-environment --force `juju env`
|
||||
juju kill-controller `juju env`
|
||||
```
|
||||
|
||||
|
||||
## More Info
|
||||
|
||||
The Kubernetes charms and bundles can be found in the `kubernetes` project on
|
||||
github.com:
|
||||
Juju works with charms and bundles to deploy solutions. The code that stands up
|
||||
a Kubernetes cluster is done in the charm code. The charm is built from using
|
||||
a layered approach to keep the code smaller and more focused on the operations
|
||||
of Kubernetes.
|
||||
|
||||
- [Bundle Repository](http://releases.k8s.io/{{page.githubbranch}}/cluster/juju/bundles)
|
||||
* [Kubernetes master charm](https://releases.k8s.io/{{page.githubbranch}}/cluster/juju/charms/trusty/kubernetes-master)
|
||||
* [Kubernetes node charm](https://releases.k8s.io/{{page.githubbranch}}/cluster/juju/charms/trusty/kubernetes)
|
||||
The Kubernetes layer and bundles can be found in the `kubernetes`
|
||||
project on github.com:
|
||||
|
||||
- [Bundle location](https://github.com/kubernetes/kubernetes/tree/master/cluster/juju/bundles)
|
||||
- [Kubernetes charm layer location](https://github.com/kubernetes/kubernetes/tree/master/cluster/juju/layers/kubernetes)
|
||||
- [More about Juju](https://jujucharms.com)
|
||||
|
||||
|
||||
|
|
@ -241,8 +272,6 @@ works with [Amazon Web Service](https://jujucharms.com/docs/stable/config-aws),
|
|||
[Vagrant](https://jujucharms.com/docs/stable/config-vagrant), and
|
||||
[Vmware vSphere](https://jujucharms.com/docs/stable/config-vmware).
|
||||
|
||||
If you do not see your favorite cloud provider listed many clouds can be
|
||||
configured for [manual provisioning](https://jujucharms.com/docs/stable/config-manual).
|
||||
|
||||
The Kubernetes bundle has been tested on GCE and AWS and found to work with
|
||||
version 1.0.0.
|
||||
If you do not see your favorite cloud provider listed many clouds with ssh
|
||||
access can be configured for
|
||||
[manual provisioning](https://jujucharms.com/docs/stable/config-manual).
|
||||
|
|
|
|||
|
|
@ -117,6 +117,32 @@ setfacl -m g:kvm:--x ~
|
|||
|
||||
By default, the libvirt-coreos setup will create a single Kubernetes master and 3 Kubernetes nodes. Because the VM drives use Copy-on-Write and because of memory ballooning and KSM, there is a lot of resource over-allocation.
|
||||
|
||||
There is both an automated way and a manual, customizable way of setting up libvert Kubernetes clusters on CoreOS.
|
||||
|
||||
#### Automated setup
|
||||
|
||||
There is an automated setup script on https://get.k8s.io that will download the tarball for Kubernetes and spawn a Kubernetes cluster on a local CoreOS instances that the script creates. To run this script, use wget or curl with the KUBERNETES_PROVIDER environment variable set to libvirt-coreos:
|
||||
|
||||
```shell
|
||||
export KUBERNETES_PROVIDER=libvirt-coreos; wget -q -O - https://get.k8s.io | bash
|
||||
```
|
||||
|
||||
Here is the curl version of this command:
|
||||
|
||||
```shell
|
||||
export KUBERNETES_PROVIDER=libvirt-coreos; curl -sS https://get.k8s.io | bash`
|
||||
```
|
||||
|
||||
This script downloads and unpacks the tarball, then spawns a Kubernetes cluster on CoreOS instances with the following characteristics:
|
||||
|
||||
- Total of 4 KVM/QEMU instances
|
||||
- 1 instance acting as a Kubernetes master node
|
||||
- 3 instances acting as minion nodes
|
||||
|
||||
If you'd like to run this cluster with customized settings, follow the manual setup instructions.
|
||||
|
||||
#### Manual setup
|
||||
|
||||
To start your local cluster, open a shell and run:
|
||||
|
||||
```shell
|
||||
|
|
@ -135,6 +161,8 @@ The `KUBE_PUSH` environment variable may be set to specify which Kubernetes bina
|
|||
* `release` (default if `KUBE_PUSH` is not set) will deploy the binaries of `_output/release-tars/kubernetes-server-….tar.gz`. This is built with `make release` or `make release-skip-tests`.
|
||||
* `local` will deploy the binaries of `_output/local/go/bin`. These are built with `make`.
|
||||
|
||||
### Management
|
||||
|
||||
You can check that your machines are there and running with:
|
||||
|
||||
```shell
|
||||
|
|
@ -233,7 +261,7 @@ On Arch:
|
|||
pacman -S qemu libvirt
|
||||
```
|
||||
|
||||
On Ubuntu 14.04.1:
|
||||
On Ubuntu 14.04:
|
||||
|
||||
```shell
|
||||
aptitude install qemu-system-x86 libvirt-bin
|
||||
|
|
@ -255,7 +283,7 @@ On Arch:
|
|||
systemctl start libvirtd
|
||||
```
|
||||
|
||||
On Ubuntu 14.04.1:
|
||||
On Ubuntu 14.04:
|
||||
|
||||
```shell
|
||||
service libvirt-bin start
|
||||
|
|
@ -291,4 +319,4 @@ usermod -a -G libvirtd $USER
|
|||
|
||||
#### error: Out of memory initializing network (virsh net-create...)
|
||||
|
||||
Ensure libvirtd has been restarted since ebtables was installed.
|
||||
Ensure libvirtd has been restarted since ebtables was installed.
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
#### Linux
|
||||
|
||||
Not running Linux? Consider running Linux in a local virtual machine with [Vagrant](/docs/getting-started-guides/vagrant), or on a cloud provider like [Google Compute Engine](/docs/getting-started-guides/gce)
|
||||
Not running Linux? Consider running Linux in a local virtual machine with [vagrant](https://www.vagrantup.com/), or on a cloud provider like [Google Compute Engine](/docs/getting-started-guides/gce)
|
||||
|
||||
#### Docker
|
||||
|
||||
At least [Docker](https://docs.docker.com/installation/#installation)
|
||||
1.3+. Ensure the Docker daemon is running and can be contacted (try `docker
|
||||
1.8.3+. Ensure the Docker daemon is running and can be contacted (try `docker
|
||||
ps`). Some of the Kubernetes components need to run as root, which normally
|
||||
works fine with docker.
|
||||
|
||||
|
|
@ -27,7 +27,8 @@ You need [go](https://golang.org/doc/install) at least 1.3+ in your path, please
|
|||
|
||||
### Starting the cluster
|
||||
|
||||
In a separate tab of your terminal, run the following (since one needs sudo access to start/stop Kubernetes daemons, it is easier to run the entire script as root):
|
||||
First, you need to [download Kubernetes](/docs/getting-started-guides/binary_release/). Then open a separate tab of your terminal
|
||||
and run the following (since one needs sudo access to start/stop Kubernetes daemons, it is easier to run the entire script as root):
|
||||
|
||||
```shell
|
||||
cd kubernetes
|
||||
|
|
@ -50,7 +51,7 @@ You can now use any of the cluster/kubectl.sh commands to interact with your loc
|
|||
```shell
|
||||
cluster/kubectl.sh get pods
|
||||
cluster/kubectl.sh get services
|
||||
cluster/kubectl.sh get replicationcontrollers
|
||||
cluster/kubectl.sh get deployments
|
||||
cluster/kubectl.sh run my-nginx --image=nginx --replicas=2 --port=80
|
||||
|
||||
## begin wait for provision to complete, you can monitor the docker pull by opening a new terminal
|
||||
|
|
@ -64,7 +65,7 @@ cluster/kubectl.sh run my-nginx --image=nginx --replicas=2 --port=80
|
|||
## introspect Kubernetes!
|
||||
cluster/kubectl.sh get pods
|
||||
cluster/kubectl.sh get services
|
||||
cluster/kubectl.sh get replicationcontrollers
|
||||
cluster/kubectl.sh get deployments
|
||||
```
|
||||
|
||||
### Running a user defined pod
|
||||
|
|
@ -81,7 +82,7 @@ cluster/kubectl.sh create -f docs/user-guide/pod.yaml
|
|||
|
||||
Congratulations!
|
||||
|
||||
### Troubleshooting
|
||||
### FAQs
|
||||
|
||||
#### I cannot reach service IPs on the network.
|
||||
|
||||
|
|
@ -95,10 +96,6 @@ docker installation, this may conflict with IPs for containers. If you find
|
|||
containers running with IPs in this range, edit hack/local-cluster-up.sh and
|
||||
change the service-cluster-ip-range flag to something else.
|
||||
|
||||
#### I cannot create a replication controller with replica size greater than 1! What gives?
|
||||
|
||||
You are running a single node setup. This has the limitation of only supporting a single replica of a given pod. If you are interested in running with larger replica sizes, we encourage you to try the local vagrant setup or one of the cloud providers.
|
||||
|
||||
#### I changed Kubernetes code, how do I run it?
|
||||
|
||||
```shell
|
||||
|
|
@ -109,8 +106,13 @@ hack/local-up-cluster.sh
|
|||
|
||||
#### kubectl claims to start a container but `get pods` and `docker ps` don't show it.
|
||||
|
||||
One or more of the KUbernetes daemons might've crashed. Tail the logs of each in /tmp.
|
||||
One or more of the Kubernetes daemons might've crashed. Tail the [logs](/docs/admin/cluster-troubleshooting/#looking-at-logs) of each in /tmp.
|
||||
|
||||
```shell
|
||||
$ ls /tmp/kube*.log
|
||||
$ tail -f /tmp/kube-apiserver.log
|
||||
```
|
||||
|
||||
#### The pods fail to connect to the services by host names
|
||||
|
||||
The local-up-cluster.sh script doesn't start a DNS service. Similar situation can be found [here](http://issue.k8s.io/6667). You can start a manually. Related documents can be found [here](https://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns#how-do-i-configure-it)
|
||||
The local-up-cluster.sh script doesn't start a DNS service. Similar situation can be found [here](http://issue.k8s.io/6667). You can start a manually. Related documents can be found [here](https://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns#how-do-i-configure-it)
|
||||
|
|
|
|||
|
|
@ -161,6 +161,6 @@ $ cat 21\:00\:00_21\:59\:59_S0.json | jq '.structPayload.log'
|
|||
...
|
||||
```
|
||||
|
||||
This page has touched briefly on the underlying mechanisms that support gathering cluster level logs on a Kubernetes deployment. The approach here only works for gathering the standard output and standard error output of the processes running in the pod's containers. To gather other logs that are stored in files one can use a sidecar container to gather the required files as described at the page [Collecting log files within containers with Fluentd](http://releases.k8s.io/{{page.githubbranch}}/contrib/logging/fluentd-sidecar-gcp/README.md) and sending them to the Google Cloud Logging service.
|
||||
This page has touched briefly on the underlying mechanisms that support gathering cluster level logs on a Kubernetes deployment. The approach here only works for gathering the standard output and standard error output of the processes running in the pod's containers. To gather other logs that are stored in files one can use a sidecar container to gather the required files as described at the page [Collecting log files within containers with Fluentd](https://github.com/kubernetes/contrib/blob/master/logging/fluentd-sidecar-gcp/README.md) and sending them to the Google Cloud Logging service.
|
||||
|
||||
Some of the material in this section also appears in the blog article [Cluster Level Logging with Kubernetes](http://blog.kubernetes.io/2015/06/cluster-level-logging-with-kubernetes)
|
||||
Some of the material in this section also appears in the blog article [Cluster Level Logging with Kubernetes](http://blog.kubernetes.io/2015/06/cluster-level-logging-with-kubernetes.html)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
**By: Sandeep Dinesh** - _July 29, 2015_
|
||||
|
||||

|
||||

|
||||
|
||||
In [a recent post](http://blog.sandeepdinesh.com/2015/07/running-mean-web-application-in-docker.html), I talked about running a MEAN stack with [Docker Containers.](http://docker.com/)
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ Thankfully, there is a system we can use to manage our containers in a cluster e
|
|||
* TOC
|
||||
{:toc}
|
||||
|
||||
## The Basics of Using Kubernetes
|
||||
## The Basics of Using Kubernetes
|
||||
|
||||
Before we jump in and start kube’ing it up, it’s important to understand some of the fundamentals of Kubernetes.
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ Instead, you have to build a custom container that has the code already inside i
|
|||
|
||||
To do this, you need to use more Docker. Make sure you have the latest version installed for the rest of this tutorial.
|
||||
|
||||
Getting the code:
|
||||
Getting the code:
|
||||
|
||||
Before starting, let’s get some code to run. You can follow along on your personal machine or a Linux VM in the cloud. I recommend using Linux or a Linux VM; running Docker on Mac and Windows is outside the scope of this tutorial.
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ First, you need a `Dockerfile`. This is basically the list of instructions Docke
|
|||
Here is the `Dockerfile` for the web server:
|
||||
|
||||
```shell
|
||||
FROM node:0.10.40
|
||||
FROM node:4.4
|
||||
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
|
@ -65,14 +65,14 @@ CMD ["node", "app.js"]
|
|||
|
||||
A `Dockerfile` is pretty self explanatory, and this one is dead simple.
|
||||
|
||||
First, it uses the official Node.js image as the base image.
|
||||
First, it uses the official Node.js LTS image as the base image.
|
||||
|
||||
Then, it creates a folder to store the code, `cd`s into that directory, copies the code in, and installs the dependencies with npm.
|
||||
|
||||
Finally, it specifies the command Docker should run when the container starts, which is to start the app.
|
||||
|
||||
|
||||
## Step 2: Building our Container
|
||||
## Step 2: Building our Container
|
||||
|
||||
Right now, the directory should look like this:
|
||||
|
||||
|
|
@ -410,11 +410,11 @@ web-controller-xxxx 1/1 Running 0 1m
|
|||
|
||||
## Step 9: Accessing the App
|
||||
|
||||
At this point, everything is up and running. The architecture looks something like this:
|
||||
At this point, everything is up and running. The architecture looks something like this:
|
||||
|
||||

|
||||
{: style="max-width:25%"}
|
||||
|
||||
By default, port 80 should be open on the load balancer. In order to find the IP address of our app, run this command:
|
||||
By default, port 80 should be open on the load balancer. In order to find the IP address of our app, run this command:
|
||||
|
||||
```shell
|
||||
$ gcloud compute forwarding-rules list
|
||||
|
|
@ -441,4 +441,3 @@ By using Container Engine and Kubernetes, we have a very robust, container based
|
|||
Hopefully I can do some more posts about advanced Kubernetes topics such as changing the cluster size and number of Node.js web server replicas, using different environments (dev, staging, prod) on the same cluster, and doing rolling updates.
|
||||
|
||||
Thanks to [Mark Mandel](https://medium.com/@markmandel), [Aja Hammerly](https://medium.com/@thagomizer), and [Jack Wilber](https://medium.com/@jack.g.wilber). [Some rights reserved](http://creativecommons.org/licenses/by/4.0/) by the author.
|
||||
|
||||
|
|
|
|||
|
|
@ -229,23 +229,23 @@ Note that we have passed these two values already as parameter to the apiserver
|
|||
|
||||
A template for an replication controller spinning up the pod with the 3 containers can be found at [cluster/addons/dns/skydns-rc.yaml.in][11] in the repository. The following steps are necessary in order to get a valid replication controller yaml file:
|
||||
|
||||
- replace `{{ pillar['dns_replicas'] }}` with `1`
|
||||
- replace `{{ pillar['dns_domain'] }}` with `cluster.local.`
|
||||
- replace `{% raw %}{{ pillar['dns_replicas'] }}{% endraw %}` with `1`
|
||||
- replace `{% raw %}{{ pillar['dns_domain'] }}{% endraw %}` with `cluster.local.`
|
||||
- add `--kube_master_url=${KUBERNETES_MASTER}` parameter to the kube2sky container command.
|
||||
|
||||
In addition the service template at [cluster/addons/dns/skydns-svc.yaml.in][12] needs the following replacement:
|
||||
|
||||
- `{{ pillar['dns_server'] }}` with `10.10.10.10`.
|
||||
- `{% raw %}{{ pillar['dns_server'] }}{% endraw %}` with `10.10.10.10`.
|
||||
|
||||
To do this automatically:
|
||||
|
||||
```shell
|
||||
```shell{% raw %}
|
||||
sed -e "s/{{ pillar\['dns_replicas'\] }}/1/g;"\
|
||||
"s,\(command = \"/kube2sky\"\),\\1\\"$'\n'" - --kube_master_url=${KUBERNETES_MASTER},;"\
|
||||
"s/{{ pillar\['dns_domain'\] }}/cluster.local/g" \
|
||||
cluster/addons/dns/skydns-rc.yaml.in > skydns-rc.yaml
|
||||
sed -e "s/{{ pillar\['dns_server'\] }}/10.10.10.10/g" \
|
||||
cluster/addons/dns/skydns-svc.yaml.in > skydns-svc.yaml
|
||||
cluster/addons/dns/skydns-svc.yaml.in > skydns-svc.yaml{% endraw %}
|
||||
```
|
||||
|
||||
Now the kube-dns pod and service are ready to be launched:
|
||||
|
|
@ -326,4 +326,4 @@ Future work will add instructions to this guide to enable support for Kubernetes
|
|||
[10]: http://open.mesosphere.com/getting-started/cloud/google/mesosphere/#vpn-setup
|
||||
[11]: https://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/skydns-rc.yaml.in
|
||||
[12]: https://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/skydns-svc.yaml.in
|
||||
[13]: https://releases.k8s.io/{{page.githubbranch}}/contrib/mesos/README.md
|
||||
[13]: https://releases.k8s.io/{{page.githubbranch}}/contrib/mesos/README.md
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
---
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## Getting started with OpenStack
|
||||
|
||||
This guide will take you through the steps of deploying Kubernetes to Openstack using `kube-up.sh`. The primary mechanisms for this are [OpenStack Heat](https://wiki.openstack.org/wiki/Heat) and the [SaltStack](https://github.com/kubernetes/kubernetes/tree/master/cluster/saltbase) distributed with Kubernetes.
|
||||
|
||||
The default OS is CentOS 7, this has not been tested on other operating systems.
|
||||
|
||||
This guide assumes you have access to a working OpenStack cluster with the following features:
|
||||
|
||||
- Nova
|
||||
- Neutron
|
||||
- Swift
|
||||
- Glance
|
||||
- Heat
|
||||
- DNS resolution of instance names
|
||||
|
||||
By default this provider provisions 4 m1.medium instances. If you do not have resources available, please see the [Set additional configuration values](#set-additional-configuration-values) section for information on reducing the footprint of your cluster.
|
||||
|
||||
## Pre-Requisites
|
||||
If you already have the required versions of the OpenStack CLI tools installed and configured, you can move on to the [Starting a cluster](#starting-a-cluster) section.
|
||||
|
||||
#### Install OpenStack CLI tools
|
||||
|
||||
```sh
|
||||
sudo pip install -U --force 'python-openstackclient==2.4.0'
|
||||
sudo pip install -U --force 'python-swiftclient==3.0.0'
|
||||
sudo pip install -U --force 'python-glanceclient==2.0.0'
|
||||
sudo pip install -U --force 'python-novaclient==3.4.0'
|
||||
```
|
||||
|
||||
#### Configure Openstack CLI tools
|
||||
|
||||
Please talk to your local OpenStack administrator for an `openrc.sh` file.
|
||||
|
||||
Once you have that file, source it into your environment by typing
|
||||
|
||||
```sh
|
||||
. ~/path/to/openrc.sh
|
||||
```
|
||||
|
||||
This provider will consume the [correct variables](http://docs.openstack.org/user-guide/common/cli_set_environment_variables_using_openstack_rc.html) to talk to OpenStack and turn-up the Kubernetes cluster.
|
||||
|
||||
Otherwise, you must set the following appropriately:
|
||||
|
||||
```sh
|
||||
export OS_USERNAME=username
|
||||
export OS_PASSWORD=password
|
||||
export OS_TENANT_NAME=projectName
|
||||
export OS_AUTH_URL=https://identityHost:portNumber/v2.0
|
||||
export OS_TENANT_ID=tenantIDString
|
||||
export OS_REGION_NAME=regionName
|
||||
```
|
||||
|
||||
#### Set additional configuration values
|
||||
|
||||
In addition, here are some commonly changed variables specific to this provider, with example values. Under most circumstances you will not have to change these. Please see the files in the next section for a full list of options.
|
||||
|
||||
```sh
|
||||
export STACK_NAME=KubernetesStack
|
||||
export NUMBER_OF_MINIONS=3
|
||||
export MAX_NUMBER_OF_MINIONS=3
|
||||
export MASTER_FLAVOR=m1.small
|
||||
export MINION_FLAVOR=m1.small
|
||||
export EXTERNAL_NETWORK=public
|
||||
export DNS_SERVER=8.8.8.8
|
||||
export IMAGE_URL_PATH=http://cloud.centos.org/centos/7/images
|
||||
export IMAGE_FILE=CentOS-7-x86_64-GenericCloud-1510.qcow2
|
||||
export SWIFT_SERVER_URL=http://192.168.123.100:8080
|
||||
export ENABLE_PROXY=false
|
||||
```
|
||||
#### Manually overriding configuration values
|
||||
|
||||
If you do not have your environment variables set, or do not want them consumed, modify the variables in the following files under `cluster/openstack-heat`:
|
||||
|
||||
- **[config-default.sh](http://releases.k8s.io/{{page.githubbranch}}/cluster/openstack-heat/config-default.sh)** Sets all parameters needed for heat template.
|
||||
- **[config-image.sh](http://releases.k8s.io/{{page.githubbranch}}/cluster/openstack-heat/config-image.sh)** Sets parameters needed to download and create new OpenStack image via glance.
|
||||
- **[openrc-default.sh](http://releases.k8s.io/{{page.githubbranch}}/cluster/openstack-heat/openrc-default.sh)** Sets environment variables for communicating to OpenStack. These are consumed by the cli tools (heat, glance, swift, nova).
|
||||
- **[openrc-swift.sh](http://releases.k8s.io/{{page.githubbranch}}/cluster/openstack-heat/openrc-swift.sh)** Some OpenStack setups require the use of seperate swift credentials. Put those credentials in this file.
|
||||
|
||||
Please see the contents of these files for documentation regarding each variable's function.
|
||||
|
||||
## Starting a cluster
|
||||
|
||||
Once you've installed the OpenStack CLI tools and have set your OpenStack environment variables, issue this command:
|
||||
|
||||
```sh
|
||||
export KUBERNETES_PROVIDER=openstack-heat; curl -sS https://get.k8s.io | bash
|
||||
```
|
||||
Alternatively, you can download a [Kubernetes release](https://github.com/kubernetes/kubernetes/releases) and extract the archive. To start your cluster, open a shell and run:
|
||||
|
||||
```sh
|
||||
cd kubernetes # Or whichever path you have extracted the release to
|
||||
KUBERNETES_PROVIDER=openstack-heat ./cluster/kube-up.sh
|
||||
```
|
||||
Or, if you are working from a checkout of the Kubernetes code base, and want to build/test from source:
|
||||
|
||||
```sh
|
||||
cd kubernetes # Or whatever your checkout root directory is called
|
||||
make clean
|
||||
make quick-release
|
||||
KUBERNETES_PROVIDER=openstack-heat ./cluster/kube-up.sh
|
||||
```
|
||||
## Inspect your cluster
|
||||
|
||||
Once kube-up is finished, your cluster should be running:
|
||||
|
||||
```console
|
||||
./cluster/kubectl.sh get cs
|
||||
NAME STATUS MESSAGE ERROR
|
||||
controller-manager Healthy ok
|
||||
scheduler Healthy ok
|
||||
etcd-1 Healthy {"health": "true"}
|
||||
etcd-0 Healthy {"health": "true"}
|
||||
```
|
||||
|
||||
You can also list the nodes in your cluster:
|
||||
|
||||
```console
|
||||
./cluster/kubectl.sh get nodes
|
||||
NAME STATUS AGE
|
||||
kubernetesstack-node-ojszyjtr Ready 42m
|
||||
kubernetesstack-node-tzotzcbp Ready 46m
|
||||
kubernetesstack-node-uah8pkju Ready 47m
|
||||
```
|
||||
Being a new cluster, there will be no pods or replication controllers in the default namespace:
|
||||
|
||||
```console
|
||||
./cluster/kubectl.sh get pods
|
||||
./cluster/kubectl.sh get replicationcontrollers
|
||||
```
|
||||
|
||||
You are now ready to create Kubernetes objects.
|
||||
|
||||
## Using your cluster
|
||||
|
||||
For a simple test, issue the following command:
|
||||
|
||||
```sh
|
||||
./cluster/kubectl.sh run nginx --image=nginx --generator=run-pod/v1
|
||||
```
|
||||
|
||||
Soon, you should have a running nginx pod:
|
||||
|
||||
```console
|
||||
./cluster/kubectl.sh get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx 1/1 Running 0 5m
|
||||
```
|
||||
|
||||
Once the nginx pod is running, use the port-forward command to set up a proxy from your machine to the pod.
|
||||
|
||||
```sh
|
||||
./cluster/kubectl.sh port-forward nginx 8888:80
|
||||
```
|
||||
|
||||
You should now see nginx on [http://localhost:8888]().
|
||||
|
||||
For more complex examples please see the [examples directory](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/).
|
||||
|
||||
## Administering your cluster with Openstack
|
||||
|
||||
You can manage the nodes in your cluster using the OpenStack CLI Tools.
|
||||
|
||||
First, set your environment variables:
|
||||
|
||||
```sh
|
||||
. cluster/openstack-heat/config-default.sh
|
||||
. cluster/openstack-heat/openrc-default.sh
|
||||
```
|
||||
|
||||
To get all information about your cluster, use heat:
|
||||
|
||||
```sh
|
||||
heat stack-show $STACK_NAME
|
||||
```
|
||||
|
||||
To see a list of nodes, use nova:
|
||||
|
||||
```sh
|
||||
nova list --name=$STACK_NAME
|
||||
```
|
||||
|
||||
See the [OpenStack CLI Reference](http://docs.openstack.org/cli-reference/) for more details.
|
||||
|
||||
## SSHing to your nodes
|
||||
|
||||
Your public key was added during the cluster turn-up, so you can easily ssh to them for troubleshooting purposes.
|
||||
|
||||
```sh
|
||||
ssh minion@IP_ADDRESS
|
||||
```
|
||||
|
||||
## Cluster deployment customization examples
|
||||
You may find the need to modify environment variables to change the behaviour of kube-up. Here are some common scenarios:
|
||||
|
||||
#### Proxy configuration
|
||||
If you are behind a proxy, and have your local environment variables setup, you can use these variables to setup your Kubernetes cluster:
|
||||
|
||||
```sh
|
||||
ENABLE_PROXY=true KUBERNETES_PROVIDER=openstack-heat ./cluster/kube-up.sh
|
||||
```
|
||||
|
||||
#### Setting different Swift URL
|
||||
Some deployments differ from the default Swift URL:
|
||||
|
||||
```sh
|
||||
SWIFT_SERVER_URL="http://10.100.0.100:8080" KUBERNETES_PROVIDER=openstack-heat ./cluster/kube-up.sh
|
||||
```
|
||||
|
||||
#### Public network name.
|
||||
Sometimes the name of the public network differs from the default `public`:
|
||||
|
||||
```sh
|
||||
EXTERNAL_NETWORK="network_external" KUBERNETES_PROVIDER=openstack-heat ./cluster/kube-up.sh
|
||||
```
|
||||
|
||||
#### Spinning up additional clusters.
|
||||
You may want to spin up another cluster within your OpenStack project. Use the `$STACK_NAME` variable to accomplish this.
|
||||
|
||||
```sh
|
||||
STACK_NAME=k8s-cluster-2 KUBERNETES_PROVIDER=openstack-heat ./cluster/kube-up.sh
|
||||
```
|
||||
|
||||
For more configuration examples, please browse the files mentioned in the [Configuration](#set-additional-configuration-values) section.
|
||||
|
||||
|
||||
## Tearing down your cluster
|
||||
|
||||
To bring down your cluster, issue the following command:
|
||||
|
||||
```sh
|
||||
KUBERNETES_PROVIDER=openstack-heat ./cluster/kube-down.sh
|
||||
```
|
||||
If you have changed the default `$STACK_NAME`, you must specify the name. Note that this will not remove any Cinder volumes created by Kubernetes.
|
||||
|
|
@ -22,8 +22,8 @@ must be running on the node.
|
|||
|
||||
rkt uses the [Container Network Interface (CNI)](https://github.com/appc/cni)
|
||||
to manage container networking. By default, all pods attempt to join a network
|
||||
called `rkt.kubernetes.io`, which is currently defined [in `rkt.go`]
|
||||
(https://github.com/kubernetes/kubernetes/blob/v1.2.0-alpha.6/pkg/kubelet/rkt/rkt.go#L91).
|
||||
called `rkt.kubernetes.io`, which is currently defined [in
|
||||
`rkt.go`](https://github.com/kubernetes/kubernetes/blob/v1.2.0-alpha.6/pkg/kubelet/rkt/rkt.go#L91).
|
||||
In order for pods to get correct IP addresses, the CNI config file must be
|
||||
edited to add this `rkt.kubernetes.io` network:
|
||||
|
||||
|
|
@ -216,4 +216,4 @@ where `$UUID` is the rkt pod's UUID, which you can find via `rkt list --full`, a
|
|||
|
||||
##### Check Kubernetes events, logs.
|
||||
|
||||
Besides above tricks, Kubernetes also provides us handy tools for debugging the pods. More information can be found [here](/docs/user-guide/application-troubleshooting)
|
||||
Besides above tricks, Kubernetes also provides us handy tools for debugging the pods. More information can be found [here](/docs/user-guide/application-troubleshooting)
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ Then you need to configure your kubelet with flag:
|
|||
|
||||
### kubelet
|
||||
|
||||
All nodes should run kubelet. See [Selecting Binaries](#selecting-binaries).
|
||||
All nodes should run kubelet. See [Software Binaries](#software-binaries).
|
||||
|
||||
Arguments to consider:
|
||||
|
||||
|
|
@ -796,17 +796,17 @@ Notes for setting up each cluster service are given below:
|
|||
* Cluster DNS:
|
||||
* required for many kubernetes examples
|
||||
* [Setup instructions](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/)
|
||||
* [Admin Guide](/admin/dns/)
|
||||
* [Admin Guide](/docs/admin/dns/)
|
||||
* Cluster-level Logging
|
||||
* Multiple implementations with different storage backends and UIs.
|
||||
* [Elasticsearch Backend Setup Instructions](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-elasticsearch/)
|
||||
* [Google Cloud Logging Backend Setup Instructions](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-gcp/).
|
||||
* Both require running fluentd on each node.
|
||||
* [User Guide](/user-guide/logging/)
|
||||
* [User Guide](/docs/user-guide/logging/)
|
||||
* Container Resource Monitoring
|
||||
* [Setup instructions](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/cluster-monitoring/)
|
||||
* GUI
|
||||
* [Setup instructions](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/kube-ui/)
|
||||
* [Setup instructions](https://github.com/kubernetes/kube-ui)
|
||||
cluster.
|
||||
|
||||
## Troubleshooting
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ Running Kubernetes with Vagrant (and VirtualBox) is an easy way to run/test/deve
|
|||
|
||||
### Prerequisites
|
||||
|
||||
1. Install latest version >= 1.7.4 of vagrant from http://www.vagrantup.com/downloads.html
|
||||
1. Install latest version >= 1.7.4 of [Vagrant](http://www.vagrantup.com/downloads.html)
|
||||
2. Install one of:
|
||||
1. The latest version of Virtual Box from https://www.virtualbox.org/wiki/Downloads
|
||||
1. The latest version of [Virtual Box](https://www.virtualbox.org/wiki/Downloads)
|
||||
2. [VMWare Fusion](https://www.vmware.com/products/fusion/) version 5 or greater as well as the appropriate [Vagrant VMWare Fusion provider](https://www.vagrantup.com/vmware)
|
||||
3. [VMWare Workstation](https://www.vmware.com/products/workstation/) version 9 or greater as well as the [Vagrant VMWare Workstation provider](https://www.vagrantup.com/vmware)
|
||||
4. [Parallels Desktop](https://www.parallels.com/products/desktop/) version 9 or greater as well as the [Vagrant Parallels provider](https://parallels.github.io/vagrant-parallels/)
|
||||
|
|
@ -20,14 +20,14 @@ Running Kubernetes with Vagrant (and VirtualBox) is an easy way to run/test/deve
|
|||
|
||||
Setting up a cluster is as simple as running:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
export KUBERNETES_PROVIDER=vagrant
|
||||
curl -sS https://get.k8s.io | bash
|
||||
```
|
||||
|
||||
Alternatively, you can download [Kubernetes release](https://github.com/kubernetes/kubernetes/releases) and extract the archive. To start your local cluster, open a shell and run:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
cd kubernetes
|
||||
|
||||
export KUBERNETES_PROVIDER=vagrant
|
||||
|
|
@ -42,7 +42,7 @@ Vagrant will provision each machine in the cluster with all the necessary compon
|
|||
|
||||
If you installed more than one Vagrant provider, Kubernetes will usually pick the appropriate one. However, you can override which one Kubernetes will use by setting the [`VAGRANT_DEFAULT_PROVIDER`](https://docs.vagrantup.com/v2/providers/default.html) environment variable:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
export VAGRANT_DEFAULT_PROVIDER=parallels
|
||||
export KUBERNETES_PROVIDER=vagrant
|
||||
./cluster/kube-up.sh
|
||||
|
|
@ -52,14 +52,14 @@ By default, each VM in the cluster is running Fedora.
|
|||
|
||||
To access the master or any node:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
vagrant ssh master
|
||||
vagrant ssh node-1
|
||||
```
|
||||
|
||||
If you are running more than one node, you can access the others by:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
vagrant ssh node-2
|
||||
vagrant ssh node-3
|
||||
```
|
||||
|
|
@ -70,7 +70,7 @@ The master node instantiates the Kubernetes master components as pods on the mac
|
|||
|
||||
To view the service status and/or logs on the kubernetes-master:
|
||||
|
||||
```shell
|
||||
```console
|
||||
[vagrant@kubernetes-master ~] $ vagrant ssh master
|
||||
[vagrant@kubernetes-master ~] $ sudo su
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ To view the service status and/or logs on the kubernetes-master:
|
|||
|
||||
To view the services on any of the nodes:
|
||||
|
||||
```shell
|
||||
```console
|
||||
[vagrant@kubernetes-master ~] $ vagrant ssh node-1
|
||||
[vagrant@kubernetes-master ~] $ sudo su
|
||||
|
||||
|
|
@ -104,20 +104,20 @@ With your Kubernetes cluster up, you can manage the nodes in your cluster with t
|
|||
|
||||
To push updates to new Kubernetes code after making source changes:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
./cluster/kube-push.sh
|
||||
```
|
||||
|
||||
To stop and then restart the cluster:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
vagrant halt
|
||||
./cluster/kube-up.sh
|
||||
```
|
||||
|
||||
To destroy the cluster:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
vagrant destroy
|
||||
```
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ Once your Vagrant machines are up and provisioned, the first thing to do is to c
|
|||
|
||||
You may need to build the binaries first, you can do this with `make`
|
||||
|
||||
```shell
|
||||
```console
|
||||
$ ./cluster/kubectl.sh get nodes
|
||||
|
||||
NAME LABELS
|
||||
|
|
@ -138,7 +138,7 @@ NAME LABELS
|
|||
|
||||
When using the vagrant provider in Kubernetes, the `cluster/kubectl.sh` script will cache your credentials in a `~/.kubernetes_vagrant_auth` file so you will not be prompted for them in the future.
|
||||
|
||||
```shell
|
||||
```sh
|
||||
cat ~/.kubernetes_vagrant_auth
|
||||
```
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ cat ~/.kubernetes_vagrant_auth
|
|||
|
||||
You should now be set to use the `cluster/kubectl.sh` script. For example try to list the nodes that you have started with:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
./cluster/kubectl.sh get nodes
|
||||
```
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ You should now be set to use the `cluster/kubectl.sh` script. For example try to
|
|||
|
||||
Your cluster is running, you can list the nodes in your cluster:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
$ ./cluster/kubectl.sh get nodes
|
||||
|
||||
NAME LABELS
|
||||
|
|
@ -175,7 +175,7 @@ Now start running some containers!
|
|||
You can now use any of the `cluster/kube-*.sh` commands to interact with your VM machines.
|
||||
Before starting a container there will be no pods, services and replication controllers.
|
||||
|
||||
```shell
|
||||
```sh
|
||||
$ ./cluster/kubectl.sh get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
|||
|
||||
Start a container running nginx with a replication controller and three replicas
|
||||
|
||||
```shell
|
||||
```sh
|
||||
$ ./cluster/kubectl.sh run my-nginx --image=nginx --replicas=3 --port=80
|
||||
```
|
||||
|
||||
When listing the pods, you will see that three containers have been started and are in Waiting state:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
$ ./cluster/kubectl.sh get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
my-nginx-5kq0g 0/1 Pending 0 10s
|
||||
|
|
@ -204,7 +204,7 @@ my-nginx-xql4j 0/1 Pending 0 10s
|
|||
|
||||
You need to wait for the provisioning to complete, you can monitor the nodes by doing:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
$ vagrant ssh node-1 -c 'sudo docker images'
|
||||
kubernetes-node-1:
|
||||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
|
||||
|
|
@ -215,7 +215,7 @@ kubernetes-node-1:
|
|||
|
||||
Once the docker image for nginx has been downloaded, the container will start and you can list it:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
$ vagrant ssh node-1 -c 'sudo docker ps'
|
||||
kubernetes-node-1:
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
|
|
@ -227,7 +227,7 @@ kubernetes-node-1:
|
|||
|
||||
Going back to listing the pods, services and replicationcontrollers, you now have:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
$ ./cluster/kubectl.sh get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
my-nginx-5kq0g 1/1 Running 0 1m
|
||||
|
|
@ -243,10 +243,10 @@ my-nginx my-nginx nginx run=my-nginx 3 1m
|
|||
```
|
||||
|
||||
We did not start any services, hence there are none listed. But we see three replicas displayed properly.
|
||||
Check the [guestbook](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) application to learn how to create a service.
|
||||
Learn about [running your first containers](../user-guide/simple-nginx/) application to learn how to create a service.
|
||||
You can already play with scaling the replicas with:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
$ ./cluster/kubectl.sh scale rc my-nginx --replicas=2
|
||||
$ ./cluster/kubectl.sh get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
|
|
@ -256,13 +256,13 @@ my-nginx-gr3hh 1/1 Running 0 2m
|
|||
|
||||
Congratulations!
|
||||
|
||||
### Troubleshooting
|
||||
## Troubleshooting
|
||||
|
||||
#### I keep downloading the same (large) box all the time!
|
||||
|
||||
By default the Vagrantfile will download the box from S3. You can change this (and cache the box locally) by providing a name and an alternate URL when calling `kube-up.sh`
|
||||
|
||||
```shell
|
||||
```sh
|
||||
export KUBERNETES_BOX_NAME=choose_your_own_name_for_your_kuber_box
|
||||
export KUBERNETES_BOX_URL=path_of_your_kuber_box
|
||||
export KUBERNETES_PROVIDER=vagrant
|
||||
|
|
@ -273,7 +273,7 @@ export KUBERNETES_PROVIDER=vagrant
|
|||
|
||||
During provision of the cluster, you may see the following message:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
Validating node-1
|
||||
.............
|
||||
Waiting for each node to be registered with cloud provider
|
||||
|
|
@ -284,7 +284,7 @@ Some users have reported VPNs may prevent traffic from being routed to the host
|
|||
|
||||
To debug, first verify that the master is binding to the proper IP address:
|
||||
|
||||
```
|
||||
```sh
|
||||
$ vagrant ssh master
|
||||
$ ifconfig | grep eth1 -C 2
|
||||
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.245.1.2 netmask
|
||||
|
|
@ -310,13 +310,13 @@ If you do see a network, but are still unable to ping the machine, check if your
|
|||
|
||||
You probably have an incorrect ~/.kubernetes_vagrant_auth file for the cluster you are attempting to contact.
|
||||
|
||||
```shell
|
||||
```sh
|
||||
rm ~/.kubernetes_vagrant_auth
|
||||
```
|
||||
|
||||
After using kubectl.sh make sure that the correct credentials are set:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
cat ~/.kubernetes_vagrant_auth
|
||||
```
|
||||
|
||||
|
|
@ -331,10 +331,6 @@ cat ~/.kubernetes_vagrant_auth
|
|||
|
||||
If this is your first time creating the cluster, the kubelet on each node schedules a number of docker pull requests to fetch prerequisite images. This can take some time and as a result may delay your initial pod getting provisioned.
|
||||
|
||||
#### I want to make changes to Kubernetes code!
|
||||
|
||||
To set up a vagrant cluster for hacking, follow the [vagrant developer guide](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/developer-guides/vagrant.md).
|
||||
|
||||
#### I have brought Vagrant up but the nodes cannot validate!
|
||||
|
||||
Log on to one of the nodes (`vagrant ssh node-1`) and inspect the salt minion log (`sudo cat /var/log/salt/minion`).
|
||||
|
|
@ -343,7 +339,7 @@ Log on to one of the nodes (`vagrant ssh node-1`) and inspect the salt minion lo
|
|||
|
||||
You can control the number of nodes that are instantiated via the environment variable `NUM_NODES` on your host machine. If you plan to work with replicas, we strongly encourage you to work with enough nodes to satisfy your largest intended replica size. If you do not plan to work with replicas, you can save some system resources by running with a single node. You do this, by setting `NUM_NODES` to 1 like so:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
export NUM_NODES=1
|
||||
```
|
||||
|
||||
|
|
@ -352,39 +348,17 @@ export NUM_NODES=1
|
|||
You can control the memory allotted to virtual machines with the `KUBERNETES_MEMORY` environment variable.
|
||||
Just set it to the number of megabytes you would like the machines to have. For example:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
export KUBERNETES_MEMORY=2048
|
||||
```
|
||||
|
||||
If you need more granular control, you can set the amount of memory for the master and nodes independently. For example:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
export KUBERNETES_MASTER_MEMORY=1536
|
||||
export KUBERNETES_NODE_MEMORY=2048
|
||||
```
|
||||
|
||||
#### I want to set proxy settings for my Kubernetes cluster boot strapping!
|
||||
|
||||
If you are behind a proxy, you need to install the Vagrant proxy plugin and set the proxy settings:
|
||||
|
||||
```shell
|
||||
vagrant plugin install vagrant-proxyconf
|
||||
export KUBERNETES_HTTP_PROXY=http://username:password@proxyaddr:proxyport
|
||||
export KUBERNETES_HTTPS_PROXY=https://username:password@proxyaddr:proxyport
|
||||
```
|
||||
|
||||
You can also specify addresses that bypass the proxy, for example:
|
||||
|
||||
```shell
|
||||
export KUBERNETES_NO_PROXY=127.0.0.1
|
||||
```
|
||||
|
||||
If you are using sudo to make Kubernetes build, use the `-E` flag to pass in the environment variables. For example, if running `make quick-release`, use:
|
||||
|
||||
```shell
|
||||
sudo -E make quick-release
|
||||
```
|
||||
|
||||
#### I ran vagrant suspend and nothing works!
|
||||
|
||||
`vagrant suspend` seems to mess up the network. This is not supported at this time.
|
||||
|
|
@ -393,6 +367,6 @@ sudo -E make quick-release
|
|||
|
||||
You can ensure that vagrant uses nfs to sync folders with virtual machines by setting the KUBERNETES_VAGRANT_USE_NFS environment variable to 'true'. nfs is faster than virtualbox or vmware's 'shared folders' and does not require guest additions. See the [vagrant docs](http://docs.vagrantup.com/v2/synced-folders/nfs.html) for details on configuring nfs on the host. This setting will have no effect on the libvirt provider, which uses nfs by default. For example:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
export KUBERNETES_VAGRANT_USE_NFS=true
|
||||
```
|
||||
|
|
|
|||
|
|
@ -26,10 +26,20 @@ Remember the project ID; it will be referred to later in this codelab as `PROJEC
|
|||
|
||||
Next, [enable billing](https://console.developers.google.com/billing) in the Developers Console in order to use Google Cloud resources and [enable the Container Engine API](https://console.developers.google.com/project/_/kubernetes/list).
|
||||
|
||||
New users of Google Cloud Platform recieve a [$300 free trial](https://console.developers.google.com/billing/freetrial?hl=en). Running through this codelab shouldn’t cost you more than a few dollars of that trial. Google Container Engine pricing is documented [here](https://cloud.google.com/container-engine/docs/#pricing).
|
||||
New users of Google Cloud Platform receive a [$300 free trial](https://console.developers.google.com/billing/freetrial?hl=en). Running through this codelab shouldn’t cost you more than a few dollars of that trial. Google Container Engine pricing is documented [here](https://cloud.google.com/container-engine/pricing).
|
||||
|
||||
Next, make sure you [download Node.js](https://nodejs.org/en/download/).
|
||||
|
||||
Then install [Docker](https://docs.docker.com/engine/installation/), and [Google Cloud SDK](https://cloud.google.com/sdk/).
|
||||
|
||||
Finally, after Google Cloud SDK installs, run the following command to install [`kubectl`](http://kubernetes.io/docs/user-guide/kubectl-overview/):
|
||||
|
||||
```shell
|
||||
gcloud components install kubectl
|
||||
```
|
||||
|
||||
You're all set up with an environment that can build container images, run Node apps, run Kubernetes clusters locally, and deploy Kubernetes clusters to Google Container Engine. Let's begin!
|
||||
|
||||
## Create your Node.js application
|
||||
|
||||
The first step is to write the application. Save this code in a folder called "`hellonode/`" with the filename `server.js`:
|
||||
|
|
@ -60,18 +70,18 @@ Now let’s package this application in a Docker container.
|
|||
|
||||
## Create a Docker container image
|
||||
|
||||
Next, create a file, also within `helloworld/` named `Dockerfile`. A Dockerfile describes the image that you want to build. Docker container images can extend from other existing images so for this image, we'll extend from an existing Node image.
|
||||
Next, create a file, also within `hellonode/` named `Dockerfile`. A Dockerfile describes the image that you want to build. Docker container images can extend from other existing images so for this image, we'll extend from an existing Node image.
|
||||
|
||||
#### Dockerfile
|
||||
|
||||
```conf
|
||||
FROM node:0.12
|
||||
FROM node:4.4
|
||||
EXPOSE 8080
|
||||
COPY server.js .
|
||||
CMD node server.js
|
||||
```
|
||||
|
||||
This "recipe" for the Docker image will start from the Node 0.12 image found on the Docker registry, expose port 8080, copy our `server.js` file to the image and start the Node server.
|
||||
This "recipe" for the Docker image will start from the official Node.js LTS image found on the Docker registry, expose port 8080, copy our `server.js` file to the image and start the Node server.
|
||||
|
||||
Now build an image of your container by running `docker build`, tagging the image with the Google Container Registry repo for your `PROJECT_ID`:
|
||||
|
||||
|
|
@ -83,14 +93,14 @@ Now there is a trusted source for getting an image of your containerized app.
|
|||
Let's try your image out with Docker:
|
||||
|
||||
```shell
|
||||
docker run -d -p 8080:8080 gcr.io/PROJECT_ID/hello-node:v1
|
||||
$ docker run -d -p 8080:8080 gcr.io/PROJECT_ID/hello-node:v1
|
||||
325301e6b2bffd1d0049c621866831316d653c0b25a496d04ce0ec6854cb7998
|
||||
```
|
||||
|
||||
Visit your app in the browser, or use `curl` or `wget` if you’d like :
|
||||
|
||||
```shell
|
||||
curl http://localhost:8080
|
||||
$ curl http://localhost:8080
|
||||
Hello World!
|
||||
```
|
||||
|
||||
|
|
@ -101,7 +111,7 @@ docker ps
|
|||
CONTAINER ID IMAGE COMMAND
|
||||
2c66d0efcbd4 gcr.io/PROJECT_ID/hello-node:v1 "/bin/sh -c 'node
|
||||
|
||||
$ docker stop 2c66d0efcbd4
|
||||
docker stop 2c66d0efcbd4
|
||||
2c66d0efcbd4
|
||||
```
|
||||
|
||||
|
|
@ -115,90 +125,140 @@ If all goes well, you should be able to see the container image listed in the co
|
|||
|
||||

|
||||
|
||||
|
||||
## Create your cluster
|
||||
|
||||
A cluster consists of a master API server and a set of worker VMs called nodes.
|
||||
A cluster consists of a master API server and a set of worker VMs called nodes.
|
||||
|
||||
Create a cluster via the Console: *Compute > Container Engine > Container Clusters > New container cluster*. Leave all the options default, and you should get a Kubernetes cluster with three nodes, ready to receive your container image.
|
||||
Create a cluster via the Console: *Compute > Container Engine > Container Clusters > New container cluster*. Set the name to 'hello-world', leaving all other options default. You should get a Kubernetes cluster with three nodes, ready to receive your container image.
|
||||
|
||||

|
||||
|
||||
It’s now time to deploy your own containerized application to the Kubernetes cluster! Please ensure that you have [configured](https://cloud.google.com/container-engine/docs/before-you-begin#optional_set_gcloud_defaults) `kubectl` to use the cluster you just created.
|
||||
It’s now time to deploy your own containerized application to the Kubernetes cluster! Please ensure that you have [configured](https://cloud.google.com/container-engine/docs/clusters/operations#configuring_kubectl) `kubectl` to use the cluster you just created:
|
||||
|
||||
```shell
|
||||
$ gcloud container clusters get-credentials hello-world
|
||||
```
|
||||
|
||||
**The rest of this document requires both the kubernetes client and server version to be 1.2. Run `kubectl version` to see your current versions.** For 1.1 see [this document](https://github.com/kubernetes/kubernetes.github.io/blob/release-1.1/docs/hellonode.md).
|
||||
|
||||
## Create your pod
|
||||
|
||||
A kubernetes **pod** is a group of containers, tied together for the purposes of administration and networking. It can contain a single container or multiple.
|
||||
A kubernetes **[pod](/docs/user-guide/pods/)** is a group of containers, tied together for the purposes of administration and networking. It can contain a single container or multiple.
|
||||
|
||||
Create a pod with the `kubectl run` command:
|
||||
|
||||
```shell
|
||||
kubectl run hello-node \
|
||||
--image=gcr.io/PROJECT_ID/hello-node:v1 \
|
||||
--port=8080
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
hello-node hello-node gcr.io/..../hello-node:v1 run=hello-node 1
|
||||
$ kubectl run hello-node --image=gcr.io/PROJECT_ID/hello-node:v1 --port=8080
|
||||
deployment "hello-node" created
|
||||
```
|
||||
|
||||
Now is probably a good time to run through some of the following interesting kubectl commands (none of these will change the state of the cluster, full documentation is available [here](https://cloud.google.com/container-engine/docs/kubectl/)):
|
||||
As shown in the output, the `kubectl run` created a **[deployment](/docs/user-guide/deployments/)** object. Deployments are the recommended way for managing creation and scaling of pods. In this example, a new deployment manages a single pod replica running the *hello-node:v1* image.
|
||||
|
||||
To view the deployment we just created run:
|
||||
|
||||
```shell
|
||||
$ kubectl get deployments
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
hello-node 1 1 1 1 3m
|
||||
```
|
||||
|
||||
To view the pod created by the deployment run:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods
|
||||
$ kubectl logs
|
||||
$ kubectl cluster-info
|
||||
$ kubectl config view
|
||||
$ kubectl get events
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hello-node-714049816-ztzrb 1/1 Running 0 6m
|
||||
```
|
||||
|
||||
To view the stdout / stderr from a pod (hello-node image has no output, so logs will be empty in this case) run:
|
||||
|
||||
```shell
|
||||
kubectl logs <POD-NAME>
|
||||
```
|
||||
|
||||
To view metadata about the cluster run:
|
||||
|
||||
```shell
|
||||
kubectl cluster-info
|
||||
```
|
||||
|
||||
To view cluster events run:
|
||||
|
||||
```shell
|
||||
kubectl get events
|
||||
```
|
||||
|
||||
To view the kubectl configuration run:
|
||||
|
||||
```shell
|
||||
kubectl config view
|
||||
```
|
||||
|
||||
Full documentation for kubectl commands is available **[here](/docs/user-guide/kubectl-overview/)**:
|
||||
|
||||
At this point you should have our container running under the control of Kubernetes but we still have to make it accessible to the outside world.
|
||||
|
||||
## Allow external traffic
|
||||
|
||||
By default, the pod is only accessible by its internal IP within the Kubernetes cluster. In order to make the `hello-node` container accessible from outside the kubernetes virtual network, you have to expose the pod as a kubernetes service.
|
||||
By default, the pod is only accessible by its internal IP within the Kubernetes cluster. In order to make the `hello-node` container accessible from outside the kubernetes virtual network, you have to expose the pod as a kubernetes **[service](/docs/user-guide/services/)**.
|
||||
|
||||
From our development machine we can expose the pod with the `kubectl` expose command and the `--type="LoadBalancer"` flag which creates an external IP to accept traffic:
|
||||
From our development machine we can expose the pod to the public internet using the `kubectl expose` command combined with the `--type="LoadBalancer"` flag. The flag is needed for the creation of an externally accessible ip:
|
||||
|
||||
```shell
|
||||
kubectl expose rc hello-node --type="LoadBalancer"
|
||||
kubectl expose deployment hello-node --type="LoadBalancer"
|
||||
```
|
||||
|
||||
The flag used in this command specifies that we’ll be using the load-balancer provided by the underlying infrastructure (in this case the [Compute Engine load balancer](https://cloud.google.com/compute/docs/load-balancing/)). The `rc` refers to the Kubernetes "replication controller" -- which is a Kubernetes service which controls load balancing and scaling behavior for your cluster.
|
||||
**If this fails, make sure your client and server are both version 1.2. See the [Create your cluster](#create-your-cluster) section for details.**
|
||||
|
||||
The flag used in this command specifies that we’ll be using the load-balancer provided by the underlying infrastructure (in this case the [Compute Engine load balancer](https://cloud.google.com/compute/docs/load-balancing/)). Note that we expose the deployment, and not the pod directly. This will cause the resulting service to load balance traffic across all pods managed by the deployment (in this case only 1 pod, but we will add more replicas later).
|
||||
|
||||
The Kubernetes master creates the load balancer and related Compute Engine forwarding rules, target pools, and firewall rules to make the service fully accessible from outside of Google Cloud Platform.
|
||||
|
||||
To find the publicly-accessible IP address, ask `kubectl` to describe the `hello-node` cluster service:
|
||||
To find the ip addresses associated with the service run:
|
||||
|
||||
```shell
|
||||
kubectl get services hello-node
|
||||
$ kubectl get services hello-node
|
||||
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
|
||||
hello-node 10.3.246.12 23.251.159.72 8080/TCP run=hello-node 53s
|
||||
hello-node 10.3.246.12 8080/TCP run=hello-node 23s
|
||||
```
|
||||
|
||||
Note there are 2 IP addresses listed, both serving port 8080. One is the internal IP that is only visible inside your cloud virtual network; the other is the external load-balanced IP. In this example, the external IP address is 23.251.159.72. Traffic to the load-balanced IP will be load balanced to the three nodes you provisioned when initially creating the cluster!
|
||||
The `EXTERNAL_IP` may take several minutes to become available and visible. If the `EXTERNAL_IP` is missing, wait a few minutes and try again.
|
||||
|
||||
You should now be able to reach the service by pointing your browser to this address: http://<EXTERNAL_IP>**:8080**
|
||||
```shell
|
||||
$ kubectl get services hello-node
|
||||
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
|
||||
hello-node 10.3.246.12 23.251.159.72 8080/TCP run=hello-node 2m
|
||||
```
|
||||
|
||||
Note there are 2 IP addresses listed, both serving port 8080. `CLUSTER_IP` is only visible inside your cloud virtual network. `EXTERNAL_IP` is externally accessible. In this example, the external IP address is 23.251.159.72.
|
||||
|
||||
You should now be able to reach the service by pointing your browser to this address: http://EXTERNAL_IP**:8080** or running `curl http://EXTERNAL_IP:8080`
|
||||
|
||||

|
||||
|
||||
## Scale up your website
|
||||
|
||||
One of the powerful features offered by Kubernetes is how easy it is to scale your application. Suppose you suddenly need more capacity for your application; you can simply tell the replication controller to manage a new number of replicas for your pod:
|
||||
One of the powerful features offered by Kubernetes is how easy it is to scale your application. Suppose you suddenly need more capacity for your application; you can simply tell the deployment to manage a new number of replicas for your pod:
|
||||
|
||||
```shell
|
||||
kubectl scale rc hello-node --replicas=4
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hello-node-6uzt8 1/1 Running 0 8m
|
||||
hello-node-gxhty 1/1 Running 0 34s
|
||||
hello-node-z2odh 1/1 Running 0 34s
|
||||
kubectl scale deployment hello-node --replicas=4
|
||||
```
|
||||
|
||||
You now have four replicas of your application, each running independently on the cluster with the load balancer you created earlier and serving traffic to all of them.
|
||||
You now have four replicas of your application, each running independently on the cluster with the load balancer you created earlier and serving traffic to all of them.
|
||||
|
||||
```shell
|
||||
kubectl get rc hello-node
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
hello-node hello-node gcr.io/..../hello-node:v1 run=hello-node 3
|
||||
$ kubectl get deployment
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
hello-node 4 4 4 3 40m
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hello-node-714049816-g4azy 1/1 Running 0 1m
|
||||
hello-node-714049816-rk0u6 1/1 Running 0 1m
|
||||
hello-node-714049816-sh812 1/1 Running 0 1m
|
||||
hello-node-714049816-ztzrb 1/1 Running 0 41m
|
||||
```
|
||||
|
||||
Note the **declarative approach** here - rather than starting or stopping new instances you declare how many instances you want to be running. Kubernetes reconciliation loops simply make sure the reality matches what you requested and take action if needed.
|
||||
|
|
@ -221,76 +281,116 @@ First, let’s modify the application. On the development machine, edit server.j
|
|||
We can now build and publish a new container image to the registry with an incremented tag:
|
||||
|
||||
```shell
|
||||
docker build -t gcr.io/PROJECT_ID/hello-node:v2 .
|
||||
docker push gcr.io/PROJECT_ID/hello-node:v2
|
||||
docker build -t gcr.io/PROJECT_ID/hello-node:v2 .
|
||||
gcloud docker push gcr.io/PROJECT_ID/hello-node:v2
|
||||
```
|
||||
|
||||
Building and pushing this updated image should be much quicker as we take full advantage of the Docker cache.
|
||||
|
||||
We’re now ready for kubernetes to smoothly update our replication controller to the new version of the application:
|
||||
We’re now ready for kubernetes to smoothly update our deployment to the new version of the application. In order to change
|
||||
the image label for our running container, we will need to edit the existing *hello-node deployment* and change the image from
|
||||
`gcr.io/PROJECT_ID/hello-node:v1` to `gcr.io/PROJECT_ID/hello-node:v2`. To do this, we will use the `kubectl edit` command.
|
||||
This will open up a text editor displaying the full deployment yaml configuration. It isn't necessary to understand the full yaml config
|
||||
right now, instead just understand that by updating the `spec.template.spec.containers.image` field in the config we are telling
|
||||
the deployment to update the pods to use the new image.
|
||||
|
||||
```shell
|
||||
kubectl rolling-update hello-node \
|
||||
--image=gcr.io/PROJECT_ID/hello-node:v2 \
|
||||
--update-period=2s
|
||||
Creating hello-node-324d23dd3e0e2474d6b76dc599abb519
|
||||
At beginning of loop: hello-node replicas: 2, hello-node-324d23dd3e0e2474d6b76dc599abb519 replicas: 1
|
||||
...
|
||||
At end of loop: hello-node replicas: 0, hello-node-324d23dd3e0e2474d6b76dc599abb519 replicas: 3
|
||||
Update succeeded. Deleting old controller: hello-node
|
||||
Renaming hello-node-324d23dd3e0e2474d6b76dc599abb519 to hello-node
|
||||
hello-node
|
||||
kubectl edit deployment hello-node
|
||||
```
|
||||
|
||||
You should see in the standard output how the rolling update actually works:
|
||||
```yaml
|
||||
# Please edit the object below. Lines beginning with a '#' will be ignored,
|
||||
# and an empty file will abort the edit. If an error occurs while saving this file will be
|
||||
# reopened with the relevant failures.
|
||||
#
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
creationTimestamp: 2016-03-24T17:55:28Z
|
||||
generation: 3
|
||||
labels:
|
||||
run: hello-node
|
||||
name: hello-node
|
||||
namespace: default
|
||||
resourceVersion: "151017"
|
||||
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/hello-node
|
||||
uid: 981fe302-f1e9-11e5-9a78-42010af00005
|
||||
spec:
|
||||
replicas: 4
|
||||
selector:
|
||||
matchLabels:
|
||||
run: hello-node
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
run: hello-node
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/PROJECT_ID/hello-node:v1 # Update this line
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: hello-node
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
protocol: TCP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
```
|
||||
|
||||
1. A new replication controller is created based on the new image
|
||||
After making the change save and close the file.
|
||||
|
||||
2. The replica count on the new and old controllers is increased/decreased by one respectively until the desired number of replicas is reached
|
||||
```
|
||||
deployment "hello-node" edited
|
||||
```
|
||||
|
||||
3. The original replication controller is deleted.
|
||||
This updates the deployment with the new image, causing new pods to be created with the new image and old pods to be deleted.
|
||||
|
||||
While this is happening, the users of the services should not see any interruption. After a little while they will start accessing the new version of your application. You can find more details on rolling updates in [this documentation](https://cloud.google.com/container-engine/docs/rolling-updates).
|
||||
```
|
||||
$ kubectl get deployments
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
hello-node 4 5 4 3 1h
|
||||
```
|
||||
|
||||
While this is happening, the users of the services should not see any interruption. After a little while they will start accessing the new version of your application. You can find more details in the [deployment documentation](/docs/user-guide/deployments/).
|
||||
|
||||
Hopefully with these deployment, scaling and update features you’ll agree that once you’ve setup your environment (your GKE/Kubernetes cluster here), Kubernetes is here to help you focus on the application rather than the infrastructure.
|
||||
|
||||
## Observe the Kubernetes Graphical dashboard (optional)
|
||||
## Observe the Kubernetes Web UI (optional)
|
||||
|
||||
While logged into your development machine, execute the following commands:
|
||||
With Kubernetes 1.2, a graphical web user interface (dashboard) has been introduced. It is enabled by default for 1.2 clusters.
|
||||
This user interface allows you to get started quickly and enables some of the functionality found in the CLI as a more approachable and discoverable way of interacting with the system.
|
||||
|
||||
```shell
|
||||
kubectl config view | grep "password"
|
||||
password: vUYwC5ATJMWa6goh
|
||||
$ kubectl cluster-info
|
||||
...
|
||||
KubeUI is running at https://<ip-address>/api/v1/proxy/namespaces/kube-system/services/kube-ui
|
||||
...
|
||||
```
|
||||
Enjoy the Kubernetes graphical dashboard and use it for deploying containerized applications, as well as for monitoring and managing your clusters!
|
||||
|
||||
Navigate to the URL that is shown under after KubeUI is running at and log in with username "admin" and the password retrieved above and enjoy the Kubernetes graphical dashboard!
|
||||

|
||||
|
||||

|
||||
Learn more about the web interface by taking the [Dashboard tour](/docs/user-guide/ui/).
|
||||
|
||||
## That's it! Time to tear it down
|
||||
|
||||
That's it for the demo! So you don't leave this all running and incur charges, let's learn how to tear things down.
|
||||
That's it for the demo! So you don't leave this all running and incur charges, let's learn how to tear things down.
|
||||
|
||||
First, delete the Service, which also deletes your external load balancer:
|
||||
Delete the Deployment (which also deletes the running pods) and Service (which also deletes your external load balancer):
|
||||
|
||||
```shell
|
||||
kubectl delete services hello-node
|
||||
```
|
||||
|
||||
Delete the running pods:
|
||||
|
||||
```shell
|
||||
kubectl delete rc hello-node
|
||||
kubectl delete service,deployment hello-node
|
||||
```
|
||||
|
||||
Delete your cluster:
|
||||
|
||||
```shell
|
||||
gcloud container clusters delete hello-world
|
||||
$ gcloud container clusters delete hello-world
|
||||
Waiting for cluster deletion...done.
|
||||
name: operation-xxxxxxxxxxxxxxxx
|
||||
operationType: deleteCluster
|
||||
|
|
@ -304,7 +404,7 @@ This deletes the Google Compute Engine instances that are running the cluster.
|
|||
Finally delete the Docker registry storage bucket hosting your image(s) :
|
||||
|
||||
```shell
|
||||
gsutil ls
|
||||
$ gsutil ls
|
||||
gs://artifacts.<PROJECT_ID>.appspot.com/
|
||||
$ gsutil rm -r gs://artifacts.<PROJECT_ID>.appspot.com/
|
||||
Removing gs://artifacts.<PROJECT_ID>.appspot.com/...
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ In the reference section, you can find reference documentation for Kubernetes AP
|
|||
|
||||
## Glossary
|
||||
|
||||
Explore the glossary of essential Kubernetes concepts. Some good starting points are the entries for [Pods](/docs/user-guide/pods/), [Nodes](/docs/user-guide/pods/), [Services](/docs/user-guide/services/), and [Replication Controllers](/docs/user-guide/replication-controller/).
|
||||
Explore the glossary of essential Kubernetes concepts. Some good starting points are the entries for [Pods](/docs/user-guide/pods/), [Nodes](/docs/admin/nodes/), [Services](/docs/user-guide/services/), and [Replication Controllers](/docs/user-guide/replication-controller/).
|
||||
|
||||
## Design Docs
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
---
|
||||
---
|
||||
We have a wide variety of samples to choose from:
|
||||
|
||||
* "Clustered Application Samples" and "Persistent Volume Samples" provide some
|
||||
examples that show how to implement some popular software packages such as OpenShift, Ceph, Cassandra, and WordPress. These guides
|
||||
try to serve as canonical walkthroughs that help you use familiar packages with Kubernetes.
|
||||
|
||||
* "Mulit-tier Application Samples" are generally of a more contrived and instructional nature, highlighting key concepts that
|
||||
you'll encounter when developing with Kubernetes, and teaching some principles of building Kubernetes applications.
|
||||
We have a wide variety of samples to choose from.
|
||||
|
||||
## Recently updated samples
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
---
|
||||
{% include templates/concept-overview.md %}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
---
|
||||
{% include templates/landing-page.md %}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
---
|
||||
|
||||
{% assign concept="Replication Controller" %}
|
||||
|
||||
{% capture what_is %}
|
||||
A Replication Controller does x and y and z...(etc, etc, text goes on)
|
||||
{% endcapture %}
|
||||
|
||||
{% capture when_to_use %}
|
||||
You should use Replication Controller when...
|
||||
{% endcapture %}
|
||||
|
||||
{% capture when_not_to_use %}
|
||||
You should not use Replication Controller if...
|
||||
{% endcapture %}
|
||||
|
||||
{% capture status %}
|
||||
The current status of Replication Controllers is...
|
||||
{% endcapture %}
|
||||
|
||||
{% capture required_fields %}
|
||||
* `kind`: Always `Pod`.
|
||||
* `apiVersion`: Currently `v1`.
|
||||
* `metadata`: An object containing:
|
||||
* `name`: Required if `generateName` is not specified. The name of this pod.
|
||||
It must be an
|
||||
[RFC1035](https://www.ietf.org/rfc/rfc1035.txt) compatible value and be
|
||||
unique within the namespace.
|
||||
{% endcapture %}
|
||||
|
||||
{% include templates/concept-overview.md %}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
---
|
||||
|
||||
# Template Demos
|
||||
|
||||
This page demonstrates new doc templates being worked on.
|
||||
|
||||
Click the headings to see the source of the template in GitHub.
|
||||
|
||||
## [Concept Overviews](https://github.com/kubernetes/kubernetes.github.io/blob/master/_includes/templates/concept-overview.md)
|
||||
|
||||
- [Blank page that is trying to use template](blank/)
|
||||
- [Partially filled out page](partial/)
|
||||
- [Completely filled out page](filledout/)
|
||||
|
||||
## [Landing Pages](https://github.com/kubernetes/kubernetes.github.io/blob/master/_includes/templates/landing-page.md)
|
||||
|
||||
- [Blank](blanklanding/)
|
||||
- [Filled Out](landingpage/)
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
cards:
|
||||
- progression: no
|
||||
- card:
|
||||
title: Mean Stack
|
||||
image: /images/docs/meanstack/image_0.png
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Guestbook + Redis
|
||||
image: /images/docs/redis.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Cassandra
|
||||
image: /images/docs/cassandra.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: WordPress + MySQL
|
||||
image: /images/docs/wordpress.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Mean Stack
|
||||
image: /images/docs/meanstack/image_0.png
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Guestbook + Redis
|
||||
image: /images/docs/redis.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Cassandra
|
||||
image: /images/docs/cassandra.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: WordPress + MySQL
|
||||
image: /images/docs/wordpress.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Mean Stack
|
||||
image: /images/docs/meanstack/image_0.png
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Guestbook + Redis
|
||||
image: /images/docs/redis.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: Cassandra
|
||||
image: /images/docs/cassandra.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
- card:
|
||||
title: WordPress + MySQL
|
||||
image: /images/docs/wordpress.svg
|
||||
description: Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum. Lorem ipsum dolor it verberum.
|
||||
---
|
||||
{% include templates/landing-page.md %}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
---
|
||||
|
||||
{% assign concept="Replication Controller" %}
|
||||
|
||||
{% include templates/concept-overview.md %}
|
||||
|
|
@ -169,7 +169,7 @@ You have several options for connecting to nodes, pods and services from outside
|
|||
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](#discovering-builtin-services).
|
||||
- Described [here](#manually-constructing-apiserver-proxy-urls).
|
||||
- Access from a node or pod in the cluster.
|
||||
- Run a pod, and then connect to a shell in it using [kubectl exec](/docs/user-guide/kubectl/kubectl_exec).
|
||||
Connect to other nodes, pods, and services from that shell.
|
||||
|
|
@ -275,4 +275,4 @@ There are several different proxies you may encounter when using Kubernetes:
|
|||
- 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.
|
||||
will typically ensure that the latter types are setup correctly.
|
||||
|
|
|
|||
|
|
@ -22,14 +22,17 @@ server.
|
|||
|
||||
## Resource Requests and Limits of Pod and Container
|
||||
|
||||
Each container of a Pod can optionally specify `spec.container[].resources.limits.cpu` and/or
|
||||
`spec.container[].resources.limits.memory` and/or `spec.container[].resources.requests.cpu`
|
||||
and/or `spec.container[].resources.requests.memory`.
|
||||
Each container of a pod can optionally specify one or more of the following:
|
||||
|
||||
* `spec.container[].resources.limits.cpu`
|
||||
* `spec.container[].resources.limits.memory`
|
||||
* `spec.container[].resources.requests.cpu`
|
||||
* `spec.container[].resources.requests.memory`.
|
||||
|
||||
Specifying resource requests and/or limits is optional. In some clusters, unset limits or requests
|
||||
may be replaced with default values when a pod is created or updated. The default value depends on
|
||||
how the cluster is configured. If value of requests is not specified, they are set to be equal
|
||||
to limits by default. Please note that resource limits must be greater than or equal to resource
|
||||
how the cluster is configured. If the requests values are not specified, they are set to be equal
|
||||
to the limits values by default. Please note that limits must always be greater than or equal to
|
||||
requests.
|
||||
|
||||
Although requests/limits can only be specified on individual containers, it is convenient to talk
|
||||
|
|
@ -171,7 +174,7 @@ Here you can see from the `Allocated resources` section that that a pod which as
|
|||
|
||||
Looking at the `Pods` section, you can see which pods are taking up space on the node.
|
||||
|
||||
The [resource quota](/docs/admin/resource-quota) feature can be configured
|
||||
The [resource quota](/docs/admin/resourcequota/) feature can be configured
|
||||
to limit the total amount of resources that can be consumed. If used in conjunction
|
||||
with namespaces, it can prevent one team from hogging all the resources.
|
||||
|
||||
|
|
@ -222,10 +225,10 @@ The `Restart Count: 5` indicates that the `simmemleak` container in this pod wa
|
|||
|
||||
You can call `get pod` with the `-o go-template=...` option to fetch the status of previously terminated containers:
|
||||
|
||||
```shell
|
||||
```shell{% raw %}
|
||||
[13:59:01] $ ./cluster/kubectl.sh get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-60xbc
|
||||
Container Name: simmemleak
|
||||
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]
|
||||
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]{% endraw %}
|
||||
```
|
||||
|
||||
We can see that this container was terminated because `reason:OOM Killed`, where *OOM* stands for Out Of Memory.
|
||||
|
|
@ -246,4 +249,4 @@ Currently, one unit of CPU means different things on different cloud providers,
|
|||
machine types within the same cloud providers. For example, on AWS, the capacity of a node
|
||||
is reported in [ECUs](http://aws.amazon.com/ec2/faqs/), while in GCE it is reported in logical
|
||||
cores. We plan to revise the definition of the cpu resource to allow for more consistency
|
||||
across providers and platforms.
|
||||
across providers and platforms.
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ This document is meant to highlight and consolidate in one place configuration b
|
|||
controller 'version names'. A desired state of an object is described by a Deployment, and if
|
||||
changes to that spec are _applied_, the deployment controller changes the actual state to the
|
||||
desired state at a controlled rate. (Deployment objects are currently part of the [`extensions`
|
||||
API Group](/docs/api/#api-groups), and are not enabled by default.)
|
||||
API Group](/docs/api/#api-groups).)
|
||||
|
||||
- You can manipulate labels for debugging. Because Kubernetes replication controllers and services
|
||||
match to pods using labels, this allows you to remove a pod from being considered by a
|
||||
|
|
@ -100,6 +100,9 @@ This document is meant to highlight and consolidate in one place configuration b
|
|||
address this by ensuring that any updates to an image bump the image tag as well (e.g.
|
||||
`myimage:v2`), and ensuring that your configs point to the correct version.
|
||||
|
||||
**Note:** you should avoid using `:latest` tag when deploying containers in production, because this makes it hard
|
||||
to track which version of the image is running and hard to roll back.
|
||||
|
||||
## Using kubectl
|
||||
|
||||
- Use `kubectl create -f <directory>` where possible. This looks for config objects in all `.yaml`, `.yml`, and `.json` files in `<directory>` and passes them to `create`.
|
||||
|
|
@ -108,6 +111,6 @@ This document is meant to highlight and consolidate in one place configuration b
|
|||
|
||||
- Use kubectl bulk operations (via files and/or labels) for get and delete. See [label selectors](/docs/user-guide/labels/#label-selectors) and [using labels effectively](/docs/user-guide/managing-deployments/#using-labels-effectively).
|
||||
|
||||
- Use `kubectl run` and `expose` to quickly create and expose single container replication controllers. See the [quick start guide](/docs/user-guide/quick-start/) for an example.
|
||||
- Use `kubectl run` and `expose` to quickly create and expose single container Deployments. See the [quick start guide](/docs/user-guide/quick-start/) for an example.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ You can use `kubectl` to see information about the ConfigMap:
|
|||
|
||||
```shell
|
||||
$ kubectl get configmap
|
||||
NAME DATA
|
||||
test-secret 2
|
||||
NAME DATA AGE
|
||||
test-configmap 2 6s
|
||||
|
||||
$ kubectl describe configMap test-configmap
|
||||
Name: test-configmap
|
||||
|
|
@ -39,7 +39,7 @@ data-2: 7 bytes
|
|||
View the values of the keys with `kubectl get`:
|
||||
|
||||
```shell
|
||||
$ cluster/kubectl.sh get configmaps test-configmap -o yaml
|
||||
$ kubectl get configmaps test-configmap -o yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
data-1: value-1
|
||||
|
|
@ -66,23 +66,24 @@ $ kubectl create -f docs/user-guide/configmap/env-pod.yaml
|
|||
This pod runs the `env` command to display the environment of the container:
|
||||
|
||||
```shell
|
||||
$ kubectl logs secret-test-pod
|
||||
$ kubectl logs config-env-test-pod | grep KUBE_CONFIG
|
||||
KUBE_CONFIG_1=value-1
|
||||
KUBE_CONFIG_2=value-2
|
||||
```
|
||||
|
||||
## Step Three: Create a pod that sets the command line using ConfigMap
|
||||
|
||||
Use the [`command-pod.yaml`](env-pod.yaml) file to create a Pod with a container
|
||||
Use the [`command-pod.yaml`](command-pod.yaml) file to create a Pod with a container
|
||||
whose command is injected with the keys of a ConfigMap
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/user-guide/configmap/env-pod.yaml
|
||||
$ kubectl create -f docs/user-guide/configmap/command-pod.yaml
|
||||
```
|
||||
|
||||
This pod runs an `echo` command to display the keys:
|
||||
|
||||
```shell
|
||||
$ kubectl logs config-cmd-test-pod
|
||||
value-1 value-2
|
||||
```
|
||||
|
||||
|
|
@ -97,5 +98,6 @@ $ kubectl create -f docs/user-guide/configmap/volume-pod.yaml
|
|||
This pod runs a `cat` command to print the value of one of the keys in the volume:
|
||||
|
||||
```shell
|
||||
$ kubectl logs config-volume-test-pod
|
||||
value-1
|
||||
```
|
||||
```
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ content of the file.
|
|||
Let's take a look at the ConfigMap that this command created:
|
||||
|
||||
```shell
|
||||
$ cluster/kubectl.sh describe configmaps game-config
|
||||
$ kubectl describe configmaps game-config
|
||||
Name: game-config
|
||||
Namespace: default
|
||||
Labels: <none>
|
||||
|
|
@ -147,7 +147,7 @@ following command yields equivalent results to the above example:
|
|||
```shell
|
||||
$ kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties --from-file=docs/user-guide/configmap/kubectl/ui.properties
|
||||
|
||||
$ cluster/kubectl.sh get configmaps game-config-2 -o yaml
|
||||
$ kubectl get configmaps game-config-2 -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
|
|
@ -237,7 +237,7 @@ metadata:
|
|||
|
||||
### Use-Case: Consume ConfigMap in environment variables
|
||||
|
||||
ConfigMaps can be used to populate the value of command line arguments. As an example, consider
|
||||
ConfigMaps can be used to populate environment variables. As an example, consider
|
||||
the following ConfigMap:
|
||||
|
||||
```yaml
|
||||
|
|
@ -267,13 +267,13 @@ spec:
|
|||
- name: SPECIAL_LEVEL_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-configmap
|
||||
name: special-config
|
||||
key: special.how
|
||||
- name: SPECIAL_TYPE_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: data-1
|
||||
key: special.type
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
|
|
@ -318,13 +318,13 @@ spec:
|
|||
- name: SPECIAL_LEVEL_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-configmap
|
||||
name: special-config
|
||||
key: special.how
|
||||
- name: SPECIAL_TYPE_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: data-1
|
||||
key: special.type
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
|
|
@ -427,25 +427,23 @@ ConfigMap instance with it:
|
|||
```shell
|
||||
$ kubectl create configmap example-redis-config --from-file=docs/user-guide/configmap/redis/redis-config
|
||||
|
||||
$ kubectl get configmap redis-config -o yaml
|
||||
$ kubectl get configmap example-redis-config -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
{
|
||||
"kind": "ConfigMap",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "example-redis-config",
|
||||
"namespace": "default",
|
||||
"selfLink": "/api/v1/namespaces/default/configmaps/example-redis-config",
|
||||
"uid": "07fd0419-d97b-11e5-b443-68f728db1985",
|
||||
"resourceVersion": "15",
|
||||
"creationTimestamp": "2016-02-22T15:43:34Z"
|
||||
},
|
||||
"data": {
|
||||
"redis-config": "maxmemory 2mb\nmaxmemory-policy allkeys-lru\n"
|
||||
}
|
||||
}
|
||||
apiVersion: v1
|
||||
data:
|
||||
redis-config: |
|
||||
maxmemory 2mb
|
||||
maxmemory-policy allkeys-lru
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-03-30T18:14:41Z
|
||||
name: example-redis-config
|
||||
namespace: default
|
||||
resourceVersion: "24686"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/example-redis-config
|
||||
uid: 460a2b6e-f6a3-11e5-8ae5-42010af00002
|
||||
```
|
||||
|
||||
Now, let's create a pod that uses this config:
|
||||
|
|
@ -117,7 +117,7 @@ The `READY` column shows how many containers in the pod are running.
|
|||
Almost immediately after it starts running, this command will terminate. `kubectl` shows that the container is no longer running and displays the exit status:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods
|
||||
$ kubectl get pods --show-all
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hello-world 0/1 ExitCode:0 0 15s
|
||||
```
|
||||
|
|
|
|||
|
|
@ -18,41 +18,24 @@ This guide uses a simple nginx server to demonstrate proof of concept. The same
|
|||
|
||||
We did this in a previous example, but lets do it once again and focus on the networking perspective. Create an nginx pod, and note that it has a container port specification:
|
||||
|
||||
```yaml
|
||||
$ cat nginxrc.yaml
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: my-nginx
|
||||
spec:
|
||||
replicas: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
```
|
||||
{% include code.html language="yaml" file="run-my-nginx.yaml" ghlink="/docs/user-guide/run-my-nginx.yaml" %}
|
||||
|
||||
This makes it accessible from any node in your cluster. Check the nodes the pod is running on:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f ./nginxrc.yaml
|
||||
$ kubectl get pods -l app=nginx -o wide
|
||||
my-nginx-6isf4 1/1 Running 0 2h e2e-test-beeps-node-93ly
|
||||
my-nginx-t26zt 1/1 Running 0 2h e2e-test-beeps-node-93ly
|
||||
$ kubectl create -f ./run-my-nginx.yaml
|
||||
$ kubectl get pods -l run=my-nginx -o wide
|
||||
NAME READY STATUS RESTARTS AGE NODE
|
||||
my-nginx-3800858182-jr4a2 1/1 Running 0 13s kubernetes-minion-905m
|
||||
my-nginx-3800858182-kna2y 1/1 Running 0 13s kubernetes-minion-ljyd
|
||||
```
|
||||
|
||||
Check your pods' IPs:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -l app=nginx -o json | grep podIP
|
||||
"podIP": "10.245.0.15",
|
||||
"podIP": "10.245.0.14",
|
||||
$ kubectl get pods -l run=my-nginx -o yaml | grep podIP
|
||||
podIP: 10.244.3.4
|
||||
podIP: 10.244.2.5
|
||||
```
|
||||
|
||||
You should be able to ssh into any node in your cluster and curl both IPs. Note that the containers are *not* using port 80 on the node, nor are there any special NAT rules to route traffic to the pod. This means you can run multiple nginx pods on the same node all using the same containerPort and access them from any other pod or node in your cluster using IP. Like Docker, ports can still be published to the host node's interface(s), but the need for this is radically diminished because of the networking model.
|
||||
|
|
@ -61,59 +44,51 @@ You can read more about [how we achieve this](/docs/admin/networking/#how-to-ach
|
|||
|
||||
## Creating a Service
|
||||
|
||||
So we have pods running nginx in a flat, cluster wide, address space. In theory, you could talk to these pods directly, but what happens when a node dies? The pods die with it, and the replication controller will create new ones, with different IPs. This is the problem a Service solves.
|
||||
So we have pods running nginx in a flat, cluster wide, address space. In theory, you could talk to these pods directly, but what happens when a node dies? The pods die with it, and the Deployment will create new ones, with different IPs. This is the problem a Service solves.
|
||||
|
||||
A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality. When created, each Service is assigned a unique IP address (also called clusterIP). This address is tied to the lifespan of the Service, and will not change while the Service is alive. Pods can be configured to talk to the Service, and know that communication to the Service will be automatically load-balanced out to some pod that is a member of the Service.
|
||||
|
||||
You can create a Service for your 2 nginx replicas with the following yaml:
|
||||
You can create a Service for your 2 nginx replicas with `kubectl expose`:
|
||||
|
||||
```yaml
|
||||
$ cat nginxsvc.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginxsvc
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: nginx
|
||||
```shell
|
||||
$ kubectl expose deployment/my-nginx
|
||||
service "my-nginx" exposed
|
||||
```
|
||||
|
||||
This is equivalent to `kubectl create -f` the following yaml:
|
||||
|
||||
{% include code.html language="yaml" file="nginx-svc.yaml" ghlink="/docs/user-guide/nginx-svc.yaml" %}
|
||||
|
||||
This specification will create a Service which targets TCP port 80 on any Pod with the `app=nginx` label, and expose it on an abstracted Service port (`targetPort`: is the port the container accepts traffic on, `port`: is the abstracted Service port, which can be any port other pods use to access the Service). View [service API object](/docs/api-reference/v1/definitions/#_v1_service) to see the list of supported fields in service definition.
|
||||
Check your Service:
|
||||
|
||||
```shell
|
||||
$ kubectl get svc
|
||||
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
|
||||
kubernetes 10.179.240.1 <none> 443/TCP <none> 8d
|
||||
nginxsvc 10.179.252.126 122.222.183.144 80/TCP,81/TCP,82/TCP run=nginx2 11m
|
||||
$ kubectl get svc my-nginx
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
my-nginx 10.0.162.149 <none> 80/TCP 21s
|
||||
```
|
||||
|
||||
As mentioned previously, a Service is backed by a group of pods. These pods are exposed through `endpoints`. The Service's selector will be evaluated continuously and the results will be POSTed to an Endpoints object also named `nginxsvc`. When a pod dies, it is automatically removed from the endpoints, and new pods matching the Service's selector will automatically get added to the endpoints. Check the endpoints, and note that the IPs are the same as the pods created in the first step:
|
||||
As mentioned previously, a Service is backed by a group of pods. These pods are exposed through `endpoints`. The Service's selector will be evaluated continuously and the results will be POSTed to an Endpoints object also named `my-nginx`. When a pod dies, it is automatically removed from the endpoints, and new pods matching the Service's selector will automatically get added to the endpoints. Check the endpoints, and note that the IPs are the same as the pods created in the first step:
|
||||
|
||||
```shell
|
||||
$ kubectl describe svc nginxsvc
|
||||
Name: nginxsvc
|
||||
$ kubectl describe svc my-nginx
|
||||
Name: my-nginx
|
||||
Namespace: default
|
||||
Labels: app=nginx
|
||||
Selector: app=nginx
|
||||
Labels: run=my-nginx
|
||||
Selector: run=my-nginx
|
||||
Type: ClusterIP
|
||||
IP: 10.0.116.146
|
||||
Port: <unnamed> 80/TCP
|
||||
Endpoints: 10.245.0.14:80,10.245.0.15:80
|
||||
IP: 10.0.162.149
|
||||
Port: <unset> 80/TCP
|
||||
Endpoints: 10.244.2.5:80,10.244.3.4:80
|
||||
Session Affinity: None
|
||||
No events.
|
||||
|
||||
$ kubectl get ep
|
||||
NAME ENDPOINTS
|
||||
nginxsvc 10.245.0.14:80,10.245.0.15:80
|
||||
$ kubectl get ep my-nginx
|
||||
NAME ENDPOINTS AGE
|
||||
my-nginx 10.244.2.5:80,10.244.3.4:80 1m
|
||||
```
|
||||
|
||||
You should now be able to curl the nginx Service on `10.0.116.146:80` from any node in your cluster. Note that the Service IP is completely virtual, it never hits the wire, if you're curious about how this works you can read more about the [service proxy](/docs/user-guide/services/#virtual-ips-and-service-proxies).
|
||||
You should now be able to curl the nginx Service on `<CLUSTER-IP>:<PORT>` from any node in your cluster. Note that the Service IP is completely virtual, it never hits the wire, if you're curious about how this works you can read more about the [service proxy](/docs/user-guide/services/#virtual-ips-and-service-proxies).
|
||||
|
||||
## Accessing the Service
|
||||
|
||||
|
|
@ -121,28 +96,35 @@ Kubernetes supports 2 primary modes of finding a Service - environment variables
|
|||
|
||||
### Environment Variables
|
||||
|
||||
When a Pod is run on a Node, the kubelet adds a set of environment variables for each active Service. This introduces an ordering problem. To see why, inspect the environment of your running nginx pods:
|
||||
When a Pod is run on a Node, the kubelet adds a set of environment variables for each active Service. This introduces an ordering problem. To see why, inspect the environment of your running nginx pods (your pod name will be different):
|
||||
|
||||
```shell
|
||||
$ kubectl exec my-nginx-6isf4 -- printenv | grep SERVICE
|
||||
$ kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
|
||||
KUBERNETES_SERVICE_HOST=10.0.0.1
|
||||
KUBERNETES_SERVICE_PORT=443
|
||||
KUBERNETES_SERVICE_PORT_HTTPS=443
|
||||
```
|
||||
|
||||
Note there's no mention of your Service. This is because you created the replicas before the Service. Another disadvantage of doing this is that the scheduler might put both pods on the same machine, which will take your entire Service down if it dies. We can do this the right way by killing the 2 pods and waiting for the replication controller to recreate them. This time around the Service exists *before* the replicas. This will given you scheduler level Service spreading of your pods (provided all your nodes have equal capacity), as well as the right environment variables:
|
||||
Note there's no mention of your Service. This is because you created the replicas before the Service. Another disadvantage of doing this is that the scheduler might put both pods on the same machine, which will take your entire Service down if it dies. We can do this the right way by killing the 2 pods and waiting for the Deployment to recreate them. This time around the Service exists *before* the replicas. This will given you scheduler level Service spreading of your pods (provided all your nodes have equal capacity), as well as the right environment variables:
|
||||
|
||||
```shell
|
||||
$ kubectl scale rc my-nginx --replicas=0; kubectl scale rc my-nginx --replicas=2;
|
||||
$ kubectl get pods -l app=nginx -o wide
|
||||
NAME READY STATUS RESTARTS AGE NODE
|
||||
my-nginx-5j8ok 1/1 Running 0 2m node1
|
||||
my-nginx-90vaf 1/1 Running 0 2m node2
|
||||
$ kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2;
|
||||
|
||||
$ kubectl exec my-nginx-5j8ok -- printenv | grep SERVICE
|
||||
$ kubectl get pods -l run=my-nginx -o wide
|
||||
NAME READY STATUS RESTARTS AGE NODE
|
||||
my-nginx-3800858182-e9ihh 1/1 Running 0 5s kubernetes-minion-ljyd
|
||||
my-nginx-3800858182-j4rm4 1/1 Running 0 5s kubernetes-minion-905m
|
||||
```
|
||||
|
||||
You may notice that the pods have different names, since they are killed and recreated.
|
||||
|
||||
```shell
|
||||
$ kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE
|
||||
KUBERNETES_SERVICE_PORT=443
|
||||
NGINXSVC_SERVICE_HOST=10.0.116.146
|
||||
MY_NGINX_SERVICE_HOST=10.0.162.149
|
||||
KUBERNETES_SERVICE_HOST=10.0.0.1
|
||||
NGINXSVC_SERVICE_PORT=80
|
||||
MY_NGINX_SERVICE_PORT=80
|
||||
KUBERNETES_SERVICE_PORT_HTTPS=443
|
||||
```
|
||||
|
||||
### DNS
|
||||
|
|
@ -151,43 +133,27 @@ Kubernetes offers a DNS cluster addon Service that uses skydns to automatically
|
|||
|
||||
```shell
|
||||
$ kubectl get services kube-dns --namespace=kube-system
|
||||
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
|
||||
kube-dns 10.179.240.10 <none> 53/UDP,53/TCP k8s-app=kube-dns 8d
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
kube-dns 10.0.0.10 <none> 53/UDP,53/TCP 8m
|
||||
```
|
||||
|
||||
If it isn't running, you can [enable it](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md#how-do-i-configure-it). The rest of this section will assume you have a Service with a long lived IP (nginxsvc), and a dns server that has assigned a name to that IP (the kube-dns cluster addon), so you can talk to the Service from any pod in your cluster using standard methods (e.g. gethostbyname). Let's create another pod to test this:
|
||||
|
||||
```yaml
|
||||
$ cat curlpod.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: curlpod
|
||||
spec:
|
||||
containers:
|
||||
- image: radial/busyboxplus:curl
|
||||
command:
|
||||
- sleep
|
||||
- "3600"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: curlcontainer
|
||||
restartPolicy: Always
|
||||
```
|
||||
|
||||
And perform a lookup of the nginx Service
|
||||
If it isn't running, you can [enable it](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md#how-do-i-configure-it). The rest of this section will assume you have a Service with a long lived IP (my-nginx), and a dns server that has assigned a name to that IP (the kube-dns cluster addon), so you can talk to the Service from any pod in your cluster using standard methods (e.g. gethostbyname). Let's run another curl application to test this:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f ./curlpod.yaml
|
||||
default/curlpod
|
||||
$ kubectl get pods curlpod
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
curlpod 1/1 Running 0 18s
|
||||
$ kubectl run curl --image=radial/busyboxplus:curl -i --tty
|
||||
Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false
|
||||
Hit enter for command prompt
|
||||
```
|
||||
|
||||
$ kubectl exec curlpod -- nslookup nginxsvc
|
||||
Then, hit enter and run `nslookup my-nginx`:
|
||||
|
||||
```shell
|
||||
[ root@curl-131556218-9fnch:/ ]$ nslookup my-nginx
|
||||
Server: 10.0.0.10
|
||||
Address 1: 10.0.0.10
|
||||
Name: nginxsvc
|
||||
Address 1: 10.0.116.146
|
||||
|
||||
Name: my-nginx
|
||||
Address 1: 10.0.162.149
|
||||
```
|
||||
|
||||
## Securing the Service
|
||||
|
|
@ -212,73 +178,27 @@ nginxsecret Opaque 2
|
|||
|
||||
Now modify your nginx replicas to start a https server using the certificate in the secret, and the Service, to expose both ports (80 and 443):
|
||||
|
||||
```yaml
|
||||
$ cat nginx-app.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginxsvc
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
name: http
|
||||
- port: 443
|
||||
protocol: TCP
|
||||
name: https
|
||||
selector:
|
||||
app: nginx
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: my-nginx
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
volumes:
|
||||
- name: secret-volume
|
||||
secret:
|
||||
secretName: nginxsecret
|
||||
containers:
|
||||
- name: nginxhttps
|
||||
image: bprashanth/nginxhttps:1.0
|
||||
ports:
|
||||
- containerPort: 443
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- mountPath: /etc/nginx/ssl
|
||||
name: secret-volume
|
||||
```
|
||||
{% include code.html language="yaml" file="nginx-secure-app.yaml" ghlink="/docs/user-guide/nginx-secure-app" %}
|
||||
|
||||
Noteworthy points about the nginx-app manifest:
|
||||
Noteworthy points about the nginx-secure-app manifest:
|
||||
|
||||
- It contains both rc and service specification in the same file
|
||||
- The [nginx server](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/https-nginx/default.conf) serves http traffic on port 80 and https traffic on 443, and nginx Service exposes both ports.
|
||||
- Each container has access to the keys through a volume mounted at /etc/nginx/ssl. This is setup *before* the nginx server is started.
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f ./nginx-secure-app.yaml
|
||||
$ kubectl delete rc,svc -l app=nginx; kubectl create -f ./nginx-app.yaml
|
||||
replicationcontrollers/my-nginx
|
||||
services/nginxsvc
|
||||
services/nginxsvc
|
||||
replicationcontrollers/my-nginx
|
||||
service "my-nginx" configured
|
||||
deployment "my-nginx" configured
|
||||
```
|
||||
|
||||
At this point you can reach the nginx server from any node.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -o json | grep -i podip
|
||||
"podIP": "10.1.0.80",
|
||||
node $ curl -k https://10.1.0.80
|
||||
$ kubectl get pods -o yaml | grep -i podip
|
||||
podIP: 10.244.3.5
|
||||
node $ curl -k https://10.244.3.5
|
||||
...
|
||||
<h1>Welcome to nginx!</h1>
|
||||
```
|
||||
|
|
@ -287,41 +207,15 @@ Note how we supplied the `-k` parameter to curl in the last step, this is becaus
|
|||
so we have to tell curl to ignore the CName mismatch. By creating a Service we linked the CName used in the certificate with the actual DNS name used by pods during Service lookup.
|
||||
Lets test this from a pod (the same secret is being reused for simplicity, the pod only needs nginx.crt to access the Service):
|
||||
|
||||
```shell
|
||||
$ cat curlpod.yaml
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: curlrc
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: curlpod
|
||||
spec:
|
||||
volumes:
|
||||
- name: secret-volume
|
||||
secret:
|
||||
secretName: nginxsecret
|
||||
containers:
|
||||
- name: curlpod
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- while true; do sleep 1; done
|
||||
image: radial/busyboxplus:curl
|
||||
volumeMounts:
|
||||
- mountPath: /etc/nginx/ssl
|
||||
name: secret-volume
|
||||
{% include code.html language="yaml" file="curlpod.yaml" ghlink="/docs/user-guide/curlpod.yaml" %}
|
||||
|
||||
```shell
|
||||
$ kubectl create -f ./curlpod.yaml
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
curlpod 1/1 Running 0 2m
|
||||
my-nginx-7006w 1/1 Running 0 24m
|
||||
|
||||
$ kubectl exec curlpod -- curl https://nginxsvc --cacert /etc/nginx/ssl/nginx.crt
|
||||
$ kubectl exec curlpod -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt
|
||||
...
|
||||
<title>Welcome to nginx!</title>
|
||||
...
|
||||
|
|
@ -332,62 +226,62 @@ $ kubectl exec curlpod -- curl https://nginxsvc --cacert /etc/nginx/ssl/nginx.cr
|
|||
For some parts of your applications you may want to expose a Service onto an external IP address. Kubernetes supports two ways of doing this: NodePorts and LoadBalancers. The Service created in the last section already used `NodePort`, so your nginx https replica is ready to serve traffic on the internet if your node has a public IP.
|
||||
|
||||
```shell
|
||||
$ kubectl get svc nginxsvc -o json | grep -i nodeport -C 5
|
||||
{
|
||||
"name": "http",
|
||||
"protocol": "TCP",
|
||||
"port": 80,
|
||||
"targetPort": 80,
|
||||
"nodePort": 32188
|
||||
},
|
||||
{
|
||||
"name": "https",
|
||||
"protocol": "TCP",
|
||||
"port": 443,
|
||||
"targetPort": 443,
|
||||
"nodePort": 30645
|
||||
}
|
||||
$ kubectl get svc my-nginx -o yaml | grep nodePort -C 5
|
||||
uid: 07191fb3-f61a-11e5-8ae5-42010af00002
|
||||
spec:
|
||||
clusterIP: 10.0.162.149
|
||||
ports:
|
||||
- name: http
|
||||
nodePort: 31704
|
||||
port: 8080
|
||||
protocol: TCP
|
||||
targetPort: 80
|
||||
- name: https
|
||||
nodePort: 32453
|
||||
port: 443
|
||||
protocol: TCP
|
||||
targetPort: 443
|
||||
selector:
|
||||
run: my-nginx
|
||||
|
||||
$ kubectl get nodes -o json | grep ExternalIP -C 2
|
||||
{
|
||||
"type": "ExternalIP",
|
||||
"address": "104.197.63.17"
|
||||
}
|
||||
$ kubectl get nodes -o yaml | grep ExternalIP -C 1
|
||||
- address: 104.197.41.11
|
||||
type: ExternalIP
|
||||
allocatable:
|
||||
--
|
||||
},
|
||||
{
|
||||
"type": "ExternalIP",
|
||||
"address": "104.154.89.170"
|
||||
}
|
||||
$ curl https://104.197.63.17:30645 -k
|
||||
- address: 23.251.152.56
|
||||
type: ExternalIP
|
||||
allocatable:
|
||||
...
|
||||
|
||||
$ curl https://<EXTERNAL-IP>:<NODE-PORT> -k
|
||||
...
|
||||
<h1>Welcome to nginx!</h1>
|
||||
```
|
||||
|
||||
Lets now recreate the Service to use a cloud load balancer, just change the `Type` of Service in the nginx-app.yaml from `NodePort` to `LoadBalancer`:
|
||||
Lets now recreate the Service to use a cloud load balancer, just change the `Type` of `my-nginx` Service from `NodePort` to `LoadBalancer`:
|
||||
|
||||
```shell
|
||||
$ kubectl delete rc,svc -l app=nginx
|
||||
$ kubectl create -f ./nginx-app.yaml
|
||||
$ kubectl get svc nginxsvc
|
||||
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
|
||||
nginxsvc 10.179.252.126 162.222.184.144 80/TCP,81/TCP,82/TCP run=nginx2 13m
|
||||
$ kubectl edit svc my-nginx
|
||||
$ kubectl get svc my-nginx
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
my-nginx 10.0.162.149 162.222.184.144 80/TCP,81/TCP,82/TCP 21s
|
||||
|
||||
$ curl https://162.22.184.144 -k
|
||||
$ curl https://<EXTERNAL-IP> -k
|
||||
...
|
||||
<title>Welcome to nginx!</title>
|
||||
```
|
||||
|
||||
The IP address in the `EXTERNAL_IP` column is the one that is available on the public internet. The `CLUSTER_IP` is only available inside your
|
||||
The IP address in the `EXTERNAL-IP` column is the one that is available on the public internet. The `CLUSTER-IP` is only available inside your
|
||||
cluster/private cloud network.
|
||||
|
||||
Note that on AWS, type `LoadBalancer` creates an ELB, which uses a (long)
|
||||
hostname, not an IP. It's too long to fit in the standard `kubectl get svc`
|
||||
output, in fact, so you'll need to do `kubectl describe service nginxsvc` to
|
||||
output, in fact, so you'll need to do `kubectl describe service my-nginx` to
|
||||
see it. You'll see something like this:
|
||||
|
||||
```shell
|
||||
> kubectl describe service nginxsvc
|
||||
$ kubectl describe service my-nginx
|
||||
...
|
||||
LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.elb.amazonaws.com
|
||||
...
|
||||
|
|
|
|||
|
|
@ -1,46 +1,46 @@
|
|||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
kubectl port-forward forwards connections to a local port to a port on a pod. Its man page is available [here](/docs/user-guide/kubectl/kubectl_port-forward). Compared to [kubectl proxy](/docs/user-guide/accessing-the-cluster/#using-kubectl-proxy), `kubectl port-forward` is more generic as it can forward TCP traffic while `kubectl proxy` can only forward HTTP traffic. This guide demonstrates how to use `kubectl port-forward` to connect to a Redis database, which may be useful for database debugging.
|
||||
|
||||
## Creating a Redis master
|
||||
|
||||
```shell
|
||||
```shell
|
||||
$ kubectl create examples/redis/redis-master.yaml
|
||||
pods/redis-master
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
wait until the Redis master pod is Running and Ready,
|
||||
|
||||
```shell
|
||||
```shell
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-master 2/2 Running 0 41s
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
## Connecting to the Redis master[a]
|
||||
|
||||
The Redis master is listening on port 6397, to verify this,
|
||||
The Redis master is listening on port 6379, to verify this,
|
||||
|
||||
```shell
|
||||
```shell{% raw %}
|
||||
$ kubectl get pods redis-master -t='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
|
||||
6379
|
||||
```
|
||||
|
||||
6379{% endraw %}
|
||||
```
|
||||
|
||||
then we forward the port 6379 on the local workstation to the port 6379 of pod redis-master,
|
||||
|
||||
```shell
|
||||
```shell
|
||||
$ kubectl port-forward redis-master 6379:6379
|
||||
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
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
To verify the connection is successful, we run a redis-cli on the local workstation,
|
||||
|
||||
```shell
|
||||
```shell
|
||||
$ redis-cli
|
||||
127.0.0.1:6379> ping
|
||||
PONG
|
||||
```
|
||||
|
||||
Now one can debug the database from the local workstation.
|
||||
```
|
||||
|
||||
Now one can debug the database from the local workstation.
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ There are currently two container hooks that are surfaced to containers:
|
|||
|
||||
*PostStart*
|
||||
|
||||
This hook is sent immediately after a container is created. It notifies the container that it has been created. No parameters are passed to the handler.
|
||||
This hook is sent immediately after a container is created. It notifies the container that it has been created. No parameters are passed to the handler. It is NOT guaranteed that the hook will execute before the container entrypoint.
|
||||
|
||||
*PreStop*
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: curl-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: curlpod
|
||||
spec:
|
||||
volumes:
|
||||
- name: secret-volume
|
||||
secret:
|
||||
secretName: nginxsecret
|
||||
containers:
|
||||
- name: curlpod
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- while true; do sleep 1; done
|
||||
image: radial/busyboxplus:curl
|
||||
volumeMounts:
|
||||
- mountPath: /etc/nginx/ssl
|
||||
name: secret-volume
|
||||
|
|
@ -45,7 +45,7 @@ case you can try several things:
|
|||
kubectl get nodes -o yaml | grep '\sname\|cpu\|memory'
|
||||
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, cap: .status.capacity}'
|
||||
|
||||
The [resource quota](/docs/admin/resource-quota/)
|
||||
The [resource quota](/docs/admin/resourcequota/)
|
||||
feature can be configured to limit the total amount of
|
||||
resources that can be consumed. If used in conjunction with namespaces, it can
|
||||
prevent one team from hogging all the resources.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
An issue that comes up rather frequently for new installations of Kubernetes is
|
||||
that `Services` are not working properly. You've run all your `Pod`s and
|
||||
`ReplicationController`s, but you get no response when you try to access them.
|
||||
`Deployment`s, but you get no response when you try to access them.
|
||||
This document will hopefully help you to figure out what's going wrong.
|
||||
|
||||
* TOC
|
||||
|
|
@ -40,37 +40,27 @@ OUTPUT
|
|||
## Running commands in a Pod
|
||||
|
||||
For many steps here you will want to see what a `Pod` running in the cluster
|
||||
sees. Kubernetes does not directly support interactive `Pod`s (yet), but you can
|
||||
approximate it:
|
||||
sees. You can start a busybox `Pod` and run commands in it:
|
||||
|
||||
```shell
|
||||
$ cat <<EOF | kubectl create -f -
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox-sleep
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox
|
||||
args:
|
||||
- sleep
|
||||
- "1000000"
|
||||
EOF
|
||||
pods/busybox-sleep
|
||||
$ kubectl run -i --tty busybox --image=busybox --generator="run-pod/v1"
|
||||
Waiting for pod default/busybox to be running, status is Pending, pod ready: false
|
||||
|
||||
Hit enter for command prompt
|
||||
|
||||
/ #
|
||||
```
|
||||
|
||||
Now, when you need to run a command (even an interactive shell) in a `Pod`-like
|
||||
context, use:
|
||||
If you already have a running `Pod`, run a command in it using:
|
||||
|
||||
```shell
|
||||
$ kubectl exec busybox-sleep -- <COMMAND>
|
||||
$ kubectl exec <POD-NAME> -c <CONTAINER-NAME> -- <COMMAND>
|
||||
```
|
||||
|
||||
or
|
||||
or run an interactive shell with:
|
||||
|
||||
```shell
|
||||
$ kubectl exec -ti busybox-sleep sh
|
||||
$ kubectl exec -ti <POD-NAME> -c <CONTAINER-NAME> sh
|
||||
/ #
|
||||
```
|
||||
|
||||
|
|
@ -85,16 +75,16 @@ $ kubectl run hostnames --image=gcr.io/google_containers/serve_hostname \
|
|||
--labels=app=hostnames \
|
||||
--port=9376 \
|
||||
--replicas=3
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
hostnames hostnames gcr.io/google_containers/serve_hostname app=hostnames 3
|
||||
deployment "hostnames" created
|
||||
```
|
||||
|
||||
Note that this is the same as if you had started the `ReplicationController` with
|
||||
`kubectl` commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands.
|
||||
Note that this is the same as if you had started the `Deployment` with
|
||||
the following YAML:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: hostnames
|
||||
spec:
|
||||
|
|
@ -118,10 +108,10 @@ Confirm your `Pod`s are running:
|
|||
|
||||
```shell
|
||||
$ kubectl get pods -l app=hostnames
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hostnames-0uton 1/1 Running 0 12s
|
||||
hostnames-bvc05 1/1 Running 0 12s
|
||||
hostnames-yp2kp 1/1 Running 0 12s
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hostnames-632524106-bbpiw 1/1 Running 0 2m
|
||||
hostnames-632524106-ly40y 1/1 Running 0 2m
|
||||
hostnames-632524106-tlaok 1/1 Running 0 2m
|
||||
```
|
||||
|
||||
## Does the Service exist?
|
||||
|
|
@ -156,7 +146,7 @@ So we have a culprit, let's create the `Service`. As before, this is for the
|
|||
walk-through - you can use your own `Service`'s details here.
|
||||
|
||||
```shell
|
||||
$ kubectl expose rc hostnames --port=80 --target-port=9376
|
||||
$ kubectl expose deployment hostnames --port=80 --target-port=9376
|
||||
service "hostnames" exposed
|
||||
```
|
||||
|
||||
|
|
@ -164,8 +154,8 @@ And read it back, just to be sure:
|
|||
|
||||
```shell
|
||||
$ kubectl get svc hostnames
|
||||
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
|
||||
hostnames 10.0.0.1 <none> 80/TCP run=hostnames 1h
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
hostnames 10.0.0.226 <none> 80/TCP 5s
|
||||
```
|
||||
|
||||
As before, this is the same as if you had started the `Service` with YAML:
|
||||
|
|
@ -580,4 +570,4 @@ Contact us on
|
|||
|
||||
## More information
|
||||
|
||||
Visit [troubleshooting document](/docs/troubleshooting/) for more information.
|
||||
Visit [troubleshooting document](/docs/troubleshooting/) for more information.
|
||||
|
|
|
|||
|
|
@ -84,9 +84,9 @@ my-nginx 2 2 2 2 2m my-nginx
|
|||
|
||||
More importantly, the pod template's labels are used to create a [`selector`](/docs/user-guide/labels/#label-selectors) that will match pods carrying those labels. You can see this field by requesting it using the [Go template output format of `kubectl get`](/docs/user-guide/kubectl/kubectl_get):
|
||||
|
||||
```shell
|
||||
```shell{% raw %}
|
||||
$ kubectl get deployment/my-nginx -o template --template="{{.spec.selector}}"
|
||||
map[matchLabels:map[run:my-nginx]]
|
||||
map[matchLabels:map[run:my-nginx]]{% endraw %}
|
||||
```
|
||||
|
||||
You could also specify the `selector` explicitly, such as if you wanted to specify labels in the pod template that you didn't want to select on, but you should ensure that the selector will match the labels of the pods created from the pod template, and that it won't match pods created by other Deployments. The most straightforward way to ensure the latter is to create a unique label value for the Deployment, and to specify it in both the pod template's labels and in the selector's
|
||||
|
|
|
|||
|
|
@ -6,23 +6,24 @@
|
|||
|
||||
## What is a _Deployment_?
|
||||
|
||||
A _Deployment_ provides declarative updates for Pods and ReplicaSets.
|
||||
You only need to describe the desired state in a Deployment object, and the deployment
|
||||
A _Deployment_ provides declarative updates for [Pods](/docs/user-guide/pods/) and [Replica Sets](/docs/user-guide/replicasets/) (the next-generation Replication Controller).
|
||||
You only need to describe the desired state in a Deployment object, and the Deployment
|
||||
controller will change the actual state to the desired state at a controlled rate for you.
|
||||
You can define Deployments to create new resources, or replace existing ones
|
||||
by new ones.
|
||||
|
||||
A typical use case is:
|
||||
|
||||
* Create a Deployment to bring up a replica set and pods.
|
||||
* Later, update that Deployment to recreate the pods (for example, to use a new image).
|
||||
* Create a Deployment to bring up a Replica Set and Pods.
|
||||
* Check the status of a Deployment to see if it succeeds or not.
|
||||
* Later, update that Deployment to recreate the Pods (for example, to use a new image).
|
||||
* Rollback to an earlier Deployment revision if the current Deployment isn't stable.
|
||||
* Pause and resume a Deployment.
|
||||
|
||||
## Creating a Deployment
|
||||
|
||||
Here is an example Deployment. It creates a replica set to
|
||||
bring up 3 nginx pods.
|
||||
Here is an example Deployment. It creates a Replica Set to
|
||||
bring up 3 nginx Pods.
|
||||
|
||||
{% include code.html language="yaml" file="nginx-deployment.yaml" ghlink="/docs/user-guide/nginx-deployment.yaml" %}
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
|||
nginx-deployment 3 3 3 3 18s
|
||||
```
|
||||
|
||||
This indicates that the Deployment has created all three replicas, and all replicas are up-to-date (contains the latest pod template) and available (pod status is ready for at least deployment's `.spec.minReadySeconds`). Running `kubectl get rs` and `kubectl get pods` will show the replica set (RS) and pods created.
|
||||
This indicates that the Deployment has created all three replicas, and all replicas are up-to-date (contains the latest pod template) and available (pod status is ready for at least Deployment's `.spec.minReadySeconds`). Running `kubectl get rs` and `kubectl get pods` will show the Replica Set (RS) and Pods created.
|
||||
|
||||
```shell
|
||||
$ kubectl get rs
|
||||
|
|
@ -61,7 +62,7 @@ NAME DESIRED CURRENT AGE
|
|||
nginx-deployment-2035384211 3 3 18s
|
||||
```
|
||||
|
||||
You may notice that the name of the replica set is always `<the name of the Deployment>-<hash value of the pod template>`.
|
||||
You may notice that the name of the Replica Set is always `<the name of the Deployment>-<hash value of the pod template>`.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --show-labels
|
||||
|
|
@ -71,13 +72,43 @@ nginx-deployment-2035384211-kzszj 1/1 Running 0 18s app
|
|||
nginx-deployment-2035384211-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
|
||||
```
|
||||
|
||||
The created replica set will ensure that there are three nginx pods at all times.
|
||||
The created Replica Set will ensure that there are three nginx Pods at all times.
|
||||
|
||||
## The Status of a Deployment
|
||||
|
||||
After creating or updating a Deployment, you would want to confirm whether it succeeded or not. The best way to do this is through checking its status.
|
||||
|
||||
To verify if the above Deployment succeeded or not, first compare the `.metadata.generation` and `.status.observedGeneration` of the Deployment:
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment/nginx-deployment -o yaml | grep [Gg]eneration
|
||||
generation: 2
|
||||
observedGeneration: 2
|
||||
```
|
||||
|
||||
When `observedGeneration` >= `generation`, the Deployment controller has observed current Deployment; if not, wait for a few more seconds.
|
||||
|
||||
Once the above condition is met, check the Deployment's up-to-date replicas (`.status.updatedReplicas`) and see if it matches the desired replicas (`.spec.replicas`):
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment/nginx-deployment
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3 3 3 3 9m
|
||||
```
|
||||
|
||||
Additionally, if you set `.spec.minReadySeconds`, you would also want to check if the available replicas (`.status.availableReplicas`) matches the desired replicas too.
|
||||
|
||||
**Note:** It's impossible to know whether a Deployment will ever succeed, so one has to timeout and give up at some point.
|
||||
|
||||
## Updating a Deployment
|
||||
|
||||
Suppose that we now want to update the nginx pods to start using the `nginx:1.9.1` image
|
||||
Suppose that we now want to update the nginx Pods to start using the `nginx:1.9.1` image
|
||||
instead of the `nginx:1.7.9` image.
|
||||
For this, we update our deployment file as follows:
|
||||
|
||||
**Note:** a Deployment's rollout is triggered if and only if the Deployment's pod template (i.e. `.spec.template`) is changed,
|
||||
e.g. updating labels or container images of the template. Other updates, such as scaling the Deployment, will not trigger a rollout.
|
||||
|
||||
First, we update our Deployment configuration as follows:
|
||||
|
||||
{% include code.html language="yaml" file="new-nginx-deployment.yaml" ghlink="/docs/user-guide/new-nginx-deployment.yaml" %}
|
||||
|
||||
|
|
@ -103,9 +134,9 @@ NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
|||
nginx-deployment 3 3 0 3 20s
|
||||
```
|
||||
|
||||
The 0 number of up-to-date replicas indicates that the deployment hasn't updated the replicas to the latest configuration. The current replicas indicates the total replicas (3 with old configuration and 0 with new configuration) this Deployment manages, and the available replicas indicates the number of current replicas that are available.
|
||||
The 0 number of up-to-date replicas indicates that the Deployment hasn't updated the replicas to the latest configuration. The current replicas indicates the total replicas (3 with old configuration and 0 with new configuration) this Deployment manages, and the available replicas indicates the number of current replicas that are available.
|
||||
|
||||
The Deployment will update all the pods in a few seconds.
|
||||
The Deployment will update all the Pods in a few seconds.
|
||||
|
||||
```shell
|
||||
$ kubectl get deployments
|
||||
|
|
@ -113,7 +144,7 @@ NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
|||
nginx-deployment 3 3 3 3 36s
|
||||
```
|
||||
|
||||
We can run `kubectl get rs` to see that the Deployment updated the pods by creating a new replica set and scaling it up to 3 replicas, as well as scaling down the old replica set to 0 replicas.
|
||||
We can run `kubectl get rs` to see that the Deployment updated the Pods by creating a new Replica Set and scaling it up to 3 replicas, as well as scaling down the old Replica Set to 0 replicas.
|
||||
|
||||
```shell
|
||||
$ kubectl get rs
|
||||
|
|
@ -122,7 +153,7 @@ nginx-deployment-1564180365 3 3 6s
|
|||
nginx-deployment-2035384211 0 0 36s
|
||||
```
|
||||
|
||||
Running `get pods` should now show only the new pods:
|
||||
Running `get pods` should now show only the new Pods:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods
|
||||
|
|
@ -132,17 +163,17 @@ nginx-deployment-1564180365-nacti 1/1 Running 0 14s
|
|||
nginx-deployment-1564180365-z9gth 1/1 Running 0 14s
|
||||
```
|
||||
|
||||
Next time we want to update these pods, we only need to update and re-apply the Deployment again.
|
||||
Next time we want to update these Pods, we only need to update and re-apply the Deployment again.
|
||||
|
||||
Deployment can ensure that only a certain number of pods may be down while they are being updated. By
|
||||
default, it ensures that at least 1 less than the desired number of pods are
|
||||
Deployment can ensure that only a certain number of Pods may be down while they are being updated. By
|
||||
default, it ensures that at least 1 less than the desired number of Pods are
|
||||
up (1 max unavailable).
|
||||
|
||||
Deployment can also ensure that only a certain number of pods may be created above the desired number of pods. By default, it ensures that at most 1 more than the desired number of pods are up (1 max surge).
|
||||
Deployment can also ensure that only a certain number of Pods may be created above the desired number of Pods. By default, it ensures that at most 1 more than the desired number of Pods are up (1 max surge).
|
||||
|
||||
For example, if you look at the above deployment closely, you will see that
|
||||
it first created a new pod, then deleted some old pods and created new ones. It
|
||||
does not kill old pods until a sufficient number of new pods have come up, and does not create new pods until a sufficient number of old pods have been killed. It makes sure that number of available pods is at least 2 and the number of total pods is at most 4.
|
||||
For example, if you look at the above Deployment closely, you will see that
|
||||
it first created a new Pod, then deleted some old Pods and created new ones. It
|
||||
does not kill old Pods until a sufficient number of new Pods have come up, and does not create new Pods until a sufficient number of old Pods have been killed. It makes sure that number of available Pods is at least 2 and the number of total Pods is at most 4.
|
||||
|
||||
```shell
|
||||
$ kubectl describe deployments
|
||||
|
|
@ -168,34 +199,41 @@ Events:
|
|||
21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3
|
||||
```
|
||||
|
||||
Here we see that when we first created the Deployment, it created a replica set (nginx-deployment-2035384211) and scaled it up to 3 replicas directly.
|
||||
When we updated the Deployment, it created a new replica set (nginx-deployment-1564180365) and scaled it up to 1 and then scaled down the old replica set to 2, so that at least 2 pods were available and at most 4 pods were created at all times.
|
||||
It then continued scaling up and down the new and the old replica set, with the same rolling update strategy. Finally, we'll have 3 available replicas in the new replica set, and the old replica set is scaled down to 0.
|
||||
Here we see that when we first created the Deployment, it created a Replica Set (nginx-deployment-2035384211) and scaled it up to 3 replicas directly.
|
||||
When we updated the Deployment, it created a new Replica Set (nginx-deployment-1564180365) and scaled it up to 1 and then scaled down the old Replica Set to 2, so that at least 2 Pods were available and at most 4 Pods were created at all times.
|
||||
It then continued scaling up and down the new and the old Replica Set, with the same rolling update strategy. Finally, we'll have 3 available replicas in the new Replica Set, and the old Replica Set is scaled down to 0.
|
||||
|
||||
### Multiple Updates
|
||||
|
||||
Each time a new deployment object is observed by the deployment controller, a replica set is
|
||||
created to bring up the desired pods if there is no existing replica set doing so.
|
||||
Existing replica set controlling pods whose labels match `.spec.selector` but whose
|
||||
Each time a new deployment object is observed by the deployment controller, a Replica Set is
|
||||
created to bring up the desired Pods if there is no existing Replica Set doing so.
|
||||
Existing Replica Set controlling Pods whose labels match `.spec.selector` but whose
|
||||
template does not match `.spec.template` are scaled down.
|
||||
Eventually, the new replica set will be scaled to `.spec.replicas` and all old replica sets will
|
||||
Eventually, the new Replica Set will be scaled to `.spec.replicas` and all old Replica Sets will
|
||||
be scaled to 0.
|
||||
|
||||
If you update a Deployment while an existing deployment is in progress,
|
||||
the Deployment will create a new replica set as per the update and start scaling that up, and
|
||||
will roll the replica set that it was scaling up previously -- it will add it to its list of old replica sets and will
|
||||
the Deployment will create a new Replica Set as per the update and start scaling that up, and
|
||||
will roll the Replica Set that it was scaling up previously -- it will add it to its list of old Replica Sets and will
|
||||
start scaling it down.
|
||||
|
||||
For example, suppose you create a Deployment to create 5 replicas of `nginx:1.7.9`,
|
||||
but then updates the Deployment to create 5 replicas of `nginx:1.9.1`, when only 3
|
||||
replicas of `nginx:1.7.9` had been created. In that case, Deployment will immediately start
|
||||
killing the 3 `nginx:1.7.9` pods that it had created, and will start creating
|
||||
`nginx:1.9.1` pods. It will not wait for 5 replicas of `nginx:1.7.9` to be created
|
||||
killing the 3 `nginx:1.7.9` Pods that it had created, and will start creating
|
||||
`nginx:1.9.1` Pods. It will not wait for 5 replicas of `nginx:1.7.9` to be created
|
||||
before changing course.
|
||||
|
||||
## Rolling Back a Deployment
|
||||
|
||||
Sometimes we may want to rollback a Deployment; for example, when the Deployment is not stable, such as crash looping.
|
||||
Sometimes you may want to rollback a Deployment; for example, when the Deployment is not stable, such as crash looping.
|
||||
By default, all of the Deployment's rollout history is kept in the system so that you can rollback anytime you want
|
||||
(you can change that by specifying [revision history limit](/docs/user-guide/deployments/#revision-history-limit)).
|
||||
|
||||
**Note:** a Deployment's revision is created when a Deployment's rollout is triggered. This means that the new revision is created
|
||||
if and only if the Deployment's pod template (i.e. `.spec.template`) is changed, e.g. updating labels or container images of the template.
|
||||
Other updates, such as scaling the Deployment, will not create a Deployment revision -- so that we can facilitate simultaneous manual- or
|
||||
auto-scaling. This implies that when you rollback to an earlier revision, only the Deployment's pod template part will be rolled back.
|
||||
|
||||
Suppose that we made a typo while updating the Deployment, by putting the image name as `nginx:1.91` instead of `nginx:1.9.1`:
|
||||
|
||||
|
|
@ -216,7 +254,7 @@ nginx-deployment-2035384211 0 0 36s
|
|||
nginx-deployment-3066724191 2 2 6s
|
||||
```
|
||||
|
||||
Looking at the pods created, you will see that the 2 pods created by new replica set are stuck in an image pull loop.
|
||||
Looking at the Pods created, you will see that the 2 Pods created by new Replica Set are stuck in an image pull loop.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods
|
||||
|
|
@ -227,7 +265,7 @@ nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s
|
|||
nginx-deployment-3066724191-eocby 0/1 ImagePullBackOff 0 6s
|
||||
```
|
||||
|
||||
Note that the Deployment controller will stop the bad rollout automatically, and will stop scaling up the new replica set.
|
||||
Note that the Deployment controller will stop the bad rollout automatically, and will stop scaling up the new Replica Set.
|
||||
|
||||
```shell
|
||||
$ kubectl describe deployment
|
||||
|
|
@ -258,6 +296,8 @@ Events:
|
|||
|
||||
To fix this, we need to rollback to a previous revision of Deployment that is stable.
|
||||
|
||||
### Checking Rollout History of a Deployment
|
||||
|
||||
First, check the revisions of this deployment:
|
||||
|
||||
```shell
|
||||
|
|
@ -282,6 +322,8 @@ Image(s): nginx:1.9.1
|
|||
No volumes.
|
||||
```
|
||||
|
||||
### Rolling Back to a Previous Revision
|
||||
|
||||
Now we've decided to undo the current rollout and rollback to the previous revision:
|
||||
|
||||
```shell
|
||||
|
|
@ -296,6 +338,8 @@ $ kubectl rollout undo deployment/nginx-deployment --to-revision=2
|
|||
deployment "nginx-deployment" rolled back
|
||||
```
|
||||
|
||||
For more details about rollout related commands, read [`kubectl rollout`](/docs/user-guide/kubectl/kubectl_rollout/).
|
||||
|
||||
The Deployment is now rolled back to a previous stable revision. As you can see, a `DeploymentRollback` event for rolling back to revision 2 is generated from Deployment controller.
|
||||
|
||||
```shell
|
||||
|
|
@ -344,7 +388,7 @@ deployment "nginx-deployment" paused
|
|||
|
||||
Note that any current state of the Deployment will continue its function, but new updates to the Deployment will not have an effect as long as the Deployment is paused.
|
||||
|
||||
The Deployment was still in progress when we paused it, so the actions of scaling up and down replica sets are paused too.
|
||||
The Deployment was still in progress when we paused it, so the actions of scaling up and down Replica Sets are paused too.
|
||||
|
||||
```shell
|
||||
$ kubectl get rs
|
||||
|
|
@ -373,6 +417,13 @@ nginx-deployment-3066724191 0 0 1h
|
|||
|
||||
Note: A paused Deployment cannot be scaled at this moment, and we will add this feature in 1.3 release, see [issue #20853](https://github.com/kubernetes/kubernetes/issues/20853). You cannot rollback a paused Deployment either, and you should resume a Deployment first before doing a rollback.
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Canary Deployment
|
||||
|
||||
If you want to roll out releases to a subset of users or servers using the Deployment, you can create multiple Deployments, one for each release,
|
||||
following the canary pattern described in [managing resources](/docs/user-guide/managing-deployments/#canary-deployments).
|
||||
|
||||
## Writing a Deployment Spec
|
||||
|
||||
As with all other Kubernetes configs, a Deployment needs `apiVersion`, `kind`, and
|
||||
|
|
@ -386,36 +437,48 @@ A Deployment also needs a [`.spec` section](https://github.com/kubernetes/kubern
|
|||
The `.spec.template` is the only required field of the `.spec`.
|
||||
|
||||
The `.spec.template` is a [pod template](/docs/user-guide/replication-controller/#pod-template). It has exactly
|
||||
the same schema as a [pod](/docs/user-guide/pods), except it is nested and does not have an
|
||||
the same schema as a [Pod](/docs/user-guide/pods), except it is nested and does not have an
|
||||
`apiVersion` or `kind`.
|
||||
|
||||
In addition to required fields for a Pod, a pod template in a Deployment must specify appropriate
|
||||
labels (i.e. don't overlap with other controllers, see [selector](#selector)) and an appropriate restart policy.
|
||||
|
||||
Only a [`.spec.template.spec.restartPolicy`](/docs/user-guide/pod-states/) equal to `Always` is allowed, which is the default
|
||||
if not specified.
|
||||
|
||||
### Replicas
|
||||
|
||||
`.spec.replicas` is an optional field that specifies the number of desired pods. It defaults
|
||||
`.spec.replicas` is an optional field that specifies the number of desired Pods. It defaults
|
||||
to 1.
|
||||
|
||||
### Selector
|
||||
|
||||
`.spec.selector` is an optional field that specifies label selectors for pods
|
||||
targeted by this deployment. Deployment kills some of these pods, if their
|
||||
template is different than `.spec.template` or if the total number of such pods
|
||||
exceeds `.spec.replicas`. It will bring up new pods with `.spec.template` if
|
||||
number of pods are less than the desired number.
|
||||
`.spec.selector` is an optional field that specifies a [label selector](/docs/user-guide/labels/#label-selectors) for the Pods
|
||||
targeted by this deployment.
|
||||
|
||||
If specified, `.spec.selector` must match `.spec.template.metadata.labels`, or it will
|
||||
be rejected by the API. If `.spec.selector` is unspecified, `.spec.selector.matchLabels` will be defaulted to
|
||||
`.spec.template.metadata.labels`.
|
||||
|
||||
Deployment may kill Pods whose labels match the selector, in the case that their
|
||||
template is different than `.spec.template` or if the total number of such Pods
|
||||
exceeds `.spec.replicas`. It will bring up new Pods with `.spec.template` if
|
||||
number of Pods are less than the desired number.
|
||||
|
||||
### Strategy
|
||||
|
||||
`.spec.strategy` specifies the strategy used to replace old pods by new ones.
|
||||
`.spec.strategy` specifies the strategy used to replace old Pods by new ones.
|
||||
`.spec.strategy.type` can be "Recreate" or "RollingUpdate". "RollingUpdate" is
|
||||
the default value.
|
||||
|
||||
#### Recreate Deployment
|
||||
|
||||
All existing pods are killed before new ones are created when
|
||||
All existing Pods are killed before new ones are created when
|
||||
`.spec.strategy.type==Recreate`.
|
||||
|
||||
#### Rolling Update Deployment
|
||||
|
||||
The Deployment updates pods in a [rolling update](/docs/user-guide/update-demo/) fashion
|
||||
The Deployment updates Pods in a [rolling update](/docs/user-guide/update-demo/) fashion
|
||||
when `.spec.strategy.type==RollingUpdate`.
|
||||
You can specify `maxUnavailable` and `maxSurge` to control
|
||||
the rolling update process.
|
||||
|
|
@ -423,42 +486,42 @@ the rolling update process.
|
|||
##### Max Unavailable
|
||||
|
||||
`.spec.strategy.rollingUpdate.maxUnavailable` is an optional field that specifies the
|
||||
maximum number of pods that can be unavailable during the update process.
|
||||
The value can be an absolute number (e.g. 5) or a percentage of desired pods
|
||||
maximum number of Pods that can be unavailable during the update process.
|
||||
The value can be an absolute number (e.g. 5) or a percentage of desired Pods
|
||||
(e.g. 10%).
|
||||
The absolute number is calculated from percentage by rounding up.
|
||||
This can not be 0 if `.spec.strategy.rollingUpdate.maxSurge` is 0.
|
||||
By default, a fixed value of 1 is used.
|
||||
|
||||
For example, when this value is set to 30%, the old replica set can be scaled down to
|
||||
70% of desired pods immediately when the rolling update starts. Once new pods are
|
||||
ready, old replica set can be scaled down further, followed by scaling up the new replica set,
|
||||
ensuring that the total number of pods available at all times during the
|
||||
update is at least 70% of the desired pods.
|
||||
For example, when this value is set to 30%, the old Replica Set can be scaled down to
|
||||
70% of desired Pods immediately when the rolling update starts. Once new Pods are
|
||||
ready, old Replica Set can be scaled down further, followed by scaling up the new Replica Set,
|
||||
ensuring that the total number of Pods available at all times during the
|
||||
update is at least 70% of the desired Pods.
|
||||
|
||||
##### Max Surge
|
||||
|
||||
`.spec.strategy.rollingUpdate.maxSurge` is an optional field that specifies the
|
||||
maximum number of pods that can be created above the desired number of pods.
|
||||
Value can be an absolute number (e.g. 5) or a percentage of desired pods
|
||||
maximum number of Pods that can be created above the desired number of Pods.
|
||||
Value can be an absolute number (e.g. 5) or a percentage of desired Pods
|
||||
(e.g. 10%).
|
||||
This can not be 0 if `MaxUnavailable` is 0.
|
||||
The absolute number is calculated from percentage by rounding up.
|
||||
By default, a value of 1 is used.
|
||||
|
||||
For example, when this value is set to 30%, the new replica set can be scaled up immediately when
|
||||
the rolling update starts, such that the total number of old and new pods do not exceed
|
||||
130% of desired pods. Once old pods have been killed,
|
||||
the new replica set can be scaled up further, ensuring that the total number of pods running
|
||||
at any time during the update is at most 130% of desired pods.
|
||||
For example, when this value is set to 30%, the new Replica Set can be scaled up immediately when
|
||||
the rolling update starts, such that the total number of old and new Pods do not exceed
|
||||
130% of desired Pods. Once old Pods have been killed,
|
||||
the new Replica Set can be scaled up further, ensuring that the total number of Pods running
|
||||
at any time during the update is at most 130% of desired Pods.
|
||||
|
||||
### Min Ready Seconds
|
||||
|
||||
`.spec.minReadySeconds` is an optional field that specifies the
|
||||
minimum number of seconds for which a newly created pod should be ready
|
||||
minimum number of seconds for which a newly created Pod should be ready
|
||||
without any of its containers crashing, for it to be considered available.
|
||||
This defaults to 0 (the pod will be considered available as soon as it is ready).
|
||||
To learn more about when a pod is considered ready, see [Container Probes](/docs/user-guide/pod-states/#container-probes).
|
||||
This defaults to 0 (the Pod will be considered available as soon as it is ready).
|
||||
To learn more about when a Pod is considered ready, see [Container Probes](/docs/user-guide/pod-states/#container-probes).
|
||||
|
||||
### Rollback To
|
||||
|
||||
|
|
@ -470,7 +533,7 @@ To learn more about when a pod is considered ready, see [Container Probes](/docs
|
|||
|
||||
### Revision History Limit
|
||||
|
||||
`.spec.revisionHistoryLimit` is an optional field that specifies the number of old replica sets to retain to allow rollback. All old replica sets will be kept by default, if this field is not set. The configuration of each Deployment revision is stored in its replica sets; therefore, once an old replica set is deleted, you lose the ability to rollback to that revision of Deployment.
|
||||
`.spec.revisionHistoryLimit` is an optional field that specifies the number of old Replica Sets to retain to allow rollback. All old Replica Sets will be kept by default, if this field is not set. The configuration of each Deployment revision is stored in its Replica Sets; therefore, once an old Replica Set is deleted, you lose the ability to rollback to that revision of Deployment.
|
||||
|
||||
### Paused
|
||||
|
||||
|
|
@ -480,5 +543,5 @@ To learn more about when a pod is considered ready, see [Container Probes](/docs
|
|||
|
||||
### kubectl rolling update
|
||||
|
||||
[Kubectl rolling update](/docs/user-guide/kubectl/kubectl_rolling-update) updates pods and replication controllers in a similar fashion.
|
||||
But deployments is recommended, since it's declarative and is server side, and has more features, such as rolling back to any previous revision even after the rolling update is done. Also, replica sets supersede replication controllers.
|
||||
[Kubectl rolling update](/docs/user-guide/kubectl/kubectl_rolling-update) updates Pods and Replication Controllers in a similar fashion.
|
||||
But Deployments are recommended, since they are declarative, server side, and have additional features, such as rolling back to any previous revision even after the rolling update is done.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ In this doc, we introduce the Kubernetes command line for interacting with the a
|
|||
|
||||
#### docker run
|
||||
|
||||
How do I run an nginx container and expose it to the world? Checkout [kubectl run](/docs/user-guide/kubectl/kubectl_run).
|
||||
How do I run an nginx Deployment and expose it to the world? Checkout [kubectl run](/docs/user-guide/kubectl/kubectl_run).
|
||||
|
||||
With docker:
|
||||
|
||||
|
|
@ -25,12 +25,20 @@ With kubectl:
|
|||
```shell
|
||||
# start the pod running nginx
|
||||
$ kubectl run --image=nginx nginx-app --port=80 --env="DOMAIN=cluster"
|
||||
replicationcontroller "nginx-app" created
|
||||
# expose a port through with a service
|
||||
$ kubectl expose rc nginx-app --port=80 --name=nginx-http
|
||||
deployment "nginx-app" created
|
||||
```
|
||||
|
||||
With kubectl, we create a [replication controller](/docs/user-guide/replication-controller) which will make sure that N pods are running nginx (where N is the number of replicas stated in the spec, which defaults to 1). We also create a [service](/docs/user-guide/services) with a selector that matches the replication controller's selector. See the [Quick start](/docs/user-guide/quick-start) for more information.
|
||||
`kubectl run` creates a Deployment named "nginx" on Kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead.
|
||||
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/kubectl_run/) for more details.
|
||||
Note that `kubectl` commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands. Now, we can expose a new Service with the deployment created above:
|
||||
|
||||
```shell
|
||||
# expose a port through with a service
|
||||
$ kubectl expose deployment nginx-app --port=80 --name=nginx-http
|
||||
service "nginx-http" exposed
|
||||
```
|
||||
|
||||
With kubectl, we create a [Deployment](/docs/user-guide/deployments) which will make sure that N pods are running nginx (where N is the number of replicas stated in the spec, which defaults to 1). We also create a [service](/docs/user-guide/services) with a selector that matches the Deployment's selector. See the [Quick start](/docs/user-guide/quick-start) for more information.
|
||||
|
||||
By default images are run in the background, similar to `docker run -d ...`, if you want to run things in the foreground, use:
|
||||
|
||||
|
|
@ -40,8 +48,8 @@ kubectl run [-i] [--tty] --attach <name> --image=<image>
|
|||
|
||||
Unlike `docker run ...`, if `--attach` is specified, we attach to `stdin`, `stdout` and `stderr`, there is no ability to control which streams are attached (`docker -a ...`).
|
||||
|
||||
Because we start a replication controller for your container, it will be restarted if you terminate the attached process (e.g. `ctrl-c`), this is different than `docker run -it`.
|
||||
To destroy the replication controller (and it's pods) you need to run `kubectl delete rc <name>`
|
||||
Because we start a Deployment for your container, it will be restarted if you terminate the attached process (e.g. `ctrl-c`), this is different than `docker run -it`.
|
||||
To destroy the Deployment (and its pods) you need to run `kubectl delete deployment <name>`
|
||||
|
||||
#### docker ps
|
||||
|
||||
|
|
@ -180,20 +188,19 @@ a9ec34d98787
|
|||
With kubectl:
|
||||
|
||||
```shell
|
||||
$ kubectl get rc nginx-app
|
||||
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||
nginx-app nginx-app nginx run=nginx-app 1
|
||||
$ kubectl get po
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-app-aualv 1/1 Running 0 16s
|
||||
$ kubectl delete rc nginx-app
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-app-aualv 1/1 Running 0 16s
|
||||
$ kubectl get po
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
$ kubectl get deployment nginx-app
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-app 1 1 1 1 2m
|
||||
$ kubectl get po -l run=nginx-app
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-app-2883164633-aklf7 1/1 Running 0 2m
|
||||
$ kubectl delete deployment nginx-app
|
||||
deployment "nginx-app" deleted
|
||||
$ kubectl get po -l run=nginx-app
|
||||
# Return nothing
|
||||
```
|
||||
|
||||
Notice that we don't delete the pod directly. With kubectl we want to delete the replication controller that owns the pod. If we delete the pod directly, the replication controller will recreate the pod.
|
||||
Notice that we don't delete the pod directly. With kubectl we want to delete the Deployment that owns the pod. If we delete the pod directly, the Deployment will recreate the pod.
|
||||
|
||||
#### docker login
|
||||
|
||||
|
|
@ -263,4 +270,4 @@ KubeUI is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/s
|
|||
Grafana is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
|
||||
Heapster is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/services/monitoring-heapster
|
||||
InfluxDB is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb
|
||||
```
|
||||
```
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ environment variable they want.
|
|||
This is an example of a pod that consumes its name and namespace via the
|
||||
downward API:
|
||||
|
||||
{% include code.html language="yaml" file="downward-api/dapi-pod.yaml" ghlink="/docs/user-guide/downward-api/dapi-pod.yaml" %}
|
||||
{% include code.html language="yaml" file="dapi-pod.yaml" ghlink="/docs/user-guide/downward-api/dapi-pod.yaml" %}
|
||||
|
||||
|
||||
### Downward API volume
|
||||
|
|
@ -86,7 +86,7 @@ In future, it will be possible to specify a specific annotation or label.
|
|||
|
||||
This is an example of a pod that consumes its labels and annotations via the downward API volume, labels and annotations are dumped in `/etc/labels` and in `/etc/annotations`, respectively:
|
||||
|
||||
{% include code.html language="yaml" file="downward-api/volume/dapi-volume.yaml" ghlink="/docs/user-guide/downward-api/volume/dapi-volume.yaml" %}
|
||||
{% include code.html language="yaml" file="volume/dapi-volume.yaml" ghlink="/docs/user-guide/downward-api/volume/dapi-volume.yaml" %}
|
||||
|
||||
|
||||
Some more thorough examples:
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
This example demonstrates running pods, replication controllers, and
|
||||
services. It shows two types of pods: frontend and backend, with
|
||||
|
|
@ -23,15 +23,15 @@ for your platform.
|
|||
## Optional: Build your own containers
|
||||
|
||||
The code for the containers is under
|
||||
[containers/](/docs/user-guide/environment-guide/containers/)
|
||||
[containers/](/docs/user-guide/containers/)
|
||||
|
||||
## Get everything running
|
||||
|
||||
```shell
|
||||
kubectl create -f ./backend-rc.yaml
|
||||
kubectl create -f ./backend-srv.yaml
|
||||
kubectl create -f ./show-rc.yaml
|
||||
kubectl create -f ./show-srv.yaml
|
||||
```shell
|
||||
kubectl create -f ./backend-rc.yaml
|
||||
kubectl create -f ./backend-srv.yaml
|
||||
kubectl create -f ./show-rc.yaml
|
||||
kubectl create -f ./show-srv.yaml
|
||||
```
|
||||
|
||||
## Query the service
|
||||
|
|
@ -46,7 +46,7 @@ your service.
|
|||
Run `curl <public ip>:80` to query the service. You should get
|
||||
something like this back:
|
||||
|
||||
```shell
|
||||
```shell
|
||||
Pod Name: show-rc-xxu6i
|
||||
Pod Namespace: default
|
||||
USER_VAR: important information
|
||||
|
|
@ -66,8 +66,8 @@ Response from backend
|
|||
Backend Container
|
||||
Backend Pod Name: backend-rc-6qiya
|
||||
Backend Namespace: default
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
First the frontend pod's information is printed. The pod name and
|
||||
[namespace](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/namespaces.md) are retrieved from the
|
||||
[Downward API](/docs/user-guide/downward-api). Next, `USER_VAR` is the name of
|
||||
|
|
@ -86,8 +86,8 @@ service. This results in a different backend pod servicing each
|
|||
request as well.
|
||||
|
||||
## Cleanup
|
||||
|
||||
|
||||
```shell
|
||||
kubectl delete rc,service -l type=show-type
|
||||
kubectl delete rc,service -l type=backend-type
|
||||
```
|
||||
kubectl delete rc,service -l type=backend-type
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
---
|
||||
---
|
||||
|
||||
This document describes the current state of Horizontal Pod Autoscaler in Kubernetes.
|
||||
|
||||
## What is Horizontal Pod Autoscaler?
|
||||
|
||||
Horizontal pod autoscaling allows to automatically scale the number of pods
|
||||
in a replication controller, deployment or replica set based on observed CPU utilization.
|
||||
|
||||
The autoscaler is implemented as a Kubernetes API resource and a controller.
|
||||
The resource describes behavior of the controller.
|
||||
The controller periodically adjusts the number of replicas in a replication controller or deployment
|
||||
to match the observed average CPU utilization to the target specified by user.
|
||||
|
||||
|
||||
## How does Horizontal Pod Autoscaler work?
|
||||
|
||||

|
||||
|
||||
The autoscaler is implemented as a control loop.
|
||||
It periodically queries CPU utilization for the pods it targets.
|
||||
(The period of the autoscaler is controlled by `--horizontal-pod-autoscaler-sync-period` flag of controller manager.
|
||||
The default value is 30 seconds).
|
||||
Then, it compares the arithmetic mean of the pods' CPU utilization with the target and adjust the number of replicas if needed.
|
||||
|
||||
CPU utilization is the recent CPU usage of a pod divided by the sum of CPU requested by the pod's containers.
|
||||
Please note that if some of the pod's containers do not have CPU request set,
|
||||
CPU utilization for the pod will not be defined and the autoscaler will not take any action.
|
||||
Further details of the autoscaling algorithm are given [here](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md#autoscaling-algorithm).
|
||||
|
||||
Autoscaler uses heapster to collect CPU utilization.
|
||||
Therefore, it is required to deploy heapster monitoring in your cluster for autoscaling to work.
|
||||
|
||||
Autoscaler accesses corresponding replication controller, deployment or replica set by scale sub-resource.
|
||||
Scale is an interface which allows to dynamically set the number of replicas and to learn the current state of them.
|
||||
More details on scale sub-resource can be found [here](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md#scale-subresource).
|
||||
|
||||
|
||||
## API Object
|
||||
|
||||
Horizontal pod autoscaler is a top-level resource in the Kubernetes REST API.
|
||||
In Kubernetes 1.2 HPA was graduated from beta to stable (more details about [api versioning](/docs/api/#api-versioning)) with compatibility between versions.
|
||||
The stable version is available in `autoscaling/v1` api group whereas the beta vesion is available in `extensions/v1beta1` api group as before.
|
||||
The transition plan is to depracate beta verion of HPA in Kubernetes 1.3 and get it rid off completely in Kubernetes 1.4.
|
||||
|
||||
**Warning!** Please have in mind that all Kubernetes components still use HPA in version `extensions/v1beta1` in Kubernetes 1.2.
|
||||
|
||||
More details about the API object can be found at
|
||||
[HorizontalPodAutoscaler Object](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md#horizontalpodautoscaler-object).
|
||||
|
||||
## Support for horizontal pod autoscaler in kubectl
|
||||
|
||||
Horizontal pod autoscaler, like every API resource, is supported in a standard way by `kubectl`.
|
||||
We can create a new autoscaler using `kubectl create` command.
|
||||
We can list autoscalers by `kubectl get hpa` and get detailed description by `kubectl describe hpa`.
|
||||
Finally, we can delete an autoscaler using `kubectl delete hpa`.
|
||||
|
||||
In addition, there is a special `kubectl autoscale` command that allows for easy creation of horizontal pod autoscaler.
|
||||
For instance, executing `kubectl autoscale rc foo --min=2 --max=5 --cpu-percent=80`
|
||||
will create an autoscaler for replication controller *foo*, with target CPU utilization set to `80%`
|
||||
and the number of replicas between 2 and 5.
|
||||
The detailed documentation of `kubectl autoscale` can be found [here](/docs/user-guide/kubectl/kubectl_autoscale).
|
||||
|
||||
|
||||
## Autoscaling during rolling update
|
||||
|
||||
Currently in Kubernetes, it is possible to perform a rolling update by managing replication controllers directly,
|
||||
or by using the deployment object, which manages the underlying replication controllers for you.
|
||||
Horizontal pod autoscaler only supports the latter approach: the horizontal pod autoscaler is bound to the deployment object,
|
||||
it sets the size for the deployment object, and the deployment is responsible for setting sizes of underlying replication controllers.
|
||||
|
||||
Horizontal pod autoscaler does not work with rolling update using direct manipulation of replication controllers,
|
||||
i.e. you cannot bind a horizontal pod autoscaler to a replication controller and do rolling update (e.g. using `kubectl rolling-update`).
|
||||
The reason this doesn't work is that when rolling update creates a new replication controller,
|
||||
the horizontal pod autoscaler will not be bound to the new replication controller.
|
||||
|
||||
|
||||
## Further reading
|
||||
|
||||
* Design documentation: [Horizontal Pod Autoscaling](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md).
|
||||
* Manual of autoscale command in kubectl: [kubectl autoscale](/docs/user-guide/kubectl/kubectl_autoscale).
|
||||
* Usage example of [Horizontal Pod Autoscaler](/docs/user-guide/horizontal-pod-autoscaling/).
|
||||
|
|
@ -1,147 +1,83 @@
|
|||
---
|
||||
---
|
||||
|
||||
This document describes the current state of Horizontal Pod Autoscaler in Kubernetes.
|
||||
|
||||
## What is Horizontal Pod Autoscaler?
|
||||
|
||||
Horizontal pod autoscaling allows to automatically scale the number of pods
|
||||
in a replication controller, deployment or replica set based on observed CPU utilization.
|
||||
In the future also other metrics will be supported.
|
||||
|
||||
In this document we explain how this feature works by walking you through an example of enabling horizontal pod autoscaling for the php-apache server.
|
||||
The autoscaler is implemented as a Kubernetes API resource and a controller.
|
||||
The resource describes behavior of the controller.
|
||||
The controller periodically adjusts the number of replicas in a replication controller or deployment
|
||||
to match the observed average CPU utilization to the target specified by user.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This example requires a running Kubernetes cluster and kubectl in the version at least 1.2.
|
||||
[Heapster](https://github.com/kubernetes/heapster) monitoring needs to be deployed in the cluster
|
||||
as horizontal pod autoscaler uses it to collect metrics
|
||||
(if you followed [getting started on GCE guide](/docs/getting-started-guides/gce),
|
||||
heapster monitoring will be turned-on by default).
|
||||
## How does Horizontal Pod Autoscaler work?
|
||||
|
||||
## Step One: Run & expose php-apache server
|
||||

|
||||
|
||||
To demonstrate horizontal pod autoscaler we will use a custom docker image based on php-apache server.
|
||||
The image can be found [here](/docs/user-guide/horizontal-pod-autoscaling/image).
|
||||
It defines [index.php](/docs/user-guide/horizontal-pod-autoscaling/image/index.php) page which performs some CPU intensive computations.
|
||||
The autoscaler is implemented as a control loop.
|
||||
It periodically queries CPU utilization for the pods it targets.
|
||||
(The period of the autoscaler is controlled by `--horizontal-pod-autoscaler-sync-period` flag of controller manager.
|
||||
The default value is 30 seconds).
|
||||
Then, it compares the arithmetic mean of the pods' CPU utilization with the target and adjust the number of replicas if needed.
|
||||
|
||||
First, we will start a deployment running the image and expose it as a service:
|
||||
CPU utilization is the recent CPU usage of a pod divided by the sum of CPU requested by the pod's containers.
|
||||
Please note that if some of the pod's containers do not have CPU request set,
|
||||
CPU utilization for the pod will not be defined and the autoscaler will not take any action.
|
||||
Further details of the autoscaling algorithm are given [here](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md#autoscaling-algorithm).
|
||||
|
||||
```shell
|
||||
$ kubectl run php-apache --image=gcr.io/google_containers/hpa-example --requests=cpu=200m --expose --port=80
|
||||
service "php-apache" created
|
||||
deployment "php-apache" created
|
||||
```
|
||||
Autoscaler uses heapster to collect CPU utilization.
|
||||
Therefore, it is required to deploy heapster monitoring in your cluster for autoscaling to work.
|
||||
|
||||
## Step Two: Create horizontal pod autoscaler
|
||||
Autoscaler accesses corresponding replication controller, deployment or replica set by scale sub-resource.
|
||||
Scale is an interface which allows to dynamically set the number of replicas and to learn the current state of them.
|
||||
More details on scale sub-resource can be found [here](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md#scale-subresource).
|
||||
|
||||
Now that the server is running, we will create the autoscaler using
|
||||
[kubectl autoscale](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/user-guide/kubectl/kubectl_autoscale.md).
|
||||
The following command will create a horizontal pod autoscaler that maintains between 1 and 10 replicas of the Pods
|
||||
controlled by the php-apache deployment we created in the first step of these instructions.
|
||||
Roughly speaking, the horizontal autoscaler will increase and decrease the number of replicas
|
||||
(via the deployment) to maintain an average CPU utilization across all Pods of 50%
|
||||
(since each pod requests 200 milli-cores by [kubectl run](#kubectl-run), this means average CPU usage of 100 milli-cores).
|
||||
See [here](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md#autoscaling-algorithm) for more details on the algorithm.
|
||||
|
||||
```shell
|
||||
$ kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
|
||||
deployment "php-apache" autoscaled
|
||||
```
|
||||
## API Object
|
||||
|
||||
We may check the current status of autoscaler by running:
|
||||
Horizontal pod autoscaler is a top-level resource in the Kubernetes REST API.
|
||||
In Kubernetes 1.2 HPA was graduated from beta to stable (more details about [api versioning](/docs/api/#api-versioning)) with compatibility between versions.
|
||||
The stable version is available in `autoscaling/v1` api group whereas the beta vesion is available in `extensions/v1beta1` api group as before.
|
||||
The transition plan is to depracate beta version of HPA in Kubernetes 1.3 and get it rid off completely in Kubernetes 1.4.
|
||||
|
||||
```shell
|
||||
$ kubectl get hpa
|
||||
NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE
|
||||
php-apache Deployment/php-apache/scale 50% 0% 1 10 18s
|
||||
**Warning!** Please have in mind that all Kubernetes components still use HPA in version `extensions/v1beta1` in Kubernetes 1.2.
|
||||
|
||||
```
|
||||
More details about the API object can be found at
|
||||
[HorizontalPodAutoscaler Object](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md#horizontalpodautoscaler-object).
|
||||
|
||||
Please note that the current CPU consumption is 0% as we are not sending any requests to the server
|
||||
(the ``CURRENT`` column shows the average across all the pods controlled by the corresponding deployment).
|
||||
## Support for horizontal pod autoscaler in kubectl
|
||||
|
||||
## Step Three: Increase load
|
||||
Horizontal pod autoscaler, like every API resource, is supported in a standard way by `kubectl`.
|
||||
We can create a new autoscaler using `kubectl create` command.
|
||||
We can list autoscalers by `kubectl get hpa` and get detailed description by `kubectl describe hpa`.
|
||||
Finally, we can delete an autoscaler using `kubectl delete hpa`.
|
||||
|
||||
Now, we will see how the autoscaler reacts on the increased load on the server.
|
||||
We will start a container with `busybox` image and an infinite loop of queries to our server inside (please run it in a different terminal):
|
||||
In addition, there is a special `kubectl autoscale` command that allows for easy creation of horizontal pod autoscaler.
|
||||
For instance, executing `kubectl autoscale rc foo --min=2 --max=5 --cpu-percent=80`
|
||||
will create an autoscaler for replication controller *foo*, with target CPU utilization set to `80%`
|
||||
and the number of replicas between 2 and 5.
|
||||
The detailed documentation of `kubectl autoscale` can be found [here](/docs/user-guide/kubectl/kubectl_autoscale).
|
||||
|
||||
```shell
|
||||
$ kubectl run -i --tty load-generator --image=busybox /bin/sh
|
||||
|
||||
Hit enter for command prompt
|
||||
## Autoscaling during rolling update
|
||||
|
||||
$ while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
|
||||
```
|
||||
Currently in Kubernetes, it is possible to perform a rolling update by managing replication controllers directly,
|
||||
or by using the deployment object, which manages the underlying replication controllers for you.
|
||||
Horizontal pod autoscaler only supports the latter approach: the horizontal pod autoscaler is bound to the deployment object,
|
||||
it sets the size for the deployment object, and the deployment is responsible for setting sizes of underlying replication controllers.
|
||||
|
||||
We may examine, how CPU load was increased by executing (it usually takes 1 minute):
|
||||
Horizontal pod autoscaler does not work with rolling update using direct manipulation of replication controllers,
|
||||
i.e. you cannot bind a horizontal pod autoscaler to a replication controller and do rolling update (e.g. using `kubectl rolling-update`).
|
||||
The reason this doesn't work is that when rolling update creates a new replication controller,
|
||||
the horizontal pod autoscaler will not be bound to the new replication controller.
|
||||
|
||||
```shell
|
||||
$ kubectl get hpa
|
||||
NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE
|
||||
php-apache Deployment/php-apache/scale 50% 305% 1 10 3m
|
||||
|
||||
```
|
||||
## Further reading
|
||||
|
||||
In the case presented here, it bumped CPU consumption to 305% of the request.
|
||||
As a result, the deployment was resized to 7 replicas:
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment php-apache
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
php-apache 7 7 7 7 19m
|
||||
```
|
||||
|
||||
**Warning!** Sometimes it may take few steps to stabilize the number of replicas.
|
||||
Since the amount of load is not controlled in any way it may happen that the final number of replicas will
|
||||
differ from this example.
|
||||
|
||||
## Step Four: Stop load
|
||||
|
||||
We will finish our example by stopping the user load.
|
||||
|
||||
In the terminal where we created container with `busybox` image we will terminate
|
||||
infinite ``while`` loop by sending `SIGINT` signal,
|
||||
which can be done using `<Ctrl> + C` combination.
|
||||
|
||||
Then we will verify the result state:
|
||||
|
||||
```shell
|
||||
$ kubectl get hpa
|
||||
NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE
|
||||
php-apache Deployment/php-apache/scale 50% 0% 1 10 11m
|
||||
|
||||
$ kubectl get deployment php-apache
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
php-apache 1 1 1 1 27m
|
||||
```
|
||||
|
||||
As we see, in the presented case CPU utilization dropped to 0, and the number of replicas dropped to 1.
|
||||
|
||||
**Warning!** Sometimes dropping number of replicas may take few steps.
|
||||
|
||||
## Appendix: Other possible scenarios
|
||||
|
||||
### Creating the autoscaler from a .yaml file
|
||||
|
||||
Instead of using `kubectl autoscale` command we can use the [hpa-php-apache.yaml](/docs/user-guide/horizontal-pod-autoscaling/hpa-php-apache.yaml) file, which looks like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: php-apache
|
||||
namespace: default
|
||||
spec:
|
||||
scaleRef:
|
||||
kind: Deployment
|
||||
name: php-apache
|
||||
subresource: scale
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
cpuUtilization:
|
||||
targetPercentage: 50
|
||||
```
|
||||
|
||||
We will create the autoscaler by executing the following command:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/user-guide/horizontal-pod-autoscaling/hpa-php-apache.yaml
|
||||
horizontalpodautoscaler "php-apache" created
|
||||
```
|
||||
* Design documentation: [Horizontal Pod Autoscaling](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md).
|
||||
* Manual of autoscale command in kubectl: [kubectl autoscale](/docs/user-guide/kubectl/kubectl_autoscale).
|
||||
* Usage example of [Horizontal Pod Autoscaler](/docs/user-guide/horizontal-pod-autoscaling/).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
---
|
||||
---
|
||||
|
||||
Horizontal pod autoscaling allows to automatically scale the number of pods
|
||||
in a replication controller, deployment or replica set based on observed CPU utilization.
|
||||
In the future also other metrics will be supported.
|
||||
|
||||
In this document we explain how this feature works by walking you through an example of enabling horizontal pod autoscaling for the php-apache server.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This example requires a running Kubernetes cluster and kubectl in the version at least 1.2.
|
||||
[Heapster](https://github.com/kubernetes/heapster) monitoring needs to be deployed in the cluster
|
||||
as horizontal pod autoscaler uses it to collect metrics
|
||||
(if you followed [getting started on GCE guide](/docs/getting-started-guides/gce),
|
||||
heapster monitoring will be turned-on by default).
|
||||
|
||||
## Step One: Run & expose php-apache server
|
||||
|
||||
To demonstrate horizontal pod autoscaler we will use a custom docker image based on php-apache server.
|
||||
The image can be found [here](/docs/user-guide/horizontal-pod-autoscaling/image).
|
||||
It defines [index.php](/docs/user-guide/horizontal-pod-autoscaling/image/index.php) page which performs some CPU intensive computations.
|
||||
|
||||
First, we will start a deployment running the image and expose it as a service:
|
||||
|
||||
```shell
|
||||
$ kubectl run php-apache --image=gcr.io/google_containers/hpa-example --requests=cpu=200m --expose --port=80
|
||||
service "php-apache" created
|
||||
deployment "php-apache" created
|
||||
```
|
||||
|
||||
## Step Two: Create horizontal pod autoscaler
|
||||
|
||||
Now that the server is running, we will create the autoscaler using
|
||||
[kubectl autoscale](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/user-guide/kubectl/kubectl_autoscale.md).
|
||||
The following command will create a horizontal pod autoscaler that maintains between 1 and 10 replicas of the Pods
|
||||
controlled by the php-apache deployment we created in the first step of these instructions.
|
||||
Roughly speaking, the horizontal autoscaler will increase and decrease the number of replicas
|
||||
(via the deployment) to maintain an average CPU utilization across all Pods of 50%
|
||||
(since each pod requests 200 milli-cores by [kubectl run](#kubectl-run), this means average CPU usage of 100 milli-cores).
|
||||
See [here](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/horizontal-pod-autoscaler.md#autoscaling-algorithm) for more details on the algorithm.
|
||||
|
||||
```shell
|
||||
$ kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
|
||||
deployment "php-apache" autoscaled
|
||||
```
|
||||
|
||||
We may check the current status of autoscaler by running:
|
||||
|
||||
```shell
|
||||
$ kubectl get hpa
|
||||
NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE
|
||||
php-apache Deployment/php-apache/scale 50% 0% 1 10 18s
|
||||
|
||||
```
|
||||
|
||||
Please note that the current CPU consumption is 0% as we are not sending any requests to the server
|
||||
(the ``CURRENT`` column shows the average across all the pods controlled by the corresponding deployment).
|
||||
|
||||
## Step Three: Increase load
|
||||
|
||||
Now, we will see how the autoscaler reacts on the increased load on the server.
|
||||
We will start a container with `busybox` image and an infinite loop of queries to our server inside (please run it in a different terminal):
|
||||
|
||||
```shell
|
||||
$ kubectl run -i --tty load-generator --image=busybox /bin/sh
|
||||
|
||||
Hit enter for command prompt
|
||||
|
||||
$ while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
|
||||
```
|
||||
|
||||
We may examine, how CPU load was increased by executing (it usually takes 1 minute):
|
||||
|
||||
```shell
|
||||
$ kubectl get hpa
|
||||
NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE
|
||||
php-apache Deployment/php-apache/scale 50% 305% 1 10 3m
|
||||
|
||||
```
|
||||
|
||||
In the case presented here, it bumped CPU consumption to 305% of the request.
|
||||
As a result, the deployment was resized to 7 replicas:
|
||||
|
||||
```shell
|
||||
$ kubectl get deployment php-apache
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
php-apache 7 7 7 7 19m
|
||||
```
|
||||
|
||||
**Warning!** Sometimes it may take few steps to stabilize the number of replicas.
|
||||
Since the amount of load is not controlled in any way it may happen that the final number of replicas will
|
||||
differ from this example.
|
||||
|
||||
## Step Four: Stop load
|
||||
|
||||
We will finish our example by stopping the user load.
|
||||
|
||||
In the terminal where we created container with `busybox` image we will terminate
|
||||
infinite ``while`` loop by sending `SIGINT` signal,
|
||||
which can be done using `<Ctrl> + C` combination.
|
||||
|
||||
Then we will verify the result state:
|
||||
|
||||
```shell
|
||||
$ kubectl get hpa
|
||||
NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE
|
||||
php-apache Deployment/php-apache/scale 50% 0% 1 10 11m
|
||||
|
||||
$ kubectl get deployment php-apache
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
php-apache 1 1 1 1 27m
|
||||
```
|
||||
|
||||
As we see, in the presented case CPU utilization dropped to 0, and the number of replicas dropped to 1.
|
||||
|
||||
**Warning!** Sometimes dropping number of replicas may take few steps.
|
||||
|
||||
## Appendix: Other possible scenarios
|
||||
|
||||
### Creating the autoscaler from a .yaml file
|
||||
|
||||
Instead of using `kubectl autoscale` command we can use the [hpa-php-apache.yaml](/docs/user-guide/horizontal-pod-autoscaling/hpa-php-apache.yaml) file, which looks like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: php-apache
|
||||
namespace: default
|
||||
spec:
|
||||
scaleRef:
|
||||
kind: Deployment
|
||||
name: php-apache
|
||||
subresource: scale
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
cpuUtilization:
|
||||
targetPercentage: 50
|
||||
```
|
||||
|
||||
We will create the autoscaler by executing the following command:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/user-guide/horizontal-pod-autoscaling/hpa-php-apache.yaml
|
||||
horizontalpodautoscaler "php-apache" created
|
||||
```
|
||||
|
|
@ -21,6 +21,8 @@ your image.
|
|||
If you did not specify tag of your image, it will be assumed as `:latest`, with
|
||||
pull image policy of `Always` correspondingly.
|
||||
|
||||
Note that you should avoid using `:latest` tag, see [Best Practices for Configuration](/docs/user-guide/config-best-practices/#container-images) for more information.
|
||||
|
||||
## Using a Private Registry
|
||||
|
||||
Private registries may require keys to read images from them.
|
||||
|
|
@ -66,9 +68,15 @@ in the Pod definition.
|
|||
All users of the cluster who can create pods will be able to run pods that use any of the
|
||||
images in the ECR registry.
|
||||
|
||||
The kubelet will fetch and periodically refresh ECR credentials. It needs the
|
||||
`ecr:GetAuthorizationToken` permission to do this.
|
||||
The kubelet will fetch and periodically refresh ECR credentials. It needs the following permissions to do this:
|
||||
|
||||
- `ecr:GetAuthorizationToken`
|
||||
- `ecr:BatchCheckLayerAvailability`
|
||||
- `ecr:GetDownloadUrlForLayer`
|
||||
- `ecr:GetRepositoryPolicy`
|
||||
- `ecr:DescribeRepositories`
|
||||
- `ecr:ListImages`
|
||||
- `ecr:BatchGetImage`
|
||||
|
||||
### Configuring Nodes to Authenticate to a Private Repository
|
||||
|
||||
|
|
|
|||
|
|
@ -39,12 +39,25 @@ It can be configured to give services externally-reachable urls, load balance tr
|
|||
|
||||
## Prerequisites
|
||||
|
||||
Before you start using the Ingress resource, there are a few things you should understand:
|
||||
Before you start using the Ingress resource, there are a few things you should understand. The Ingress is a beta resource, not available in any Kubernetes release prior to 1.1. You need an Ingress controller to satisfy an Ingress, simply creating the resource will have no effect.
|
||||
|
||||
* The Ingress is a beta resource, not available in any Kubernetes release prior to 1.1.
|
||||
* You need an Ingress controller to satisfy an Ingress. Simply creating the resource will have no effect.
|
||||
* On GCE/GKE there should be a [L7 cluster addon](https://releases.k8s.io/{{page.githubbranch}}/cluster/addons/cluster-loadbalancing/glbc/README.md#prerequisites), on other platforms you either need to write your own or [deploy an existing controller](https://github.com/kubernetes/contrib/tree/master/ingress) as a pod.
|
||||
* The resource currently does not support HTTPS, but will do so before it leaves beta.
|
||||
On GCE/GKE there should be a [L7 cluster addon](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/README.md), deployed into the `kube-system` namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=kube-system -l name=glbc
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
l7-lb-controller-v0.6.0-chnan 2/2 Running 0 1d
|
||||
```
|
||||
|
||||
Make sure you review the [beta limitations](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/gce/BETA_LIMITATIONS.md) of this controller. In particular, you need to create a single firewall-rule on your cloudprovider, to allow health checks. On GKE this would be:
|
||||
|
||||
```shell
|
||||
$ gcloud compute firewall-rules create allow-130-211-0-0-22 \
|
||||
--source-ranges 130.211.0.0/22 \
|
||||
--allow tcp:30000-32767
|
||||
```
|
||||
|
||||
In environments other than GCE/GKE, you need to [deploy a controller](https://github.com/kubernetes/contrib/tree/master/ingress/controllers) as a pod.
|
||||
|
||||
## The Ingress Resource
|
||||
|
||||
|
|
@ -202,7 +215,7 @@ metadata:
|
|||
name: no-rules-map
|
||||
spec:
|
||||
tls:
|
||||
secretName: testsecret
|
||||
- secretName: testsecret
|
||||
backend:
|
||||
serviceName: s1
|
||||
servicePort: 80
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ your pods. But there are a number of ways to get even more information about you
|
|||
|
||||
## Using `kubectl describe pod` to fetch details about pods
|
||||
|
||||
For this example we'll use a ReplicationController to create two pods, similar to the earlier example.
|
||||
For this example we'll use a Deployment to create two pods, similar to the earlier example.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: my-nginx
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 2
|
||||
template:
|
||||
|
|
@ -35,53 +35,67 @@ spec:
|
|||
- containerPort: 80
|
||||
```
|
||||
|
||||
Copy this to a file *./my-nginx-dep.yaml*
|
||||
|
||||
```shell
|
||||
$ kubectl create -f ./my-nginx-rc.yaml
|
||||
replicationcontrollers/my-nginx
|
||||
$ kubectl create -f ./my-nginx-dep.yaml
|
||||
deployment "nginx-deployment" created
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl get pods
|
||||
NAME READY REASON RESTARTS AGE
|
||||
my-nginx-gy1ij 1/1 Running 0 1m
|
||||
my-nginx-yv5cn 1/1 Running 0 1m
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-deployment-1006230814-6winp 1/1 Running 0 11s
|
||||
nginx-deployment-1006230814-fmgu3 1/1 Running 0 11s
|
||||
```
|
||||
|
||||
We can retrieve a lot more information about each of these pods using `kubectl describe pod`. For example:
|
||||
|
||||
```shell
|
||||
$ kubectl describe pod my-nginx-gy1ij
|
||||
Name: my-nginx-gy1ij
|
||||
Image(s): nginx
|
||||
Node: kubernetes-node-y3vk/10.240.154.168
|
||||
Labels: app=nginx
|
||||
Status: Running
|
||||
Reason:
|
||||
Message:
|
||||
IP: 10.244.1.4
|
||||
Replication Controllers: my-nginx (2/2 replicas created)
|
||||
$ kubectl describe pod nginx-deployment-1006230814-6winp
|
||||
Name: nginx-deployment-1006230814-6winp
|
||||
Namespace: default
|
||||
Node: kubernetes-node-wul5/10.240.0.9
|
||||
Start Time: Thu, 24 Mar 2016 01:39:49 +0000
|
||||
Labels: app=nginx,pod-template-hash=1006230814
|
||||
Status: Running
|
||||
IP: 10.244.0.6
|
||||
Controllers: ReplicaSet/nginx-deployment-1006230814
|
||||
Containers:
|
||||
nginx:
|
||||
Image: nginx
|
||||
Container ID: docker://90315cc9f513c724e9957a4788d3e625a078de84750f244a40f97ae355eb1149
|
||||
Image: nginx
|
||||
Image ID: docker://6f62f48c4e55d700cf3eb1b5e33fa051802986b77b874cc351cce539e5163707
|
||||
Port: 80/TCP
|
||||
QoS Tier:
|
||||
cpu: Guaranteed
|
||||
memory: Guaranteed
|
||||
Limits:
|
||||
cpu: 500m
|
||||
cpu: 500m
|
||||
memory: 128Mi
|
||||
Requests:
|
||||
memory: 128Mi
|
||||
cpu: 500m
|
||||
State: Running
|
||||
Started: Thu, 09 Jul 2015 15:33:07 -0700
|
||||
Started: Thu, 24 Mar 2016 01:39:51 +0000
|
||||
Ready: True
|
||||
Restart Count: 0
|
||||
Environment Variables:
|
||||
Conditions:
|
||||
Type Status
|
||||
Ready True
|
||||
Volumes:
|
||||
default-token-4bcbi:
|
||||
Type: Secret (a volume populated by a Secret)
|
||||
SecretName: default-token-4bcbi
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Reason Message
|
||||
Thu, 09 Jul 2015 15:32:58 -0700 Thu, 09 Jul 2015 15:32:58 -0700 1 {scheduler } scheduled Successfully assigned my-nginx-gy1ij to kubernetes-node-y3vk
|
||||
Thu, 09 Jul 2015 15:32:58 -0700 Thu, 09 Jul 2015 15:32:58 -0700 1 {kubelet kubernetes-node-y3vk} implicitly required container POD pulled Pod container image "gcr.io/google_containers/pause:0.8.0" already present on machine
|
||||
Thu, 09 Jul 2015 15:32:58 -0700 Thu, 09 Jul 2015 15:32:58 -0700 1 {kubelet kubernetes-node-y3vk} implicitly required container POD created Created with docker id cd1644065066
|
||||
Thu, 09 Jul 2015 15:32:58 -0700 Thu, 09 Jul 2015 15:32:58 -0700 1 {kubelet kubernetes-node-y3vk} implicitly required container POD started Started with docker id cd1644065066
|
||||
Thu, 09 Jul 2015 15:33:06 -0700 Thu, 09 Jul 2015 15:33:06 -0700 1 {kubelet kubernetes-node-y3vk} spec.containers{nginx} pulled Successfully pulled image "nginx"
|
||||
Thu, 09 Jul 2015 15:33:06 -0700 Thu, 09 Jul 2015 15:33:06 -0700 1 {kubelet kubernetes-node-y3vk} spec.containers{nginx} created Created with docker id 56d7a7b14dac
|
||||
Thu, 09 Jul 2015 15:33:07 -0700 Thu, 09 Jul 2015 15:33:07 -0700 1 {kubelet kubernetes-node-y3vk} spec.containers{nginx} started Started with docker id 56d7a7b14dac
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
54s 54s 1 {default-scheduler } Normal Scheduled Successfully assigned nginx-deployment-1006230814-6winp to kubernetes-node-wul5
|
||||
54s 54s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Pulling pulling image "nginx"
|
||||
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Pulled Successfully pulled image "nginx"
|
||||
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Created Created container with docker id 90315cc9f513
|
||||
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Started Started container with docker id 90315cc9f513
|
||||
```
|
||||
|
||||
Here you can see configuration information about the container(s) and Pod (labels, resource requirements, etc.), as well as status information about the container(s) and Pod (state, readiness, restart count, events, etc.)
|
||||
|
|
@ -98,48 +112,59 @@ Lastly, you see a log of recent events related to your Pod. The system compresse
|
|||
|
||||
## Example: debugging Pending Pods
|
||||
|
||||
A common scenario that you can detect using events is when you've created a Pod that won't fit on any node. For example, the Pod might request more resources than are free on any node, or it might specify a label selector that doesn't match any nodes. Let's say we created the previous Replication Controller with 5 replicas (instead of 2) and requesting 600 millicores instead of 500, on a four-node cluster where each (virtual) machine has 1 CPU. In that case one of the Pods will not be able to schedule. (Note that because of the cluster addon pods such as fluentd, skydns, etc., that run on each node, if we requested 1000 millicores then none of the Pods would be able to schedule.)
|
||||
A common scenario that you can detect using events is when you've created a Pod that won't fit on any node. For example, the Pod might request more resources than are free on any node, or it might specify a label selector that doesn't match any nodes. Let's say we created the previous Deployment with 5 replicas (instead of 2) and requesting 600 millicores instead of 500, on a four-node cluster where each (virtual) machine has 1 CPU. In that case one of the Pods will not be able to schedule. (Note that because of the cluster addon pods such as fluentd, skydns, etc., that run on each node, if we requested 1000 millicores then none of the Pods would be able to schedule.)
|
||||
|
||||
```shell
|
||||
$ kubectl get pods
|
||||
NAME READY REASON RESTARTS AGE
|
||||
my-nginx-9unp9 0/1 Pending 0 8s
|
||||
my-nginx-b7zs9 0/1 Running 0 8s
|
||||
my-nginx-i595c 0/1 Running 0 8s
|
||||
my-nginx-iichp 0/1 Running 0 8s
|
||||
my-nginx-tc2j9 0/1 Running 0 8s
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-deployment-1006230814-6winp 1/1 Running 0 7m
|
||||
nginx-deployment-1006230814-fmgu3 1/1 Running 0 7m
|
||||
nginx-deployment-1370807587-6ekbw 1/1 Running 0 1m
|
||||
nginx-deployment-1370807587-fg172 0/1 Pending 0 1m
|
||||
nginx-deployment-1370807587-fz9sd 0/1 Pending 0 1m
|
||||
```
|
||||
|
||||
To find out why the my-nginx-9unp9 pod is not running, we can use `kubectl describe pod` on the pending Pod and look at its events:
|
||||
To find out why the nginx-deployment-1370807587-fz9sd pod is not running, we can use `kubectl describe pod` on the pending Pod and look at its events:
|
||||
|
||||
```shell
|
||||
$ kubectl describe pod my-nginx-9unp9
|
||||
Name: my-nginx-9unp9
|
||||
Image(s): nginx
|
||||
Node: /
|
||||
Labels: app=nginx
|
||||
Status: Pending
|
||||
Reason:
|
||||
Message:
|
||||
IP:
|
||||
Replication Controllers: my-nginx (5/5 replicas created)
|
||||
Containers:
|
||||
nginx:
|
||||
Image: nginx
|
||||
Limits:
|
||||
cpu: 600m
|
||||
memory: 128Mi
|
||||
State: Waiting
|
||||
Ready: False
|
||||
Restart Count: 0
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Reason Message
|
||||
Thu, 09 Jul 2015 23:56:21 -0700 Fri, 10 Jul 2015 00:01:30 -0700 21 {scheduler } failedScheduling Failed for reason PodFitsResources and possibly others
|
||||
$ kubectl describe pod nginx-deployment-1370807587-fz9sd
|
||||
Name: nginx-deployment-1370807587-fz9sd
|
||||
Namespace: default
|
||||
Node: /
|
||||
Labels: app=nginx,pod-template-hash=1370807587
|
||||
Status: Pending
|
||||
IP:
|
||||
Controllers: ReplicaSet/nginx-deployment-1370807587
|
||||
Containers:
|
||||
nginx:
|
||||
Image: nginx
|
||||
Port: 80/TCP
|
||||
QoS Tier:
|
||||
memory: Guaranteed
|
||||
cpu: Guaranteed
|
||||
Limits:
|
||||
cpu: 1
|
||||
memory: 128Mi
|
||||
Requests:
|
||||
cpu: 1
|
||||
memory: 128Mi
|
||||
Environment Variables:
|
||||
Volumes:
|
||||
default-token-4bcbi:
|
||||
Type: Secret (a volume populated by a Secret)
|
||||
SecretName: default-token-4bcbi
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
1m 48s 7 {default-scheduler } Warning FailedScheduling pod (nginx-deployment-1370807587-fz9sd) failed to fit in any node
|
||||
fit failure on node (kubernetes-node-6ta5): Node didn't have enough resource: CPU, requested: 1000, used: 1420, capacity: 2000
|
||||
fit failure on node (kubernetes-node-wul5): Node didn't have enough resource: CPU, requested: 1000, used: 1100, capacity: 2000
|
||||
```
|
||||
|
||||
Here you can see the event generated by the scheduler saying that the Pod failed to schedule for reason `PodFitsResources` (and possibly others). `PodFitsResources` means there were not enough resources for the Pod on any of the nodes. Due to the way the event is generated, there may be other reasons as well, hence "and possibly others."
|
||||
Here you can see the event generated by the scheduler saying that the Pod failed to schedule for reason `FailedScheduling` (and possibly others). The message tells us that there were not enough resources for the Pod on any of the nodes.
|
||||
|
||||
To correct this situation, you can use `kubectl scale` to update your Replication Controller to specify four or fewer replicas. (Or you could just leave the one Pod pending, which is harmless.)
|
||||
To correct this situation, you can use `kubectl scale` to update your Deployment to specify four or fewer replicas. (Or you could just leave the one Pod pending, which is harmless.)
|
||||
|
||||
Events such as the ones you saw at the end of `kubectl describe pod` are persisted in etcd and provide high-level information on what is happening in the cluster. To list all events you can use
|
||||
|
||||
|
|
@ -158,65 +183,75 @@ To see events from all namespaces, you can use the `--all-namespaces` argument.
|
|||
In addition to `kubectl describe pod`, another way to get extra information about a pod (beyond what is provided by `kubectl get pod`) is to pass the `-o yaml` output format flag to `kubectl get pod`. This will give you, in YAML format, even more information than `kubectl describe pod`--essentially all of the information the system has about the Pod. Here you will see things like annotations (which are key-value metadata without the label restrictions, that is used internally by Kubernetes system components), restart policy, ports, and volumes.
|
||||
|
||||
```yaml
|
||||
$ kubectl get pod my-nginx-i595c -o yaml
|
||||
$kubectl get pod nginx-deployment-1006230814-6winp -o yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/created-by: '{"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicationController","namespace":"default","name":"my-nginx","uid":"c555c14f-26d0-11e5-99cb-42010af00e4b","apiVersion":"v1","resourceVersion":"26174"}}'
|
||||
creationTimestamp: 2015-07-10T06:56:21Z
|
||||
generateName: my-nginx-
|
||||
kubernetes.io/created-by: |
|
||||
{"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"default","name":"nginx-deployment-1006230814","uid":"4c84c175-f161-11e5-9a78-42010af00005","apiVersion":"extensions","resourceVersion":"133434"}}
|
||||
creationTimestamp: 2016-03-24T01:39:50Z
|
||||
generateName: nginx-deployment-1006230814-
|
||||
labels:
|
||||
app: nginx
|
||||
name: my-nginx-i595c
|
||||
pod-template-hash: "1006230814"
|
||||
name: nginx-deployment-1006230814-6winp
|
||||
namespace: default
|
||||
resourceVersion: "26243"
|
||||
selfLink: /api/v1/namespaces/default/pods/my-nginx-i595c
|
||||
uid: c558e44b-26d0-11e5-99cb-42010af00e4b
|
||||
resourceVersion: "133447"
|
||||
selfLink: /api/v1/namespaces/default/pods/nginx-deployment-1006230814-6winp
|
||||
uid: 4c879808-f161-11e5-9a78-42010af00005
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: IfNotPresent
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
protocol: TCP
|
||||
resources:
|
||||
limits:
|
||||
cpu: 600m
|
||||
cpu: 500m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 128Mi
|
||||
terminationMessagePath: /dev/termination-log
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
|
||||
name: default-token-zkhkk
|
||||
name: default-token-4bcbi
|
||||
readOnly: true
|
||||
dnsPolicy: ClusterFirst
|
||||
nodeName: kubernetes-node-u619
|
||||
nodeName: kubernetes-node-wul5
|
||||
restartPolicy: Always
|
||||
securityContext: {}
|
||||
serviceAccount: default
|
||||
serviceAccountName: default
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: default-token-zkhkk
|
||||
- name: default-token-4bcbi
|
||||
secret:
|
||||
secretName: default-token-zkhkk
|
||||
secretName: default-token-4bcbi
|
||||
status:
|
||||
conditions:
|
||||
- status: "True"
|
||||
- lastProbeTime: null
|
||||
lastTransitionTime: 2016-03-24T01:39:51Z
|
||||
status: "True"
|
||||
type: Ready
|
||||
containerStatuses:
|
||||
- containerID: docker://9506ace0eb91fbc31aef1d249e0d1d6d6ef5ebafc60424319aad5b12e3a4e6a9
|
||||
- containerID: docker://90315cc9f513c724e9957a4788d3e625a078de84750f244a40f97ae355eb1149
|
||||
image: nginx
|
||||
imageID: docker://319d2015d149943ff4d2a20ddea7d7e5ce06a64bbab1792334c0d3273bbbff1e
|
||||
imageID: docker://6f62f48c4e55d700cf3eb1b5e33fa051802986b77b874cc351cce539e5163707
|
||||
lastState: {}
|
||||
name: nginx
|
||||
ready: true
|
||||
restartCount: 0
|
||||
state:
|
||||
running:
|
||||
startedAt: 2015-07-10T06:56:28Z
|
||||
hostIP: 10.240.112.234
|
||||
startedAt: 2016-03-24T01:39:51Z
|
||||
hostIP: 10.240.0.9
|
||||
phase: Running
|
||||
podIP: 10.244.3.4
|
||||
startTime: 2015-07-10T06:56:21Z
|
||||
podIP: 10.244.0.6
|
||||
startTime: 2016-03-24T01:39:49Z
|
||||
```
|
||||
|
||||
## Example: debugging a down/unreachable node
|
||||
|
|
|
|||
|
|
@ -181,6 +181,45 @@ sometimes be started twice.
|
|||
If you do specify `.spec.parallelism` and `.spec.completions` both greater than 1, then there may be
|
||||
multiple pods running at once. Therefore, your pods must also be tolerant of concurrency.
|
||||
|
||||
## Job Termination and Cleanup
|
||||
|
||||
When a Job completes, no more Pods are created, but the Pods are not deleted either. Since they are terminated,
|
||||
they don't show up with `kubectl get pods`, but they will show up with `kubectl get pods -a`. Keeping them around
|
||||
allows you to still view the logs of completed pods to check for errors, warnings, or other diagnostic output.
|
||||
The job object also remains after it is completed so that you can view its status. It is up to the user to delete
|
||||
old jobs after noting their status. Delete the job with `kubectl` (e.g. `kubectl delete jobs/pi` or `kubectl delete -f ./job.yaml`). When you delete the job using `kubectl`, all the pods it created are deleted too.
|
||||
|
||||
If a Job's pods are failing repeatedly, the Job will keep creating new pods forever, by default.
|
||||
Retrying forever can be a useful pattern. If an external dependency of the Job's
|
||||
pods is missing (for example an input file on a networked storage volume is not present), then the
|
||||
Job will keep trying Pods, and when you later resolve the external dependency (for example, creating
|
||||
the missing file) the Job will then complete without any further action.
|
||||
|
||||
However, if you prefer not to retry forever, you can set a deadline on the job. Do this by setting the
|
||||
`spec.activeDeadlineSeconds` field of the job to a number of seconds. The job will have status with
|
||||
`reason: DeadlineExceeded`. No more pods will be created, and existing pods will be deleted.
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi-with-timeout
|
||||
spec:
|
||||
activeDeadlineSeconds: 100
|
||||
template:
|
||||
metadata:
|
||||
name: pi
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
Note that both the Job Spec and the Pod Template Spec within the Job have a field with the same name.
|
||||
Set the one on the Job.
|
||||
|
||||
## Job Patterns
|
||||
|
||||
The Job object can be used to support reliable parallel execution of Pods. The Job object is not
|
||||
|
|
@ -214,7 +253,7 @@ The pattern names are also links to examples and more detailed description.
|
|||
| -------------------------------------------------------------------------- |:-----------------:|:---------------------------:|:-------------------:|:-------------------:|
|
||||
| [Job Template Expansion](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/job/expansions/README.md) | | | ✓ | ✓ |
|
||||
| [Queue with Pod Per Work Item](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/job/work-queue-1/README.md) | ✓ | | sometimes | ✓ |
|
||||
| [Queue with Variable Pod Count](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/job/work-queue-2/README.md) | | ✓ | ✓ | | ✓ |
|
||||
| [Queue with Variable Pod Count](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/job/work-queue-2/README.md) | ✓ | ✓ | | ✓ |
|
||||
| Single Job with Static Work Assignment | ✓ | | ✓ | |
|
||||
|
||||
When you specify completions with `.spec.completions`, each Pod created by the Job controller
|
||||
|
|
@ -333,5 +372,4 @@ object, but complete control over what pods are created and how work is assigned
|
|||
|
||||
## Future work
|
||||
|
||||
Support for creating Jobs at specified times/dates (i.e. cron) is expected in the next minor
|
||||
release.
|
||||
Support for creating Jobs at specified times/dates (i.e. cron) is expected in [1.3](https://github.com/kubernetes/kubernetes/pull/11980).
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ after kubeconfig is loaded/merged. Available credentials are `client-certificate
|
|||
`client-key`, `token`, and `username/password`. `username/password` and `token`
|
||||
are mutually exclusive, but client certs and keys can be combined with them.
|
||||
You can add or modify `user` entries using
|
||||
[`kubectl config set-credentials`](kubectl/kubectl_config_set-credentials.md).
|
||||
[`kubectl config set-credentials`](/docs/user-guide/kubectl/kubectl_config_set-credentials).
|
||||
|
||||
#### context
|
||||
|
||||
|
|
@ -118,13 +118,13 @@ contexts:
|
|||
name: federal-context
|
||||
```
|
||||
|
||||
A `context` defines a named [`cluster`](#cluster),[`user`](#user),[`namespace`](namespaces.md) tuple
|
||||
A `context` defines a named [`cluster`](#cluster),[`user`](#user),[`namespace`](/docs/user-guide/namespaces) tuple
|
||||
which is used to send requests to the specified cluster using the provided authentication info and
|
||||
namespace. Each of the three is optional; it is valid to specify a context with only one of `cluster`,
|
||||
`user`,`namespace`, or to specify none. Unspecified values, or named values that don't have corresponding
|
||||
entries in the loaded kubeconfig (e.g. if the context specified a `pink-user` for the above kubeconfig file)
|
||||
will be replaced with the default. See [Loading and merging rules](#loading-and-merging) below for override/merge behavior.
|
||||
You can add or modify `context` entries with [`kubectl config set-conext`](kubectl/kubectl_config_set-context.md).
|
||||
You can add or modify `context` entries with [`kubectl config set-context`](/docs/user-guide/kubectl/kubectl_config_set-context).
|
||||
|
||||
#### current-context
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ current-context: federal-context
|
|||
`current-context` is the nickname or 'key' for the cluster,user,namespace tuple that kubectl
|
||||
will use by default when loading config from this file. You can override any of the values in kubectl
|
||||
from the commandline, by passing `--context=CONTEXT`, `--cluster=CLUSTER`, `--user=USER`, and/or `--namespace=NAMESPACE` respectively.
|
||||
You can change the `current-context` with [`kubectl config use-context`](kubectl/kubectl_config_use-context.md).
|
||||
You can change the `current-context` with [`kubectl config use-context`](/docs/user-guide/kubectl/kubectl_config_use-context).
|
||||
|
||||
#### miscellaneous
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ be edited manually.
|
|||
`kubectl config view` will display the current kubeconfig settings. By default
|
||||
it will show you all loaded kubeconfig settings; you can filter the view to just
|
||||
the settings relevant to the `current-context` by passing `--minify`. See
|
||||
[`kubectl config view`](kubectl/kubectl_config_view.md) for other options.
|
||||
[`kubectl config view`](/docs/user-guide/kubectl/kubectl_config_view) for other options.
|
||||
|
||||
## Building your own kubeconfig file
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## Using `kubectl` in Reusable Scripts
|
||||
|
||||
If you need stable output in a script, you should:
|
||||
|
||||
* Request one of the machine-oriented output forms, such as `-o name`, `-o json`, `-o yaml`, `-o go-template`, or `-o jsonpath`
|
||||
* Specify `--output-version`, since those output forms (other than `-o name`) output the resource using a particular API version
|
||||
* Specify `--generator` to pin to a specific behavior forever, if using generator-based commands (such as `kubectl run` or `kubectl expose`)
|
||||
* Don't rely on context, preferences, or other implicit state
|
||||
|
||||
## Best Practices
|
||||
|
||||
### `kubectl run`
|
||||
|
||||
In order for `kubectl run` to satisfy infrastructure as code:
|
||||
|
||||
* Always tag your image with a version-specific tag and don't move that tag to a new version. For example, use `:v1234`, `v1.2.3`, `r03062016-1-4`, rather than `:latest` (see [Best Practices for Configuration](/docs/user-guide/config-best-practices/#container-images) for more information.)
|
||||
* If the image is lightly parameterized, capture the parameters in a checked-in script, or at least use `--record`, to annotate the created objects with the command line.
|
||||
* If the image is heavily parameterized, definitely check in the script.
|
||||
* If features are needed that are not expressible via `kubectl run` flags, switch to configuration files checked into source control.
|
||||
* Pin to a specific generator version, such as `kubectl run --generator=deployment/v1beta1`
|
||||
|
||||
### `kubectl apply`
|
||||
|
||||
* To use `kubectl apply` to update resources, always create resources initially with `kubectl apply` or with `--save-config`. See [managing resources with kubectl apply](/docs/user-guide/managing-deployments/#kubectl-apply) for the reason behind it.
|
||||
|
|
@ -269,4 +269,4 @@ $ kubectl logs -f <pod-name>
|
|||
|
||||
## Next steps
|
||||
|
||||
Start using the [kubectl](/docs/user-guide/kubectl/kubectl) commands.
|
||||
Start using the [kubectl](/docs/user-guide/kubectl/kubectl) commands.
|
||||
|
|
|
|||
|
|
@ -45,37 +45,37 @@ kubectl
|
|||
|
||||
### SEE ALSO
|
||||
|
||||
* [kubectl annotate](kubectl_annotate/) - Update the annotations on a resource
|
||||
* [kubectl api-versions](kubectl_api-versions/) - Print the supported API versions on the server, in the form of "group/version".
|
||||
* [kubectl apply](kubectl_apply/) - Apply a configuration to a resource by filename or stdin
|
||||
* [kubectl attach](kubectl_attach/) - Attach to a running container.
|
||||
* [kubectl autoscale](kubectl_autoscale/) - Auto-scale a deployment or replication controller
|
||||
* [kubectl cluster-info](kubectl_cluster-info/) - Display cluster info
|
||||
* [kubectl config](kubectl_config/) - config modifies kubeconfig files
|
||||
* [kubectl convert](kubectl_convert/) - Convert config files between different API versions
|
||||
* [kubectl cordon](kubectl_cordon/) - Mark node as unschedulable
|
||||
* [kubectl create](kubectl_create/) - Create a resource by filename or stdin
|
||||
* [kubectl delete](kubectl_delete/) - Delete resources by filenames, stdin, resources and names, or by resources and label selector.
|
||||
* [kubectl describe](kubectl_describe/) - Show details of a specific resource or group of resources
|
||||
* [kubectl drain](kubectl_drain/) - Drain node in preparation for maintenance
|
||||
* [kubectl edit](kubectl_edit/) - Edit a resource on the server
|
||||
* [kubectl exec](kubectl_exec/) - Execute a command in a container.
|
||||
* [kubectl explain](kubectl_explain/) - Documentation of resources.
|
||||
* [kubectl expose](kubectl_expose/) - Take a replication controller, service or pod and expose it as a new Kubernetes Service
|
||||
* [kubectl get](kubectl_get/) - Display one or many resources
|
||||
* [kubectl label](kubectl_label/) - Update the labels on a resource
|
||||
* [kubectl logs](kubectl_logs/) - Print the logs for a container in a pod.
|
||||
* [kubectl namespace](kubectl_namespace/) - SUPERSEDED: Set and view the current Kubernetes namespace
|
||||
* [kubectl patch](kubectl_patch/) - Update field(s) of a resource using strategic merge patch.
|
||||
* [kubectl port-forward](kubectl_port-forward/) - Forward one or more local ports to a pod.
|
||||
* [kubectl proxy](kubectl_proxy/) - Run a proxy to the Kubernetes API server
|
||||
* [kubectl replace](kubectl_replace/) - Replace a resource by filename or stdin.
|
||||
* [kubectl rolling-update](kubectl_rolling-update/) - Perform a rolling update of the given ReplicationController.
|
||||
* [kubectl rollout](kubectl_rollout/) - rollout manages a deployment
|
||||
* [kubectl run](kubectl_run/) - Run a particular image on the cluster.
|
||||
* [kubectl scale](kubectl_scale/) - Set a new size for a Replication Controller, Job, or Deployment.
|
||||
* [kubectl uncordon](kubectl_uncordon/) - Mark node as schedulable
|
||||
* [kubectl version](kubectl_version/) - Print the client and server version information.
|
||||
* [kubectl annotate](/docs/user-guide/kubectl/kubectl_annotate/) - Update the annotations on a resource
|
||||
* [kubectl api-versions](/docs/user-guide/kubectl/kubectl_api-versions/) - Print the supported API versions on the server, in the form of "group/version".
|
||||
* [kubectl apply](/docs/user-guide/kubectl/kubectl_apply/) - Apply a configuration to a resource by filename or stdin
|
||||
* [kubectl attach](/docs/user-guide/kubectl/kubectl_attach/) - Attach to a running container.
|
||||
* [kubectl autoscale](/docs/user-guide/kubectl/kubectl_autoscale/) - Auto-scale a deployment or replication controller
|
||||
* [kubectl cluster-info](/docs/user-guide/kubectl/kubectl_cluster-info/) - Display cluster info
|
||||
* [kubectl config](/docs/user-guide/kubectl/kubectl_config/) - config modifies kubeconfig files
|
||||
* [kubectl convert](/docs/user-guide/kubectl/kubectl_convert/) - Convert config files between different API versions
|
||||
* [kubectl cordon](/docs/user-guide/kubectl/kubectl_cordon/) - Mark node as unschedulable
|
||||
* [kubectl create](/docs/user-guide/kubectl/kubectl_create/) - Create a resource by filename or stdin
|
||||
* [kubectl delete](/docs/user-guide/kubectl/kubectl_delete/) - Delete resources by filenames, stdin, resources and names, or by resources and label selector.
|
||||
* [kubectl describe](/docs/user-guide/kubectl/kubectl_describe/) - Show details of a specific resource or group of resources
|
||||
* [kubectl drain](/docs/user-guide/kubectl/kubectl_drain/) - Drain node in preparation for maintenance
|
||||
* [kubectl edit](/docs/user-guide/kubectl/kubectl_edit/) - Edit a resource on the server
|
||||
* [kubectl exec](/docs/user-guide/kubectl/kubectl_exec/) - Execute a command in a container.
|
||||
* [kubectl explain](/docs/user-guide/kubectl/kubectl_explain/) - Documentation of resources.
|
||||
* [kubectl expose](/docs/user-guide/kubectl/kubectl_expose/) - Take a replication controller, service or pod and expose it as a new Kubernetes Service
|
||||
* [kubectl get](/docs/user-guide/kubectl/kubectl_get/) - Display one or many resources
|
||||
* [kubectl label](/docs/user-guide/kubectl/kubectl_label/) - Update the labels on a resource
|
||||
* [kubectl logs](/docs/user-guide/kubectl/kubectl_logs/) - Print the logs for a container in a pod.
|
||||
* [kubectl namespace](/docs/user-guide/kubectl/kubectl_namespace/) - SUPERSEDED: Set and view the current Kubernetes namespace
|
||||
* [kubectl patch](/docs/user-guide/kubectl/kubectl_patch/) - Update field(s) of a resource using strategic merge patch.
|
||||
* [kubectl port-forward](/docs/user-guide/kubectl/kubectl_port-forward/) - Forward one or more local ports to a pod.
|
||||
* [kubectl proxy](/docs/user-guide/kubectl/kubectl_proxy/) - Run a proxy to the Kubernetes API server
|
||||
* [kubectl replace](/docs/user-guide/kubectl/kubectl_replace/) - Replace a resource by filename or stdin.
|
||||
* [kubectl rolling-update](/docs/user-guide/kubectl/kubectl_rolling-update/) - Perform a rolling update of the given ReplicationController.
|
||||
* [kubectl rollout](/docs/user-guide/kubectl/kubectl_rollout/) - rollout manages a deployment
|
||||
* [kubectl run](/docs/user-guide/kubectl/kubectl_run/) - Run a particular image on the cluster.
|
||||
* [kubectl scale](/docs/user-guide/kubectl/kubectl_scale/) - Set a new size for a Replication Controller, Job, or Deployment.
|
||||
* [kubectl uncordon](/docs/user-guide/kubectl/kubectl_uncordon/) - Mark node as schedulable
|
||||
* [kubectl version](/docs/user-guide/kubectl/kubectl_version/) - Print the client and server version information.
|
||||
|
||||
###### Auto generated by spf13/cobra on 2-Mar-2016
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,6 @@ kubectl annotate pods foo description-
|
|||
|
||||
### SEE ALSO
|
||||
|
||||
* [kubectl](kubectl/) - kubectl controls the Kubernetes cluster manager
|
||||
* [kubectl](/docs/user-guide/kubectl/kubectl/) - kubectl controls the Kubernetes cluster manager
|
||||
|
||||
###### Auto generated by spf13/cobra on 11-Mar-2016
|
||||
|
|
@ -42,6 +42,6 @@ kubectl api-versions
|
|||
|
||||
### SEE ALSO
|
||||
|
||||
* [kubectl](kubectl/) - kubectl controls the Kubernetes cluster manager
|
||||
* [kubectl](/docs/user-guide/kubectl/kubectl/) - kubectl controls the Kubernetes cluster manager
|
||||
|
||||
###### Auto generated by spf13/cobra on 2-Mar-2016
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue