diff --git a/.gitignore b/.gitignore index 460a88c521..efdcc2a53e 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ Session.vim tags kubernetes.github.io.iml +_redirects diff --git a/.travis.yml b/.travis.yml index e527e16dbc..691d897659 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,15 +7,33 @@ install: - export PATH=$GOPATH/bin:$PATH - mkdir -p $HOME/gopath/src/k8s.io - mv $TRAVIS_BUILD_DIR $HOME/gopath/src/k8s.io/kubernetes.github.io + +# (1) Fetch dependencies for us to run the tests in test/examples_test.go - go get -t -v k8s.io/kubernetes.github.io/test -- git clone --depth=50 --branch=master https://github.com/kubernetes/md-check $HOME/gopath/src/k8s.io/md-check -- go get -t -v k8s.io/md-check + +# The dependencies are complicated for test/examples_test.go +# k8s.io/kubernetes/pkg is a dependency, which in turn depends on apimachinery +# but we also have apimachinery directly as one of our dependencies, which causes a conflict. +# Additionally, we get symlinks when we clone the directory. The below steps do the following: + +# (a) Replace the symlink with the actual dependencies from kubernetes/staging/src/ +# (b) copy all the vendored files to $GOPATH/src - rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery - rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/apiserver - rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/client-go +- rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/sample-apiserver +- rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/kube-aggregator - cp -r $GOPATH/src/k8s.io/kubernetes/vendor/* $GOPATH/src/ - rm -rf $GOPATH/src/k8s.io/kubernetes/vendor/* - cp -r $GOPATH/src/k8s.io/kubernetes/staging/src/* $GOPATH/src/ +- cp -r $GOPATH/src/k8s.io/apimachinery/vendor/* $GOPATH/src/ +- rm -rf $GOPATH/src/k8s.io/apimachinery/vendor/* + +# (2) Fetch md-check along with all its dependencies. +- git clone --depth=50 --branch=master https://github.com/kubernetes/md-check $HOME/gopath/src/k8s.io/md-check +- go get -t -v k8s.io/md-check + +# (3) Fetch mungedocs - go get -v k8s.io/kubernetes/cmd/mungedocs script: diff --git a/Makefile b/Makefile index 3657cb577a..36a4842840 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all build build-preview help serve +.PHONY: all build build-preview generate-redirects help serve help: ## Show this help. @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) @@ -11,5 +11,8 @@ build: ## Build site with production settings and put deliverables in _site. build-preview: ## Build site with drafts and future posts enabled. jekyll build --drafts --future +generate-redirects: ## Generate a redirects file and copy it into the _site directory. + mkdir -p _site && REDIRECTS_PATH=_site/_redirects ruby redirects.rb + serve: ## Boot the development server. jekyll serve diff --git a/_data/concepts.yml b/_data/concepts.yml index 4f41c2c818..31bfd9396b 100644 --- a/_data/concepts.yml +++ b/_data/concepts.yml @@ -3,30 +3,63 @@ abstract: "Detailed explanations of Kubernetes system concepts and abstractions. toc: - docs/concepts/index.md -- title: Kubectl Command Line +- title: Overview section: - - docs/concepts/tools/kubectl/object-management-overview.md - - docs/concepts/tools/kubectl/object-management-using-imperative-commands.md - - docs/concepts/tools/kubectl/object-management-using-imperative-config.md - - docs/concepts/tools/kubectl/object-management-using-declarative-config.md - + - docs/concepts/overview/what-is-kubernetes.md + - docs/concepts/overview/components.md + - title: Working with Kubernetes Objects + section: + - docs/concepts/overview/working-with-objects/kubernetes-objects.md + - docs/concepts/overview/working-with-objects/labels.md + - docs/concepts/overview/working-with-objects/annotations.md + - docs/concepts/overview/kubernetes-api.md + - title: Kubernetes Objects section: - - docs/concepts/abstractions/overview.md - - docs/concepts/abstractions/pod.md - + - title: Pods + section: + - docs/concepts/abstractions/pod.md + - docs/concepts/abstractions/init-containers.md - title: Controllers section: - docs/concepts/abstractions/controllers/statefulsets.md + - docs/concepts/abstractions/controllers/petsets.md + - docs/concepts/abstractions/controllers/garbage-collection.md -- title: Object Metadata +- title: Workloads section: - - docs/concepts/object-metadata/annotations.md + - title: Pods + section: + - docs/concepts/workloads/pods/pod-lifecycle.md + - title: Jobs + section: + - docs/concepts/jobs/run-to-completion-finite-workloads.md + +- title: Cluster Administration + section: + - docs/concepts/cluster-administration/manage-deployment.md + - docs/concepts/cluster-administration/networking.md + - docs/concepts/cluster-administration/network-plugins.md + - docs/concepts/cluster-administration/logging.md + - docs/concepts/cluster-administration/audit.md + - docs/concepts/cluster-administration/out-of-resource.md + - docs/concepts/cluster-administration/multiple-clusters.md + - docs/concepts/cluster-administration/federation.md + - docs/concepts/cluster-administration/guaranteed-scheduling-critical-addon-pods.md + - docs/concepts/cluster-administration/static-pod.md + - docs/concepts/cluster-administration/sysctl-cluster.md + +- title: Services, Load Balancing, and Networking + section: + - docs/concepts/services-networking/dns-pod-service.md - title: Configuration section: + - docs/concepts/configuration/overview.md - docs/concepts/configuration/container-command-args.md + - docs/concepts/configuration/manage-compute-resources-container.md - title: Policies section: - docs/concepts/policy/container-capabilities.md + - docs/concepts/policy/resource-quotas.md diff --git a/_data/guides.yml b/_data/guides.yml index 511ece0885..0a06052579 100644 --- a/_data/guides.yml +++ b/_data/guides.yml @@ -5,6 +5,8 @@ toc: - docs/whatisk8s.md +- docs/user-guide/index.md + - title: Accessing the Cluster section: - docs/user-guide/prereqs.md @@ -12,20 +14,15 @@ toc: - docs/user-guide/sharing-clusters.md - docs/user-guide/kubeconfig-file.md -- docs/user-guide/index.md - - docs/user-guide/ui.md - title: Workload Deployment and Management section: - - docs/user-guide/quick-start.md - - docs/user-guide/deploying-applications.md - docs/user-guide/managing-deployments.md - docs/user-guide/replication-controller/operations.md - docs/user-guide/resizing-a-replication-controller.md - docs/user-guide/rolling-updates.md - docs/user-guide/update-demo/index.md - - docs/user-guide/secrets/walkthrough.md - docs/user-guide/configmap/index.md - docs/user-guide/horizontal-pod-autoscaling/walkthrough.md - docs/user-guide/config-best-practices.md @@ -56,14 +53,9 @@ toc: - title: Containers and Pods section: - - docs/user-guide/simple-nginx.md - - docs/user-guide/pods/single-container.md - docs/user-guide/pods/multi-container.md - docs/user-guide/pods/init-container.md - - docs/user-guide/configuring-containers.md - docs/user-guide/pod-templates.md - - docs/user-guide/production-pods.md - - docs/user-guide/containers.md - docs/user-guide/environment-guide/index.md - docs/user-guide/compute-resources.md - docs/user-guide/pod-states.md @@ -72,7 +64,6 @@ toc: - docs/user-guide/node-selection/index.md - docs/user-guide/downward-api/index.md - docs/user-guide/downward-api/volume/index.md - - docs/user-guide/persistent-volumes/walkthrough.md - docs/user-guide/petset/bootstrapping/index.md - title: Monitoring, Logging, and Debugging Containers @@ -178,6 +169,7 @@ toc: section: - docs/admin/index.md - docs/admin/cluster-management.md + - docs/admin/upgrade-1-6.md - docs/admin/kubeadm.md - docs/admin/addons.md - docs/admin/audit.md @@ -228,5 +220,5 @@ toc: - title: Federation Components section: - docs/admin/federation-apiserver.md - - title : federation-controller-mananger + - title : federation-controller-manager path: /docs/admin/federation-controller-manager diff --git a/_data/tasks.yml b/_data/tasks.yml index de066c9ed2..c113a1fa87 100644 --- a/_data/tasks.yml +++ b/_data/tasks.yml @@ -3,28 +3,46 @@ abstract: "Step-by-step instructions for performing operations with Kubernetes." toc: - docs/tasks/index.md +- title: Using the kubectl Command-Line + section: + - docs/tasks/kubectl/list-all-running-container-images.md + - docs/tasks/kubectl/get-shell-running-container.md + - title: Configuring Pods and Containers section: - docs/tasks/configure-pod-container/define-environment-variable-container.md - docs/tasks/configure-pod-container/define-command-argument-container.md - docs/tasks/configure-pod-container/assign-cpu-ram-container.md + - docs/tasks/configure-pod-container/limit-range.md + - docs/tasks/configure-pod-container/apply-resource-quota-limit.md - docs/tasks/configure-pod-container/configure-volume-storage.md - docs/tasks/configure-pod-container/configure-persistent-volume-storage.md + - docs/tasks/configure-pod-container/environment-variable-expose-pod-information.md + - docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information.md - docs/tasks/configure-pod-container/distribute-credentials-secure.md - docs/tasks/configure-pod-container/pull-image-private-registry.md - docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md - docs/tasks/configure-pod-container/communicate-containers-same-pod.md - docs/tasks/configure-pod-container/configure-pod-initialization.md - docs/tasks/configure-pod-container/attach-handler-lifecycle-event.md + - docs/tasks/configure-pod-container/configure-pod-disruption-budget.md + +- title: Running Applications + section: + - docs/tasks/run-application/rolling-update-replication-controller.md - title: Accessing Applications in a Cluster section: - docs/tasks/access-application-cluster/port-forward-access-application-cluster.md - docs/tasks/access-application-cluster/load-balance-access-application-cluster.md -- title: Debugging Applications in a Cluster +- title: Monitoring, Logging, and Debugging section: - docs/tasks/debug-application-cluster/determine-reason-pod-failure.md + - docs/tasks/debug-application-cluster/debug-init-containers.md + - docs/tasks/debug-application-cluster/logging-stackdriver.md + - docs/tasks/debug-application-cluster/monitor-node-health.md + - docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md - title: Accessing the Kubernetes API section: @@ -36,6 +54,18 @@ toc: - docs/tasks/administer-cluster/dns-horizontal-autoscaling.md - docs/tasks/administer-cluster/safely-drain-node.md - docs/tasks/administer-cluster/change-pv-reclaim-policy.md + - docs/tasks/administer-cluster/limit-storage-consumption.md + +- title: Administering Federation + section: + - docs/tasks/administer-federation/configmap.md + - docs/tasks/administer-federation/daemonset.md + - docs/tasks/administer-federation/deployment.md + - docs/tasks/administer-federation/events.md + - docs/tasks/administer-federation/ingress.md + - docs/tasks/administer-federation/namespaces.md + - docs/tasks/administer-federation/replicaset.md + - docs/tasks/administer-federation/secret.md - title: Managing Stateful Applications section: @@ -44,8 +74,3 @@ toc: - docs/tasks/manage-stateful-set/deleting-a-statefulset.md - docs/tasks/manage-stateful-set/debugging-a-statefulset.md - docs/tasks/manage-stateful-set/delete-pods.md - -- title: Troubleshooting - section: - - docs/tasks/troubleshoot/debug-init-containers.md - - docs/tasks/administer-cluster/access-control-identity-management/ diff --git a/_data/tutorials.yml b/_data/tutorials.yml index 695d2b8805..b0b173a82b 100644 --- a/_data/tutorials.yml +++ b/_data/tutorials.yml @@ -32,11 +32,18 @@ toc: - title: Online Training Course path: https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615 - docs/tutorials/stateless-application/hello-minikube.md +- title: Object Management Using kubectl + section: + - docs/tutorials/object-management-kubectl/object-management.md + - docs/tutorials/object-management-kubectl/imperative-object-management-command.md + - docs/tutorials/object-management-kubectl/imperative-object-management-configuration.md + - docs/tutorials/object-management-kubectl/declarative-object-management-configuration.md - title: Stateless Applications section: - docs/tutorials/stateless-application/run-stateless-application-deployment.md - docs/tutorials/stateless-application/expose-external-ip-address-service.md - docs/tutorials/stateless-application/expose-external-ip-address.md + - docs/tutorials/stateless-application/run-stateless-ap-replication-controller.md - title: Stateful Applications section: - docs/tutorials/stateful-application/basic-stateful-set.md @@ -46,6 +53,12 @@ toc: - title: Connecting Applications section: - docs/tutorials/connecting-apps/connecting-frontend-backend.md +- title: Clusters + section: + - docs/tutorials/clusters/apparmor.md - title: Services section: - docs/tutorials/services/source-ip.md +- title: Federated Cluster Administration + section: + - docs/tutorials/federation/set-up-cluster-federation-kubefed.md diff --git a/_includes/1-5-beta.md b/_includes/1-5-beta.md new file mode 100644 index 0000000000..abccaa303c --- /dev/null +++ b/_includes/1-5-beta.md @@ -0,0 +1 @@ +***NOTE: This feature is beta in Kubernetes 1.5.*** \ No newline at end of file diff --git a/_includes/partner-script.js b/_includes/partner-script.js index 4d0a117620..43352b0f03 100644 --- a/_includes/partner-script.js +++ b/_includes/partner-script.js @@ -279,14 +279,120 @@ logo: 'harbur', link: 'https://harbur.io/', blurb: 'Based in Barcelona, Harbur is a consulting firm that helps companies deploy self-healing solutions empowered by Container technologies' - }, + }, { type: 1, name: 'Endocode', logo: 'endocode', link: 'https://endocode.com/kubernetes/', blurb: 'Endocode practices and teaches the open source way. Kernel to cluster - Dev to Ops. We offer Kubernetes trainings, services and support.' - } + }, + { + type: 0, + name: 'Spotinst', + logo: 'spotinst', + link: 'http://blog.spotinst.com/2016/08/04/elastigroup-kubernetes-minions-steroids/', + blurb: 'Spotinst uses a prediction algorithm in the Amazon EC2 Spot allowing k8s clusters to increase performance and lower the infrastructure costs' + }, + { + type: 1, + name: 'inwinSTACK', + logo: 'inwinstack', + link: 'http://www.inwinstack.com/index.php/en/solutions-en/', + blurb: 'Our container service leverages OpenStack-based infrastructure and its container orchestration engine Magnum to manage Kubernetes clusters.' + }, + { + type: 1, + name: 'Semantix', + logo: 'semantix', + link: 'http://www.semantix.com.br/', + blurb: 'Semantix is a company that works with data analytics and distributed systems. Kubernetes is used to orchestrate services for our customers.' + }, + { + type: 0, + name: 'ASM Technologies Limited', + logo: 'asm', + link: 'http://www.asmtech.com/', + blurb: 'Our technology supply chain portfolio enables your software products to be accessible, viable and available more effectively.' + }, + { + type: 1, + name: 'InfraCloud Technologies', + logo: 'infracloud', + link: 'http://blog.infracloud.io/state-of-kubernetes/', + blurb: 'InfraCloud Technologies is software consultancy which provides services in Containers, Cloud and DevOps.' + }, + { + type: 0, + name: 'SignalFx', + logo: 'signalfx', + link: 'https://github.com/signalfx/integrations/tree/master/kubernetes', + blurb: 'Gain real-time visibility across metrics & the most intelligent alerts for todays architectures, including deep integration with Kubernetes' + }, + { + type: 0, + name: 'NATS', + logo: 'nats', + link: 'https://github.com/pires/kubernetes-nats-cluster', + blurb: 'NATS is a simple, secure, and scalable cloud native messaging system.' + }, + { + type: 1, + name: 'RX-M', + logo: 'rxm', + link: 'http://rx-m.com/training/kubernetes-training/', + blurb: 'Market neutral Kubernetes Dev, DevOps and Production training and consulting services' + }, + { + type: 1, + name: 'Emerging Technology Advisors', + logo: 'eta', + link: 'https://www.emergingtechnologyadvisors.com/services/kubernetes.html', + blurb: 'ETA helps companies architect, implement, and manage scalable applications using Kubernetes on on public or private cloud.' + }, + { + type: 0, + name: 'CloudPlex.io', + logo: 'cloudplex', + link: 'http://www.cloudplex.io', + blurb: 'CloudPlex enables operations teams to visually deploy, orchestrate, manage, and monitor infrastructure, applications, and services in public or private cloud.' + }, + { + type: 1, + name: 'Kumina', + logo: 'kumina', + link: 'https://www.kumina.nl/managed_kubernetes', + blurb: 'Kumina creates Kubernetes solutions on your choice of infrastructure with around-the-clock management and unlimited support.' + }, + { + type: 0, + name: 'CA Technologies', + logo: 'ca', + link: 'https://www.ca.com/us/products/application-deployment.html', + blurb: 'The RA CDE Kubernetes plugin enables an automated process for pushing changes to production by applying standard Kubernetes YAML files' + }, + { + type: 0, + name: 'CoScale', + logo: 'coscale', + link: 'http://www.coscale.com/blog/how-to-monitor-your-kubernetes-cluster', + blurb: 'Full stack monitoring of containers and microservices orchestrated by Kubernetes. Powered by anomaly detection to find problems faster.' + }, + { + type: 0, + name: 'Supergiant.io', + logo: 'supergiant', + link: 'https://supergiant.io/blog/supergiant-packing-algorithm-unique-save-money', + blurb: 'Supergiant autoscales hardware for Kubernetes. Open-source, it makes HA, distributed, stateful apps easy to deploy, manage, and scale.' + }, + { + type: 0, + name: 'Avi Networks', + logo: 'avinetworks', + link: 'https://kb.avinetworks.com/avi-vantage-openshift-installation-guide/', + blurb: 'Avis elastic application services fabric provides scalable, feature rich & integrated L4-7 networking for K8S environments.' + } + ] var isvContainer = document.getElementById('isvContainer') diff --git a/_includes/user-guide-migration-notice.md b/_includes/user-guide-migration-notice.md new file mode 100644 index 0000000000..7e64abe8d0 --- /dev/null +++ b/_includes/user-guide-migration-notice.md @@ -0,0 +1,12 @@ + + + + + + +
+

NOTICE

+

As of March 14, 2017, the @kubernetes/sig-docs-maintainers have begun migration of the User Guide content as announced previously to the SIG Docs community through the kubernetes-sig-docs group and kubernetes.slack.com #sig-docs channel.

+

The user guides within this section are being refactored into topics within Tutorials, Tasks, and Concepts. Anything that has been moved will have a notice placed in its previous location as well as a link to its new location. The reorganization implements the table of contents (ToC) outlined in the kubernetes-docs-toc document and should improve the documentation's findability and readability for a wider range of audiences.

+

For any questions, please contact: kubernetes-sig-docs@googlegroups.com

+
diff --git a/_includes/v1.5/extensions-v1beta1-definitions.html b/_includes/v1.5/extensions-v1beta1-definitions.html index bd86db7daa..f210a6350b 100755 --- a/_includes/v1.5/extensions-v1beta1-definitions.html +++ b/_includes/v1.5/extensions-v1beta1-definitions.html @@ -3453,7 +3453,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

nodeSelector

-

NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection/README

+

NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection

false

object

diff --git a/_includes/v1.5/v1-definitions.html b/_includes/v1.5/v1-definitions.html index faaa0e847d..b42f1ad675 100755 --- a/_includes/v1.5/v1-definitions.html +++ b/_includes/v1.5/v1-definitions.html @@ -4172,7 +4172,7 @@ The resulting set of endpoints can be viewed as:

nodeSelector

-

NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection/README

+

NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection

false

object

@@ -8146,7 +8146,7 @@ The resulting set of endpoints can be viewed as:

unschedulable

-

Unschedulable controls node schedulability of new pods. By default, node is schedulable. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#manual-node-administration"

+

Unschedulable controls node schedulability of new pods. By default, node is schedulable. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#manual-node-administration

false

boolean

false

@@ -8263,4 +8263,4 @@ Last updated 2016-11-17 06:26:10 UTC - \ No newline at end of file + diff --git a/_layouts/docwithnav.html b/_layouts/docwithnav.html index 073e1c9344..3d12017366 100755 --- a/_layouts/docwithnav.html +++ b/_layouts/docwithnav.html @@ -33,7 +33,7 @@
  • SUPPORT
  • diff --git a/_sass/_base.sass b/_sass/_base.sass index 3ad4f81dc5..97aacc41be 100644 --- a/_sass/_base.sass +++ b/_sass/_base.sass @@ -816,9 +816,9 @@ dd font-weight: 500 p - font-size: 14px + font-size: 16px font-weight: 300 - line-height: 1.25em + line-height: 1.75em p + p margin-top: 10px @@ -856,6 +856,7 @@ dd display: block margin: 20px 0 padding: 15px + position: relative overflow-x: auto h1 code, h2 code, h3 code, h4 code, h5 code, h6 code @@ -893,6 +894,8 @@ dd li margin-bottom: 0.75em + font-size: 16px + line-height: 1.75em table width: 100% @@ -1277,7 +1280,7 @@ $feature-box-div-margin-bottom: 40px background-color: $white box-shadow: 0 5px 5px rgba(0,0,0,.24),0 0 5px rgba(0,0,0,.12) - #calendarWrapper + #calendarMeetings position: relative width: 80vw height: 60vw @@ -1285,6 +1288,14 @@ $feature-box-div-margin-bottom: 40px max-height: 900px margin: 20px auto + #calendarEvents + position: relative + width: 80vw + height: 30vw + max-width: 1200px + max-height: 450px + margin: 20px auto + iframe position: absolute border: 0 diff --git a/case-studies/index.html b/case-studies/index.html index e4e15111c5..cf96a049d5 100644 --- a/case-studies/index.html +++ b/case-studies/index.html @@ -94,6 +94,6 @@ cid: caseStudies
    - +
    diff --git a/cn/docs/.gitkeep b/cn/docs/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/community/index.html b/community/index.html index 201c70a776..f967dc23cc 100644 --- a/community/index.html +++ b/community/index.html @@ -27,10 +27,17 @@ cid: community lists of SIGs, from AWS and Openstack to Big Data and Scalability, there's a place for you to contribute and instructions for forming a new SIG if your special interest isn't covered (yet).

    + +

    As a member of the Kubernetes community, you are welcome to join any of the SIG meetings + you are interested in. No registration required.

    +
    + +

    Events

    -
    +
    diff --git a/docs/admin/addons.md b/docs/admin/addons.md index aeee68cc30..fc1c4ec83c 100644 --- a/docs/admin/addons.md +++ b/docs/admin/addons.md @@ -14,6 +14,7 @@ Add-ons in each section are sorted alphabetically - the ordering does not imply * [Calico](http://docs.projectcalico.org/v2.0/getting-started/kubernetes/installation/hosted/) is a secure L3 networking and network policy provider. * [Canal](https://github.com/tigera/canal/tree/master/k8s-install/kubeadm) unites Flannel and Calico, providing networking and network policy. +* [Contiv](http://contiv.github.io) provides configurable networking (native L3 using BGP, overlay using vxlan, classic L2, and Cisco-SDN/ACI) for various use cases and a rich policy framework. Contiv project is fully [open sourced](http://github.com/contiv). The [installer](http://github.com/contiv/install) provides both kubeadm and non-kubeadm based installation options. * [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kube-flannel.yml) is an overlay network provider that can be used with Kubernetes. * [Romana](http://romana.io) is a Layer 3 networking solution for pod networks that also supports the [NetworkPolicy API](/docs/user-guide/networkpolicies/). Kubeadm add-on installation details available [here](https://github.com/romana/romana/tree/master/containerize). * [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/) provides networking and network policy, will carry on working on both sides of a network partition, and does not require an external database. diff --git a/docs/admin/admission-controllers.md b/docs/admin/admission-controllers.md index 089dce2605..e3d839f0d5 100644 --- a/docs/admin/admission-controllers.md +++ b/docs/admin/admission-controllers.md @@ -87,7 +87,7 @@ The ImagePolicyWebhook plug-in allows a backend webhook to make admission decisi ``` #### Configuration File Format -ImagePolicyWebhook uses the admission controller config file (`--admission-controller-config-file`) to set configuration options for the behavior of the backend. This file may be json or yaml and has the following format: +ImagePolicyWebhook uses the admission config file `--admission-controller-config-file` to set configuration options for the behavior of the backend. This file may be json or yaml and has the following format: ```javascript { @@ -252,6 +252,11 @@ This plugin ignores any `PersistentVolumeClaim` updates, it acts only on creatio See [persistent volume](/docs/user-guide/persistent-volumes) documentation about persistent volume claims and storage classes and how to mark a storage class as default. +### DefaultTolerationSeconds + +This plug-in sets the default forgiveness toleration for pods, which have no forgiveness tolerations, to tolerate +the taints `notready:NoExecute` and `unreachable:NoExecute` for 5 minutes. + ## Is there a recommended set of plug-ins to use? Yes. diff --git a/docs/admin/apparmor/index.md b/docs/admin/apparmor/index.md index 224f0bbdeb..60835fd5bf 100644 --- a/docs/admin/apparmor/index.md +++ b/docs/admin/apparmor/index.md @@ -4,389 +4,6 @@ assignees: title: AppArmor --- -AppArmor is a Linux kernel enhancement that can reduce the potential attack surface of an -application and provide greater defense in depth for Applications. Beta support for AppArmor was -added in Kubernetes v1.4. +{% include user-guide-content-moved.md %} -* TOC -{:toc} - -## What is AppArmor - -AppArmor is a Linux kernel security module that supplements the standard Linux user and group based -permissions to confine programs to a limited set of resources. AppArmor can be configured for any -application to reduce its potential attack surface and provide greater defense in depth. It is -configured through profiles tuned to whitelist the access needed by a specific program or container, -such as Linux capabilities, network access, file permissions, etc. Each profile can be run in either -enforcing mode, which blocks access to disallowed resources, or complain mode, which only reports -violations. - -AppArmor can help you to run a more secure deployment by restricting what containers are allowed to -do, and /or providing better auditing through system logs. However, it is important to keep in mind -that AppArmor is not a silver bullet, and can only do so much to protect against exploits in your -application code. It is important to provide good, restrictive profiles, and harden your -applications and cluster from other angles as well. - -AppArmor support in Kubernetes is currently in beta. - -## Prerequisites - -1. **Kubernetes version is at least v1.4**. Kubernetes support for AppArmor was added in - v1.4. Kubernetes components older than v1.4 are not aware of the new AppArmor annotations, and - will **silently ignore** any AppArmor settings that are provided. To ensure that your Pods are - receiving the expected protections, it is important to verify the Kubelet version of your nodes: - - $ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.kubeletVersion}\n{end}' - gke-test-default-pool-239f5d02-gyn2: v1.4.0 - gke-test-default-pool-239f5d02-x1kf: v1.4.0 - gke-test-default-pool-239f5d02-xwux: v1.4.0 - -2. **AppArmor kernel module is enabled**. For the Linux kernel to enforce an AppArmor profile, the - AppArmor kernel module must be installed and enabled. Several distributions enable the module by - default, such as Ubuntu and SUSE, and many others provide optional support. To check whether the - module is enabled, check the `/sys/module/apparmor/parameters/enabled` file: - - $ cat /sys/module/apparmor/parameters/enabled - Y - - If the Kubelet contains AppArmor support (>= v1.4), it will refuse to run a Pod with AppArmor - options if the kernel module is not enabled. - - *Note: Ubuntu carries many AppArmor patches that have not been merged into the upstream Linux - kernel, including patches that add additional hooks and features. Kubernetes has only been - tested with the upstream version, and does not promise support for other features.* - -3. **Container runtime is Docker**. Currently the only Kubernetes-supported container runtime that - also supports AppArmor is Docker. As more runtimes add AppArmor support, the options will be - expanded. You can verify that your nodes are running docker with: - - $ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.containerRuntimeVersion}\n{end}' - gke-test-default-pool-239f5d02-gyn2: docker://1.11.2 - gke-test-default-pool-239f5d02-x1kf: docker://1.11.2 - gke-test-default-pool-239f5d02-xwux: docker://1.11.2 - - If the Kubelet contains AppArmor support (>= v1.4), it will refuse to run a Pod with AppArmor - options if the runtime is not Docker. - -4. **Profile is loaded**. AppArmor is applied to a Pod by specifying an AppArmor profile that each - container should be run with. If any of the specified profiles is not already loaded in the - kernel, the Kubelet (>= v1.4) will reject the Pod. You can view which profiles are loaded on a - node by checking the `/sys/kernel/security/apparmor/profiles` file. For example: - - $ ssh gke-test-default-pool-239f5d02-gyn2 "sudo cat /sys/kernel/security/apparmor/profiles | sort" - apparmor-test-deny-write (enforce) - apparmor-test-audit-write (enforce) - docker-default (enforce) - k8s-nginx (enforce) - - For more details on loading profiles on nodes, see - [Setting up nodes with profiles](#setting-up-nodes-with-profiles). - -As long as the Kubelet version includes AppArmor support (>= v1.4), the Kubelet will reject a Pod -with AppArmor options if any of the prerequisites are not met. You can also verify AppArmor support -on nodes by checking the node ready condition message (though this is likely to be removed in a -later release): - - $ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {.status.conditions[?(@.reason=="KubeletReady")].message}\n{end}' - gke-test-default-pool-239f5d02-gyn2: kubelet is posting ready status. AppArmor enabled - gke-test-default-pool-239f5d02-x1kf: kubelet is posting ready status. AppArmor enabled - gke-test-default-pool-239f5d02-xwux: kubelet is posting ready status. AppArmor enabled - -## Securing a Pod - -*Note: AppArmor is currently in beta, so options are specified as annotations. Once support graduates to -general availability, the annotations will be replaced with first-class fields (more details in -[Upgrade path to GA](#upgrade-path-to-general-availability)).* - -AppArmor profiles are specified *per-container*. To specify the AppArmor profile to run a Pod -container with, add an annotation to the Pod's metadata: - - container.apparmor.security.beta.kubernetes.io/: - -Where `` is the name of the container to apply the profile to, and `` -specifies the profile to apply. The `profile_ref` can be one of: - -- `runtime/default` to apply the runtime's default profile. -- `localhost/` to apply the profile loaded on the host with the name `` - -See the [API Reference](#api-reference) for the full details on the annotation and profile name formats. - -The Kubernetes AppArmor enforcement works by first checking that all the prerequisites have been -met, and then forwarding the profile selection to the container runtime for enforcement. If the -prerequisites have not been met, the Pod will be rejected, and will not run. - -To verify that the profile was applied, you can expect to see the AppArmor security option listed in the container created event: - - $ kubectl get events | grep Created - 22s 22s 1 hello-apparmor Pod spec.containers{hello} Normal Created {kubelet e2e-test-stclair-minion-group-31nt} Created container with docker id 269a53b202d3; Security:[seccomp=unconfined apparmor=k8s-apparmor-example-deny-write] - -You can also verify directly that the container's root process is running with the correct profile by checking its proc attr: - - $ kubectl exec cat /proc/1/attr/current - k8s-apparmor-example-deny-write (enforce) - -## Example - -In this example you'll see: - -- One way to load a profile on a node -- How to enforce the profile on a Pod -- How to check that the profile is loaded -- What happens when a profile is violated -- What happens when a profile cannot be loaded - -*This example assumes you have already set up a cluster with AppArmor support.* - -First, we need to load the profile we want to use onto our nodes. The profile we'll use simply -denies all file writes: - -{% include code.html language="text" file="deny-write.profile" ghlink="/docs/admin/apparmor/deny-write.profile" %} - -Since we don't know where the Pod will be scheduled, we'll need to load the profile on all our -nodes. For this example we'll just use SSH to install the profiles, but other approaches are -discussed in [Setting up nodes with profiles](#setting-up-nodes-with-profiles). - - $ NODES=( - # The SSH-accessible domain names of your nodes - gke-test-default-pool-239f5d02-gyn2.us-central1-a.my-k8s - gke-test-default-pool-239f5d02-x1kf.us-central1-a.my-k8s - gke-test-default-pool-239f5d02-xwux.us-central1-a.my-k8s) - $ for NODE in ${NODES[*]}; do ssh $NODE 'sudo apparmor_parser -q < - - profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { - #include - - file, - - # Deny all file writes. - deny /** w, - } - EOF' - done - -Next, we'll run a simple "Hello AppArmor" pod with the deny-write profile: - -{% include code.html language="yaml" file="hello-apparmor-pod.yaml" ghlink="/docs/admin/apparmor/hello-apparmor-pod.yaml" %} - - $ kubectl create -f /dev/stdin < - Status: Failed - Reason: AppArmor - Message: Pod Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded - IP: - Controllers: - Containers: - hello: - Image: busybox - Port: - Command: - sh - -c - echo 'Hello AppArmor!' && sleep 1h - Requests: - cpu: 100m - Environment Variables: - Volumes: - default-token-dnz7v: - Type: Secret (a volume populated by a Secret) - SecretName: default-token-dnz7v - QoS Tier: Burstable - Events: - FirstSeen LastSeen Count From SubobjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 23s 23s 1 {default-scheduler } Normal Scheduled Successfully assigned hello-apparmor-2 to e2e-test-stclair-minion-group-t1f5 - 23s 23s 1 {kubelet e2e-test-stclair-minion-group-t1f5} Warning AppArmor Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded - -Note the pod status is Failed, with a helpful error message: `Pod Cannot enforce AppArmor: profile -"k8s-apparmor-example-allow-write" is not loaded`. An event was also recorded with the same message. - -## Administration - -### Setting up nodes with profiles - -Kubernetes does not currently provide any native mechanisms for loading AppArmor profiles onto -nodes. There are lots of ways to setup the profiles though, such as: - -- Through a [DaemonSet](../daemons/) that runs a Pod on each node to - ensure the correct profiles are loaded. An example implementation can be found - [here](https://github.com/kubernetes/contrib/tree/master/apparmor/loader). -- At node initialization time, using your node initialization scripts (e.g. Salt, Ansible, etc.) or - image. -- By copying the profiles to each node and loading them through SSH, as demonstrated in the - [Example](#example). - -The scheduler is not aware of which profiles are loaded onto which node, so the full set of profiles -must be loaded onto every node. An alternative approach is to add a node label for each profile (or -class of profiles) on the node, and use a -[node selector](../../user-guide/node-selection/) to ensure the Pod is run on a -node with the required profile. - -### Restricting profiles with the PodSecurityPolicy - -If the PodSecurityPolicy extension is enabled, cluster-wide AppArmor restrictions can be applied. To -enable the PodSecurityPolicy, two flags must be set on the `apiserver`: - - --admission-control=PodSecurityPolicy[,others...] - --runtime-config=extensions/v1beta1/podsecuritypolicy[,others...] - -With the extension enabled, the AppArmor options can be specified as annotations on the PodSecurityPolicy: - - apparmor.security.beta.kubernetes.io/defaultProfileName: - apparmor.security.beta.kubernetes.io/allowedProfileNames: [,others...] - -The default profile name option specifies the profile to apply to containers by default when none is -specified. The allowed profile names option specifies a list of profiles that Pod containers are -allowed to be run with. If both options are provided, the default must be allowed. The profiles are -specified in the same format as on containers. See the [API Reference](#api-reference) for the full -specification. - -### Disabling AppArmor - -If you do not want AppArmor to be available on your cluster, it can be disabled by a command-line flag: - - --feature-gates=AppArmor=false - -When disabled, any Pod that includes an AppArmor profile will fail validation with a "Forbidden" -error. Note that by default docker always enables the "docker-default" profile on non-privileged -pods (if the AppArmor kernel module is enabled), and will continue to do so even if the feature-gate -is disabled. The option to disable AppArmor will be removed when AppArmor graduates to general -availability (GA). - -### Upgrading to Kubernetes v1.4 with AppArmor - -No action is required with respect to AppArmor to upgrade your cluster to v1.4. However, if any -existing pods had an AppArmor annotation, they will not go through validation (or PodSecurityPolicy -admission). If permissive profiles are loaded on the nodes, a malicious user could pre-apply a -permissive profile to escalate the pod privileges above the docker-default. If this is a concern, it -is recommended to scrub the cluster of any pods containing an annotation with -`apparmor.security.beta.kubernetes.io`. - -### Upgrade path to General Availability - -When AppArmor is ready to be graduated to general availability (GA), the options currently specified -through annotations will be converted to fields. Supporting all the upgrade and downgrade paths -through the transition is very nuanced, and will be explained in detail when the transition -occurs. We will commit to supporting both fields and annotations for at least 2 releases, and will -explicitly reject the annotations for at least 2 releases after that. - -## Authoring Profiles - -Getting AppArmor profiles specified correctly can be a tricky business. Fortunately there are some -tools to help with that: - -- `aa-genprof` and `aa-logprof` generate profile rules by monitoring an application's activity and - logs, and admitting the actions it takes. Further instructions are provided by the - [AppArmor documentation](http://wiki.apparmor.net/index.php/Profiling_with_tools). -- [bane](https://github.com/jfrazelle/bane) is an AppArmor profile generator for Docker that uses a - simplified profile language. - -It is recommended to run your application through Docker on a development workstation to generate -the profiles, but there is nothing preventing running the tools on the Kubernetes node where your -Pod is running. - -To debug problems with AppArmor, you can check the system logs to see what, specifically, was -denied. AppArmor logs verbose messages to `dmesg`, and errors can usually be found in the system -logs or through `journalctl`. More information is provided in -[AppArmor failures](http://wiki.apparmor.net/index.php/AppArmor_Failures). - -Additional resources: - -- [Quick guide to the AppArmor profile language](http://wiki.apparmor.net/index.php/QuickProfileLanguage) -- [AppArmor core policy reference](http://wiki.apparmor.net/index.php/ProfileLanguage) - -## API Reference - -**Pod Annotation**: - -Specifying the profile a container will run with: - -- **key**: `container.apparmor.security.beta.kubernetes.io/` - Where `` matches the name of a container in the Pod. - A separate profile can be specified for each container in the Pod. -- **value**: a profile reference, described below - -**Profile Reference**: - -- `runtime/default`: Refers to the default runtime profile. - - Equivalent to not specifying a profile (without a PodSecurityPolicy default), except it still - requires AppArmor to be enabled. - - For Docker, this resolves to the - [`docker-default`](https://docs.docker.com/engine/security/apparmor/) profile for non-privileged - containers, and unconfined (no profile) for privileged containers. -- `localhost/`: Refers to a profile loaded on the node (localhost) by name. - - The possible profile names are detailed in the - [core policy reference](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#Profile_names_and_attachment_specifications) - -Any other profile reference format is invalid. - -**PodSecurityPolicy Annotations** - -Specifying the default profile to apply to containers when none is provided: - -- **key**: `apparmor.security.beta.kubernetes.io/defaultProfileName` -- **value**: a profile reference, described above - -Specifying the list of profiles Pod containers is allowed to specify: - -- **key**: `apparmor.security.beta.kubernetes.io/allowedProfileNames` -- **value**: a comma-separated list of profile references (described above) - - Although an escaped comma is a legal character in a profile name, it cannot be explicitly - allowed here +[AppArmor](/docs/tutorials/clusters/apparmor/) diff --git a/docs/admin/audit.md b/docs/admin/audit.md index ec4f7b2e95..33a0f1f722 100644 --- a/docs/admin/audit.md +++ b/docs/admin/audit.md @@ -5,63 +5,6 @@ assignees: title: Audit in Kubernetes --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -Kubernetes Audit provides a security-relevant chronological set of records documenting -the sequence of activities that have affected system by individual users, administrators -or other components of the system. It allows cluster administrator to -answer the following questions: - - what happened? - - when did it happen? - - who initiated it? - - on what did it happen? - - where was it observed? - - from where was it initiated? - - to where was it going? - -NOTE: Currently, Kubernetes provides only basic audit capabilities, there is still a lot -of work going on to provide fully featured auditing capabilities (see [this issue](https://github.com/kubernetes/features/issues/22)). - -Kubernetes audit is part of [kube-apiserver](/docs/admin/kube-apiserver) logging all requests -coming to the server. Each audit log contains two entries: - -1. The request line containing: - - unique id allowing to match the response line (see 2) - - source ip of the request - - HTTP method being invoked - - original user invoking the operation - - impersonated user for the operation - - namespace of the request or - - URI as requested -2. The response line containing: - - the unique id from 1 - - response code - -Example output for user `admin` asking for a list of pods: - -``` -2016-09-07T13:03:57.400333046Z AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" ip="127.0.0.1" method="GET" user="admin" as="" namespace="default" uri="/api/v1/namespaces/default/pods" -2016-09-07T13:03:57.400710987Z AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" response="200" -``` - -NOTE: The audit capabilities are available *only* for the secured endpoint of the API server. - -## Configuration - -[Kube-apiserver](/docs/admin/kube-apiserver) provides following options which are responsible -for configuring where and how audit logs are handled: - -- `audit-log-path` - enables the audit log pointing to a file where the requests are being logged to. -- `audit-log-maxage` - specifies maximum number of days to retain old audit log files based on the timestamp encoded in their filename. -- `audit-log-maxbackup` - specifies maximum number of old audit log files to retain. -- `audit-log-maxsize` - specifies maximum size in megabytes of the audit log file before it gets rotated. Defaults to 100MB - -If an audit log file already exists, Kubernetes appends new audit logs to that file. -Otherwise, Kubernetes creates an audit log file at the location you specified in -`audit-log-path`. If the audit log file exceeds the size you specify in `audit-log-maxsize`, -Kubernetes will rename the current log file by appending the current timestamp on -the file name (before the file extension) and create a new audit log file. -Kubernetes may delete old log files when creating a new log file; you can configure -how many files are retained and how old they can be by specifying the `audit-log-maxbackup` -and `audit-log-maxage` options. +[Auditing](/docs/concepts/cluster-administration/audit/) diff --git a/docs/admin/authentication.md b/docs/admin/authentication.md index 7c59c955ac..63335e9d77 100644 --- a/docs/admin/authentication.md +++ b/docs/admin/authentication.md @@ -85,9 +85,9 @@ See [APPENDIX](#appendix) for how to generate a client cert. The API server reads bearer tokens from a file when given the `--token-auth-file=SOMEFILE` option on the command line. Currently, tokens last indefinitely, and the token list cannot be changed without restarting API server. -The token file format is implemented in `plugin/pkg/auth/authenticator/token/tokenfile/...` -and is a csv file with a minimum of 3 columns: token, user name, user uid, followed by -optional group names. Note, if you have more than one group the column must be double quoted e.g. +The token file is a csv file with a minimum of 3 columns: token, user name, user uid, +followed by optional group names. Note, if you have more than one group the column must be +double quoted e.g. ```conf token,user,uid,"group1,group2,group3" @@ -115,9 +115,9 @@ and the password cannot be changed without restarting API server. Note that basi authentication is currently supported for convenience while we finish making the more secure modes described above easier to use. -The basic auth file format is implemented in `plugin/pkg/auth/authenticator/password/passwordfile/...` -and is a csv file with a minimum of 3 columns: password, user name, user id, followed by -optional group names. Note, if you have more than one group the column must be double quoted e.g. +The basic auth file is a csv file with a minimum of 3 columns: password, +user name, user id, followed by optional group names. Note, if you have more than +one group the column must be double quoted e.g. ```conf password,user,uid,"group1,group2,group3" @@ -541,8 +541,8 @@ Finally, add the following parameters into API server start parameters: 1. Generate server certificate and key. (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`, and `pki/private/kubernetes-master.key` to your directory. + ./easyrsa --subject-alt-name="IP:${MASTER_IP}" build-server-full server nopass +1. Copy `pki/ca.crt`, `pki/issued/server.crt`, and `pki/private/server.key` to your directory. 1. Fill in and add the following parameters into the API server start parameters: --client-ca-file=/yourdirectory/ca.crt diff --git a/docs/admin/authorization.md b/docs/admin/authorization.md index d398bba2c8..2c3e29338b 100644 --- a/docs/admin/authorization.md +++ b/docs/admin/authorization.md @@ -87,15 +87,25 @@ 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. - `group`, type string; if you specify `group`, it must match one of the groups of the authenticated user. `system:authenticated` matches all authenticated requests. `system:unauthenticated` matches all unauthenticated 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. + - `apiGroup`, type string; an API group. + - Ex: `extensions` + - Wildard: `*` matches all API groups. + - `namespace`, type string; a namespace. + - Ex: `kube-system` + - Wildard: `*` matches all resource requests. + - `resource`, type string; a resource type + - Ex: `pods` + - Wildcard: `*` 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. + - `nonResourcePath`, type string; non-resource request paths. + - Ex: `/version` or `/apis` + - Wildcard: + - `*` matches all non-resource requests. + - `/foo/*` matches `/foo/` and all of its subpaths. + - `readonly`, type boolean, when true, means that the policy only applies to get, list, and watch operations. -An unset property is the same as a property set to the zero value for its type +**NOTES:** 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. @@ -221,20 +231,20 @@ don't already have even when the RBAC authorizer it disabled__. If "user-1" does not have the ability to read secrets in "namespace-a", they cannot create a binding that would grant that permission to themselves or any other user. -For bootstrapping the first roles, it becomes necessary for someone to get -around these limitations. For the alpha release of RBAC, an API Server flag was -added to allow one user to step around all RBAC authorization and privilege -escalation checks. NOTE: _This is subject to change with future releases._ +When bootstrapping, superuser credentials should include the `system:masters` +group, for example by creating a client cert with `/O=system:masters`. This +gives those credentials full access to the API and allows an admin to then set +up bindings for other users. + +In Kubernetes versions 1.4 and 1.5, there was a similar flag that gave a user +full access: ``` --authorization-rbac-super-user=admin ``` -Once set the specified super user, in this case "admin", can be used to create -the roles and role bindings to initialize the system. - -This flag is optional and once the initial bootstrapping is performed can be -unset. +__This flag will be removed in 1.6__. Admins should prefer the `system:masters` +group when setting up clusters. ### Roles, RolesBindings, ClusterRoles, and ClusterRoleBindings @@ -445,6 +455,7 @@ subjects: ``` For all authenticated users: + ```yaml subjects: - kind: Group @@ -452,6 +463,7 @@ subjects: ``` For all unauthenticated users: + ```yaml subjects: - kind: Group @@ -459,6 +471,7 @@ subjects: ``` For all users: + ```yaml subjects: - kind: Group diff --git a/docs/admin/cluster-components.md b/docs/admin/cluster-components.md index a3d4f37779..49154b1750 100644 --- a/docs/admin/cluster-components.md +++ b/docs/admin/cluster-components.md @@ -4,133 +4,6 @@ assignees: title: Kubernetes Components --- -This document outlines the various binary components that need to run to -deliver a functioning Kubernetes cluster. +{% include user-guide-content-moved.md %} -## Master Components - -Master components are those that provide the cluster's control plane. For -example, master components are responsible for making global decisions about the -cluster (e.g., scheduling), and detecting and responding to cluster events -(e.g., starting up a new pod when a replication controller's 'replicas' field is -unsatisfied). - -Master components could in theory be run on any node in the cluster. However, -for simplicity, current set up scripts typically start all master components on -the same VM, and does not run user containers on this VM. See -[high-availability.md](/docs/admin/high-availability) for an example multi-master-VM setup. - -Even in the future, when Kubernetes is fully self-hosting, it will probably be -wise to only allow master components to schedule on a subset of nodes, to limit -co-running with user-run pods, reducing the possible scope of a -node-compromising security exploit. - -### kube-apiserver - -[kube-apiserver](/docs/admin/kube-apiserver) exposes the Kubernetes API; it is the front-end for the -Kubernetes control plane. It is designed to scale horizontally (i.e., one scales -it by running more of them-- [high-availability.md](/docs/admin/high-availability)). - -### etcd - -[etcd](/docs/admin/etcd) is used as Kubernetes' backing store. All cluster data is stored here. -Proper administration of a Kubernetes cluster includes a backup plan for etcd's -data. - -### kube-controller-manager - -[kube-controller-manager](/docs/admin/kube-controller-manager) is a binary that runs controllers, which are the -background threads that handle routine tasks in the cluster. Logically, each -controller is a separate process, but to reduce the number of moving pieces in -the system, they are all compiled into a single binary and run in a single -process. - -These controllers include: - -* Node Controller: Responsible for noticing & responding when nodes go down. -* Replication Controller: Responsible for maintaining the correct number of pods for every replication - controller object in the system. -* Endpoints Controller: Populates the Endpoints object (i.e., join Services & Pods). -* Service Account & Token Controllers: Create default accounts and API access tokens for new namespaces. -* ... and others. - -### kube-scheduler - -[kube-scheduler](/docs/admin/kube-scheduler) watches newly created pods that have no node assigned, and -selects a node for them to run on. - -### addons - -Addons are pods and services that implement cluster features. The pods may be managed -by Deployments, ReplicationContollers, etc. Namespaced addon objects are created in -the "kube-system" namespace. - -Addon manager takes the responsibility for creating and maintaining addon resources. -See [here](http://releases.k8s.io/HEAD/cluster/addons) for more details. - -#### DNS - -While the other addons are not strictly required, all Kubernetes -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. - -Containers started by Kubernetes automatically include this DNS server -in their DNS searches. - -#### User interface - -The kube-ui provides a read-only overview of the cluster state. Access -[the UI using kubectl proxy](/docs/user-guide/connecting-to-applications-proxy/#connecting-to-the-kube-ui-service-from-your-local-workstation) - -#### Container Resource Monitoring - -[Container Resource Monitoring](/docs/user-guide/monitoring) records generic time-series metrics -about containers in a central database, and provides a UI for browsing that data. - -#### Cluster-level Logging - -A [Cluster-level logging](/docs/user-guide/logging/overview) mechanism is responsible for -saving container logs to a central log store with search/browsing interface. - -## Node components - -Node components run on every node, maintaining running pods and providing them -the Kubernetes runtime environment. - -### kubelet - -[kubelet](/docs/admin/kubelet) is the primary node agent. It: - -* Watches for pods that have been assigned to its node (either by apiserver - or via local configuration file) and: -* Mounts the pod's required volumes -* Downloads the pod's secrets -* Runs the pod's containers via docker (or, experimentally, rkt). -* Periodically executes any requested container liveness probes. -* Reports the status of the pod back to the rest of the system, by creating a - "mirror pod" if necessary. -* Reports the status of the node back to the rest of the system. - -### kube-proxy - -[kube-proxy](/docs/admin/kube-proxy) enables the Kubernetes service abstraction by maintaining -network rules on the host and performing connection forwarding. - -### docker - -`docker` is of course used for actually running containers. - -### rkt - -`rkt` is supported experimentally as an alternative to docker. - -### supervisord - -`supervisord` is a lightweight process babysitting system for keeping kubelet and docker -running. - -### fluentd - -`fluentd` is a daemon which helps provide [cluster-level logging](#cluster-level-logging). +[Kubernetes Components](/docs/concepts/overview/components/) diff --git a/docs/admin/cluster-management.md b/docs/admin/cluster-management.md index 310128fd77..ebe5687f2e 100644 --- a/docs/admin/cluster-management.md +++ b/docs/admin/cluster-management.md @@ -19,7 +19,9 @@ To install Kubernetes on a set of machines, consult one of the existing [Getting ## Upgrading a cluster -The current state of cluster upgrades is provider dependent. +The current state of cluster upgrades is provider dependent, and some releases may require special care when upgrading. It is recommended that administrators consult both the [release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md), as well as the version specific upgrade notes prior to upgrading their clusters. + +* [Upgrading to 1.6](/docs/admin/upgrade) ### Upgrading Google Compute Engine clusters @@ -56,8 +58,12 @@ The node upgrade process is user-initiated and is described in the [GKE document ### Upgrading clusters on other platforms -The `cluster/kube-push.sh` script will do a rudimentary update. This process is still quite experimental, we -recommend testing the upgrade on an experimental cluster before performing the update on a production cluster. +Different providers, and tools, will manage upgrades differently. It is recommended that you consult their main documentation regarding upgrades. + +* [kops](https://github.com/kubernetes/kops) +* [kargo](https://github.com/kubernetes-incubator/kargo) +* [CoreOS Tectonic](https://coreos.com/tectonic/docs/latest/admin/upgrade.html) +* ... ## Resizing a cluster @@ -92,7 +98,7 @@ an extended period of time (10min but it may change in the future). Cluster autoscaler is configured per instance group (GCE) or node pool (GKE). If you are using GCE then you can either enable it while creating a cluster with kube-up.sh script. -To configure cluster autoscaler you have to set 3 environment variables: +To configure cluster autoscaler you have to set three environment variables: * `KUBE_ENABLE_CLUSTER_AUTOSCALER` - it enables cluster autoscaler if set to true. * `KUBE_AUTOSCALER_MIN_NODES` - minimum number of nodes in the cluster. diff --git a/docs/admin/disruptions.md b/docs/admin/disruptions.md index 6c4ee7df4a..d5ec02f8d5 100644 --- a/docs/admin/disruptions.md +++ b/docs/admin/disruptions.md @@ -3,93 +3,7 @@ assignees: - davidopp title: Pod Disruption Budget --- -This guide is for anyone wishing to specify safety constraints on pods or anyone -wishing to write software (typically automation software) that respects those -constraints. -* TOC -{:toc} +{% include user-guide-content-moved.md %} -## Rationale - -Various cluster management operations may voluntarily evict pods. "Voluntary" -means an eviction can be safely delayed for a reasonable period of time. The -principal examples today are draining a node for maintenance or upgrade -(`kubectl drain`), and cluster autoscaling down. In the future the -[rescheduler](https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/rescheduling.md) -may also perform voluntary evictions. By contrast, something like evicting pods -because a node has become unreachable or reports `NotReady`, is not "voluntary." - -For voluntary evictions, it can be useful for applications to be able to limit -the number of pods that are down simultaneously. For example, a quorum-based application would -like to ensure that the number of replicas running is never brought below the -number needed for a quorum, even temporarily. Or a web front end might want to -ensure that the number of replicas serving load never falls below a certain -percentage of the total, even briefly. `PodDisruptionBudget` is an API object -that specifies the minimum number or percentage of replicas of a collection that -must be up at a time. Components that wish to evict a pod subject to disruption -budget use the `/eviction` subresource; unlike a regular pod deletion, this -operation may be rejected by the API server if the eviction would cause a -disruption budget to be violated. - -## Specifying a PodDisruptionBudget - -A `PodDisruptionBudget` has two components: a label selector `selector` to specify the set of -pods to which it applies, and `minAvailable` which is a description of the number of pods from that -set that must still be available after the eviction, i.e. even in the absence -of the evicted pod. `minAvailable` can be either an absolute number or a percentage. -So for example, 100% means no voluntary evictions from the set are permitted. In -typical usage, a single budget would be used for a collection of pods managed by -a controller—for example, the pods in a single ReplicaSet. - -Note that a disruption budget does not truly guarantee that the specified -number/percentage of pods will always be up. For example, a node that hosts a -pod from the collection may fail when the collection is at the minimum size -specified in the budget, thus bringing the number of available pods from the -collection below the specified size. The budget can only protect against -voluntary evictions, not all causes of unavailability. - -## Requesting an eviction - -If you are writing infrastructure software that wants to produce these voluntary -evictions, you will need to use the eviction API. The eviction subresource of a -pod can be thought of as a kind of policy-controlled DELETE operation on the pod -itself. To attempt an eviction (perhaps more REST-precisely, to attempt to -*create* an eviction), you POST an attempted operation. Here's an example: - -```json -{ - "apiVersion": "policy/v1beta1", - "kind": "Eviction", - "metadata": { - "name": "quux", - "namespace": "default" - } -} -``` - -You can attempt an eviction using `curl`: - -```bash -$ curl -v -H 'Content-type: application/json' http://127.0.0.1:8080/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json -``` - -The API can respond in one of three ways. - - 1. If the eviction is granted, then the pod is deleted just as if you had sent - a `DELETE` request to the pod's URL and you get back `200 OK`. - 2. If the current state of affairs wouldn't allow an eviction by the rules set - forth in the budget, you get back `429 Too Many Requests`. This is - typically used for generic rate limiting of *any* requests, but here we mean - that this request isn't allowed *right now* but it may be allowed later. - Currently, callers do not get any `Retry-After` advice, but they may in - future versions. - 3. If there is some kind of misconfiguration, like multiple budgets pointing at - the same pod, you will get `500 Internal Server Error`. - -For a given eviction request, there are two cases. - - 1. There is no budget that matches this pod. In this case, the server always - returns `200 OK`. - 2. There is at least one budget. In this case, any of the three above responses may - apply. +[Configuring a Pod Disruption Budget](/docs/tasks/configure-pod-container/configure-pod-disruption-budget/) diff --git a/docs/admin/dns.md b/docs/admin/dns.md index 7a845c9f3f..84e97ce2bc 100644 --- a/docs/admin/dns.md +++ b/docs/admin/dns.md @@ -5,385 +5,6 @@ assignees: title: Using DNS Pods and Services --- -## Introduction +{% include user-guide-content-moved.md %} -As of Kubernetes 1.3, DNS is a built-in service launched automatically using the addon manager [cluster add-on](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/README.md). - -Kubernetes DNS schedules a DNS Pod and Service on the cluster, and configures -the kubelets to tell individual containers to use the DNS Service's IP to -resolve DNS names. - -## What things get DNS names? - -Every Service defined in the cluster (including the DNS server itself) is -assigned a DNS name. By default, a client Pod's DNS search list will -include the Pod's own namespace and the cluster's default domain. This is best -illustrated by example: - -Assume a Service named `foo` in the Kubernetes namespace `bar`. A Pod running -in namespace `bar` can look up this service by simply doing a DNS query for -`foo`. A Pod running in namespace `quux` can look up this service by doing a -DNS query for `foo.bar`. - -## Supported DNS schema - -The following sections detail the supported record types and layout that is -supported. Any other layout or names or queries that happen to work are -considered implementation details and are subject to change without warning. - -### Services - -#### A records - -"Normal" (not headless) Services are assigned a DNS A record for a name of the -form `my-svc.my-namespace.svc.cluster.local`. This resolves to the cluster IP -of the Service. - -"Headless" (without a cluster IP) Services are also assigned a DNS A record for -a name of the form `my-svc.my-namespace.svc.cluster.local`. Unlike normal -Services, this resolves to the set of IPs of the pods selected by the Service. -Clients are expected to consume the set or else use standard round-robin -selection from the set. - -### SRV records - -SRV Records are created for named ports that are part of normal or [Headless -Services](http://releases.k8s.io/docs/user-guide/services/#headless-services). -For each named port, the SRV record would have the form -`_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local`. -For a regular service, this resolves to the port number and the CNAME: -`my-svc.my-namespace.svc.cluster.local`. -For a headless service, this resolves to multiple answers, one for each pod -that is backing the service, and contains the port number and a CNAME of the pod -of the form `auto-generated-name.my-svc.my-namespace.svc.cluster.local`. - -### Backwards compatibility - -Previous versions of kube-dns made names of the form -`my-svc.my-namespace.cluster.local` (the 'svc' level was added later). This -is no longer supported. - -### Pods - -#### A Records - -When enabled, pods are assigned a DNS A record in the form of `pod-ip-address.my-namespace.pod.cluster.local`. - -For example, a pod with IP `1.2.3.4` in the namespace `default` with a DNS name of `cluster.local` would have an entry: `1-2-3-4.default.pod.cluster.local`. - -#### A Records and hostname based on Pod's hostname and subdomain fields - -Currently when a pod is created, its hostname is the Pod's `metadata.name` value. - -With v1.2, users can specify a Pod annotation, `pod.beta.kubernetes.io/hostname`, to specify what the Pod's hostname should be. -The Pod annotation, if specified, takes precedence over the Pod's name, to be the hostname of the pod. -For example, given a Pod with annotation `pod.beta.kubernetes.io/hostname: my-pod-name`, the Pod will have its hostname set to "my-pod-name". - -With v1.3, the PodSpec has a `hostname` field, which can be used to specify the Pod's hostname. This field value takes precedence over the -`pod.beta.kubernetes.io/hostname` annotation value. - -v1.2 introduces a beta feature where the user can specify a Pod annotation, `pod.beta.kubernetes.io/subdomain`, to specify the Pod's subdomain. -The final domain will be "...svc.". -For example, a Pod with the hostname annotation set to "foo", and the subdomain annotation set to "bar", in namespace "my-namespace", will have the FQDN "foo.bar.my-namespace.svc.cluster.local" - -With v1.3, the PodSpec has a `subdomain` field, which can be used to specify the Pod's subdomain. This field value takes precedence over the -`pod.beta.kubernetes.io/subdomain` annotation value. - -Example: - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: default-subdomain -spec: - selector: - name: busybox - clusterIP: None - ports: - - name: foo # Actually, no port is needed. - port: 1234 - targetPort: 1234 ---- -apiVersion: v1 -kind: Pod -metadata: - name: busybox1 - labels: - name: busybox -spec: - hostname: busybox-1 - subdomain: default-subdomain - containers: - - image: busybox - command: - - sleep - - "3600" - name: busybox ---- -apiVersion: v1 -kind: Pod -metadata: - name: busybox2 - labels: - name: busybox -spec: - hostname: busybox-2 - subdomain: default-subdomain - containers: - - image: busybox - command: - - sleep - - "3600" - name: busybox -``` - -If there exists a headless service in the same namespace as the pod and with the same name as the subdomain, the cluster's KubeDNS Server also returns an A record for the Pod's fully qualified hostname. -Given a Pod with the hostname set to "busybox-1" and the subdomain set to "default-subdomain", and a headless Service named "default-subdomain" in the same namespace, the pod will see it's own FQDN as "busybox-1.default-subdomain.my-namespace.svc.cluster.local". DNS serves an A record at that name, pointing to the Pod's IP. Both pods "busybox1" and "busybox2" can have their distinct A records. - -As of Kubernetes v1.2, the Endpoints object also has the annotation `endpoints.beta.kubernetes.io/hostnames-map`. Its value is the json representation of map[string(IP)][endpoints.HostRecord], for example: '{"10.245.1.6":{HostName: "my-webserver"}}'. -If the Endpoints are for a headless service, an A record is created with the format ...svc. -For the example json, if endpoints are for a headless service named "bar", and one of the endpoints has IP "10.245.1.6", an A record is created with the name "my-webserver.bar.my-namespace.svc.cluster.local" and the A record lookup would return "10.245.1.6". -This endpoints annotation generally does not need to be specified by end-users, but can used by the internal service controller to deliver the aforementioned feature. - -With v1.3, The Endpoints object can specify the `hostname` for any endpoint, along with its IP. The hostname field takes precedence over the hostname value -that might have been specified via the `endpoints.beta.kubernetes.io/hostnames-map` annotation. - -With v1.3, the following annotations are deprecated: `pod.beta.kubernetes.io/hostname`, `pod.beta.kubernetes.io/subdomain`, `endpoints.beta.kubernetes.io/hostnames-map` - -## How do I test if it is working? - -### Create a simple Pod to use as a test environment - -Create a file named busybox.yaml with the -following contents: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: busybox - namespace: default -spec: - containers: - - image: busybox - command: - - sleep - - "3600" - imagePullPolicy: IfNotPresent - name: busybox - restartPolicy: Always -``` - -Then create a pod using this file: - -``` -kubectl create -f busybox.yaml -``` - -### Wait for this pod to go into the running state - -You can get its status with: -``` -kubectl get pods busybox -``` - -You should see: - -``` -NAME READY STATUS RESTARTS AGE -busybox 1/1 Running 0 -``` - -### Validate that DNS is working - -Once that pod is running, you can exec nslookup in that environment: - -``` -kubectl exec -ti busybox -- nslookup kubernetes.default -``` - -You should see something like: - -``` -Server: 10.0.0.10 -Address 1: 10.0.0.10 - -Name: kubernetes.default -Address 1: 10.0.0.1 -``` - -If you see that, DNS is working correctly. - -### Troubleshooting Tips - -If the nslookup command fails, check the following: - -#### Check the local DNS configuration first -Take a look inside the resolv.conf file. (See "Inheriting DNS from the node" and "Known issues" below for more information) - -``` -kubectl exec busybox cat /etc/resolv.conf -``` - -Verify that the search path and name server are set up like the following (note that search path may vary for different cloud providers): - -``` -search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal -nameserver 10.0.0.10 -options ndots:5 -``` - -#### Quick diagnosis - -Errors such as the following indicate a problem with the kube-dns add-on or associated Services: - -``` -$ kubectl exec -ti busybox -- nslookup kubernetes.default -Server: 10.0.0.10 -Address 1: 10.0.0.10 - -nslookup: can't resolve 'kubernetes.default' -``` - -or - -``` -$ kubectl exec -ti busybox -- nslookup kubernetes.default -Server: 10.0.0.10 -Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local - -nslookup: can't resolve 'kubernetes.default' -``` - -#### Check if the DNS pod is running - -Use the kubectl get pods command to verify that the DNS pod is running. - -``` -kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -``` - -You should see something like: - -``` -NAME READY STATUS RESTARTS AGE -... -kube-dns-v19-ezo1y 3/3 Running 0 1h -... -``` - -If you see that no pod is running or that the pod has failed/completed, the DNS add-on may not be deployed by default in your current environment and you will have to deploy it manually. - -#### Check for Errors in the DNS pod - -Use `kubectl logs` command to see logs for the DNS daemons. - -``` -kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns -kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq -kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c healthz -``` - -See if there is any suspicious log. W, E, F letter at the beginning represent Warning, Error and Failure. Please search for entries that have these as the logging level and use [kubernetes issues](https://github.com/kubernetes/kubernetes/issues) to report unexpected errors. - -#### Is DNS service up? - -Verify that the DNS service is up by using the `kubectl get service` command. - -``` -kubectl get svc --namespace=kube-system -``` - -You should see: - -``` -NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE -... -kube-dns 10.0.0.10 53/UDP,53/TCP 1h -... -``` - -If you have created the service or in the case it should be created by default but it does not appear, see this [debugging services page](http://kubernetes.io/docs/user-guide/debugging-services/) for more information. - -#### Are DNS endpoints exposed? - -You can verify that DNS endpoints are exposed by using the `kubectl get endpoints` command. - -``` -kubectl get ep kube-dns --namespace=kube-system -``` - -You should see something like: -``` -NAME ENDPOINTS AGE -kube-dns 10.180.3.17:53,10.180.3.17:53 1h -``` - -If you do not see the endpoints, see endpoints section in the [debugging services documentation](http://kubernetes.io/docs/user-guide/debugging-services/). - -For additional Kubernetes DNS examples, see the [cluster-dns examples](https://github.com/kubernetes/kubernetes/tree/master/examples/cluster-dns) in the Kubernetes GitHub repository. - -## Kubernetes Federation (Multiple Zone support) - -Release 1.3 introduced Cluster Federation support for multi-site -Kubernetes installations. This required some minor -(backward-compatible) changes to the way -the Kubernetes cluster DNS server processes DNS queries, to facilitate -the lookup of federated services (which span multiple Kubernetes clusters). -See the [Cluster Federation Administrators' Guide](/docs/admin/federation) for more -details on Cluster Federation and multi-site support. - -## How it Works - -The running Kubernetes DNS pod holds 3 containers - kubedns, dnsmasq and a health check called healthz. -The kubedns process watches the Kubernetes master for changes in Services and Endpoints, and maintains -in-memory lookup structures to service DNS requests. The dnsmasq container adds DNS caching to improve -performance. The healthz container provides a single health check endpoint while performing dual healthchecks -(for dnsmasq and kubedns). - -The DNS pod is exposed as a Kubernetes Service with a static IP. Once assigned the -kubelet passes DNS configured using the `--cluster-dns=10.0.0.10` flag to each -container. - -DNS names also need domains. The local domain is configurable, in the kubelet using -the flag `--cluster-domain=` - -The Kubernetes cluster DNS server (based off the [SkyDNS](https://github.com/skynetservices/skydns) library) -supports forward lookups (A records), service lookups (SRV records) and reverse IP address lookups (PTR records). - -## Inheriting DNS from the node -When running a pod, kubelet will prepend the cluster DNS server and search -paths to the node's own DNS settings. If the node is able to resolve DNS names -specific to the larger environment, pods should be able to, also. See "Known -issues" below for a caveat. - -If you don't want this, or if you want a different DNS config for pods, you can -use the kubelet's `--resolv-conf` flag. Setting it to "" means that pods will -not inherit DNS. Setting it to a valid file path means that kubelet will use -this file instead of `/etc/resolv.conf` for DNS inheritance. - -## Known issues -Kubernetes installs do not configure the nodes' resolv.conf files to use the -cluster DNS by default, because that process is inherently distro-specific. -This should probably be implemented eventually. - -Linux's libc is impossibly stuck ([see this bug from -2005](https://bugzilla.redhat.com/show_bug.cgi?id=168253)) with limits of just -3 DNS `nameserver` records and 6 DNS `search` records. Kubernetes needs to -consume 1 `nameserver` record and 3 `search` records. This means that if a -local installation already uses 3 `nameserver`s or uses more than 3 `search`es, -some of those settings will be lost. As a partial workaround, the node can run -`dnsmasq` which will provide more `nameserver` entries, but not more `search` -entries. You can also use kubelet's `--resolv-conf` flag. - -If you are using Alpine version 3.3 or earlier as your base image, DNS may not -work properly owing to a known issue with Alpine. Check [here](https://github.com/kubernetes/kubernetes/issues/30215) -for more information. - -## References - -- [Docs for the DNS cluster addon](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md) - -## What's next -- [Autoscaling the DNS Service in a Cluster](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/). +[DNS Pods and Services](/docs/concepts/services-networking/dns-pod-service/) diff --git a/docs/admin/etcd.md b/docs/admin/etcd.md index 41a3e35ddb..06b0eda07c 100644 --- a/docs/admin/etcd.md +++ b/docs/admin/etcd.md @@ -20,7 +20,7 @@ Data Reliability: for reasonable safety, either etcd needs to be run as a etcd) or etcd's data directory should be located on durable storage (e.g., GCE's persistent disk). In either case, if high availability is required--as it might be in a production cluster--the data directory ought to be [backed up -periodically](https://coreos.com/etcd/docs/2.2.1/admin_guide.html#disaster-recovery), +periodically](https://coreos.com/etcd/docs/latest/op-guide/recovery.html), to reduce downtime in case of corruption. ## Default configuration diff --git a/docs/admin/federation-controller-manager.md b/docs/admin/federation-controller-manager.md index d3dca5bf06..caa001e4c8 100644 --- a/docs/admin/federation-controller-manager.md +++ b/docs/admin/federation-controller-manager.md @@ -1,5 +1,5 @@ --- -title: federation-controller-mananger +title: federation-controller-manager notitle: true --- diff --git a/docs/admin/federation/kubefed.md b/docs/admin/federation/kubefed.md index 9685271b85..7b1b8f499a 100644 --- a/docs/admin/federation/kubefed.md +++ b/docs/admin/federation/kubefed.md @@ -4,205 +4,6 @@ assignees: title: Setting up Cluster Federation with Kubefed --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -Kubernetes version 1.5 includes a new command line tool called -`kubefed` to help you administrate your federated clusters. -`kubefed` helps you to deploy a new Kubernetes cluster federation -control plane, and to add clusters to or remove clusters from an -existing federation control plane. - -This guide explains how to administer a Kubernetes Cluster Federation -using `kubefed`. - -> Note: `kubefed` is an alpha feature in Kubernetes 1.5. - -## Prerequisites - -This guide assumes that you have a running Kubernetes cluster. Please -see one of the [getting started](/docs/getting-started-guides/) guides -for installation instructions for your platform. - - -## Getting `kubefed` - -Download the client tarball corresponding to Kubernetes version 1.5 -or later -[from the release page](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md), -extract the binaries in the tarball to one of the directories -in your `$PATH` and set the executable permission on those binaries. - -Note: The URL in the curl command below downloads the binaries for -Linux amd64. If you are on a different platform, please use the URL -for the binaries appropriate for your platform. You can find the list -of available binaries on the [release page](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md#client-binaries-3) - - -```shell -curl -O https://storage.googleapis.com/kubernetes-release/release/v1.5.0/kubernetes-client-linux-amd64.tar.gz -tar -xzvf kubernetes-client-linux-amd64.tar.gz -sudo cp kubernetes/client/bin/kubefed /usr/local/bin -sudo chmod +x /usr/local/bin/kubefed -sudo cp kubernetes/client/bin/kubectl /usr/local/bin -sudo chmod +x /usr/local/bin/kubectl -``` - - -## Choosing a host cluster. - -You'll need to choose one of your Kubernetes clusters to be the -*host cluster*. The host cluster hosts the components that make up -your federation control plane. Ensure that you have a `kubeconfig` -entry in your local `kubeconfig` that corresponds to the host cluster. -You can verify that you have the required `kubeconfig` entry by -running: - -```shell -kubectl config get-contexts -``` - -The output should contain an entry corresponding to your host cluster, -similar to the following: - -``` -CURRENT NAME CLUSTER AUTHINFO NAMESPACE - gke_myproject_asia-east1-b_gce-asia-east1 gke_myproject_asia-east1-b_gce-asia-east1 gke_myproject_asia-east1-b_gce-asia-east1 -``` - - -You'll need to provide the `kubeconfig` context (called name in the -entry above) for your host cluster when you deploy your federation -control plane. - - -## Deploying a federation control plane. - -"To deploy a federation control plane on your host cluster, run -`kubefed init` command. When you use `kubefed init`, you must provide -the following: - -* Federation name -* `--host-cluster-context`, the `kubeconfig` context for the host cluster -* `--dns-zone-name`, a domain name suffix for your federated services - -The following example command deploys a federation control plane with -the name `fellowship`, a host cluster context `rivendell`, and the -domain suffix `example.com`: - -```shell -kubefed init fellowship --host-cluster-context=rivendell --dns-zone-name="example.com" -``` - -The domain suffix you specify in `--dns-zone-name` must be an existing -domain that you control, and that is programmable by your DNS provider. - -`kubefed init` sets up the federation control plane in the host -cluster and also adds an entry for the federation API server in your -local kubeconfig. Note that in the alpha release in Kubernetes 1.5, -`kubefed init` does not automatically set the current context to the -newly deployed federation. You can set the current context manually by -running: - -```shell -kubectl config use-context fellowship -``` - -where `fellowship` is the name of your federation. - - -## Adding a cluster to a federation - -Once you've deployed a federation control plane, you'll need to make -that control plane aware of the clusters it should manage. You can add -a cluster to your federation by using the `kubefed join` command. - -To use `kubefed join`, you'll need to provide the name of the cluster -you want to add to the federation, and the `--host-cluster-context` -for the federation control plane's host cluster. - -The following example command adds the cluster `gondor` to the -federation with host cluster `rivendell`: - -``` -kubefed join gondor --host-cluster-context=rivendell -``` - -> Note: Kubernetes requires that you manually join clusters to a -federation because the federation control plane manages only those -clusters that it is responsible for managing. Adding a cluster tells -the federation control plane that it is responsible for managing that -cluster. - -### Naming rules and customization - -The cluster name you supply to `kubefed join` must be a valid RFC 1035 -label. - -Furthermore, federation control plane requires credentials of the -joined clusters to operate on them. These credentials are obtained -from the local kubeconfig. `kubefed join` uses the cluster name -specified as the argument to look for the cluster's context in the -local kubeconfig. If it fails to find a matching context, it exits -with an error. - -This might cause issues in cases where context names for each cluster -in the federation don't follow -[RFC 1035](https://www.ietf.org/rfc/rfc1035.txt) label naming rules. -In such cases, you can specify a cluster name that conforms to the -[RFC 1035](https://www.ietf.org/rfc/rfc1035.txt) label naming rules -and specify the cluster context using the `--cluster-context` flag. -For example, if context of the cluster your are joining is -`gondor_needs-no_king`, then you can join the cluster by running: - -```shell -kubefed join gondor --host-cluster-context=rivendell --cluster-context=gondor_needs-no_king -``` - -#### Secret name - -Cluster credentials required by the federation control plane as -described above are stored as a secret in the host cluster. The name -of the secret is also derived from the cluster name. - -However, the name of a secret object in Kubernetes should conform -to the DNS subdomain name specification described in -[RFC 1123](https://tools.ietf.org/html/rfc1123). If this isn't the -case, you can pass the secret name to `kubefed join` using the -`--secret-name` flag. For example, if the cluster name is `noldor` and -the secret name is `11kingdom`, you can join the cluster by -running: - -```shell -kubefed join noldor --host-cluster-context=rivendell --secret-name=11kingdom -``` - -Note: If your cluster name does not conform to the DNS subdomain name -specification, all you need to do is supply the secret name via the -`--secret-name` flag. `kubefed join` automatically creates the secret -for you. - - -## Removing a cluster from a federation - -To remove a cluster from a federation, run the `kubefed unjoin` -command with the cluster name and the federation's -`--host-cluster-context`: - -``` -kubefed unjoin gondor --host-cluster-context=rivendell -``` - - -## Turning down the federation control plane: - -Proper cleanup of federation control plane is not fully implemented in -this alpha release of `kubefed`. However, for the time being, deleting -the federation system namespace should remove all the resources except -the persistent storage volume dynamically provisioned for the -federation control plane's etcd. You can delete the federation -namespace by running the following command: - -``` -$ kubectl delete ns federation-system -``` +[Setting up Cluster Federation with kubefed](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) diff --git a/docs/admin/garbage-collection.md b/docs/admin/garbage-collection.md index a960172426..ad7eabad9d 100644 --- a/docs/admin/garbage-collection.md +++ b/docs/admin/garbage-collection.md @@ -23,10 +23,10 @@ threshold has been met. ### Container Collection -The policy for garbage collecting containers considers three user-defined variables. `MinAge` is the minimum age at which a container can be garbage collected. `MaxPerPodContainer` is the maximum number of dead containers any single -pod (UID, container name) pair is allowed to have. `MaxContainers` is the maximum number of total dead containers. These variables can be individually disabled by setting 'MinAge' to zero and setting 'MaxPerPodContainer' and 'MaxContainers' respectively to less than zero. +The policy for garbage collecting containers considers three user-defined variables. `MinAge` is the minimum age at which a container can be garbage collected. `MaxPerPodContainer` is the maximum number of dead containers every single +pod (UID, container name) pair is allowed to have. `MaxContainers` is the maximum number of total dead containers. These variables can be individually disabled by setting `MinAge` to zero and setting `MaxPerPodContainer` and `MaxContainers` respectively to less than zero. -Kubelet will act on containers that are unidentified, deleted, or outside of the boundaries set by the previously mentioned flags. The oldest containers will generally be removed first. 'MaxPerPodContainer' and 'MaxContainer' may potentially conflict with each other in situations where retaining the maximum number of containers per pod ('MaxPerPodContainer') would go outside the allowable range of global dead containers ('MaxContainers'). 'MaxPerPodContainer' would be adjusted in this situation: A worst case scenario would be to downgrade 'MaxPerPodContainer' to 1 and evict the oldest containers. Additionally, containers owned by pods that have been deleted are removed once they are older than `MinAge`. +Kubelet will act on containers that are unidentified, deleted, or outside of the boundaries set by the previously mentioned flags. The oldest containers will generally be removed first. `MaxPerPodContainer` and `MaxContainer` may potentially conflict with each other in situations where retaining the maximum number of containers per pod (`MaxPerPodContainer`) would go outside the allowable range of global dead containers (`MaxContainers`). `MaxPerPodContainer` would be adjusted in this situation: A worst case scenario would be to downgrade `MaxPerPodContainer` to 1 and evict the oldest containers. Additionally, containers owned by pods that have been deleted are removed once they are older than `MinAge`. Containers that are not managed by kubelet are not subject to container garbage collection. @@ -42,15 +42,34 @@ to free. Default is 80%. We also allow users to customize garbage collection policy through the following kubelet flags: 1. `minimum-container-ttl-duration`, minimum age for a finished container before it is -garbage collected. Default is 1 minute. -2. `maximum-dead-containers-per-container`, maximum number of old instances to retain -per container. Default is 2. +garbage collected. Default is 0 minute, which means every finished container will be garbaged collected. +2. `maximum-dead-containers-per-container`, maximum number of old instances to be retained +per container. Default is 1. 3. `maximum-dead-containers`, maximum number of old instances of containers to retain globally. -Default is 100. +Default is -1, which means there is no global limit. Containers can potentially be garbage collected before their usefulness has expired. These containers can contain logs and other data that can be useful for troubleshooting. A sufficiently large value for -`maximum-dead-containers-per-container` is highly recommended to allow at least 2 dead containers to be +`maximum-dead-containers-per-container` is highly recommended to allow at least 1 dead container to be retained per expected container. A higher value for `maximum-dead-containers` is also recommended for a similar reason. See [this issue](https://github.com/kubernetes/kubernetes/issues/13287) for more details. + + +### Deprecation + +Some kubelet Garbage Collection features in this doc will be replaced by kubelet eviction in the future. + +Including: + +| Existing Flag | New Flag | Rationale | +| ------------- | -------- | --------- | +| `--image-gc-high-threshold` | `--eviction-hard` or `--eviction-soft` | existing eviction signals can trigger image garbage collection | +| `--image-gc-low-threshold` | `--eviction-minimum-reclaim` | eviction reclaims achieve the same behavior | +| `--maximum-dead-containers` | | deprecated once old logs are stored outside of container's context | +| `--maximum-dead-containers-per-container` | | deprecated once old logs are stored outside of container's context | +| `--minimum-container-ttl-duration` | | deprecated once old logs are stored outside of container's context | +| `--low-diskspace-threshold-mb` | `--eviction-hard` or `eviction-soft` | eviction generalizes disk thresholds to other resources | +| `--outofdisk-transition-frequency` | `--eviction-pressure-transition-period` | eviction generalizes disk pressure transition to other resources | + +See [Configuring Out Of Resource Handling](/docs/admin/out-of-resource/) for more details. diff --git a/docs/admin/ha-master-gce.md b/docs/admin/ha-master-gce.md index 025035cca7..27c51c9d25 100644 --- a/docs/admin/ha-master-gce.md +++ b/docs/admin/ha-master-gce.md @@ -107,7 +107,7 @@ This operation may be sped up by migrating etcd data directory, as described [he ## Implementation notes -![](ha-master-gce.png) +![ha-master-gce](/images/docs/ha-master-gce.png) ### Overview diff --git a/docs/admin/kube-apiserver.md b/docs/admin/kube-apiserver.md index 1e2c8a602e..51dbcac500 100644 --- a/docs/admin/kube-apiserver.md +++ b/docs/admin/kube-apiserver.md @@ -71,10 +71,17 @@ DynamicKubeletConfig=true|false (ALPHA - default=false) DynamicVolumeProvisioning=true|false (ALPHA - default=true) ExperimentalHostUserNamespaceDefaulting=true|false (ALPHA - default=false) StreamingProxyRedirects=true|false (ALPHA - default=false) - --google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication. --insecure-allow-any-token username/group1,group2 If set, your server will be INSECURE. Any token will be allowed and user information will be parsed from the token as username/group1,group2 --insecure-bind-address ip The IP address on which to serve the --insecure-port (set to 0.0.0.0 for all interfaces). Defaults to localhost. (default 127.0.0.1) --insecure-port int The port on which to serve unsecured, unauthenticated access. Default 8080. It is assumed that firewall rules are set up such that this port is not reachable from outside of the cluster and that port 443 on the cluster's public address is proxied to this port. This is performed by nginx in the default setup. (default 8080) + --ir-data-source string Data source used by InitialResources. Supported options: influxdb, gcm. (default "influxdb") +      --ir-dbname string                                       InfluxDB database name which contains metrics required by InitialResources. (default "k8s") + --ir-hawkular string Hawkular configuration URL. + --ir-influxdb-host string Address of InfluxDB which contains metrics required by InitialResources. (default "localhost:8080/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb:api") + --ir-namespace-only Whether the estimation should be made only based on data from the same namespace. + --ir-password string Password used for connecting to InfluxDB. (default "root") + --ir-percentile int Which percentile of samples should InitialResources use when estimating resources. For experiment purposes. (default 90) + --ir-user string User used for connecting to InfluxDB. (default "root") --kubelet-certificate-authority string Path to a cert file for the certificate authority. --kubelet-client-certificate string Path to a client cert file for TLS. --kubelet-client-key string Path to a client key file for TLS. diff --git a/docs/admin/kube-controller-manager.md b/docs/admin/kube-controller-manager.md index 82dd43cbcd..f3978033cd 100644 --- a/docs/admin/kube-controller-manager.md +++ b/docs/admin/kube-controller-manager.md @@ -28,6 +28,7 @@ kube-controller-manager ``` --address ip The IP address to serve on (set to 0.0.0.0 for all interfaces) (default 0.0.0.0) --allocate-node-cidrs Should CIDRs for Pods be allocated and set on the cloud provider. + --allow-verification-with-non-compliant-keys Allow a SignatureVerifier to use keys which are technically non-compliant with RFC6962. --cloud-config string The path to the cloud provider configuration file. Empty string for no configuration file. --cloud-provider string The provider for cloud services. Empty string for no provider. --cluster-cidr string CIDR Range for Pods in cluster. @@ -59,7 +60,6 @@ DynamicVolumeProvisioning=true|false (ALPHA - default=true) ExperimentalHostUserNamespaceDefaulting=true|false (ALPHA - default=false) StreamingProxyRedirects=true|false (ALPHA - default=false) --flex-volume-plugin-dir string Full path of the directory in which the flex volume plugin should search for additional third party volume plugins. (default "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/") - --google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication. --horizontal-pod-autoscaler-sync-period duration The period for syncing the number of pods in horizontal pod autoscaler. (default 30s) --insecure-experimental-approve-all-kubelet-csrs-for-group string The group for which the controller-manager will auto approve all CSRs for kubelet client certificates. --kube-api-burst int32 Burst to use while talking with Kubernetes apiserver (default 30) diff --git a/docs/admin/kube-proxy.md b/docs/admin/kube-proxy.md index ea13d528e3..bf72aee787 100644 --- a/docs/admin/kube-proxy.md +++ b/docs/admin/kube-proxy.md @@ -41,7 +41,6 @@ DynamicKubeletConfig=true|false (ALPHA - default=false) DynamicVolumeProvisioning=true|false (ALPHA - default=true) ExperimentalHostUserNamespaceDefaulting=true|false (ALPHA - default=false) StreamingProxyRedirects=true|false (ALPHA - default=false) - --google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication. --healthz-bind-address ip The IP address for the health check server to serve on, defaulting to 127.0.0.1 (set to 0.0.0.0 for all interfaces) (default 127.0.0.1) --healthz-port int32 The port to bind the health check server. Use 0 to disable. (default 10249) --hostname-override string If non-empty, will use this string as identification instead of the actual hostname. diff --git a/docs/admin/kube-scheduler.md b/docs/admin/kube-scheduler.md index 15e47d2f46..91ffc303aa 100644 --- a/docs/admin/kube-scheduler.md +++ b/docs/admin/kube-scheduler.md @@ -36,7 +36,6 @@ DynamicKubeletConfig=true|false (ALPHA - default=false) DynamicVolumeProvisioning=true|false (ALPHA - default=true) ExperimentalHostUserNamespaceDefaulting=true|false (ALPHA - default=false) StreamingProxyRedirects=true|false (ALPHA - default=false) - --google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication. --hard-pod-affinity-symmetric-weight int RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule. (default 1) --kube-api-burst int32 Burst to use while talking with Kubernetes apiserver (default 100) --kube-api-content-type string Content type of requests sent to apiserver. (default "application/vnd.kubernetes.protobuf") diff --git a/docs/admin/kubeadm.md b/docs/admin/kubeadm.md index 1014ee1ab6..ce9a83fc29 100644 --- a/docs/admin/kubeadm.md +++ b/docs/admin/kubeadm.md @@ -31,10 +31,10 @@ server, as well as an additional kubeconfig file for administration. controller manager and scheduler, and placing them in `/etc/kubernetes/manifests`. The kubelet watches this directory for static resources to create on startup. These are the core components of Kubernetes, and -once they are up and running we can use `kubectl` to set up/manage any +once they are up and running we can use `kubectl` to set up or manage any additional components. -1. kubeadm installs any add-on components, such as DNS or discovery, via the API +1. kubeadm installs some add-on components, such as DNS or discovery, via the API server. Running `kubeadm join` on each node in the cluster consists of the following steps: @@ -180,48 +180,49 @@ available as configuration file options. ### Sample Master Configuration - ```yaml - apiVersion: kubeadm.k8s.io/v1alpha1 - kind: MasterConfiguration - api: - advertiseAddresses: - - - - - bindPort: - externalDNSNames: - - - - - cloudProvider: - discovery: - bindPort: - etcd: - endpoints: - - - - - caFile: - certFile: - keyFile: - kubernetesVersion: - networking: - dnsDomain: - serviceSubnet: - podSubnet: - secrets: - givenToken: - ``` +```yaml +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: MasterConfiguration +api: + advertiseAddresses: + - + - + bindPort: + externalDNSNames: + - + - +authorizationMode: +cloudProvider: +discovery: + bindPort: +etcd: + endpoints: + - + - + caFile: + certFile: + keyFile: +kubernetesVersion: +networking: + dnsDomain: + serviceSubnet: + podSubnet: +secrets: + givenToken: +``` ### Sample Node Configuration - ```yaml - apiVersion: kubeadm.k8s.io/v1alpha1 - kind: NodeConfiguration - apiPort: - discoveryPort: - masterAddresses: - - - secrets: - givenToken: - ``` +```yaml +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: NodeConfiguration +apiPort: +discoveryPort: +masterAddresses: +- +secrets: + givenToken: +``` ## Automating kubeadm @@ -257,6 +258,24 @@ These environment variables are a short-term solution, eventually they will be i | `KUBE_ETCD_IMAGE` | `gcr.io/google_containers/etcd-:2.2.5` | The etcd container image to use. | | `KUBE_REPO_PREFIX` | `gcr.io/google_containers` | The image prefix for all images that are used. | +If you want to use kubeadm with an http proxy, you may need to configure it to support http_proxy, https_proxy, or no_proxy. + +For example, if your kube master node IP address is 10.18.17.16 and you have proxy support both http/https on 10.18.17.16 port 8080, you can use the following command: + +You can using following command + +```bash +export PROXY_PORT=8080 +export PROXY_IP=10.18.17.16 +export http_proxy=http://$PROXY_IP:$PROXY_PORT +export HTTP_PROXY=$http_proxy +export https_proxy=$http_proxy +export HTTPS_PROXY=$http_proxy +export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com,example.com,10.18.17.16" +``` + +Remember to change ```proxy_ip``` and add a kube master node IP address to ```no_proxy```. + ## Releases and release notes If you already have kubeadm installed and want to upgrade, run `apt-get update && apt-get upgrade` or `yum update` to get the latest version of kubeadm. diff --git a/docs/admin/kubelet.md b/docs/admin/kubelet.md index 258db1e3aa..4a57e00d60 100644 --- a/docs/admin/kubelet.md +++ b/docs/admin/kubelet.md @@ -96,7 +96,7 @@ StreamingProxyRedirects=true|false (ALPHA - default=false) --google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication. --hairpin-mode string How should the kubelet setup hairpin NAT. This allows endpoints of a Service to loadbalance back to themselves if they should try to access their own Service. Valid values are "promiscuous-bridge", "hairpin-veth" and "none". (default "promiscuous-bridge") --healthz-bind-address ip The IP address for the healthz server to serve on, defaulting to 127.0.0.1 (set to 0.0.0.0 for all interfaces) (default 127.0.0.1) - --healthz-port int32 The port of the localhost healthz endpoint (default 10248) + --healthz-port int32 (Deprecated) The port of the localhost healthz endpoint (default 10248) --host-ipc-sources stringSlice Comma-separated list of sources from which the Kubelet allows pods to use the host ipc namespace. [default="*"] (default [*]) --host-network-sources stringSlice Comma-separated list of sources from which the Kubelet allows pods to use of host network. [default="*"] (default [*]) --host-pid-sources stringSlice Comma-separated list of sources from which the Kubelet allows pods to use the host pid namespace. [default="*"] (default [*]) @@ -137,7 +137,7 @@ StreamingProxyRedirects=true|false (ALPHA - default=false) --pods-per-core int32 Number of Pods per core that can run on this Kubelet. The total number of Pods on this Kubelet cannot exceed max-pods, so max-pods will be used if this calculation results in a larger number of Pods allowed on the Kubelet. A value of 0 disables this limit. --port int32 The port for the Kubelet to serve on. (default 10250) --protect-kernel-defaults Default kubelet behaviour for kernel tuning. If set, kubelet errors if any of kernel tunables is different than kubelet defaults. - --read-only-port int32 The read-only port for the Kubelet to serve on with no authentication/authorization (set to 0 to disable) (default 10255) + --read-only-port int32 The read-only port for the Kubelet to serve on with no authentication/authorization, and for localhost healthz endpoint (set to 0 to disable) (default 10255) --really-crash-for-testing If true, when panics occur crash. Intended for testing. --register-node Register the node with the apiserver (defaults to true if --api-servers is set) (default true) --register-schedulable Register the node as schedulable. Won't have any effect if register-node is false. [default=true] (default true) diff --git a/docs/admin/limitrange/index.md b/docs/admin/limitrange/index.md index 3a31b9e732..6d982a9aae 100644 --- a/docs/admin/limitrange/index.md +++ b/docs/admin/limitrange/index.md @@ -5,210 +5,6 @@ assignees: title: Setting Pod CPU and Memory Limits --- -By default, pods run with unbounded CPU and memory 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. +{% include user-guide-content-moved.md %} -Users may want to impose restrictions on the amount of resources a single pod in the system may consume -for a variety of reasons. - -For example: - -1. Each node in the cluster has 2GB of memory. The cluster operator does not want to accept pods -that require more than 2GB of memory since no node in the cluster can support the requirement. To prevent a -pod from being permanently unscheduled to a node, the operator instead chooses to reject pods that exceed 2GB -of memory as part of admission control. -2. A cluster is shared by two communities in an organization that runs production and development workloads -respectively. Production workloads may consume up to 8GB of memory, but development workloads may consume up -to 512MB of memory. The cluster operator creates a separate namespace for each workload, and applies limits to -each namespace. -3. Users may create a pod which consumes resources just below the capacity of a machine. The left over space -may be too small to be useful, but big enough for the waste to be costly over the entire cluster. As a result, -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](/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. - -See [LimitRange design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/admission_control_limit_range.md) for more information. For a detailed description of the Kubernetes resource model, see [Resources](/docs/user-guide/compute-resources/) - -## Step 0: Prerequisites - -This example requires a running Kubernetes cluster. See the [Getting Started guides](/docs/getting-started-guides/) for how to get started. - -Change to the `` directory if you're not already there. - -## 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 limit-example: - -```shell -$ 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 STATUS AGE -default Active 51s -limit-example Active 45s -``` - -## Step 2: Apply a limit to the namespace - -Let's create a simple limit in our namespace. - -```shell -$ kubectl create -f docs/admin/limitrange/limits.yaml --namespace=limit-example -limitrange "mylimits" created -``` - -Let's describe the limits that we have imposed in our namespace. - -```shell -$ kubectl describe limits mylimits --namespace=limit-example -Name: mylimits -Namespace: limit-example -Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ----- -------- --- --- --------------- ------------- ----------------------- -Pod cpu 200m 2 - - - -Pod memory 6Mi 1Gi - - - -Container cpu 100m 2 200m 300m - -Container memory 3Mi 1Gi 100Mi 200Mi - -``` - -In this scenario, we have said the following: - -1. If a max constraint is specified for a resource (2 CPU and 1Gi memory in this case), then a limit -must be specified for that resource across all containers. Failure to specify a limit will result in -a validation error when attempting to create the pod. Note that a default value of limit is set by -*default* in file `limits.yaml` (300m CPU and 200Mi memory). -2. If a min constraint is specified for a resource (100m CPU and 3Mi memory in this case), then a -request must be specified for that resource across all containers. Failure to specify a request will -result in a validation error when attempting to create the pod. Note that a default value of request is -set by *defaultRequest* in file `limits.yaml` (200m CPU and 100Mi memory). -3. For any pod, the sum of all containers memory requests must be >= 6Mi and the sum of all containers -memory limits must be <= 1Gi; the sum of all containers CPU requests must be >= 200m and the sum of all -containers CPU limits must be <= 2. - -## Step 3: Enforcing limits at point of creation - -The limits enumerated in a namespace are only enforced when a pod is created or updated in -the cluster. If you change the limits to a different value range, it does not affect pods that -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 [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 -deployment "nginx" created -``` - -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*. - -Let's create a pod that exceeds our allowed limits by having it have a container that requests 3 CPU cores. - -```shell -$ kubectl create -f docs/admin/limitrange/invalid-pod.yaml --namespace=limit-example -Error from server: error when creating "docs/admin/limitrange/invalid-pod.yaml": Pod "invalid-pod" is forbidden: [Maximum cpu usage per Pod is 2, but limit is 3., Maximum cpu usage per Container is 2, but limit is 3.] -``` - -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 -``` - -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 enforced in the default Kubernetes setup on the physical node -that runs the container unless the administrator deploys the kubelet with the following flag: - -```shell -$ kubelet --help -Usage of kubelet -.... - --cpu-cfs-quota[=true]: Enable CPU CFS quota enforcement for containers that specify CPU limits -$ kubelet --cpu-cfs-quota=false ... -``` - -## Step 4: Cleanup - -To remove the resources used by this example, you can just delete the limit-example namespace. - -```shell -$ kubectl delete namespace limit-example -namespace "limit-example" deleted -$ kubectl get namespaces -NAME STATUS AGE -default Active 12m -``` - -## Summary - -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. +[Setting Pod CPU and Memory Limits](/docs/tasks/configure-pod-container/limit-range/) diff --git a/docs/admin/multi-cluster.md b/docs/admin/multi-cluster.md index 085a9afa9f..4fe4e8b6ae 100644 --- a/docs/admin/multi-cluster.md +++ b/docs/admin/multi-cluster.md @@ -4,63 +4,6 @@ assignees: title: Using Multiple Clusters --- -You may want to set up multiple Kubernetes clusters, both to -have clusters in different regions to be nearer to your users, and to tolerate failures and/or invasive maintenance. -This document describes some of the issues to consider when making a decision about doing so. +{% include user-guide-content-moved.md %} -If you decide to have multiple clusters, Kubernetes provides a way to [federate them](/docs/admin/federation/). - -## Scope of a single cluster - -On IaaS providers such as Google Compute Engine or Amazon Web Services, a VM exists in a -[zone](https://cloud.google.com/compute/docs/zones) or [availability -zone](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). -We suggest that all the VMs in a Kubernetes cluster should be in the same availability zone, because: - - - compared to having a single global Kubernetes cluster, there are fewer single-points of failure - - compared to a cluster that spans availability zones, it is easier to reason about the availability properties of a - single-zone cluster. - - when the Kubernetes developers are designing the system (e.g. making assumptions about latency, bandwidth, or - correlated failures) they are assuming all the machines are in a single data center, or otherwise closely connected. - -It is okay to have multiple clusters per availability zone, though on balance we think fewer is better. -Reasons to prefer fewer clusters are: - - - improved bin packing of Pods in some cases with more nodes in one cluster (less resource fragmentation) - - reduced operational overhead (though the advantage is diminished as ops tooling and processes matures) - - reduced costs for per-cluster fixed resource costs, e.g. apiserver VMs (but small as a percentage - of overall cluster cost for medium to large clusters). - -Reasons to have multiple clusters include: - - - strict security policies requiring isolation of one class of work from another (but, see Partitioning Clusters - below). - - test clusters to canary new Kubernetes releases or other cluster software. - -## Selecting the right number of clusters - -The selection of the number of Kubernetes clusters may be a relatively static choice, only revisited occasionally. -By contrast, the number of nodes in a cluster and the number of pods in a service may change frequently according to -load and growth. - -To pick the number of clusters, first, decide which regions you need to be in to have adequate latency to all your end users, for services that will run -on Kubernetes (if you use a Content Distribution Network, the latency requirements for the CDN-hosted content need not -be considered). Legal issues might influence this as well. For example, a company with a global customer base might decide to have clusters in US, EU, AP, and SA regions. -Call the number of regions to be in `R`. - -Second, decide how many clusters should be able to be unavailable at the same time, while still being available. Call -the number that can be unavailable `U`. If you are not sure, then 1 is a fine choice. - -If it is allowable for load-balancing to direct traffic to any region in the event of a cluster failure, then -you need at least the larger of `R` or `U + 1` clusters. If it is not (e.g. you want to ensure low latency for all -users in the event of a cluster failure), then you need to have `R * (U + 1)` clusters -(`U + 1` in each of `R` regions). In any case, try to put each cluster in a different zone. - -Finally, if any of your clusters would need more than the maximum recommended number of nodes for a Kubernetes cluster, then -you may need even more clusters. Kubernetes v1.3 supports clusters up to 1000 nodes in size. - -## Working with multiple clusters - -When you have multiple clusters, you would typically create services with the same config in each cluster and put each of those -service instances behind a load balancer (AWS Elastic Load Balancer, GCE Forwarding Rule or HTTP Load Balancer) spanning all of them, so that -failures of a single cluster are not visible to end users. +[Using Multiple Clusters](/docs/concepts/cluster-administration/multiple-clusters/) diff --git a/docs/admin/multiple-schedulers.md b/docs/admin/multiple-schedulers.md index bf7386e492..e4f1b4a9f1 100644 --- a/docs/admin/multiple-schedulers.md +++ b/docs/admin/multiple-schedulers.md @@ -34,7 +34,7 @@ to build the image: ```docker FROM busybox -ADD _output/local/go/bin/kube-scheduler /usr/local/bin/kube-scheduler +ADD ./_output/dockerized/bin/linux/amd64/kube-scheduler /usr/local/bin/kube-scheduler ``` Save the file as `Dockerfile`, build the image and push it to a registry. This example @@ -45,7 +45,7 @@ For more details, please read the GCR ```shell docker build -t my-kube-scheduler:1.0 . -gcloud docker push gcr.io/my-gcp-project/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 @@ -61,7 +61,7 @@ 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. +argument to the scheduler command in the container spec should be unique. This is the name that is matched against the value of the optional `spec.schedulername` on pods, to determine whether this scheduler is responsible for scheduling a particular pod. Please see the [kube-scheduler documentation](/docs/admin/kube-scheduler/) for @@ -92,14 +92,14 @@ 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. +scheduler in that pod spec. Let's look at three examples. -1. Pod spec without any scheduler annotation +- Pod spec without any scheduler name {% 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 + When no scheduler name is supplied, the pod is automatically scheduled using the default-scheduler. Save this file as `pod1.yaml` and submit it to the Kubernetes cluster. @@ -108,12 +108,11 @@ scheduler as an annotation in that pod spec. Let's look at three examples. kubectl create -f pod1.yaml ``` -2. Pod spec with `default-scheduler` annotation +- Pod spec with `default-scheduler` {% 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 + A scheduler is specified by supplying the scheduler name as a value to `spec.schedulername`. In this case, we supply the name of the default scheduler which is `default-scheduler`. Save this file as `pod2.yaml` and submit it to the Kubernetes cluster. @@ -122,26 +121,25 @@ scheduler as an annotation in that pod spec. Let's look at three examples. kubectl create -f pod2.yaml ``` -3. Pod spec with `my-scheduler` annotation +- Pod spec with `my-scheduler` {% 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 + deployed - `my-scheduler`. Note that the value of `spec.schedulername` 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 - ``` +```shell +kubectl create -f pod3.yaml +``` Verify that all three pods are running. - ```shell - kubectl get pods - ``` +```shell +kubectl get pods +``` ### Verifying that the pods were scheduled using the desired schedulers @@ -149,9 +147,9 @@ In order to make it easier to work through these examples, we did not verify tha 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 +we see that the pod `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 +and our new scheduler starts running, the `second-scheduler` pod gets scheduled as well. Alternatively, one could just look at the "Scheduled" entries in the event logs to diff --git a/docs/admin/multiple-schedulers/my-scheduler.yaml b/docs/admin/multiple-schedulers/my-scheduler.yaml index 0a140deead..5e97f46434 100644 --- a/docs/admin/multiple-schedulers/my-scheduler.yaml +++ b/docs/admin/multiple-schedulers/my-scheduler.yaml @@ -16,8 +16,11 @@ spec: version: second spec: containers: - - command: [/usr/local/bin/kube-scheduler, --address=0.0.0.0, - --scheduler-name=my-scheduler] + - command: + - /usr/local/bin/kube-scheduler + - --address=0.0.0.0 + - --leader-elect=false + - --scheduler-name=my-scheduler image: gcr.io/my-gcp-project/my-kube-scheduler:1.0 livenessProbe: httpGet: @@ -37,4 +40,4 @@ spec: volumeMounts: [] hostNetwork: false hostPID: false - volumes: [] \ No newline at end of file + volumes: [] diff --git a/docs/admin/multiple-schedulers/pod2.yaml b/docs/admin/multiple-schedulers/pod2.yaml index 2f9fdf9875..26b0376967 100644 --- a/docs/admin/multiple-schedulers/pod2.yaml +++ b/docs/admin/multiple-schedulers/pod2.yaml @@ -2,11 +2,10 @@ apiVersion: v1 kind: Pod metadata: name: annotation-default-scheduler - annotations: - scheduler.alpha.kubernetes.io/name: default-scheduler labels: name: multischeduler-example spec: + schedulername: default-scheduler containers: - name: pod-with-default-annotation-container image: gcr.io/google_containers/pause:2.0 \ No newline at end of file diff --git a/docs/admin/multiple-schedulers/pod3.yaml b/docs/admin/multiple-schedulers/pod3.yaml index 52276df5f6..e64070abfa 100644 --- a/docs/admin/multiple-schedulers/pod3.yaml +++ b/docs/admin/multiple-schedulers/pod3.yaml @@ -2,11 +2,10 @@ apiVersion: v1 kind: Pod metadata: name: annotation-second-scheduler - annotations: - scheduler.alpha.kubernetes.io/name: my-scheduler labels: name: multischeduler-example spec: + schedulername: my-scheduler containers: - name: pod-with-second-annotation-container image: gcr.io/google_containers/pause:2.0 \ No newline at end of file diff --git a/docs/admin/namespaces/index.md b/docs/admin/namespaces/index.md index 887f14cd91..8da2107960 100644 --- a/docs/admin/namespaces/index.md +++ b/docs/admin/namespaces/index.md @@ -44,9 +44,9 @@ You can list the current namespaces in a cluster using: ```shell $ kubectl get namespaces -NAME LABELS STATUS -default Active -kube-system Active +NAME STATUS AGE +default Active 11d +kube-system Active 11d ``` Kubernetes starts with two initial namespaces: diff --git a/docs/admin/namespaces/walkthrough.md b/docs/admin/namespaces/walkthrough.md index 7576d2c2e0..e3aa0c7bfc 100644 --- a/docs/admin/namespaces/walkthrough.md +++ b/docs/admin/namespaces/walkthrough.md @@ -145,7 +145,7 @@ 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. +Let's create some contents. ```shell $ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2 diff --git a/docs/admin/network-plugins.md b/docs/admin/network-plugins.md index d5e05ac7b1..bd22f4eb9f 100644 --- a/docs/admin/network-plugins.md +++ b/docs/admin/network-plugins.md @@ -6,68 +6,6 @@ assignees: title: Network Plugins --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -__Disclaimer__: Network plugins are in alpha. Its contents will change rapidly. - -Network plugins in Kubernetes come in a few flavors: - -* CNI plugins: adhere to the appc/CNI specification, designed for interoperability. -* Kubenet plugin: implements basic `cbr0` using the `bridge` and `host-local` CNI plugins - -## Installation - -The kubelet has a single default network plugin, and a default network common to the entire cluster. It probes for plugins when it starts up, remembers what it found, and executes the selected plugin at appropriate times in the pod lifecycle (this is only true for docker, as rkt manages its own CNI plugins). There are two Kubelet command line parameters to keep in mind when using plugins: - -* `network-plugin-dir`: Kubelet probes this directory for plugins on startup -* `network-plugin`: The network plugin to use from `network-plugin-dir`. It must match the name reported by a plugin probed from the plugin directory. For CNI plugins, this is simply "cni". - -## Network Plugin Requirements - -Besides providing the [`NetworkPlugin` interface](https://github.com/kubernetes/kubernetes/tree/{{page.version}}/pkg/kubelet/network/plugins.go) to configure and clean up pod networking, the plugin may also need specific support for kube-proxy. The iptables proxy obviously depends on iptables, and the plugin may need to ensure that container traffic is made available to iptables. For example, if the plugin connects containers to a Linux bridge, the plugin must set the `net/bridge/bridge-nf-call-iptables` sysctl to `1` to ensure that the iptables proxy functions correctly. If the plugin does not use a Linux bridge (but instead something like Open vSwitch or some other mechanism) it should ensure container traffic is appropriately routed for the proxy. - -By default if no kubelet network plugin is specified, the `noop` plugin is used, which sets `net/bridge/bridge-nf-call-iptables=1` to ensure simple configurations (like docker with a bridge) work correctly with the iptables proxy. - -### CNI - -The CNI plugin is selected by passing Kubelet the `--network-plugin=cni` command-line option. Kubelet reads a file from `--cni-conf-dir` (default `/etc/cni/net.d`) and uses the CNI configuration from that file to set up each pod's network. The CNI configuration file must match the [CNI specification](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration), and any required CNI plugins referenced by the configuration must be present in `--cni-bin-dir` (default `/opt/cni/bin`). - -If there are multiple CNI configuration files in the directory, the first one in lexicographic order of file name is used. - -In addition to the CNI plugin specified by the configuration file, Kubernetes requires the standard CNI [`lo`](https://github.com/containernetworking/cni/blob/master/plugins/main/loopback/loopback.go) plugin, at minimum version 0.2.0 - -Limitation: Due to [#31307](https://github.com/kubernetes/kubernetes/issues/31307), `HostPort` won't work with CNI networking plugin at the moment. That means all `hostPort` attribute in pod would be simply ignored. - -### kubenet - -Kubenet is a very basic, simple network plugin, on Linux only. It does not, of itself, implement more advanced features like cross-node networking or network policy. It is typically used together with a cloud provider that sets up routing rules for communication between nodes, or in single-node environments. - -Kubenet creates a Linux bridge named `cbr0` and creates a veth pair for each pod with the host end of each pair connected to `cbr0`. The pod end of the pair is assigned an IP address allocated from a range assigned to the node either through configuration or by the controller-manager. `cbr0` is assigned an MTU matching the smallest MTU of an enabled normal interface on the host. - -The plugin requires a few things: - -* The standard CNI `bridge`, `lo` and `host-local` plugins are required, at minimum version 0.2.0. Kubenet will first search for them in `/opt/cni/bin`. Specify `network-plugin-dir` to supply additional search path. The first found match will take effect. -* Kubelet must be run with the `--network-plugin=kubenet` argument to enable the plugin -* Kubelet should also be run with the `--non-masquerade-cidr=` argumment to ensure traffic to IPs outside this range will use IP masquerade. -* The node must be assigned an IP subnet through either the `--pod-cidr` kubelet command-line option or the `--allocate-node-cidrs=true --cluster-cidr=` controller-manager command-line options. - -### Customizing the MTU (with kubenet) - -The MTU should always be configured correctly to get the best networking performance. Network plugins will usually try -to infer a sensible MTU, but sometimes the logic will not result in an optimal MTU. For example, if the -Docker bridge or another interface has a small MTU, kubenet will currently select that MTU. Or if you are -using IPSEC encapsulation, the MTU must be reduced, and this calculation is out-of-scope for -most network plugins. - -Where needed, you can specify the MTU explicitly with the `network-plugin-mtu` kubelet option. For example, -on AWS the `eth0` MTU is typically 9001, so you might specify `--network-plugin-mtu=9001`. If you're using IPSEC you -might reduce it to allow for encapsulation overhead e.g. `--network-plugin-mtu=8873`. - -This option is provided to the network-plugin; currently **only kubenet supports `network-plugin-mtu`**. - -## Usage Summary - -* `--network-plugin=cni` specifies that we use the `cni` network plugin with actual CNI plugin binaries located in `--cni-bin-dir` (default `/opt/cni/bin`) and CNI plugin configuration located in `--cni-conf-dir` (default `/etc/cni/net.d`). -* `--network-plugin=kubenet` specifies that we use the `kubenet` network plugin with CNI `bridge` and `host-local` plugins placed in `/opt/cni/bin` or `network-plugin-dir`. -* `--network-plugin-mtu=9001` specifies the MTU to use, currently only used by the `kubenet` network plugin. +[Network Plugins](/docs/concepts/cluster-administration/network-plugins/) diff --git a/docs/admin/networking.md b/docs/admin/networking.md index a2b7d37110..7041b1b7e7 100644 --- a/docs/admin/networking.md +++ b/docs/admin/networking.md @@ -4,212 +4,6 @@ assignees: title: Networking in Kubernetes --- -Kubernetes approaches networking somewhat differently than Docker does by -default. There are 4 distinct networking problems to solve: +{% include user-guide-content-moved.md %} -1. Highly-coupled container-to-container communications: this is solved by - [pods](/docs/user-guide/pods/) and `localhost` communications. -2. Pod-to-Pod communications: this is the primary focus of this document. -3. Pod-to-Service communications: this is covered by [services](/docs/user-guide/services/). -4. External-to-Service communications: this is covered by [services](/docs/user-guide/services/). - -* TOC -{:toc} - - -## Summary - -Kubernetes assumes that pods can communicate with other pods, regardless of -which host they land on. We give every pod its own IP address so you do not -need to explicitly create links between pods and you almost never need to deal -with mapping container ports to host ports. This creates a clean, -backwards-compatible model where pods can be treated much like VMs or physical -hosts from the perspectives of port allocation, naming, service discovery, load -balancing, application configuration, and migration. - -To achieve this we must impose some requirements on how you set up your cluster -networking. - -## Docker model - -Before discussing the Kubernetes approach to networking, it is worthwhile to -review the "normal" way that networking works with Docker. By default, Docker -uses host-private networking. It creates a virtual bridge, called `docker0` by -default, and allocates a subnet from one of the private address blocks defined -in [RFC1918](https://tools.ietf.org/html/rfc1918) for that bridge. For each -container that Docker creates, it allocates a virtual ethernet device (called -`veth`) which is attached to the bridge. The veth is mapped to appear as `eth0` -in the container, using Linux namespaces. The in-container `eth0` interface is -given an IP address from the bridge's address range. - -The result is that Docker containers can talk to other containers only if they -are on the same machine (and thus the same virtual bridge). Containers on -different machines can not reach each other - in fact they may end up with the -exact same network ranges and IP addresses. - -In order for Docker containers to communicate across nodes, they must be -allocated ports on the machine's own IP address, which are then forwarded or -proxied to the containers. This obviously means that containers must either -coordinate which ports they use very carefully or else be allocated ports -dynamically. - -## Kubernetes model - -Coordinating ports across multiple developers is very difficult to do at -scale and exposes users to cluster-level issues outside of their control. -Dynamic port allocation brings a lot of complications to the system - every -application has to take ports as flags, the API servers have to know how to -insert dynamic port numbers into configuration blocks, services have to know -how to find each other, etc. Rather than deal with this, Kubernetes takes a -different approach. - -Kubernetes imposes the following fundamental requirements on any networking -implementation (barring any intentional network segmentation policies): - - * all containers can communicate with all other containers without NAT - * all nodes can communicate with all containers (and vice-versa) without NAT - * the IP that a container sees itself as is the same IP that others see it as - -What this means in practice is that you can not just take two computers -running Docker and expect Kubernetes to work. You must ensure that the -fundamental requirements are met. - -This model is not only less complex overall, but it is principally compatible -with the desire for Kubernetes to enable low-friction porting of apps from VMs -to containers. If your job previously ran in a VM, your VM had an IP and could -talk to other VMs in your project. This is the same basic model. - -Until now this document has talked about containers. In reality, Kubernetes -applies IP addresses at the `Pod` scope - containers within a `Pod` share their -network namespaces - including their IP address. This means that containers -within a `Pod` can all reach each other's ports on `localhost`. This does imply -that containers within a `Pod` must coordinate port usage, but this is no -different than processes in a VM. We call this the "IP-per-pod" model. This -is implemented in Docker as a "pod container" which holds the network namespace -open while "app containers" (the things the user specified) join that namespace -with Docker's `--net=container:` function. - -As with Docker, it is possible to request host ports, but this is reduced to a -very niche operation. In this case a port will be allocated on the host `Node` -and traffic will be forwarded to the `Pod`. The `Pod` itself is blind to the -existence or non-existence of host ports. - -## How to achieve this - -There are a number of ways that this network model can be implemented. This -document is not an exhaustive study of the various methods, but hopefully serves -as an introduction to various technologies and serves as a jumping-off point. - -The following networking options are sorted alphabetically - the order does not -imply any preferential status. - -### 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. - -### Flannel - -[Flannel](https://github.com/coreos/flannel#flannel) is a very simple overlay -network that satisfies the Kubernetes requirements. Many -people have reported success with Flannel and Kubernetes. - -### Google Compute Engine (GCE) - -For the Google Compute Engine cluster configuration scripts, we use [advanced -routing](https://cloud.google.com/compute/docs/networking#routing) to -assign each VM a subnet (default is `/24` - 254 IPs). Any traffic bound for that -subnet will be routed directly to the VM by the GCE network fabric. This is in -addition to the "main" IP address assigned to the VM, which is NAT'ed for -outbound internet access. A linux bridge (called `cbr0`) is configured to exist -on that subnet, and is passed to docker's `--bridge` flag. - -We start Docker with: - -```shell -DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false" -``` - -This bridge is created by Kubelet (controlled by the `--network-plugin=kubenet` -flag) according to the `Node`'s `spec.podCIDR`. - -Docker will now allocate IPs from the `cbr-cidr` block. Containers can reach -each other and `Nodes` over the `cbr0` bridge. Those IPs are all routable -within the GCE project network. - -GCE itself does not know anything about these IPs, though, so it will not NAT -them for outbound internet traffic. To achieve that we use an iptables rule to -masquerade (aka SNAT - to make it seem as if packets came from the `Node` -itself) traffic that is bound for IPs outside the GCE project network -(10.0.0.0/8). - -```shell -iptables -t nat -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE -``` - -Lastly we enable IP forwarding in the kernel (so the kernel will process -packets for bridged containers): - -```shell -sysctl net.ipv4.ip_forward=1 -``` - -The result of all this is that all `Pods` can reach each other and can egress -traffic to the internet. - -### L2 networks and linux bridging - -If you have a "dumb" L2 network, such as a simple switch in a "bare-metal" -environment, you should be able to do something similar to the above GCE setup. -Note that these instructions have only been tried very casually - it seems to -work, but has not been thoroughly tested. If you use this technique and -perfect the process, please let us know. - -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. - -### Nuage Networks VCS (Virtualized Cloud Services) - -[Nuage](http://www.nuagenetworks.net) provides a highly scalable policy-based Software-Defined Networking (SDN) platform. Nuage uses the open source Open vSwitch for the data plane along with a feature rich SDN Controller built on open standards. - -The Nuage platform uses overlays to provide seamless policy-based networking between Kubernetes Pods and non-Kubernetes environments (VMs and bare metal servers). Nuage's policy abstraction model is designed with applications in mind and makes it easy to declare fine-grained policies for applications.The platform's real-time analytics engine enables visibility and security monitoring for Kubernetes applications. - -### OpenVSwitch - -[OpenVSwitch](/docs/admin/ovs-networking) is a somewhat more mature but also -complicated way to build an overlay network. This is endorsed by several of the -"Big Shops" for networking. - -### OVN (Open Virtual Networking) - -OVN is an opensource network virtualization solution developed by the -Open vSwitch community. It lets one create logical switches, logical routers, -stateful ACLs, load-balancers etc to build different virtual networking -topologies. The project has a specific Kubernetes plugin and documentation -at [ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes). - -### Project Calico - -[Project Calico](http://docs.projectcalico.org/) is an open source container networking provider and network policy engine. - -Calico provides a highly scalable networking and network policy solution for connecting Kubernetes pods based on the same IP networking principles as the internet. Calico can be deployed without encapsulation or overlays to provide high-performance, high-scale data center networking. Calico also provides fine-grained, intent based network security policy for Kubernetes pods via its distributed firewall. - -Calico can also be run in policy enforcement mode in conjunction with other networking solutions such as Flannel, aka [canal](https://github.com/tigera/canal), or native GCE networking. - -### Romana - -[Romana](http://romana.io) is an open source network and security automation solution that lets you deploy Kubernetes without an overlay network. Romana supports Kubernetes [Network Policy](/docs/user-guide/networkpolicies/) to provide isolation across network namespaces. - -### Weave Net from Weaveworks - -[Weave Net](https://www.weave.works/products/weave-net/) 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/docs/net/latest/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. - -## Other reading - -The early design of the networking model and its rationale, and some future -plans are described in more detail in the [networking design -document](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/networking.md). +[Cluster Networking](/docs/concepts/cluster-administration/networking/) diff --git a/docs/admin/node-problem.md b/docs/admin/node-problem.md index 08ca3208dd..dd882f7e5e 100644 --- a/docs/admin/node-problem.md +++ b/docs/admin/node-problem.md @@ -5,244 +5,6 @@ assignees: title: Monitoring Node Health --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -## Node Problem Detector - -*Node problem detector* is a [DaemonSet](/docs/admin/daemons/) monitoring the -node health. It collects node problems from various daemons and reports them -to the apiserver as [NodeCondition](/docs/admin/node/#node-condition) and -[Event](/docs/api-reference/v1/definitions/#_v1_event). - -It supports some known kernel issue detection now, and will detect more and -more node problems over time. - -Currently Kubernetes won't take any action on the node conditions and events -generated by node problem detector. In the future, a remedy system could be -introduced to deal with node problems. - -See more information -[here](https://github.com/kubernetes/node-problem-detector). - -## Limitations - -* The kernel issue detection of node problem detector only supports file based -kernel log now. It doesn't support log tools like journald. - -* The kernel issue detection of node problem detector has assumption on kernel -log format, and now it only works on Ubuntu and Debian. However, it is easy to extend -it to [support other log format](/docs/admin/node-problem/#support-other-log-format). - -## Enable/Disable in GCE cluster - -Node problem detector is [running as a cluster addon](cluster-large.md/#addon-resources) enabled by default in the -gce cluster. - -You can enable/disable it by setting the environment variable -`KUBE_ENABLE_NODE_PROBLEM_DETECTOR` before `kube-up.sh`. - -## Use in Other Environment - -To enable node problem detector in other environment outside of GCE, you can use -either `kubectl` or addon pod. - -### Kubectl - -This is the recommended way to start node problem detector outside of GCE. It -provides more flexible management, such as overwriting the default -configuration to fit it into your environment or detect -customized node problems. - -* **Step 1:** Create `node-problem-detector.yaml`: - -```yaml -apiVersion: extensions/v1beta1 -kind: DaemonSet -metadata: - name: node-problem-detector-v0.1 - namespace: kube-system - labels: - k8s-app: node-problem-detector - version: v0.1 - kubernetes.io/cluster-service: "true" -spec: - template: - metadata: - labels: - k8s-app: node-problem-detector - version: v0.1 - kubernetes.io/cluster-service: "true" - spec: - hostNetwork: true - containers: - - name: node-problem-detector - image: gcr.io/google_containers/node-problem-detector:v0.1 - securityContext: - privileged: true - resources: - limits: - cpu: "200m" - memory: "100Mi" - requests: - cpu: "20m" - memory: "20Mi" - volumeMounts: - - name: log - mountPath: /log - readOnly: true - volumes: - - name: log - hostPath: - path: /var/log/ -``` - -***Notice that you should make sure the system log directory is right for your -OS distro.*** - -* **Step 2:** Start node problem detector with `kubectl`: - -```shell -kubectl create -f node-problem-detector.yaml -``` - -### Addon Pod - -This is for those who have their own cluster bootstrap solution, and don't need -to overwrite the default configuration. They could leverage the addon pod to -further automate the deployment. - -Just create `node-problem-detector.yaml`, and put it under the addon pods directory -`/etc/kubernetes/addons/node-problem-detector` on master node. - -## Overwrite the Configuration - -The [default configuration](https://github.com/kubernetes/node-problem-detector/tree/v0.1/config) -is embedded when building the docker image of node problem detector. - -However, you can use [ConfigMap](/docs/user-guide/configmap/) to overwrite it -following the steps: - -* **Step 1:** Change the config files in `config/`. -* **Step 2:** Create the ConfigMap `node-problem-detector-config` with `kubectl create configmap -node-problem-detector-config --from-file=config/`. -* **Step 3:** Change the `node-problem-detector.yaml` to use the ConfigMap: - -```yaml -apiVersion: extensions/v1beta1 -kind: DaemonSet -metadata: - name: node-problem-detector-v0.1 - namespace: kube-system - labels: - k8s-app: node-problem-detector - version: v0.1 - kubernetes.io/cluster-service: "true" -spec: - template: - metadata: - labels: - k8s-app: node-problem-detector - version: v0.1 - kubernetes.io/cluster-service: "true" - spec: - hostNetwork: true - containers: - - name: node-problem-detector - image: gcr.io/google_containers/node-problem-detector:v0.1 - securityContext: - privileged: true - resources: - limits: - cpu: "200m" - memory: "100Mi" - requests: - cpu: "20m" - memory: "20Mi" - volumeMounts: - - name: log - mountPath: /log - readOnly: true - - name: config # Overwrite the config/ directory with ConfigMap volume - mountPath: /config - readOnly: true - volumes: - - name: log - hostPath: - path: /var/log/ - - name: config # Define ConfigMap volume - configMap: - name: node-problem-detector-config -``` - -* **Step 4:** Re-create the node problem detector with the new yaml file: - -```shell -kubectl delete -f node-problem-detector.yaml # If you have a node-problem-detector running -kubectl create -f node-problem-detector.yaml -``` - -***Notice that this approach only applies to node problem detector started with `kubectl`.*** - -For node problem detector running as cluster addon, because addon manager doesn't support -ConfigMap, configuration overwriting is not supported now. - -## Kernel Monitor - -*Kernel Monitor* is a problem daemon in node problem detector. It monitors kernel log -and detects known kernel issues following predefined rules. - -The Kernel Monitor matches kernel issues according to a set of predefined rule list in -[`config/kernel-monitor.json`](https://github.com/kubernetes/node-problem-detector/blob/v0.1/config/kernel-monitor.json). -The rule list is extensible, and you can always extend it by [overwriting the -configuration](/docs/admin/node-problem/#overwrite-the-configuration). - -### Add New NodeConditions - -To support new node conditions, you can extend the `conditions` field in -`config/kernel-monitor.json` with new condition definition: - -```json -{ - "type": "NodeConditionType", - "reason": "CamelCaseDefaultNodeConditionReason", - "message": "arbitrary default node condition message" -} -``` - -### Detect New Problems - -To detect new problems, you can extend the `rules` field in `config/kernel-monitor.json` -with new rule definition: - -```json -{ - "type": "temporary/permanent", - "condition": "NodeConditionOfPermanentIssue", - "reason": "CamelCaseShortReason", - "message": "regexp matching the issue in the kernel log" -} -``` - -### Change Log Path - -Kernel log in different OS distros may locate in different path. The `log` -field in `config/kernel-monitor.json` is the log path inside the container. -You can always configure it to match your OS distro. - -### Support Other Log Format - -Kernel monitor uses [`Translator`](https://github.com/kubernetes/node-problem-detector/blob/v0.1/pkg/kernelmonitor/translator/translator.go) -plugin to translate kernel log the internal data structure. It is easy to -implement a new translator for a new log format. - -## Caveats - -It is recommended to run the node problem detector in your cluster to monitor -the node health. However, you should be aware that this will introduce extra -resource overhead on each node. Usually this is fine, because: - -* The kernel log is generated relatively slowly. -* Resource limit is set for node problem detector. -* Even under high load, the resource usage is acceptable. -(see [benchmark result](https://github.com/kubernetes/node-problem-detector/issues/2#issuecomment-220255629)) +[Monitoring Node Health](/docs/tasks/debug-application-cluster/monitor-node-health/) diff --git a/docs/admin/node.md b/docs/admin/node.md index 0923169256..5e591ea99a 100644 --- a/docs/admin/node.md +++ b/docs/admin/node.md @@ -172,10 +172,13 @@ register itself with the API server. This is the preferred pattern, used by mos For self-registration, the kubelet is started with the following options: - - `--api-servers=` - Location of the apiservers. - - `--kubeconfig=` - Path to credentials to authenticate itself to the apiserver. - - `--cloud-provider=` - How to talk to a cloud provider to read metadata about itself. + - `--api-servers` - Location of the apiservers. + - `--kubeconfig` - Path to credentials to authenticate itself to the apiserver. + - `--cloud-provider` - How to talk to a cloud provider to read metadata about itself. - `--register-node` - Automatically register with the API server. + - `--node-ip` IP address of the node. + - `--node-labels` - Labels to add when registering the node in the cluster. + - `--node-status-update-frequency` - Specifies how often kubelet posts node status to master. Currently, any kubelet is authorized to create/modify any node resource, but in practice it only creates/modifies its own. (In the future, we plan to only allow a kubelet to modify its own node resource.) diff --git a/docs/admin/out-of-resource.md b/docs/admin/out-of-resource.md index 30b8744624..00f92cecf7 100644 --- a/docs/admin/out-of-resource.md +++ b/docs/admin/out-of-resource.md @@ -6,364 +6,6 @@ assignees: title: Configuring Out Of Resource Handling --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -The `kubelet` needs to preserve node stability when available compute resources are low. - -This is especially important when dealing with incompressible resources such as memory or disk. - -If either resource is exhausted, the node would become unstable. - -## Eviction Policy - -The `kubelet` can pro-actively monitor for and prevent against total starvation of a compute resource. In -cases where it could appear to occur, the `kubelet` can pro-actively fail one or more pods in order to reclaim -the starved resource. When the `kubelet` fails a pod, it terminates all containers in the pod, and the `PodPhase` -is transitioned to `Failed`. - -### Eviction Signals - -The `kubelet` can support the ability to trigger eviction decisions on the signals described in the -table below. The value of each signal is described in the description column based on the `kubelet` -summary API. - -| Eviction Signal | Description | -|----------------------------|-----------------------------------------------------------------------| -| `memory.available` | `memory.available` := `node.status.capacity[memory]` - `node.stats.memory.workingSet` | -| `nodefs.available` | `nodefs.available` := `node.stats.fs.available` | -| `nodefs.inodesFree` | `nodefs.inodesFree` := `node.stats.fs.inodesFree` | -| `imagefs.available` | `imagefs.available` := `node.stats.runtime.imagefs.available` | -| `imagefs.inodesFree` | `imagefs.inodesFree` := `node.stats.runtime.imagefs.inodesFree` | - -Each of the above signals support either a literal or percentage based value. The percentage based value -is calculated relative to the total capacity associated with each signal. - -`kubelet` supports only two filesystem partitions. - -1. The `nodefs` filesystem that kubelet uses for volumes, daemon logs, etc. -1. The `imagefs` filesystem that container runtimes uses for storing images and container writable layers. - -`imagefs` is optional. `kubelet` auto-discovers these filesystems using cAdvisor. `kubelet` does not care about any -other filesystems. Any other types of configurations are not currently supported by the kubelet. For example, it is -*not OK* to store volumes and logs in a dedicated `filesystem`. - -In future releases, the `kubelet` will deprecate the existing [garbage collection](/docs/admin/garbage-collection/) -support in favor of eviction in response to disk pressure. - -### Eviction Thresholds - -The `kubelet` supports the ability to specify eviction thresholds that trigger the `kubelet` to reclaim resources. - -Each threshold is of the following form: - -`` - -* valid `eviction-signal` tokens as defined above. -* valid `operator` tokens are `<` -* valid `quantity` tokens must match the quantity representation used by Kubernetes -* an eviction threshold can be expressed as a percentage if ends with `%` token. - -For example, if a node has `10Gi` of memory, and the desire is to induce eviction -if available memory falls below `1Gi`, an eviction threshold can be specified as either -of the following (but not both). - -* `memory.available<10%` -* `memory.available<1Gi` - -#### Soft Eviction Thresholds - -A soft eviction threshold pairs an eviction threshold with a required -administrator specified grace period. No action is taken by the `kubelet` -to reclaim resources associated with the eviction signal until that grace -period has been exceeded. If no grace period is provided, the `kubelet` will -error on startup. - -In addition, if a soft eviction threshold has been met, an operator can -specify a maximum allowed pod termination grace period to use when evicting -pods from the node. If specified, the `kubelet` will use the lesser value among -the `pod.Spec.TerminationGracePeriodSeconds` and the max allowed grace period. -If not specified, the `kubelet` will kill pods immediately with no graceful -termination. - -To configure soft eviction thresholds, the following flags are supported: - -* `eviction-soft` describes a set of eviction thresholds (e.g. `memory.available<1.5Gi`) that if met over a -corresponding grace period would trigger a pod eviction. -* `eviction-soft-grace-period` describes a set of eviction grace periods (e.g. `memory.available=1m30s`) that -correspond to how long a soft eviction threshold must hold before triggering a pod eviction. -* `eviction-max-pod-grace-period` describes the maximum allowed grace period (in seconds) to use when terminating -pods in response to a soft eviction threshold being met. - -#### Hard Eviction Thresholds - -A hard eviction threshold has no grace period, and if observed, the `kubelet` -will take immediate action to reclaim the associated starved resource. If a -hard eviction threshold is met, the `kubelet` will kill the pod immediately -with no graceful termination. - -To configure hard eviction thresholds, the following flag is supported: - -* `eviction-hard` describes a set of eviction thresholds (e.g. `memory.available<1Gi`) that if met -would trigger a pod eviction. - -The `kubelet` has the following default hard eviction thresholds: - -* `--eviction-hard=memory.available<100Mi` - -### Eviction Monitoring Interval - -The `kubelet` evaluates eviction thresholds per its configured housekeeping interval. - -* `housekeeping-interval` is the interval between container housekeepings. - -### Node Conditions - -The `kubelet` will map one or more eviction signals to a corresponding node condition. - -If a hard eviction threshold has been met, or a soft eviction threshold has been met -independent of its associated grace period, the `kubelet` will report a condition that -reflects the node is under pressure. - -The following node conditions are defined that correspond to the specified eviction signal. - -| Node Condition | Eviction Signal | Description | -|-------------------------|-------------------------------|--------------------------------------------| -| `MemoryPressure` | `memory.available` | Available memory on the node has satisfied an eviction threshold | -| `DiskPressure` | `nodefs.available`, `nodefs.inodesFree`, `imagefs.available`, or `imagefs.inodesFree` | Available disk space and inodes on either the node's root filesytem or image filesystem has satisfied an eviction threshold | - -The `kubelet` will continue to report node status updates at the frequency specified by -`--node-status-update-frequency` which defaults to `10s`. - -### Oscillation of node conditions - -If a node is oscillating above and below a soft eviction threshold, but not exceeding -its associated grace period, it would cause the corresponding node condition to -constantly oscillate between true and false, and could cause poor scheduling decisions -as a consequence. - -To protect against this oscillation, the following flag is defined to control how -long the `kubelet` must wait before transitioning out of a pressure condition. - -* `eviction-pressure-transition-period` is the duration for which the `kubelet` has -to wait before transitioning out of an eviction pressure condition. - -The `kubelet` would ensure that it has not observed an eviction threshold being met -for the specified pressure condition for the period specified before toggling the -condition back to `false`. - -### Reclaiming node level resources - -If an eviction threshold has been met and the grace period has passed, -the `kubelet` will initiate the process of reclaiming the pressured resource -until it has observed the signal has gone below its defined threshold. - -The `kubelet` attempts to reclaim node level resources prior to evicting end-user pods. If -disk pressure is observed, the `kubelet` reclaims node level resources differently if the -machine has a dedicated `imagefs` configured for the container runtime. - -#### With Imagefs - -If `nodefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order: - -1. Delete dead pods/containers - -If `imagefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order: - -1. Delete all unused images - -#### Without Imagefs - -If `nodefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order: - -1. Delete dead pods/containers -1. Delete all unused images - -### Evicting end-user pods - -If the `kubelet` is unable to reclaim sufficient resource on the node, -it will begin evicting pods. - -The `kubelet` ranks pods for eviction as follows: - -* by their quality of service -* by the consumption of the starved compute resource relative to the pods scheduling request. - -As a result, pod eviction occurs in the following order: - -* `BestEffort` pods that consume the most of the starved resource are failed -first. -* `Burstable` pods that consume the greatest amount of the starved resource -relative to their request for that resource are killed first. If no pod -has exceeded its request, the strategy targets the largest consumer of the -starved resource. -* `Guaranteed` pods that consume the greatest amount of the starved resource -relative to their request are killed first. If no pod has exceeded its request, -the strategy targets the largest consumer of the starved resource. - -A `Guaranteed` pod is guaranteed to never be evicted because of another pod's -resource consumption. If a system daemon (i.e. `kubelet`, `docker`, `journald`, etc.) -is consuming more resources than were reserved via `system-reserved` or `kube-reserved` allocations, -and the node only has `Guaranteed` pod(s) remaining, then the node must choose to evict a -`Guaranteed` pod in order to preserve node stability, and to limit the impact -of the unexpected consumption to other `Guaranteed` pod(s). - -Local disk is a `BestEffort` resource. If necessary, `kubelet` will evict pods one at a time to reclaim -disk when `DiskPressure` is encountered. The `kubelet` will rank pods by quality of service. If the `kubelet` -is responding to `inode` starvation, it will reclaim `inodes` by evicting pods with the lowest quality of service -first. If the `kubelet` is responding to lack of available disk, it will rank pods within a quality of service -that consumes the largest amount of disk and kill those first. - -#### With Imagefs - -If `nodefs` is triggering evictions, `kubelet` will sort pods based on the usage on `nodefs` -- local volumes + logs of all its containers. - -If `imagefs` is triggering evictions, `kubelet` will sort pods based on the writable layer usage of all its containers. - -#### Without Imagefs - -If `nodefs` is triggering evictions, `kubelet` will sort pods based on their total disk usage -- local volumes + logs & writable layer of all its containers. - -### Minimum eviction reclaim - -In certain scenarios, eviction of pods could result in reclamation of small amount of resources. This can result in -`kubelet` hitting eviction thresholds in repeated successions. In addition to that, eviction of resources like `disk`, - is time consuming. - -To mitigate these issues, `kubelet` can have a per-resource `minimum-reclaim`. Whenever `kubelet` observes -resource pressure, `kubelet` will attempt to reclaim at least `minimum-reclaim` amount of resource below -the configured eviction threshold. - -For example, with the following configuration: - -``` ---eviction-hard=memory.available<500Mi,nodefs.available<1Gi,imagefs.available<100Gi ---eviction-minimum-reclaim="memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi"` -``` - -If an eviction threshold is triggered for `memory.available`, the `kubelet` will work to ensure -that `memory.available` is at least `500Mi`. For `nodefs.available`, the `kubelet` will work -to ensure that `nodefs.available` is at least `1.5Gi`, and for `imagefs.available` it will -work to ensure that `imagefs.available` is at least `102Gi` before no longer reporting pressure -on their associated resources. - -The default `eviction-minimum-reclaim` is `0` for all resources. - -### Scheduler - -The node will report a condition when a compute resource is under pressure. The -scheduler views that condition as a signal to dissuade placing additional -pods on the node. - -| Node Condition | Scheduler Behavior | -| ---------------- | ------------------------------------------------ | -| `MemoryPressure` | No new `BestEffort` pods are scheduled to the node. | -| `DiskPressure` | No new pods are scheduled to the node. | - -## Node OOM Behavior - -If the node experiences a system OOM (out of memory) event prior to the `kubelet` is able to reclaim memory, -the node depends on the [oom_killer](https://lwn.net/Articles/391222/) to respond. - -The `kubelet` sets a `oom_score_adj` value for each container based on the quality of service for the pod. - -| Quality of Service | oom_score_adj | -|----------------------------|-----------------------------------------------------------------------| -| `Guaranteed` | -998 | -| `BestEffort` | 1000 | -| `Burstable` | min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999) | - -If the `kubelet` is unable to reclaim memory prior to a node experiencing system OOM, the `oom_killer` will calculate -an `oom_score` based on the percentage of memory its using on the node, and then add the `oom_score_adj` to get an -effective `oom_score` for the container, and then kills the container with the highest score. - -The intended behavior should be that containers with the lowest quality of service that -are consuming the largest amount of memory relative to the scheduling request should be killed first in order -to reclaim memory. - -Unlike pod eviction, if a pod container is OOM killed, it may be restarted by the `kubelet` based on its `RestartPolicy`. - -## Best Practices - -### Schedulable resources and eviction policies - -Let's imagine the following scenario: - -* Node memory capacity: `10Gi` -* Operator wants to reserve 10% of memory capacity for system daemons (kernel, `kubelet`, etc.) -* Operator wants to evict pods at 95% memory utilization to reduce thrashing and incidence of system OOM. - -To facilitate this scenario, the `kubelet` would be launched as follows: - -``` ---eviction-hard=memory.available<500Mi ---system-reserved=memory=1.5Gi -``` - -Implicit in this configuration is the understanding that "System reserved" should include the amount of memory -covered by the eviction threshold. - -To reach that capacity, either some pod is using more than its request, or the system is using more than `500Mi`. - -This configuration will ensure that the scheduler does not place pods on a node that immediately induce memory pressure -and trigger eviction assuming those pods use less than their configured request. - -### DaemonSet - -It is never desired for a `kubelet` to evict a pod that was derived from -a `DaemonSet` since the pod will immediately be recreated and rescheduled -back to the same node. - -At the moment, the `kubelet` has no ability to distinguish a pod created -from `DaemonSet` versus any other object. If/when that information is -available, the `kubelet` could pro-actively filter those pods from the -candidate set of pods provided to the eviction strategy. - -In general, it is strongly recommended that `DaemonSet` not -create `BestEffort` pods to avoid being identified as a candidate pod -for eviction. Instead `DaemonSet` should ideally launch `Guaranteed` pods. - -## Deprecation of existing feature flags to reclaim disk - -`kubelet` has been freeing up disk space on demand to keep the node stable. - -As disk based eviction matures, the following `kubelet` flags will be marked for deprecation -in favor of the simpler configuration supported around eviction. - -| Existing Flag | New Flag | -| ------------- | -------- | -| `--image-gc-high-threshold` | `--eviction-hard` or `eviction-soft` | -| `--image-gc-low-threshold` | `--eviction-minimum-reclaim` | -| `--maximum-dead-containers` | deprecated | -| `--maximum-dead-containers-per-container` | deprecated | -| `--minimum-container-ttl-duration` | deprecated | -| `--low-diskspace-threshold-mb` | `--eviction-hard` or `eviction-soft` | -| `--outofdisk-transition-frequency` | `--eviction-pressure-transition-period` | - -## Known issues - -### kubelet may not observe memory pressure right away - -The `kubelet` currently polls `cAdvisor` to collect memory usage stats at a regular interval. If memory usage -increases within that window rapidly, the `kubelet` may not observe `MemoryPressure` fast enough, and the `OOMKiller` -will still be invoked. We intend to integrate with the `memcg` notification API in a future release to reduce this -latency, and instead have the kernel tell us when a threshold has been crossed immediately. - -If you are not trying to achieve extreme utilization, but a sensible measure of overcommit, a viable workaround for -this issue is to set eviction thresholds at approximately 75% capacity. This increases the ability of this feature -to prevent system OOMs, and promote eviction of workloads so cluster state can rebalance. - -### kubelet may evict more pods than needed - -The pod eviction may evict more pods than needed due to stats collection timing gap. This can be mitigated by adding -the ability to get root container stats on an on-demand basis (https://github.com/google/cadvisor/issues/1247) in the future. - -### How kubelet ranks pods for eviction in response to inode exhaustion - -At this time, it is not possible to know how many inodes were consumed by a particular container. If the `kubelet` observes -inode exhaustion, it will evict pods by ranking them by quality of service. The following issue has been opened in cadvisor -to track per container inode consumption (https://github.com/google/cadvisor/issues/1422) which would allow us to rank pods -by inode consumption. For example, this would let us identify a container that created large numbers of 0 byte files, and evict -that pod over others. +[Configuring Out of Resource Handling](/docs/concepts/cluster-administration/out-of-resource/) diff --git a/docs/admin/rescheduler.md b/docs/admin/rescheduler.md index 9e3fc61c39..d8d418ac2b 100644 --- a/docs/admin/rescheduler.md +++ b/docs/admin/rescheduler.md @@ -6,52 +6,6 @@ assignees: title: Guaranteed Scheduling For Critical Add-On Pods --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -## Overview - -In addition to Kubernetes core components like api-server, scheduler, controller-manager running on a master machine -there are a number of add-ons which, for various reasons, must run on a regular cluster node (rather than the Kubernetes master). -Some of these add-ons are critical to a fully functional cluster, such as Heapster, DNS, and UI. -A cluster may stop working properly if a critical add-on is evicted (either manually or as a side effect of another operation like upgrade) -and becomes pending (for example when the cluster is highly utilized and either there are other pending pods that schedule into the space -vacated by the evicted critical add-on pod or the amount of resources available on the node changed for some other reason). - -## Rescheduler: guaranteed scheduling of critical add-ons - -Rescheduler ensures that critical add-ons are always scheduled -(assuming the cluster has enough resources to run the critical add-on pods in the absence of regular pods). -If the scheduler determines that no node has enough free resources to run the critical add-on pod -given the pods that are already running in the cluster -(indicated by critical add-on pod's pod condition PodScheduled set to false, the reason set to Unschedulable) -the rescheduler tries to free up space for the add-on by evicting some pods; then the scheduler will schedule the add-on pod. - -To avoid situation when another pod is scheduled into the space prepared for the critical add-on, -the chosen node gets a temporary taint "CriticalAddonsOnly" before the eviction(s) -(see [more details](https://github.com/kubernetes/kubernetes/blob/master/docs/design/taint-toleration-dedicated.md)). -Each critical add-on has to tolerate it, -while the other pods shouldn't tolerate the taint. The taint is removed once the add-on is successfully scheduled. - -*Warning:* currently there is no guarantee which node is chosen and which pods are being killed -in order to schedule critical pods, so if rescheduler is enabled your pods might be occasionally -killed for this purpose. - -## Config - -Rescheduler doesn't have any user facing configuration (component config) or API. -It's enabled by default. It can be disabled: - -* during cluster setup by setting `ENABLE_RESCHEDULER` flag to `false` -* on running cluster by deleting its manifest from master node -(default path `/etc/kubernetes/manifests/rescheduler.manifest`) - -### Marking add-on as critical - -To be critical an add-on has to run in `kube-system` namespace (configurable via flag) -and have the following annotations specified: - -* `scheduler.alpha.kubernetes.io/critical-pod` set to empty string -* `scheduler.alpha.kubernetes.io/tolerations` set to `[{"key":"CriticalAddonsOnly", "operator":"Exists"}]` - -The first one marks a pod a critical. The second one is required by Rescheduler algorithm. +[Guaranteed Scheduling for Critical Add-On Pods](/docs/concepts/cluster-administration/guaranteed-scheduling-critical-addon-pods/) diff --git a/docs/admin/resourcequota/index.md b/docs/admin/resourcequota/index.md index 24d7a09246..f90049dfdc 100644 --- a/docs/admin/resourcequota/index.md +++ b/docs/admin/resourcequota/index.md @@ -4,237 +4,6 @@ assignees: title: Resource Quotas --- -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. +{% include user-guide-content-moved.md %} -Resource quotas are a tool for administrators to address this concern. - -A resource quota, defined by a `ResourceQuota` object, provides constraints that limit -aggregate resource consumption per namespace. It can limit the quantity of objects that can -be created in a namespace by type, as well as the total amount of compute resources that may -be consumed by resources in that project. - -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 one or more Resource Quota objects for each namespace. -- Users create resources (pods, services, etc.) in the namespace, and the quota system - tracks usage to ensure it does not exceed hard resource limits defined in a Resource Quota. -- If creating or updating a resource violates a quota constraint, the request will fail with HTTP - status code `403 FORBIDDEN` with a message explaining the constraint that would have been violated. -- If quota is enabled in a namespace for compute resources like `cpu` and `memory`, users must specify - requests or limits for those values; otherwise, the quota system may reject pod creation. Hint: Use - the LimitRange admission controller to force defaults for pods that make no compute resource requirements. - See the [walkthrough](/docs/admin/resourcequota/walkthrough/) for an example 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 created resources. - -## 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 - -You can limit the total sum of [compute resources](/docs/user-guide/compute-resources) that can be requested in a given namespace. - -The following resource types are supported: - -| Resource Name | Description | -| --------------------- | ----------------------------------------------------------- | -| `cpu` | Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. | -| `limits.cpu` | Across all pods in a non-terminal state, the sum of CPU limits cannot exceed this value. | -| `limits.memory` | Across all pods in a non-terminal state, the sum of memory limits cannot exceed this value. | -| `memory` | Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. | -| `requests.cpu` | Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. | -| `requests.memory` | Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. | - -## Storage Resource Quota - -You can limit the total sum of [storage resources](/docs/user-guide/persistent-volumes) that can be requested in a given namespace. - -In addition, you can limit consumption of storage resources based on associated storage-class. - -| Resource Name | Description | -| --------------------- | ----------------------------------------------------------- | -| `requests.storage` | Across all persistent volume claims, the sum of storage requests cannot exceed this value. | -| `persistentvolumeclaims` | The total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. | -| `.storageclass.storage.k8s.io/requests.storage` | Across all persistent volume claims associated with the storage-class-name, the sum of storage requests cannot exceed this value. | -| `.storageclass.storage.k8s.io/persistentvolumeclaims` | Across all persistent volume claims associated with the storage-class-name, the total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. | - -For example, if an operator wants to quota storage with `gold` storage class separate from `bronze` storage class, the operator can -define a quota as follows: - -* `gold.storageclass.storage.k8s.io/requests.storage: 500Gi` -* `bronze.storageclass.storage.k8s.io/requests.storage: 100Gi` - -## Object Count Quota - -The number of objects of a given type can be restricted. The following types -are supported: - -| Resource Name | Description | -| ------------------------------- | ------------------------------------------------- | -| `configmaps` | The total number of config maps that can exist in the namespace. | -| `persistentvolumeclaims` | The total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. | -| `pods` | The total number of pods in a non-terminal state that can exist in the namespace. A pod is in a terminal state if `status.phase in (Failed, Succeeded)` is true. | -| `replicationcontrollers` | The total number of replication controllers that can exist in the namespace. | -| `resourcequotas` | The total number of [resource quotas](/docs/admin/admission-controllers/#resourcequota) that can exist in the namespace. | -| `services` | The total number of services that can exist in the namespace. | -| `services.loadbalancers` | The total number of services of type load balancer that can exist in the namespace. | -| `services.nodeports` | The total number of services of type node port that can exist in the namespace. | -| `secrets` | The total number of secrets that can exist in the namespace. | - -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. - -## Quota Scopes - -Each quota can have an associated set of scopes. A quota will only measure usage for a resource if it matches -the intersection of enumerated scopes. - -When a scope is added to the quota, it limits the number of resources it supports to those that pertain to the scope. -Resources specified on the quota outside of the allowed set results in a validation error. - -| Scope | Description | -| ----- | ----------- | -| `Terminating` | Match pods where `spec.activeDeadlineSeconds >= 0` | -| `NotTerminating` | Match pods where `spec.activeDeadlineSeconds is nil` | -| `BestEffort` | Match pods that have best effort quality of service. | -| `NotBestEffort` | Match pods that do not have best effort quality of service. | - -The `BestEffort` scope restricts a quota to tracking the following resource: `pods` - -The `Terminating`, `NotTerminating`, and `NotBestEffort` scopes restrict a quota to tracking the following resources: - -* `cpu` -* `limits.cpu` -* `limits.memory` -* `memory` -* `pods` -* `requests.cpu` -* `requests.memory` - -## Requests vs Limits - -When allocating compute resources, each container may specify a request and a limit value for either CPU or memory. -The quota can be configured to quota either value. - -If the quota has a value specified for `requests.cpu` or `requests.memory`, then it requires that every incoming -container makes an explicit request for those resources. If the quota has a value specified for `limits.cpu` or `limits.memory`, -then it requires that every incoming container specifies an explicit limit for those resources. - -## Viewing and Setting Quotas - -Kubectl supports creating, updating, and viewing quotas: - -```shell -$ kubectl create namespace myspace - -$ cat < compute-resources.yaml -apiVersion: v1 -kind: ResourceQuota -metadata: - name: compute-resources -spec: - hard: - pods: "4" - requests.cpu: "1" - requests.memory: 1Gi - limits.cpu: "2" - limits.memory: 2Gi -EOF -$ kubectl create -f ./compute-resources.yaml --namespace=myspace - -$ cat < object-counts.yaml -apiVersion: v1 -kind: ResourceQuota -metadata: - name: object-counts -spec: - hard: - configmaps: "10" - persistentvolumeclaims: "4" - replicationcontrollers: "20" - secrets: "10" - services: "10" - services.loadbalancers: "2" -EOF -$ kubectl create -f ./object-counts.yaml --namespace=myspace - -$ kubectl get quota --namespace=myspace -NAME AGE -compute-resources 30s -object-counts 32s - -$ kubectl describe quota compute-resources --namespace=myspace -Name: compute-resources -Namespace: myspace -Resource Used Hard --------- ---- ---- -limits.cpu 0 2 -limits.memory 0 2Gi -pods 0 4 -requests.cpu 0 1 -requests.memory 0 1Gi - -$ kubectl describe quota object-counts --namespace=myspace -Name: object-counts -Namespace: myspace -Resource Used Hard --------- ---- ---- -configmaps 0 10 -persistentvolumeclaims 0 4 -replicationcontrollers 0 20 -secrets 1 10 -services 0 10 -services.loadbalancers 0 2 -``` - -## 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. +[Resource Quotas](/docs/concepts/policy/resource-quotas/) diff --git a/docs/admin/resourcequota/limitstorageconsumption.md b/docs/admin/resourcequota/limitstorageconsumption.md index 1c88088d8f..d1f3116cb0 100644 --- a/docs/admin/resourcequota/limitstorageconsumption.md +++ b/docs/admin/resourcequota/limitstorageconsumption.md @@ -4,75 +4,8 @@ assignees: - janetkuo title: Limiting Storage Consumption --- -This example demonstrates an easy way to limit the amount of storage consumed in a namespace. -The following resources are used in the demonstration: +{% include user-guide-content-moved.md %} -* [Resource Quota](/docs/admin/resourcequota/) -* [Limit Range](/docs/admin/limitrange/) -* [Persistent Volume Claim](/docs/user-guide/persistent-volumes/) +[Limiting Storage Consumption](/docs/tasks/administer-cluster/limit-storage-consumption/) -This example assumes you have a functional Kubernetes setup. - -## Limiting Storage Consumption - -The cluster-admin is operating a cluster on behalf of a user population and the admin wants to control -how much storage a single namespace can consume in order to control cost. - -The admin would like to limit: - -1. The number of persistent volume claims in a namespace -2. The amount of storage each claim can request -3. The amount of cumulative storage the namespace can have - - -## LimitRange to limit requests for storage - -Adding a `LimitRange` to a namespace enforces storage request sizes to a minimum and maximum. Storage is requested -via `PersistentVolumeClaim`. The admission controller that enforces limit ranges will reject any PVC that is above or below -the values set by the admin. - -In this example, a PVC requesting 10Gi of storage would be rejected because it exceeds the 2Gi max. - -``` -apiVersion: v1 -kind: LimitRange -metadata: - name: storagelimits -spec: - limits: - - type: PersistentVolumeClaim - max: - storage: 2Gi - min: - storage: 1Gi -``` - -Minimum storage requests are used when the underlying storage provider requires certain minimums. For example, -AWS EBS volumes have a 1Gi minimum requirement. - -## StorageQuota to limit PVC count and cumulative storage capacity - -Admins can limit the number of PVCs in a namespace as well as the cumulative capacity of those PVCs. New PVCs that exceed -either maximum value will be rejected. - -In this example, a 6th PVC in the namespace would be rejected because it exceeds the maximum count of 5. Alternatively, -a 5Gi maximum quota when combined with the 2Gi max limit above, cannot have 3 PVCs where each has 2Gi. That would be 6Gi requested - for a namespace capped at 5Gi. - -``` -apiVersion: v1 -kind: ResourceQuota -metadata: - name: storagequota -spec: - hard: - persistentvolumeclaims: "5" - requests.storage: "5Gi" -``` - -## Summary - -A limit range can put a ceiling on how much storage is requested while a resource quota can effectively cap the storage -consumed by a namespace through claim counts and cumulative storage capacity. The allows a cluster-admin to plan their -cluster's storage budget without risk of any one project going over their allotment. diff --git a/docs/admin/resourcequota/walkthrough.md b/docs/admin/resourcequota/walkthrough.md index 1120e7550d..cf90328c96 100644 --- a/docs/admin/resourcequota/walkthrough.md +++ b/docs/admin/resourcequota/walkthrough.md @@ -5,362 +5,6 @@ assignees: title: Applying Resource Quotas and Limits --- -This example demonstrates a typical setup to control for resource usage in a namespace. +{% include user-guide-content-moved.md %} -It demonstrates using the following resources: - -* [Namespace](/docs/admin/namespaces) -* [Resource Quota](/docs/admin/resourcequota/) -* [Limit Range](/docs/admin/limitrange/) - -This example assumes you have a functional Kubernetes setup. - -## Scenario - -The cluster-admin is operating a cluster on behalf of a user population and the cluster-admin -wants to control the amount of resources that can be consumed in a particular namespace to promote -fair sharing of the cluster and control cost. - -The cluster-admin has the following goals: - -* Limit the amount of compute resource for running pods -* Limit the number of persistent volume claims to control access to storage -* Limit the number of load balancers to control cost -* Prevent the use of node ports to preserve scarce resources -* Provide default compute resource requests to enable better scheduling decisions - -## 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 STATUS AGE -default Active 2m -kube-system Active 2m -quota-example Active 39s -``` - -## Step 2: Apply an object-count quota to the namespace - -The cluster-admin wants to control the following resources: - -* persistent volume claims -* load balancers -* node ports - -Let's create a simple quota that controls object counts for those resource types in this namespace. - -```shell -$ kubectl create -f docs/admin/resourcequota/object-counts.yaml --namespace=quota-example -resourcequota "object-counts" created -``` - -The quota system will observe that a quota has been created, and will calculate consumption -in the namespace in response. This should happen quickly. - -Let's describe the quota to see what is currently being consumed in this namespace: - -```shell -$ kubectl describe quota object-counts --namespace=quota-example -Name: object-counts -Namespace: quota-example -Resource Used Hard --------- ---- ---- -persistentvolumeclaims 0 2 -services.loadbalancers 0 2 -services.nodeports 0 0 -``` - -The quota system will now prevent users from creating more than the specified amount for each resource. - - -## Step 3: Apply a compute-resource quota to the namespace - -To limit the amount of compute resource that can be consumed in this namespace, -let's create a quota that tracks compute resources. - -```shell -$ kubectl create -f docs/admin/resourcequota/compute-resources.yaml --namespace=quota-example -resourcequota "compute-resources" created -``` - -Let's describe the quota to see what is currently being consumed in this namespace: - -```shell -$ kubectl describe quota compute-resources --namespace=quota-example -Name: compute-resources -Namespace: quota-example -Resource Used Hard --------- ---- ---- -limits.cpu 0 2 -limits.memory 0 2Gi -pods 0 4 -requests.cpu 0 1 -requests.memory 0 1Gi -``` - -The quota system will now prevent the namespace from having more than 4 non-terminal pods. In -addition, it will enforce that each container in a pod makes a `request` and defines a `limit` for -`cpu` and `memory`. - -## Step 4: 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 -``` - -Now let's look at the pods that were created. - -```shell -$ kubectl get pods --namespace=quota-example -``` - -What happened? I have no pods! Let's describe the deployment to get a view of what is happening. - -```shell -$ kubectl describe deployment nginx --namespace=quota-example -Name: nginx -Namespace: quota-example -CreationTimestamp: Mon, 06 Jun 2016 16:11:37 -0400 -Labels: run=nginx -Selector: run=nginx -Replicas: 0 updated | 1 total | 0 available | 1 unavailable -StrategyType: RollingUpdate -MinReadySeconds: 0 -RollingUpdateStrategy: 1 max unavailable, 1 max surge -OldReplicaSets: -NewReplicaSet: nginx-3137573019 (0/1 replicas created) -... -``` - -A deployment created a corresponding replica set and attempted to size it to create a single pod. - -Let's look at the replica set to get more detail. - -```shell -$ kubectl describe rs nginx-3137573019 --namespace=quota-example -Name: nginx-3137573019 -Namespace: quota-example -Image(s): nginx -Selector: pod-template-hash=3137573019,run=nginx -Labels: pod-template-hash=3137573019 - 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 - --------- -------- ----- ---- ------------- -------- ------ ------- - 4m 7s 11 {replicaset-controller } Warning FailedCreate Error creating: pods "nginx-3137573019-" is forbidden: Failed quota: compute-resources: must specify limits.cpu,limits.memory,requests.cpu,requests.memory -``` - -The Kubernetes API server is rejecting the replica set requests to create a pod because our pods -do not specify `requests` or `limits` for `cpu` and `memory`. - -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 memory - - 256Mi 512Mi - -Container cpu - - 100m 200m - -``` - -If the Kubernetes API server observes a request to create a pod in this namespace, and the containers -in that pod do not make any compute resource requests, a default request and default limit will be applied -as part of admission control. - -In this example, each pod created will have compute resources equivalent to the following: - -```shell -$ kubectl run nginx \ - --image=nginx \ - --replicas=1 \ - --requests=cpu=100m,memory=256Mi \ - --limits=cpu=200m,memory=512Mi \ - --namespace=quota-example -``` - -Now that we have applied default compute resources for our namespace, our replica set should be able to create -its pods. - -```shell -$ kubectl get pods --namespace=quota-example -NAME READY STATUS RESTARTS AGE -nginx-3137573019-fvrig 1/1 Running 0 6m -``` - -And if we print out our quota usage in the namespace: - -```shell -$ kubectl describe quota --namespace=quota-example -Name: compute-resources -Namespace: quota-example -Resource Used Hard --------- ---- ---- -limits.cpu 200m 2 -limits.memory 512Mi 2Gi -pods 1 4 -requests.cpu 100m 1 -requests.memory 256Mi 1Gi - - -Name: object-counts -Namespace: quota-example -Resource Used Hard --------- ---- ---- -persistentvolumeclaims 0 2 -services.loadbalancers 0 2 -services.nodeports 0 0 -``` - -As you can see, the pod that was created is consuming explicit amounts of compute resources, and the usage is being -tracked by Kubernetes properly. - -## Step 5: Advanced quota scopes - -Let's imagine you did not want to specify default compute resource consumption in your namespace. - -Instead, you want to let users run a specific number of `BestEffort` pods in their namespace to take -advantage of slack compute resources, and then require that users make an explicit resource request for -pods that require a higher quality of service. - -Let's create a new namespace with two quotas to demonstrate this behavior: - -```shell -$ kubectl create namespace quota-scopes -namespace "quota-scopes" created -$ kubectl create -f docs/admin/resourcequota/best-effort.yaml --namespace=quota-scopes -resourcequota "best-effort" created -$ kubectl create -f docs/admin/resourcequota/not-best-effort.yaml --namespace=quota-scopes -resourcequota "not-best-effort" created -$ kubectl describe quota --namespace=quota-scopes -Name: best-effort -Namespace: quota-scopes -Scopes: BestEffort - * Matches all pods that have best effort quality of service. -Resource Used Hard --------- ---- ---- -pods 0 10 - - -Name: not-best-effort -Namespace: quota-scopes -Scopes: NotBestEffort - * Matches all pods that do not have best effort quality of service. -Resource Used Hard --------- ---- ---- -limits.cpu 0 2 -limits.memory 0 2Gi -pods 0 4 -requests.cpu 0 1 -requests.memory 0 1Gi -``` - -In this scenario, a pod that makes no compute resource requests will be tracked by the `best-effort` quota. - -A pod that does make compute resource requests will be tracked by the `not-best-effort` quota. - -Let's demonstrate this by creating two deployments: - -```shell -$ kubectl run best-effort-nginx --image=nginx --replicas=8 --namespace=quota-scopes -deployment "best-effort-nginx" created -$ kubectl run not-best-effort-nginx \ - --image=nginx \ - --replicas=2 \ - --requests=cpu=100m,memory=256Mi \ - --limits=cpu=200m,memory=512Mi \ - --namespace=quota-scopes -deployment "not-best-effort-nginx" created -``` - -Even though no default limits were specified, the `best-effort-nginx` deployment will create -all 8 pods. This is because it is tracked by the `best-effort` quota, and the `not-best-effort` -quota will just ignore it. The `not-best-effort` quota will track the `not-best-effort-nginx` -deployment since it creates pods with `Burstable` quality of service. - -Let's list the pods in the namespace: - -```shell -$ kubectl get pods --namespace=quota-scopes -NAME READY STATUS RESTARTS AGE -best-effort-nginx-3488455095-2qb41 1/1 Running 0 51s -best-effort-nginx-3488455095-3go7n 1/1 Running 0 51s -best-effort-nginx-3488455095-9o2xg 1/1 Running 0 51s -best-effort-nginx-3488455095-eyg40 1/1 Running 0 51s -best-effort-nginx-3488455095-gcs3v 1/1 Running 0 51s -best-effort-nginx-3488455095-rq8p1 1/1 Running 0 51s -best-effort-nginx-3488455095-udhhd 1/1 Running 0 51s -best-effort-nginx-3488455095-zmk12 1/1 Running 0 51s -not-best-effort-nginx-2204666826-7sl61 1/1 Running 0 23s -not-best-effort-nginx-2204666826-ke746 1/1 Running 0 23s -``` - -As you can see, all 10 pods have been allowed to be created. - -Let's describe current quota usage in the namespace: - -```shell -$ kubectl describe quota --namespace=quota-scopes -Name: best-effort -Namespace: quota-scopes -Scopes: BestEffort - * Matches all pods that have best effort quality of service. -Resource Used Hard --------- ---- ---- -pods 8 10 - - -Name: not-best-effort -Namespace: quota-scopes -Scopes: NotBestEffort - * Matches all pods that do not have best effort quality of service. -Resource Used Hard --------- ---- ---- -limits.cpu 400m 2 -limits.memory 1Gi 2Gi -pods 2 4 -requests.cpu 200m 1 -requests.memory 512Mi 1Gi -``` - -As you can see, the `best-effort` quota has tracked the usage for the 8 pods we created in -the `best-effort-nginx` deployment, and the `not-best-effort` quota has tracked the usage for -the 2 pods we created in the `not-best-effort-nginx` quota. - -Scopes provide a mechanism to subdivide the set of resources that are tracked by -any quota document to allow greater flexibility in how operators deploy and track resource -consumption. - -In addition to `BestEffort` and `NotBestEffort` scopes, there are scopes to restrict -long-running versus time-bound pods. The `Terminating` scope will match any pod -where `spec.activeDeadlineSeconds is not nil`. The `NotTerminating` scope will match any pod -where `spec.activeDeadlineSeconds is nil`. These scopes allow you to quota pods based on their -anticipated permanence on a node in your cluster. - -## Summary - -Actions that consume node resources for cpu and memory can be subject to hard quota limits defined by the namespace quota. - -Any action that consumes those resources can be tweaked, or can pick up namespace level defaults to meet your end goal. - -Quota can be apportioned based on quality of service and anticipated permanence on a node in your cluster. +[Applying Resource Quotas and Limits](/docs/tasks/configure-pod-container/apply-resource-quota-limit/) diff --git a/docs/admin/salt.md b/docs/admin/salt.md index 05d0ae9250..b570dc8473 100644 --- a/docs/admin/salt.md +++ b/docs/admin/salt.md @@ -10,11 +10,11 @@ The Salt scripts are shared across multiple hosting providers and depending on w ## Salt cluster setup -The **salt-master** service runs on the kubernetes-master [(except on the default GCE setup)](#standalone-salt-configuration-on-gce). +The **salt-master** service runs on the kubernetes-master [(except on the default GCE and OpenStack-Heat setup)](#standalone-salt-configuration-on-gce-and-others). The **salt-minion** service runs on the kubernetes-master and each kubernetes-node in the cluster. -Each salt-minion service is configured to interact with the **salt-master** service hosted on the kubernetes-master via the **master.conf** file [(except on GCE)](#standalone-salt-configuration-on-gce). +Each salt-minion service is configured to interact with the **salt-master** service hosted on the kubernetes-master via the **master.conf** file [(except on GCE and OpenStack-Heat)](#standalone-salt-configuration-on-gce-and-others). ```shell [root@kubernetes-master] $ cat /etc/salt/minion.d/master.conf @@ -25,15 +25,15 @@ The salt-master is contacted by each salt-minion and depending upon the machine If you are running the Vagrant based environment, the **salt-api** service is running on the kubernetes-master. It is configured to enable the vagrant user to introspect the salt cluster in order to find out about machines in the Vagrant environment via a REST API. -## Standalone Salt Configuration on GCE +## Standalone Salt Configuration on GCE and others -On GCE, the master and nodes are all configured as [standalone minions](http://docs.saltstack.com/en/latest/topics/tutorials/standalone_minion.html). The configuration for each VM is derived from the VM's [instance metadata](https://cloud.google.com/compute/docs/metadata) and then stored in Salt grains (`/etc/salt/minion.d/grains.conf`) and pillars (`/srv/salt-overlay/pillar/cluster-params.sls`) that local Salt uses to enforce state. +On GCE and OpenStack, using the Openstack-Heat provider, the master and nodes are all configured as [standalone minions](http://docs.saltstack.com/en/latest/topics/tutorials/standalone_minion.html). The configuration for each VM is derived from the VM's [instance metadata](https://cloud.google.com/compute/docs/metadata) and then stored in Salt grains (`/etc/salt/minion.d/grains.conf`) and pillars (`/srv/salt-overlay/pillar/cluster-params.sls`) that local Salt uses to enforce state. -All remaining sections that refer to master/minion setups should be ignored for GCE. One fallout of the GCE setup is that the Salt mine doesn't exist - there is no sharing of configuration amongst nodes. +All remaining sections that refer to master/minion setups should be ignored for GCE and OpenStack. One fallout of this setup is that the Salt mine doesn't exist - there is no sharing of configuration amongst nodes. ## Salt security -*(Not applicable on default GCE setup.)* +*(Not applicable on default GCE and OpenStack-Heat setup.)* Security is not enabled on the salt-master, and the salt-master is configured to auto-accept incoming requests from minions. It is not recommended to use this security configuration in production environments without deeper study. (In some environments this isn't as bad as it might sound if the salt master port isn't externally accessible and you trust everyone on your network.) diff --git a/docs/admin/service-accounts-admin.md b/docs/admin/service-accounts-admin.md index 4a31fbeced..0c7b495a10 100644 --- a/docs/admin/service-accounts-admin.md +++ b/docs/admin/service-accounts-admin.md @@ -71,8 +71,9 @@ account. To create additional API tokens for a service account, create a secret of type `ServiceAccountToken` with an annotation referencing the service account, and the controller will update it with a generated token: -```json secret.json: + +```json { "kind": "Secret", "apiVersion": "v1", @@ -100,4 +101,4 @@ kubectl delete secret mysecretname ### Service Account Controller Service Account Controller manages ServiceAccount inside namespaces, and ensures -a ServiceAccount named "default" exists in every active namespace. \ No newline at end of file +a ServiceAccount named "default" exists in every active namespace. diff --git a/docs/admin/static-pods.md b/docs/admin/static-pods.md index 8c9e482d0d..d924319fd9 100644 --- a/docs/admin/static-pods.md +++ b/docs/admin/static-pods.md @@ -4,123 +4,6 @@ assignees: title: Static Pods --- -**If you are running clustered Kubernetes and are using static pods to run a pod on every node, you should probably be using a [DaemonSet](/docs/admin/daemons/)!** +{% include user-guide-content-moved.md %} -*Static pods* are managed directly by kubelet daemon on a specific node, without API server observing it. It does not have associated any replication controller, kubelet daemon itself watches it and restarts it when it crashes. There is no health check though. Static pods are always bound to one kubelet daemon and always run on the same node with it. - -Kubelet automatically creates so-called *mirror pod* on Kubernetes API server for each static pod, so the pods are visible there, but they cannot be controlled from the API server. - -## Static pod creation - -Static pod can be created in two ways: either by using configuration file(s) or by HTTP. - -### Configuration files - -The configuration files are just standard pod definition in json or yaml format in specific directory. Use `kubelet --pod-manifest-path=` to start kubelet daemon, which periodically scans the directory and creates/deletes static pods as yaml/json files appear/disappear there. - -For example, this is how to start a simple web server as a static pod: - -1. Choose a node where we want to run the static pod. In this example, it's `my-node1`. - -```shell -[joe@host ~] $ ssh my-node1 -``` - -2. Choose a directory, say `/etc/kubelet.d` and place a web server pod definition there, e.g. `/etc/kubernetes.d/static-web.yaml`: - -```shell -[root@my-node1 ~] $ mkdir /etc/kubernetes.d/ -[root@my-node1 ~] $ cat </etc/kubernetes.d/static-web.yaml -apiVersion: v1 -kind: Pod -metadata: - name: static-web - labels: - role: myrole -spec: - containers: - - name: web - image: nginx - ports: - - name: web - containerPort: 80 - protocol: TCP -EOF -``` - -2. Configure your kubelet daemon on the node to use this directory by running it with `--pod-manifest-path=/etc/kubelet.d/` argument. On Fedora edit `/etc/kubernetes/kubelet` to include this line: - -```conf -KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/" -``` - -Instructions for other distributions or Kubernetes installations may vary. - -3. Restart kubelet. On Fedora, this is: - -```shell -[root@my-node1 ~] $ systemctl restart kubelet -``` - -## Pods created via HTTP - -Kubelet periodically downloads a file specified by `--manifest-url=` argument and interprets it as a json/yaml file with a pod definition. It works the same as `--pod-manifest-path=`, i.e. it's reloaded every now and then and changes are applied to running static pods (see below). - -## Behavior of static pods - -When kubelet starts, it automatically starts all pods defined in directory specified in `--pod-manifest-path=` or `--manifest-url=` arguments, i.e. our static-web. (It may take some time to pull nginx image, be patient…): - -```shell -[joe@my-node1 ~] $ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES -f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c -``` - -If we look at our Kubernetes API server (running on host `my-master`), we see that a new mirror-pod was created there too: - -```shell -[joe@host ~] $ ssh my-master -[joe@my-master ~] $ kubectl get pods -POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED MESSAGE -static-web-my-node1 172.17.0.3 my-node1/192.168.100.71 role=myrole Running 11 minutes - web nginx Running 11 minutes -``` - -Labels from the static pod are propagated into the mirror-pod and can be used as usual for filtering. - -Notice we cannot delete the pod with the API server (e.g. via [`kubectl`](/docs/user-guide/kubectl/) command), kubelet simply won't remove it. - -```shell -[joe@my-master ~] $ kubectl delete pod static-web-my-node1 -pods/static-web-my-node1 -[joe@my-master ~] $ kubectl get pods -POD IP CONTAINER(S) IMAGE(S) HOST ... -static-web-my-node1 172.17.0.3 my-node1/192.168.100.71 ... -``` - -Back to our `my-node1` host, we can try to stop the container manually and see, that kubelet automatically restarts it in a while: - -```shell -[joe@host ~] $ ssh my-node1 -[joe@my-node1 ~] $ docker stop f6d05272b57e -[joe@my-node1 ~] $ sleep 20 -[joe@my-node1 ~] $ docker ps -CONTAINER ID IMAGE COMMAND CREATED ... -5b920cbaf8b1 nginx:latest "nginx -g 'daemon of 2 seconds ago ... -``` - -## Dynamic addition and removal of static pods - -Running kubelet periodically scans the configured directory (`/etc/kubelet.d` in our example) for changes and adds/removes pods as files appear/disappear in this directory. - -```shell -[joe@my-node1 ~] $ mv /etc/kubernetes.d/static-web.yaml /tmp -[joe@my-node1 ~] $ sleep 20 -[joe@my-node1 ~] $ docker ps -// no nginx container is running -[joe@my-node1 ~] $ mv /tmp/static-web.yaml /etc/kubernetes.d/ -[joe@my-node1 ~] $ sleep 20 -[joe@my-node1 ~] $ docker ps -CONTAINER ID IMAGE COMMAND CREATED ... -e7a62e3427f1 nginx:latest "nginx -g 'daemon of 27 seconds ago -``` +[Static Pods](/docs/concepts/cluster-administration/static-pod/) diff --git a/docs/admin/sysctls.md b/docs/admin/sysctls.md index aa75c4df2a..4931a8d6bf 100644 --- a/docs/admin/sysctls.md +++ b/docs/admin/sysctls.md @@ -4,119 +4,6 @@ assignees: title: Using Sysctls in a Kubernetes Cluster --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -This document describes how sysctls are used within a Kubernetes cluster. - -## What is a Sysctl? - -In Linux, the sysctl interface allows an administrator to modify kernel -parameters at runtime. Parameters are available via the `/proc/sys/` virtual -process file system. The parameters cover various subsystems such as: - -- kernel (common prefix: `kernel.`) -- networking (common prefix: `net.`) -- virtual memory (common prefix: `vm.`) -- MDADM (common prefix: `dev.`) -- More subsystems are described in [Kernel docs](https://www.kernel.org/doc/Documentation/sysctl/README). - -To get a list of all parameters, you can run - -``` -$ sudo sysctl -a -``` - -## Namespaced vs. Node-Level Sysctls - -A number of sysctls are _namespaced_ in today's Linux kernels. This means that -they can be set independently for each pod on a node. Being namespaced is a -requirement for sysctls to be accessible in a pod context within Kubernetes. - -The following sysctls are known to be _namespaced_: - -- `kernel.shm*`, -- `kernel.msg*`, -- `kernel.sem`, -- `fs.mqueue.*`, -- `net.*`. - -Sysctls which are not namespaced are called _node-level_ and must be set -manually by the cluster admin, either by means of the underlying Linux -distribution of the nodes (e.g. via `/etc/sysctls.conf`) or using a DaemonSet -with privileged containers. - -**Note**: it is good practice to consider nodes with special sysctl settings as -_tainted_ within a cluster, and only schedule pods onto them which need those -sysctl settings. It is suggested to use the Kubernetes [_taints and toleration_ -feature](/docs/user-guide/kubectl/kubectl_taint.md) to implement this. - -## Safe vs. Unsafe Sysctls - -Sysctls are grouped into _safe_ and _unsafe_ sysctls. In addition to proper -namespacing a _safe_ sysctl must be properly _isolated_ between pods on the same -node. This means that setting a _safe_ sysctl for one pod - -- must not have any influence on any other pod on the node -- must not allow to harm the node's health -- must not allow to gain CPU or memory resources outside of the resource limits - of a pod. - -By far, most of the _namespaced_ sysctls are not necessarily considered _safe_. - -For Kubernetes 1.4, the following sysctls are supported in the _safe_ set: - -- `kernel.shm_rmid_forced`, -- `net.ipv4.ip_local_port_range`, -- `net.ipv4.tcp_syncookies`. - -This list will be extended in future Kubernetes versions when the kubelet -supports better isolation mechanisms. - -All _safe_ sysctls are enabled by default. - -All _unsafe_ sysctls are disabled by default and must be allowed manually by the -cluster admin on a per-node basis. Pods with disabled unsafe sysctls will be -scheduled, but will fail to launch. - -**Warning**: Due to their nature of being _unsafe_, the use of _unsafe_ sysctls -is at-your-own-risk and can lead to severe problems like wrong behavior of -containers, resource shortage or complete breakage of a node. - -## Enabling Unsafe Sysctls - -With the warning above in mind, the cluster admin can allow certain _unsafe_ -sysctls for very special situations like e.g. high-performance or real-time -application tuning. _Unsafe_ sysctls are enabled on a node-by-node basis with a -flag of the kubelet, e.g.: - -```shell -$ kubelet --experimental-allowed-unsafe-sysctls 'kernel.msg*,net.ipv4.route.min_pmtu' ... -``` - -Only _namespaced_ sysctls can be enabled this way. - -## Setting Sysctls for a Pod - -The sysctl feature is an alpha API in Kubernetes 1.4. Therefore, sysctls are set -using annotations on pods. They apply to all containers in the same pod. - -Here is an example, with different annotations for _safe_ and _unsafe_ sysctls: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: sysctl-example - annotations: - security.alpha.kubernetes.io/sysctls: kernel.shm_rmid_forced=1 - security.alpha.kubernetes.io/unsafe-sysctls: net.ipv4.route.min_pmtu=1000,kernel.msgmax=1 2 3 -spec: - ... -``` - -**Note**: a pod with the _unsafe_ sysctls specified above will fail to launch on -any node which has not enabled those two _unsafe_ sysctls explicitly. As with -_node-level_ sysctls it is recommended to use [_taints and toleration_ -feature](/docs/user-guide/kubectl/kubectl_taint.md) or [labels on nodes](/docs -/user-guide/labels.md) to schedule those pods onto the right nodes. +[Using Sysctls in a Kubernetes Cluster](/docs/concepts/cluster-administration/sysctl-cluster/) diff --git a/docs/admin/upgrade-1-6.md b/docs/admin/upgrade-1-6.md new file mode 100644 index 0000000000..ca73f04e26 --- /dev/null +++ b/docs/admin/upgrade-1-6.md @@ -0,0 +1,26 @@ +--- +assignees: +- mml +title: Cluster Management Guide +--- + +* TOC +{:toc} + +This document outlines the potentially disruptive changes that exist in the 1.6 release cycle. Operators, administrators, and developers should +take note of the changes below in order to maintain continuity across their upgrade process. + +## Cluster defaults set to etcd 3 + +In the 1.6 release cycle, the default backend storage layer has been upgraded to fully leverage [etcd 3 capabilities](https://coreos.com/blog/etcd3-a-new-etcd.html) by default. +For new clusters, there is nothing an operator will need to do, it should "just work". However, if you are upgrading from a 1.5 cluster, care should be taken to ensure +continuity. + +It is possible to maintain v2 compatibility mode while running etcd 3 for an interim period of time. To do this, you will simply need to update an argument passed to your apiserver during +startup: + +``` +$ kube-apiserver --storage-backend='etcd2' $(EXISTING_ARGS) +``` + +However, for long-term maintenance of the cluster, we recommend that the operator plan an outage window in order to perform a [v2->v3 data upgrade](https://coreos.com/etcd/docs/latest/upgrades/upgrade_3_0.html). \ No newline at end of file diff --git a/docs/api-reference/apps/v1beta1/definitions.html b/docs/api-reference/apps/v1beta1/definitions.html index 77ef25e10c..c62a8bf681 100755 --- a/docs/api-reference/apps/v1beta1/definitions.html +++ b/docs/api-reference/apps/v1beta1/definitions.html @@ -3620,7 +3620,7 @@ The StatefulSet guarantees that a given network identity will always map to the

    nodeSelector

    -

    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection/README

    +

    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection

    false

    object

    diff --git a/docs/api-reference/batch/v1/definitions.html b/docs/api-reference/batch/v1/definitions.html index 9989f4c4ca..0a17bce0a7 100755 --- a/docs/api-reference/batch/v1/definitions.html +++ b/docs/api-reference/batch/v1/definitions.html @@ -3609,7 +3609,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

    nodeSelector

    -

    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection/README

    +

    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection

    false

    object

    diff --git a/docs/api-reference/extensions/v1beta1/definitions.html b/docs/api-reference/extensions/v1beta1/definitions.html index 3f1129b1b6..47dc1d4f76 100755 --- a/docs/api-reference/extensions/v1beta1/definitions.html +++ b/docs/api-reference/extensions/v1beta1/definitions.html @@ -3457,7 +3457,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

    nodeSelector

    -

    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection/README

    +

    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection

    false

    object

    diff --git a/docs/api-reference/v1.5/index.html b/docs/api-reference/v1.5/index.html index 84caadbe95..ae50987334 100644 --- a/docs/api-reference/v1.5/index.html +++ b/docs/api-reference/v1.5/index.html @@ -8010,7 +8010,7 @@ Appears In Pod PodTemplateSp nodeSelector
    object -NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info:
    http://kubernetes.io/docs/user-guide/node-selection/README +NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection restartPolicy
    string diff --git a/docs/api.md b/docs/api.md index 1c85283028..45d8fcccce 100644 --- a/docs/api.md +++ b/docs/api.md @@ -6,104 +6,6 @@ assignees: title: Kubernetes API Overview --- -Primary system and API concepts are documented in the [User guide](/docs/user-guide/). +{% include user-guide-content-moved.md %} -Overall API conventions are described in the [API conventions doc](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md). - -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) command-line tool can be used to create, update, delete, and get API objects. - -Kubernetes also stores its serialized state (currently in [etcd](https://coreos.com/docs/distributed-configuration/getting-started-with-etcd/)) in terms of the API resources. - -Kubernetes itself is decomposed into multiple components, which interact through its API. - -## API changes - -In our experience, any system that is successful needs to grow and change as new use cases emerge or existing ones change. Therefore, we expect the Kubernetes API to continuously change and grow. However, we intend to not break compatibility with existing clients, for an extended period of time. In general, new API resources and new resource fields can be expected to be added frequently. Elimination of resources or fields will require following a deprecation process. The precise deprecation policy for eliminating features is TBD, but once we reach our 1.0 milestone, there will be a specific policy. - -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). - -## OpenAPI and Swagger definitions - -Complete API details are documented using [Swagger v1.2](http://swagger.io/) and [OpenAPI](https://www.openapis.org/). The Kubernetes apiserver (aka "master") exposes an API that can be used to retrieve the Swagger v1.2 Kubernetes API spec located at `/swaggerapi`. You can also enable a UI to browse the API documentation at `/swagger-ui` by passing the `--enable-swagger-ui=true` flag to apiserver. - -We also host a version of the [latest v1.2 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. - -Starting with kubernetes 1.4, OpenAPI spec is also available at `/swagger.json`. While we are transitioning from Swagger v1.2 to OpenAPI (aka Swagger v2.0), some of the tools such as kubectl and swagger-ui are still using v1.2 spec. OpenAPI spec is in Beta as of Kubernetes 1.5. - -Kubernetes implements an alternative Protobuf based serialization format for the API that is primarily intended for intra-cluster communication, documented in the [design proposal](https://github.com/kubernetes/kubernetes/blob/{{ page.githubbranch }}/docs/proposals/protobuf.md) and the IDL files for each schema are located in the Go packages that define the API objects. - -## API versioning - -To make it easier to eliminate fields or restructure resource representations, Kubernetes supports -multiple API versions, each at a different API path, such as `/api/v1` or -`/apis/extensions/v1beta1`. - -We chose to version at the API level rather than at the resource or field level to ensure that the API presents a clear, consistent view of system resources and behavior, and to enable controlling access to end-of-lifed and/or experimental APIs. The JSON and Protobuf serialization schemas follow the same guidelines for schema changes - all descriptions below cover both formats. - -Note that API versioning and Software versioning are only indirectly related. The [API and release -versioning proposal](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/versioning.md) describes the relationship between API versioning and -software versioning. - - -Different API versions imply different levels of stability and support. The criteria for each level are described -in more detail in the [API Changes documentation](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api_changes.md#alpha-beta-and-stable-versions). They are summarized here: - -- Alpha level: - - The version names contain `alpha` (e.g. `v1alpha1`). - - May be buggy. Enabling the feature may expose bugs. Disabled by default. - - Support for feature may be dropped at any time without notice. - - The API may change in incompatible ways in a later software release without notice. - - Recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support. -- Beta level: - - The version names contain `beta` (e.g. `v2beta3`). - - Code is well tested. Enabling the feature is considered safe. Enabled by default. - - Support for the overall feature will not be dropped, though details may change. - - The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, - we will provide instructions for migrating to the next version. This may require deleting, editing, and re-creating - API objects. The editing process may require some thought. This may require downtime for applications that rely on the feature. - - Recommended for only non-business-critical uses because of potential for incompatible changes in subsequent releases. If you have - multiple clusters which can be upgraded independently, you may be able to relax this restriction. - - **Please do try our beta features and give feedback on them! Once they exit beta, it may not be practical for us to make more changes.** -- Stable level: - - The version name is `vX` where `X` is an integer. - - Stable versions of features will appear in released software for many subsequent versions. - -## API groups - -To make it easier to extend the Kubernetes API, we implemented [*API groups*](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-group.md). -The API group is specified in a REST path and in the `apiVersion` field of a serialized object. - -Currently there are several API groups in use: - -1. the "core" (oftentimes called "legacy", due to not having explicit group name) group, which is at - REST path `/api/v1` and is not specified as part of the `apiVersion` field, e.g. `apiVersion: v1`. -1. the named groups are at REST path `/apis/$GROUP_NAME/$VERSION`, and use `apiVersion: $GROUP_NAME/$VERSION` - (e.g. `apiVersion: batch/v1`). Full list of supported API groups can be seen in [Kubernetes API reference](/docs/reference/). - - -There are two supported paths to extending the API. -1. [Third Party Resources](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/extending-api.md) - are for users with very basic CRUD needs. -1. Coming soon: users needing the full set of Kubernetes API semantics can implement their own apiserver - and use the [aggregator](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/aggregated-api-servers.md) - to make it seamless for clients. - - -## Enabling API groups - -Certain resources and API groups are enabled by default. They can be enabled or disabled by setting `--runtime-config` -on apiserver. `--runtime-config` accepts comma separated values. For ex: to disable batch/v1, set -`--runtime-config=batch/v1=false`, to enable batch/v2alpha1, set `--runtime-config=batch/v2alpha1`. -The flag accepts comma separated set of key=value pairs describing runtime configuration of the apiserver. - -IMPORTANT: Enabling or disabling groups or resources requires restarting apiserver and controller-manager -to pick up the `--runtime-config` changes. - -## Enabling resources in the groups - -DaemonSets, Deployments, HorizontalPodAutoscalers, Ingress, Jobs and ReplicaSets are enabled by default. -Other extensions resources can be enabled by setting `--runtime-config` on -apiserver. `--runtime-config` accepts comma separated values. For ex: to disable deployments and jobs, set -`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/jobs=false` +[The Kubernetes API](/docs/concepts/overview/kubernetes-api/) diff --git a/docs/concepts/abstractions/controllers/garbage-collection.md b/docs/concepts/abstractions/controllers/garbage-collection.md new file mode 100644 index 0000000000..889049c1ba --- /dev/null +++ b/docs/concepts/abstractions/controllers/garbage-collection.md @@ -0,0 +1,110 @@ +--- +title: Garbage Collection +--- + +{% capture overview %} + +The role of the Kubernetes garbage collector is to delete certain objects +that once had an owner, but no longer have an owner. + +**Note**: Garbage collection is a beta feature and is enabled by default in +Kubernetes version 1.4 and later. + +{% endcapture %} + + +{% capture body %} + +## Owners and dependents + +Some Kubernetes objects are owners of other objects. For example, a ReplicaSet +is the owner of a set of Pods. The owned objects are called *dependents* of the +owner object. Every dependent object has a `metadata.ownerReferences` field that +points to the owning object. + +Sometimes, Kubernetes sets the value of `ownerReference` automatically. For +example, when you create a ReplicaSet, Kubernetes automatically sets the +`ownerReference` field of each Pod in the ReplicaSet. You can also specify +relationships between owners and dependents by manually setting the +`ownerReference` field. + +Here's a configuration file for a ReplicaSet that has three Pods: + +{% include code.html language="yaml" file="my-repset.yaml" ghlink="/docs/concepts/abstractions/controllers/my-repset.yaml" %} + +If you create the ReplicaSet and then view the Pod metadata, you can see +OwnerReferences field: + +```shell +kubectl create -f http://k8s.io/docs/concepts/abstractions/controllers/my-repset.yaml +kubectl get pods --output=yaml +``` + +The output shows that the Pod owner is a ReplicaSet named my-repset: + +```shell +apiVersion: v1 +kind: Pod +metadata: + ... + ownerReferences: + - apiVersion: extensions/v1beta1 + controller: true + kind: ReplicaSet + name: my-repset + uid: d9607e19-f88f-11e6-a518-42010a800195 + ... +``` + +## Controlling whether the garbage collector deletes dependents + +When you delete object, you can specify whether the object's dependents +are deleted automatically. Deleting dependents automatically is called +*cascading deletion*. If you delete an object without deleting its +dependents automatically, the dependents are said to be *orphaned*. + +To delete dependent objects automatically, set the `orphanDependents` query +parameter to false in your request to delete the owner object. + +To orphan the dependents of an owner object, set the `orphanDependents` query +parameter to true in your request to delete the owner object. + +The default value for `orphanDependents` is true. So unless you specify +otherwise, dependent objects are orphaned. + +Here's an example that deletes dependents automatically: + +```shell +kubectl proxy --port=8080 +curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset?orphanDependents=false +``` + +To delete dependents automatically using kubectl, set `--cascade` to true. +To orphan dependents, set `--cascade` to false. The default value for +`--cascade` is true. + +Here's an example that orphans the dependents of a ReplicaSet: + +```shell +kubectl delete replicaset my-repset --cascade=false +``` + +## Ongoing development + +In Kubernetes version 1.5, synchronous garbage collection is under active +development. See the tracking +[issue](https://github.com/kubernetes/kubernetes/issues/29891) for more details. + +{% endcapture %} + + +{% capture whatsnext %} + +[Design Doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/garbage-collection.md) + +[Known issues](https://github.com/kubernetes/kubernetes/issues/26120) + +{% endcapture %} + + +{% include templates/concept.md %} diff --git a/docs/concepts/abstractions/controllers/my-repset.yaml b/docs/concepts/abstractions/controllers/my-repset.yaml new file mode 100644 index 0000000000..54befd8f9d --- /dev/null +++ b/docs/concepts/abstractions/controllers/my-repset.yaml @@ -0,0 +1,17 @@ +apiVersion: extensions/v1beta1 +kind: ReplicaSet +metadata: + name: my-repset +spec: + replicas: 3 + selector: + matchLabels: + pod-is-for: garbage-collection-example + template: + metadata: + labels: + pod-is-for: garbage-collection-example + spec: + containers: + - name: nginx + image: nginx diff --git a/docs/concepts/abstractions/controllers/petsets.md b/docs/concepts/abstractions/controllers/petsets.md new file mode 100644 index 0000000000..760e7e882a --- /dev/null +++ b/docs/concepts/abstractions/controllers/petsets.md @@ -0,0 +1,15 @@ +--- +assignees: +- bprashanth +- enisoc +- erictune +- foxish +- janetkuo +- kow3ns +- smarterclayton +title: PetSets +--- + +__Warning:__ Starting in Kubernetes version 1.5, PetSet has been renamed to [StatefulSet](/docs/concepts/abstractions/controllers/statefulsets). To use (or continue to use) PetSet in Kubernetes 1.5, you _must_ [migrate](/docs/tasks/manage-stateful-set/upgrade-pet-set-to-stateful-set/) your existing PetSets to StatefulSets. For information on working with StatefulSet, see the tutorial on [how to run replicated stateful applications](/docs/tutorials/stateful-application/run-replicated-stateful-application). + +__This document has been deprecated__. diff --git a/docs/concepts/abstractions/init-containers.md b/docs/concepts/abstractions/init-containers.md new file mode 100644 index 0000000000..2d647a834a --- /dev/null +++ b/docs/concepts/abstractions/init-containers.md @@ -0,0 +1,276 @@ +--- +assignees: +- erictune +title: Init Containers +--- + +{% capture overview %} +This page provides an overview of Init Containers, which are specialized +Containers that run before app Containers and can contain utilities or setup +scripts not present in an app image. +{% endcapture %} + +{:toc} + +{% include 1-5-beta.md %} + +**Once the feature exits beta, Init Containers will be specified in the PodSpec +alongside the app `containers` array.** + +{% capture body %} +## Understanding Init Containers + +A [Pod](/docs/concepts/abstractions/pod/) can have multiple Containers running +apps within it, but it can also have one or more Init Containers, which are run +before the app Containers are started. + +Init Containers are exactly like regular Containers, except: + +* They always run to completion. +* Each one must complete successfully before the next one is started. + +If an Init Container fails for a Pod, Kubernetes restarts the Pod repeatedly until the Init +Container succeeds. However, if the Pod has a `restartPolicy` of Never, it is not restarted. + +To specify a Container as an Init Container, add the `annotations` key +`pod.beta.kubernetes.io/init-containers`. Its value should be a +JSON array of objects of type +[Container](http://kubernetes.io/docs/api-reference/v1/definitions/#_v1_container). + +The status of an Init Container is returned as another annotation, +`pod.beta.kubernetes.io/init-container-statuses`, which is an array of +container statuses similar to the `status.containerStatuses` field. + +### Differences from regular Containers + +Init Containers support all the fields and features of app Containers, +including resource limits, volumes, and security settings. However, the +resource requests and limits for an Init Container are handled slightly +differently, which are documented in [Resources](#resources) below. Also, Init Containers do not +support readiness probes because they must run to completion before the Pod can +be ready. + +If multiple Init Containers are specified for a Pod, those Containers are run +one at a time in sequential order. Each must succeed before the next can run. +When all of the Init Containers have run to completion, Kubernetes initializes +the Pod and runs the application Containers as usual. + +## What can Init Containers be used for? + +Because Init Containers have separate images from app Containers, they +have some advantages for start-up related code: + +* They can contain and run utilities that are not desirable to include in the + app Container image for security reasons. +* They can contain utilities or custom code for setup that is not present in an app + image. For example, there is no need to make an image `FROM` another image just to use a tool like + `sed`, `awk`, `python`, or `dig` during setup. +* The application image builder and deployer roles can work independently without + the need to jointly build a single app image. +* They use Linux namespaces so that they have different filesystem views from app Containers. + Consequently, they can be given access to Secrets that app Containers are not able to + access. +* They run to completion before any app Containers start, whereas app + Containers run in parallel, so Init Containers provide an easy way to block or + delay the startup of app Containers until some set of preconditions are met. + +### Examples +Here are some ideas for how to use Init Containers: + +* Wait for a service to be created with a shell command like: + + for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1 + +* Register this Pod with a remote server from the downward API with a command like: + + curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$()&ip=$()' + +* Wait for some time before starting the app Container with a command like `sleep 60`. +* Clone a git repository into a volume. +* Place values into a configuration file and run a template tool to dynamically + generate a configuration file for the the main app Container. For example, + place the POD_IP value in a configuration and generate the main app + configuration file using Jinja. + +More detailed usage examples can be found in the [StatefulSets documentation](/docs/concepts/abstractions/controllers/statefulsets/) +and the [Production Pods guide](/docs/user-guide/production-pods.md#handling-initialization). + +### Init Containers in use + +The following yaml file outlines a simple Pod which has two Init Containers. +The first waits for `myservice` and the second waits for `mydb`. Once both +containers complete the Pod will begin. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: myapp-pod + labels: + app: myapp + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init-myservice", + "image": "busybox", + "command": ["sh", "-c", "until nslookup myservice; do echo waiting for myservice; sleep 2; done;"] + }, + { + "name": "init-mydb", + "image": "busybox", + "command": ["sh", "-c", "until nslookup mydb; do echo waiting for mydb; sleep 2; done;"] + } + ]' +spec: + containers: + - name: myapp-container + image: busybox + command: ['sh', '-c', 'echo The app is running! && sleep 3600'] +``` + +This Pod can be started and debugged with the following commands: + +``` +$ kubectl create -f myapp.yaml +pod "myapp-pod" created +$ kubectl get -f myapp.yaml +NAME READY STATUS RESTARTS AGE +myapp-pod 0/1 Init:0/2 0 6m +$ kubectl describe -f myapp.yaml +i11:32 $ kubectl describe -f examples/init-container.yaml +Name: myapp-pod +Namespace: default +[...] +Labels: app=myapp +Status: Pending +[...] +Init Containers: + init-myservice: +[...] + State: Running +[...] + init-mydb: +[...] + State: Running +[...] +Containers: + myapp-container: +[...] + State: Waiting + Reason: PodInitializing + Ready: False +[...] +Events: + FirstSeen LastSeen Count From SubObjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.201 + 16s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image "busybox" + 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox" + 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined] + 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634 +$ kubectl logs myapp-pod -c init-myservice # Inspect the first init container +$ kubectl logs myapp-pod -c init-mydd # Inspect the second init container +``` + +Once we start the `mydb` and `myservice` Services we can see the Init Containers +complete and the `myapp-pod` is created: + +``` +$ kubectl create -f services.yaml +service "myservice" created +service "mydb" created +$ kubectl get -f myapp.yaml +NAME READY STATUS RESTARTS AGE +myapp-pod 1/1 Running 0 9m +``` + +This example is very simple but should provide some inspiration for you to +create your own Init Containers. + +## Detailed behavior + +During the startup of a Pod, the Init Containers are started in order, after the +network and volumes are initialized. Each Container must exit successfully before +the next is started. If a Container fails to start due to the runtime or +exits with failure, it is retried according to the Pod `restartPolicy`. However, +if the Pod `restartPolicy` is set to Always, the Init Containers use +`RestartPolicy` OnFailure. + +A Pod cannot be `Ready` until all Init Containers have succeeded. The ports on an +Init Container are not aggregated under a service. A Pod that is initializing +is in the `Pending` state but should have a condition `Initializing` set to true. + +If the Pod is [restarted](#pod-restart-reasons), all Init Containers must +execute again. + +Changes to the Init Container spec are limited to the container image field. +Altering an Init Container image field is equivalent to restarting the Pod. + +Because Init Containers can be restarted, retried, or re-executed, Init Container +code should be idempotent. In particular, code that writes to files on `EmptyDirs` +should be prepared for the possibility that an output file already exists. + +Init Containers have all of the fields of an app Container. However, Kubernetes +prohibits `readinessProbe` from being used because Init Containers cannot +define readiness distinct from completion. This is enforced during validation. + +Use `activeDeadlineSeconds` on the Pod and `livenessProbe` on the Container to +prevent Init Containers from failing forever. The active deadline includes Init +Containers. + +The name of each app and Init Container in a Pod must be unique; a +validation error is thrown for any Container sharing a name with another. + +### Resources + +Given the ordering and execution for Init Containers, the following rules +for resource usage apply: + +* The highest of any particular resource request or limit defined on all Init + Containers is the *effective init request/limit* +* The Pod's *effective request/limit* for a resource is the higher of: + * the sum of all app Containers request/limit for a resource + * the effective init request/limit for a resource +* Scheduling is done based on effective requests/limits, which means + Init Containers can reserve resources for initialization that are not used + during the life of the Pod. +* QoS tier of the Pod's *effective QoS tier* is the QoS tier for Init Containers + and app containers alike. + +Quota and limits are applied based on the effective Pod request and +limit. + +Pod level cgroups are based on the effective Pod request and limit, the +same as the scheduler. + + +### Pod restart reasons + +A Pod can restart, causing re-execution of Init Containers, for the following +reasons: + +* A user updates the PodSpec causing the Init Container image to change. + App Container image changes only restart the app Container. +* The Pod infrastructure container is restarted. This is uncommon and would + have to be done by someone with root access to nodes. +* All containers in a Pod are terminated while `restartPolicy` is set to Always, + forcing a restart, and the Init Container completion record has been lost due + to garbage collection. + +## Support and compatibility + +A cluster with Kubelet and Apiserver version 1.4.0 or greater supports Init +Containers with the beta annotations. Support varies for other combinations of +Kubelet and Apiserver versions; see the [release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md) for details. + +{% endcapture %} + + +{% capture whatsnext %} + +* [Creating a Pod that has an Init Container](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container) + +{% endcapture %} + + +{% include templates/concept.md %} diff --git a/docs/concepts/abstractions/pod.md b/docs/concepts/abstractions/pod.md index 07f0d18934..f3ff457b97 100644 --- a/docs/concepts/abstractions/pod.md +++ b/docs/concepts/abstractions/pod.md @@ -27,7 +27,7 @@ The [Kubernetes Blog](http://blog.kubernetes.io) has some additional information * [The Distributed System Toolkit: Patterns for Composite Containers](http://blog.kubernetes.io/2015/06/the-distributed-system-toolkit-patterns.html) * [Container Design Patterns](http://blog.kubernetes.io/2016/06/container-design-patterns.html) -Each Pod is meant to run a single instance of a given application. If you want to scale your application horizontally (e.g., run muliple instances), you should use multiple Pods, one for each instance. In Kubernetes, this is generally referred to as _replication_. Replicated Pods are usually created and managed as a group by an abstraction called a Controller. See [Pods and Controllers](#pods-and-controllers) for more information. +Each Pod is meant to run a single instance of a given application. If you want to scale your application horizontally (e.g., run multiple instances), you should use multiple Pods, one for each instance. In Kubernetes, this is generally referred to as _replication_. Replicated Pods are usually created and managed as a group by an abstraction called a Controller. See [Pods and Controllers](#pods-and-controllers) for more information. ### How Pods Manage Multiple Containers @@ -41,7 +41,7 @@ Pods provide two kinds of shared resources for their constituent containers: *ne #### Networking -Each Pod is assigned a unique IP address. Every the container in a Pod shares the network namespace, including the IP address and network ports. Containers *inside a Pod* can communicate with one another using `localhost`. When containers in a Pod communicate with entities *outside the Pod*, they must coordinate how they use the shared network resources (such as ports). +Each Pod is assigned a unique IP address. Every container in a Pod shares the network namespace, including the IP address and network ports. Containers *inside a Pod* can communicate with one another using `localhost`. When containers in a Pod communicate with entities *outside the Pod*, they must coordinate how they use the shared network resources (such as ports). #### Storage @@ -49,7 +49,7 @@ A Pod can specify a set of shared storage *volumes*. All containers in the Pod c ## Working with Pods -You'll rarely create individual Pods directly in Kubernetes--even singleton Pods. This is because Pods are designed as relatively ephemeral, disposable entities. When a Pod gets created (directly by you, or indirectly by a Controller), it is scheduled to run on a Node in your your cluster. The Pod remains on that Node until the process is terminated, the pod object is deleted, or the pod is *evicted* for lack of resources, or the Node fails. +You'll rarely create individual Pods directly in Kubernetes--even singleton Pods. This is because Pods are designed as relatively ephemeral, disposable entities. When a Pod gets created (directly by you, or indirectly by a Controller), it is scheduled to run on a Node in your cluster. The Pod remains on that Node until the process is terminated, the pod object is deleted, or the pod is *evicted* for lack of resources, or the Node fails. > Note: Restarting a container in a Pod should not be confused with restarting the Pod. The Pod itself does not run, but is an environment the containers run in and persists until it is deleted. @@ -57,7 +57,7 @@ Pods do not, by themselves, self-heal. If a Pod is scheduled to a Node that fail ### Pods and Controllers -A Controller can create and manage multiple Pods for you, handling replication and rollout and providing self-healing capabilities at cluster scope. For example, if a Node fails, the Controller might automatically replace the Pod by scheduling an identical replacement on a different Node). +A Controller can create and manage multiple Pods for you, handling replication and rollout and providing self-healing capabilities at cluster scope. For example, if a Node fails, the Controller might automatically replace the Pod by scheduling an identical replacement on a different Node. Some examples of Controllers that contain one or more pods include: diff --git a/docs/concepts/cluster-administration/audit.md b/docs/concepts/cluster-administration/audit.md new file mode 100644 index 0000000000..e60ad728b9 --- /dev/null +++ b/docs/concepts/cluster-administration/audit.md @@ -0,0 +1,67 @@ +--- +assignees: +- soltysh +- sttts +title: Auditing +--- + +* TOC +{:toc} + +Kubernetes Audit provides a security-relevant chronological set of records documenting +the sequence of activities that have affected system by individual users, administrators +or other components of the system. It allows cluster administrator to +answer the following questions: + - what happened? + - when did it happen? + - who initiated it? + - on what did it happen? + - where was it observed? + - from where was it initiated? + - to where was it going? + +NOTE: Currently, Kubernetes provides only basic audit capabilities, there is still a lot +of work going on to provide fully featured auditing capabilities (see [this issue](https://github.com/kubernetes/features/issues/22)). + +Kubernetes audit is part of [kube-apiserver](/docs/admin/kube-apiserver) logging all requests +coming to the server. Each audit log contains two entries: + +1. The request line containing: + - unique id allowing to match the response line (see 2) + - source ip of the request + - HTTP method being invoked + - original user invoking the operation + - impersonated user for the operation + - namespace of the request or + - URI as requested +2. The response line containing: + - the unique id from 1 + - response code + +Example output for user `admin` asking for a list of pods: + +``` +2016-09-07T13:03:57.400333046Z AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" ip="127.0.0.1" method="GET" user="admin" as="" namespace="default" uri="/api/v1/namespaces/default/pods" +2016-09-07T13:03:57.400710987Z AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" response="200" +``` + +NOTE: The audit capabilities are available *only* for the secured endpoint of the API server. + +## Configuration + +[Kube-apiserver](/docs/admin/kube-apiserver) provides following options which are responsible +for configuring where and how audit logs are handled: + +- `audit-log-path` - enables the audit log pointing to a file where the requests are being logged to. +- `audit-log-maxage` - specifies maximum number of days to retain old audit log files based on the timestamp encoded in their filename. +- `audit-log-maxbackup` - specifies maximum number of old audit log files to retain. +- `audit-log-maxsize` - specifies maximum size in megabytes of the audit log file before it gets rotated. Defaults to 100MB + +If an audit log file already exists, Kubernetes appends new audit logs to that file. +Otherwise, Kubernetes creates an audit log file at the location you specified in +`audit-log-path`. If the audit log file exceeds the size you specify in `audit-log-maxsize`, +Kubernetes will rename the current log file by appending the current timestamp on +the file name (before the file extension) and create a new audit log file. +Kubernetes may delete old log files when creating a new log file; you can configure +how many files are retained and how old they can be by specifying the `audit-log-maxbackup` +and `audit-log-maxage` options. diff --git a/docs/user-guide/logging/examples/counter-pod.yaml b/docs/concepts/cluster-administration/counter-pod.yaml similarity index 100% rename from docs/user-guide/logging/examples/counter-pod.yaml rename to docs/concepts/cluster-administration/counter-pod.yaml diff --git a/docs/concepts/cluster-administration/federation.md b/docs/concepts/cluster-administration/federation.md new file mode 100644 index 0000000000..8d151df3e9 --- /dev/null +++ b/docs/concepts/cluster-administration/federation.md @@ -0,0 +1,137 @@ +--- +title: Federation +--- + +This guide explains why and how to manage multiple Kubernetes clusters using +federation. + + +* TOC +{:toc} + + +## Why federation + +Federation makes it easy to manage multiple clusters. It does so by providing 2 +major building blocks: + + * Sync resources across clusters: Federation provides the ability to keep + resources in multiple clusters in sync. This can be used, for example, to + ensure that the same deployment exists in multiple clusters. + * Cross cluster discovery: It provides the ability to auto-configure DNS + servers and load balancers with backends from all clusters. This can be used, + for example, to ensure that a global VIP or DNS record can be used to access + backends from multiple clusters. + +Some other use cases that federation enables are: + +* High Availability: By spreading load across clusters and auto configuring DNS + servers and load balancers, federation minimises the impact of cluster + failure. +* Avoiding provider lock-in: By making it easier to migrate applications across + clusters, federation prevents cluster provider lock-in. + + +Federation is not helpful unless you have multiple clusters. Some of the reasons +why you might want multiple clusters are: + +* Low latency: Having clusters in multiple regions minimises latency by serving + users from the cluster that is closest to them. +* Fault isolation: It might be better to have multiple small clusters rather + than a single large cluster for fault isolation (for example: multiple + clusters in different availability zones of a cloud provider). + [Multi cluster guide](/docs/admin/multi-cluster) has more details on this. +* Scalability: There are scalability limits to a single kubernetes cluster (this + should not be the case for most users. For more details: + [Kubernetes Scaling and Performance Goals](https://github.com/kubernetes/community/blob/master/sig-scalability/goals.md)). +* Hybrid cloud: You can have multiple clusters on different cloud providers or + on-premises data centers. + + +### Caveats + +While there are a lot of attractive use cases for federation, there are also +some caveats. + +* Increased network bandwidth and cost: The federation control plane watches all + clusters to ensure that the current state is as expected. This can lead to + significant network cost if the clusters are running in different regions on + a cloud provider or on different cloud providers. +* Reduced cross cluster isolation: A bug in the federation control plane can + impact all clusters. This is mitigated by keeping the logic in federation + control plane to a minimum. It mostly delegates to the control plane in + kubernetes clusters whenever it can. The design and implementation also errs + on the side of safety and avoiding multicluster outage. +* Maturity: The federation project is relatively new and is not very mature. + Not all resources are available and many are still alpha. [Issue + 38893](https://github.com/kubernetes/kubernetes/issues/38893) ennumerates + known issues with the system that the team is busy solving. + +## Setup + +To be able to federate multiple clusters, we first need to setup a federation +control plane. +Follow the [setup guide](/docs/admin/federation/) to setup the +federation control plane. + +## Hybrid cloud capabilities + +Federations of Kubernetes Clusters can include clusters running in +different cloud providers (e.g. Google Cloud, AWS), and on-premises +(e.g. on OpenStack). Simply create all of the clusters that you +require, in the appropriate cloud providers and/or locations, and +register each cluster's API endpoint and credentials with your +Federation API Server (See the +[federation admin guide](/docs/admin/federation/) for details). + +Thereafter, your API resources can span different clusters +and cloud providers. + +## API resources + +Once we have the control plane setup, we can start creating federation API +resources. +The following guides explain some of the resources in detail: + +* [ConfigMap](https://kubernetes.io/docs/user-guide/federation/configmap/) +* [DaemonSets](https://kubernetes.io/docs/user-guide/federation/daemonsets/) +* [Deployment](https://kubernetes.io/docs/user-guide/federation/deployment/) +* [Events](https://kubernetes.io/docs/user-guide/federation/events/) +* [Ingress](https://kubernetes.io/docs/user-guide/federation/federated-ingress/) +* [Namespaces](https://kubernetes.io/docs/user-guide/federation/namespaces/) +* [ReplicaSets](https://kubernetes.io/docs/user-guide/federation/replicasets/) +* [Secrets](https://kubernetes.io/docs/user-guide/federation/secrets/) +* [Services](https://kubernetes.io/docs/user-guide/federation/federated-services/) + +[API reference docs](/docs/federation/api-reference/) lists all the +resources supported by federation apiserver. + +## Cascading deletion + +Kubernetes version 1.5 includes support for cascading deletion of federated +resources. With cascading deletion, when you delete a resource from the +federation control plane, the corresponding resources in all underlying clusters +are also deleted. + +To enable cascading deletion, set the option +`DeleteOptions.orphanDependents=false` when you delete a resource from the +federation control plane. + +The following Federated resources are affected by cascading deletion: + +* [Ingress](https://kubernetes.io/docs/user-guide/federation/federated-ingress/) +* [Namespaces](https://kubernetes.io/docs/user-guide/federation/namespaces/) +* [ReplicaSets](https://kubernetes.io/docs/user-guide/federation/replicasets/) +* [Secrets](https://kubernetes.io/docs/user-guide/federation/secrets/) +* [Deployment](https://kubernetes.io/docs/user-guide/federation/deployment/) +* [DaemonSets](https://kubernetes.io/docs/user-guide/federation/daemonsets/) + +Note: By default, deleting a resource from federation control plane does not +delete the corresponding resources from underlying clusters. + + +## For more information + +* [Federation + proposal](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/federation.md) +* [Kubecon2016 talk on federation](https://www.youtube.com/watch?v=pq9lbkmxpS8) diff --git a/docs/user-guide/logging/examples/fluentd-sidecar-config.yaml b/docs/concepts/cluster-administration/fluentd-sidecar-config.yaml similarity index 100% rename from docs/user-guide/logging/examples/fluentd-sidecar-config.yaml rename to docs/concepts/cluster-administration/fluentd-sidecar-config.yaml diff --git a/docs/concepts/cluster-administration/guaranteed-scheduling-critical-addon-pods.md b/docs/concepts/cluster-administration/guaranteed-scheduling-critical-addon-pods.md new file mode 100644 index 0000000000..9e3fc61c39 --- /dev/null +++ b/docs/concepts/cluster-administration/guaranteed-scheduling-critical-addon-pods.md @@ -0,0 +1,57 @@ +--- +assignees: +- davidopp +- filipg +- piosz +title: Guaranteed Scheduling For Critical Add-On Pods +--- + +* TOC +{:toc} + +## Overview + +In addition to Kubernetes core components like api-server, scheduler, controller-manager running on a master machine +there are a number of add-ons which, for various reasons, must run on a regular cluster node (rather than the Kubernetes master). +Some of these add-ons are critical to a fully functional cluster, such as Heapster, DNS, and UI. +A cluster may stop working properly if a critical add-on is evicted (either manually or as a side effect of another operation like upgrade) +and becomes pending (for example when the cluster is highly utilized and either there are other pending pods that schedule into the space +vacated by the evicted critical add-on pod or the amount of resources available on the node changed for some other reason). + +## Rescheduler: guaranteed scheduling of critical add-ons + +Rescheduler ensures that critical add-ons are always scheduled +(assuming the cluster has enough resources to run the critical add-on pods in the absence of regular pods). +If the scheduler determines that no node has enough free resources to run the critical add-on pod +given the pods that are already running in the cluster +(indicated by critical add-on pod's pod condition PodScheduled set to false, the reason set to Unschedulable) +the rescheduler tries to free up space for the add-on by evicting some pods; then the scheduler will schedule the add-on pod. + +To avoid situation when another pod is scheduled into the space prepared for the critical add-on, +the chosen node gets a temporary taint "CriticalAddonsOnly" before the eviction(s) +(see [more details](https://github.com/kubernetes/kubernetes/blob/master/docs/design/taint-toleration-dedicated.md)). +Each critical add-on has to tolerate it, +while the other pods shouldn't tolerate the taint. The taint is removed once the add-on is successfully scheduled. + +*Warning:* currently there is no guarantee which node is chosen and which pods are being killed +in order to schedule critical pods, so if rescheduler is enabled your pods might be occasionally +killed for this purpose. + +## Config + +Rescheduler doesn't have any user facing configuration (component config) or API. +It's enabled by default. It can be disabled: + +* during cluster setup by setting `ENABLE_RESCHEDULER` flag to `false` +* on running cluster by deleting its manifest from master node +(default path `/etc/kubernetes/manifests/rescheduler.manifest`) + +### Marking add-on as critical + +To be critical an add-on has to run in `kube-system` namespace (configurable via flag) +and have the following annotations specified: + +* `scheduler.alpha.kubernetes.io/critical-pod` set to empty string +* `scheduler.alpha.kubernetes.io/tolerations` set to `[{"key":"CriticalAddonsOnly", "operator":"Exists"}]` + +The first one marks a pod a critical. The second one is required by Rescheduler algorithm. diff --git a/docs/concepts/cluster-administration/logging.md b/docs/concepts/cluster-administration/logging.md new file mode 100644 index 0000000000..e9ceec0a71 --- /dev/null +++ b/docs/concepts/cluster-administration/logging.md @@ -0,0 +1,226 @@ +--- +assignees: +- crassirostris +- piosz +title: Logging and Monitoring Cluster Activity +redirect_from: +- "/docs/concepts/clusters/logging/" +- "/docs/concepts/clusters/logging.html" +--- + +Application and systems logs can help you understand what is happening inside your cluster. The logs are particularly useful for debugging problems and monitoring cluster activity. Most modern applications have some kind of logging mechanism; as such, most container engines are likewise designed to support some kind of logging. The easiest and most embraced logging method for containerized applications is to write to the standard output and standard error streams. + +However, the native functionality provided by a container engine or runtime is usually not enough for a complete logging solution. For example, if a container crashes, a pod is evicted, or a node dies, you'll usually still want to access your application's logs. As such, logs should have a separate storage and lifecycle independent of nodes, pods, or containers. This concept is called _cluster-level-logging_. Cluster-level logging requires a separate backend to store, analyze, and query logs. Kubernetes provides no native storage solution for log data, but you can integrate many existing logging solutions into your Kubernetes cluster. + +This document includes: + +* A basic demonstration of logging in Kubernetes using the standard output stream +* A detailed description of the node logging architecture in Kubernetes +* Guidance for implementing cluster-level logging in Kubernetes + +The guidance for cluster-level logging assumes that a logging backend is present inside or outside of your cluster. If you're not interested in having cluster-level logging, you might still find the description of how logs are stored and handled on the node to be useful. + +## Basic logging in Kubernetes + +In this section, you can see an example of basic logging in Kubernetes that +outputs data to the standard output stream. This demonstration uses +a [pod specification](/docs/concepts/cluster-administration/counter-pod.yaml) with +a container that writes some text to standard output once per second. + +{% include code.html language="yaml" file="counter-pod.yaml" ghlink="/docs/tasks/debug-application-cluster/counter-pod.yaml" %} + +To run this pod, use the following command: + +```shell +$ kubectl create -f http://k8s.io/docs/tasks/debug-application-cluster/counter-pod.yaml +pod "counter" created +``` + +To fetch the logs, use the `kubectl logs` command, as follows + +```shell +$ kubectl logs counter +0: Mon Jan 1 00:00:00 UTC 2001 +1: Mon Jan 1 00:00:01 UTC 2001 +2: Mon Jan 1 00:00:02 UTC 2001 +... +``` + +You can use `kubectl logs` to retrieve logs from a previous instantiation of a container with `--previous` flag, in case the container has crashed. If your pod has multiple containers, you should specify which container's logs you want to access by appending a container name to the command. See the [`kubectl logs` documentation](/docs/user-guide/kubectl/kubectl_logs/) for more details. + +## Logging at the node level + +![Node level logging](/images/docs/user-guide/logging/logging-node-level.png) + +Everything a containerized application writes to `stdout` and `stderr` is handled and redirected somewhere by a container engine. For example, the Docker container engine redirects those two streams to [a logging driver](https://docs.docker.com/engine/admin/logging/overview), which is configured in Kubernetes to write to a file in json format. + +**Note:** The Docker json logging driver treats each line as a separate message. When using the Docker logging driver, there is no direct support for multi-line messages. You need to handle multi-line messages at the logging agent level or higher. + +By default, if a container restarts, the kubelet keeps one terminated container with its logs. If a pod is evicted from the node, all corresponding containers are also evicted, along with their logs. + +An important consideration in node-level logging is implementing log rotation, so that logs don't consume all available storage on the node. Kubernetes uses the [`logrotate`](http://www.linuxcommand.org/man_pages/logrotate8.html) tool to implement log rotation. + +Kubernetes performs log rotation daily, or if the log file grows beyond 10MB in size. Each rotation belongs to a single container; if the container repeatedly fails or the pod is evicted, all previous rotations for the container are lost. By default, Kubernetes keeps up to five logging rotations per container. + +The Kubernetes logging configuration differs depending on the node type. For example, you can find detailed information for GCI in the corresponding [configure helper](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/cluster/gce/gci/configure-helper.sh#L96). + +When you run [`kubectl logs`](/docs/user-guide/kubectl/kubectl_logs), as in the basic logging example, the kubelet on the node handles the request and reads directly from the log file, returning the contents in the response. Note that `kubectl logs` **only returns the last rotation**; you must manually extract prior rotations, if desired and cluster-level logging is not enabled. + +### System component logs + +There are two types of system components: those that run in a container and those +that do not run in a container. For example: + +* The Kubernetes scheduler and kube-proxy run in a container. +* The kubelet and container runtime, for example Docker, do not run in containers. + +On machines with systemd, the kubelet and container runtime write to journald. If +systemd is not present, they write to `.log` files in the `/var/log` directory. +System components inside containers always write to the `/var/log` directory, +bypassing the default logging mechanism. They use the [glog](https://godoc.org/github.com/golang/glog) +logging library. You can find the conventions for logging severity for those +components in the [development docs on logging](https://github.com/kubernetes/community/blob/master/contributors/devel/logging.md). + +Similarly to the container logs, system component logs in the `/var/log` +directory are rotated daily and based on the log size. However, +system component logs have a higher size retention: by default, +they can store up to 100MB. + +## Cluster-level logging architectures + +While Kubernetes does not provide a native solution for cluster-level logging, there are several common approaches you can consider. Here are some options: + +* Use a node-level logging agent that runs on every node. +* Include a dedicated sidecar container for logging in an application pod. +* Push logs directly to a backend from within an application. + +### Using a node logging agent + +![Using a node level logging agent](/images/docs/user-guide/logging/logging-with-node-agent.png) + +You can implement cluster-level logging by including a _node-level logging agent_ on each node. The logging agent is a dedicated tool that exposes logs or pushes logs to a backend. Commonly, the logging agent is a container that has access to a directory with log files from all of the application containers on that node. + +Because the logging agent must run on every node, it's common to implement it as either a DaemonSet replica, a manifest pod, or a dedicated native process on the node. However the latter two approaches are deprecated and highly discouraged. + +Using a node-level logging agent is the most common and encouraged approach for a Kubernetes cluster, because it creates only one agent per node, and it doesn't require any changes to the applications running on the node. However, node-level logging _only works for applications' standard output and standard error_. + +Kubernetes doesn't specify a logging agent, but two optional logging agents are packaged with the Kubernetes release: [Stackdriver Logging](/docs/user-guide/logging/stackdriver) for use with Google Cloud Platform, and [Elasticsearch](/docs/user-guide/logging/elasticsearch). You can find more information and instructions in the dedicated documents. Both use [fluentd](http://www.fluentd.org/) with custom configuration as an agent on the node. + +### Using a sidecar container with the logging agent + +You can use a sidecar container in one of the following ways: + +* The sidecar container streams application logs to its own `stdout`. +* The sidecar container runs a logging agent, which is configured to pick up logs from an application container. + +#### Streaming sidecar container + +![Sidecar container with a streaming container](/images/docs/user-guide/logging/logging-with-streaming-sidecar.png) + +By having your sidecar containers stream to their own `stdout` and `stderr` +streams, you can take advantage of the kubelet and the logging agent that +already run on each node. The sidecar containers read logs from a file, a socket, +or the journald. Each individual sidecar container prints log to its own `stdout` +or `stderr` stream. + +This approach allows you to separate several log streams from different +parts of your application, some of which can lack support +for writing to `stdout` or `stderr`. The logic behind redirecting logs +is minimal, so it's hardly a significant overhead. Additionally, because +`stdout` and `stderr` are handled by the kubelet, you can use built-in tools +like `kubectl logs`. + +Consider the following example. A pod runs a single container, and the container +writes to two different log files, using two different formats. Here's a +configuration file for the Pod: + +{% include code.html language="yaml" file="two-files-counter-pod.yaml" ghlink="/docs/concepts/cluster-administration/two-files-counter-pod.yaml" %} + +It would be a mess to have log entries of different formats in the same log +stream, even if you managed to redirect both components to the `stdout` stream of +the container. Instead, you could introduce two sidecar containers. Each sidecar +container could tail a particular log file from a shared volume and then redirect +the logs to its own `stdout` stream. + +Here's a configuration file for a pod that has two sidecar containers: + +{% include code.html language="yaml" file="two-files-counter-pod-streaming-sidecar.yaml" ghlink="/docs/concepts/cluster-administration/two-files-counter-pod-streaming-sidecar.yaml" %} + +Now when you run this pod, you can access each log stream separately by +running the following commands: + +```shell +$ kubectl logs counter count-log-1 +0: Mon Jan 1 00:00:00 UTC 2001 +1: Mon Jan 1 00:00:01 UTC 2001 +2: Mon Jan 1 00:00:02 UTC 2001 +... +``` + +```shell +$ kubectl logs counter count-log-2 +Mon Jan 1 00:00:00 UTC 2001 INFO 0 +Mon Jan 1 00:00:01 UTC 2001 INFO 1 +Mon Jan 1 00:00:02 UTC 2001 INFO 2 +... +``` + +The node-level agent installed in your cluster picks up those log streams +automatically without any further configuration. If you like, you can configure +the agent to parse log lines depending on the source container. + +Note, that despite low CPU and memory usage (order of couple of millicores +for cpu and order of several megabytes for memory), writing logs to a file and +then streaming them to `stdout` can double disk usage. If you have +an application that writes to a single file, it's generally better to set +`/dev/stdout` as destination rather than implementing the streaming sidecar +container approach. + +Sidecar containers can also be used to rotate log files that cannot be +rotated by the application itself. [An example](https://github.com/samsung-cnct/logrotate) +of this approach is a small container running logrotate periodically. +However, it's recommended to use `stdout` and `stderr` directly and leave rotation +and retention policies to the kubelet. + +#### Sidecar container with a logging agent + +![Sidecar container with a logging agent](/images/docs/user-guide/logging/logging-with-sidecar-agent.png) + +If the node-level logging agent is not flexible enough for your situation, you +can create a sidecar container with a separate logging agent that you have +configured specifically to run with your application. + +**Note**: Using a logging agent in a sidecar container can lead +to significant resource consumption. Moreover, you won't be able to access +those logs using `kubectl logs` command, because they are not controlled +by the kubelet. + +As an example, you could use [Stackdriver](/docs/user-guide/logging/stackdriver/), +which uses fluentd as a logging agent. Here are two configuration files that +you can use to implement this approach. The first file contains +a [ConfigMap](/docs/user-guide/configmap/) to configure fluentd. + +{% include code.html language="yaml" file="fluentd-sidecar-config.yaml" ghlink="/docs/concepts/cluster-administration/fluentd-sidecar-config.yaml" %} + +**Note**: The configuration of fluentd is beyond the scope of this article. For +information about configuring fluentd, see the +[official fluentd documentation](http://docs.fluentd.org/). + +The second file describes a pod that has a sidecar container running fluentd. +The pod mounts a volume where fluentd can pick up its configuration data. + +{% include code.html language="yaml" file="two-files-counter-pod-agent-sidecar.yaml" ghlink="/docs/concepts/cluster-administration/two-files-counter-pod-agent-sidecar.yaml" %} + +After some time you can find log messages in the Stackdriver interface. + +Remember, that this is just an example and you can actually replace fluentd +with any logging agent, reading from any source inside an application +container. + +### Exposing logs directly from the application + +![Exposing logs directly from the application](/images/docs/user-guide/logging/logging-from-application.png) + +You can implement cluster-level logging by exposing or pushing logs directly from +every application; however, the implementation for such a logging mechanism +is outside the scope of Kubernetes. diff --git a/docs/concepts/cluster-administration/manage-deployment.md b/docs/concepts/cluster-administration/manage-deployment.md new file mode 100644 index 0000000000..aef8bbfaf8 --- /dev/null +++ b/docs/concepts/cluster-administration/manage-deployment.md @@ -0,0 +1,438 @@ +--- +assignees: +- bgrant0607 +- janetkuo +- mikedanese +title: Managing Resources +--- + +You've deployed your application and exposed it via a service. Now what? Kubernetes provides a number of tools to help you manage your application deployment, including scaling and updating. Among the features we'll discuss in more depth are [configuration files](/docs/user-guide/configuring-containers/#configuration-in-kubernetes) and [labels](/docs/user-guide/deploying-applications/#labels). + +You can find all the files for this example [in our docs +repo here](https://github.com/kubernetes/kubernetes.github.io/tree/{{page.docsbranch}}/docs/user-guide/). + +* TOC +{:toc} + +## Organizing resource configurations + +Many applications require multiple resources to be created, such as a Deployment and a Service. Management of multiple resources can be simplified by grouping them together in the same file (separated by `---` in YAML). For example: + +{% include code.html language="yaml" file="nginx-app.yaml" ghlink="/docs/user-guide/nginx-app.yaml" %} + +Multiple resources can be created the same way as a single resource: + +```shell +$ kubectl create -f docs/user-guide/nginx-app.yaml +service "my-nginx-svc" created +deployment "my-nginx" created +``` + +The resources will be created in the order they appear in the file. Therefore, it's best to specify the service first, since that will ensure the scheduler can spread the pods associated with the service as they are created by the controller(s), such as Deployment. + +`kubectl create` also accepts multiple `-f` arguments: + +```shell +$ kubectl create -f docs/user-guide/nginx/nginx-svc.yaml -f docs/user-guide/nginx/nginx-deployment.yaml +``` + +And a directory can be specified rather than or in addition to individual files: + +```shell +$ kubectl create -f docs/user-guide/nginx/ +``` + +`kubectl` will read any files with suffixes `.yaml`, `.yml`, or `.json`. + +It is a recommended practice to put resources related to the same microservice or application tier into the same file, and to group all of the files associated with your application in the same directory. If the tiers of your application bind to each other using DNS, then you can then simply deploy all of the components of your stack en masse. + +A URL can also be specified as a configuration source, which is handy for deploying directly from configuration files checked into github: + +```shell +$ kubectl create -f https://raw.githubusercontent.com/kubernetes/kubernetes/master/docs/user-guide/nginx-deployment.yaml +deployment "nginx-deployment" created +``` + +## Bulk operations in kubectl + +Resource creation isn't the only operation that `kubectl` can perform in bulk. It can also extract resource names from configuration files in order to perform other operations, in particular to delete the same resources you created: + +```shell +$ kubectl delete -f docs/user-guide/nginx/ +deployment "my-nginx" deleted +service "my-nginx-svc" deleted +``` + +In the case of just two resources, it's also easy to specify both on the command line using the resource/name syntax: + +```shell +$ kubectl delete deployments/my-nginx services/my-nginx-svc +``` + +For larger numbers of resources, you'll find it easier to specify the selector (label query) specified using `-l` or `--selector`, to filter resources by their labels: + +```shell +$ kubectl delete deployment,services -l app=nginx +deployment "my-nginx" deleted +service "my-nginx-svc" deleted +``` + +Because `kubectl` outputs resource names in the same syntax it accepts, it's easy to chain operations using `$()` or `xargs`: + +```shell +$ kubectl get $(kubectl create -f docs/user-guide/nginx/ -o name | grep service) +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +my-nginx-svc 10.0.0.208 80/TCP 0s +``` + +With the above commands, we first create resources under docs/user-guide/nginx/ and print the resources created with `-o name` output format +(print each resource as resource/name). Then we `grep` only the "service", and then print it with `kubectl get`. + +If you happen to organize your resources across several subdirectories within a particular directory, you can recursively perform the operations on the subdirectories also, by specifying `--recursive` or `-R` alongside the `--filename,-f` flag. + +For instance, assume there is a directory `project/k8s/development` that holds all of the manifests needed for the development environment, organized by resource type: + +``` +project/k8s/development +├── configmap +│   └── my-configmap.yaml +├── deployment +│   └── my-deployment.yaml +└── pvc + └── my-pvc.yaml +``` + +By default, performing a bulk operation on `project/k8s/development` will stop at the first level of the directory, not processing any subdirectories. If we tried to create the resources in this directory using the following command, we'd encounter an error: + +```shell +$ kubectl create -f project/k8s/development +error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin) +``` + +Instead, specify the `--recursive` or `-R` flag with the `--filename,-f` flag as such: + +```shell +$ kubectl create -f project/k8s/development --recursive +configmap "my-config" created +deployment "my-deployment" created +persistentvolumeclaim "my-pvc" created +``` + +The `--recursive` flag works with any operation that accepts the `--filename,-f` flag such as: `kubectl {create,get,delete,describe,rollout} etc.` + +The `--recursive` flag also works when multiple `-f` arguments are provided: + +```shell +$ kubectl create -f project/k8s/namespaces -f project/k8s/development --recursive +namespace "development" created +namespace "staging" created +configmap "my-config" created +deployment "my-deployment" created +persistentvolumeclaim "my-pvc" created +``` + +If you're interested in learning more about `kubectl`, go ahead and read [kubectl Overview](/docs/user-guide/kubectl-overview). + +## Using labels effectively + +The examples we've used so far apply at most a single label to any resource. There are many scenarios where multiple labels should be used to distinguish sets from one another. + +For instance, different applications would use different values for the `app` label, but a multi-tier application, such as the [guestbook example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/), would additionally need to distinguish each tier. The frontend could carry the following labels: + +```yaml + labels: + app: guestbook + tier: frontend +``` + +while the Redis master and slave would have different `tier` labels, and perhaps even an additional `role` label: + +```yaml + labels: + app: guestbook + tier: backend + role: master +``` + +and + +```yaml + labels: + app: guestbook + tier: backend + role: slave +``` + +The labels allow us to slice and dice our resources along any dimension specified by a label: + +```shell +$ kubectl create -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml +$ kubectl get pods -Lapp -Ltier -Lrole +NAME READY STATUS RESTARTS AGE APP TIER ROLE +guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend +guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend +guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend +guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master +guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave +guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave +my-nginx-divi2 1/1 Running 0 29m nginx +my-nginx-o0ef1 1/1 Running 0 29m nginx +$ kubectl get pods -lapp=guestbook,role=slave +NAME READY STATUS RESTARTS AGE +guestbook-redis-slave-2q2yf 1/1 Running 0 3m +guestbook-redis-slave-qgazl 1/1 Running 0 3m +``` + +## Canary deployments + +Another scenario where multiple labels are needed is to distinguish deployments of different releases or configurations of the same component. It is common practice to deploy a *canary* of a new application release (specified via image tag in the pod template) side by side with the previous release so that the new release can receive live production traffic before fully rolling it out. + +For instance, you can use a `track` label to differentiate different releases. + +The primary, stable release would have a `track` label with value as `stable`: + +```yaml + name: frontend + replicas: 3 + ... + labels: + app: guestbook + tier: frontend + track: stable + ... + image: gb-frontend:v3 +``` + +and then you can create a new release of the guestbook frontend that carries the `track` label with different value (i.e. `canary`), so that two sets of pods would not overlap: + +```yaml + name: frontend-canary + replicas: 1 + ... + labels: + app: guestbook + tier: frontend + track: canary + ... + image: gb-frontend:v4 +``` + + +The frontend service would span both sets of replicas by selecting the common subset of their labels (i.e. omitting the `track` label), so that the traffic will be redirected to both applications: + +```yaml + selector: + app: guestbook + tier: frontend +``` + +You can tweak the number of replicas of the stable and canary releases to determine the ratio of each release that will receive live production traffic (in this case, 3:1). +Once you're confident, you can update the stable track to the new application release and remove the canary one. + +For a more concrete example, check the [tutorial of deploying Ghost](https://github.com/kelseyhightower/talks/tree/master/kubecon-eu-2016/demo#deploy-a-canary). + +## Updating labels + +Sometimes existing pods and other resources need to be relabeled before creating new resources. This can be done with `kubectl label`. +For example, if you want to label all your nginx pods as frontend tier, simply run: + +```shell +$ kubectl label pods -l app=nginx tier=fe +pod "my-nginx-2035384211-j5fhi" labeled +pod "my-nginx-2035384211-u2c7e" labeled +pod "my-nginx-2035384211-u3t6x" labeled +``` + +This first filters all pods with the label "app=nginx", and then labels them with the "tier=fe". +To see the pods you just labeled, run: + +```shell +$ kubectl get pods -l app=nginx -L tier +NAME READY STATUS RESTARTS AGE TIER +my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe +my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe +my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe +``` + +This outputs all "app=nginx" pods, with an additional label column of pods' tier (specified with `-L` or `--label-columns`). + +For more information, please see [labels](/docs/user-guide/labels/) and [kubectl label](/docs/user-guide/kubectl/kubectl_label/) document. + +## Updating annotations + +Sometimes you would want to attach annotations to resources. Annotations are arbitrary non-identifying metadata for retrieval by API clients such as tools, libraries, etc. This can be done with `kubectl annotate`. For example: + +```shell +$ kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx' +$ kubectl get pods my-nginx-v4-9gw19 -o yaml +apiversion: v1 +kind: pod +metadata: + annotations: + description: my frontend running nginx +... +``` + +For more information, please see [annotations](/docs/user-guide/annotations/) and [kubectl annotate](/docs/user-guide/kubectl/kubectl_annotate/) document. + +## Scaling your application + +When load on your application grows or shrinks, it's easy to scale with `kubectl`. For instance, to decrease the number of nginx replicas from 3 to 1, do: + +```shell +$ kubectl scale deployment/my-nginx --replicas=1 +deployment "my-nginx" scaled +``` + +Now you only have one pod managed by the deployment. + +```shell +$ kubectl get pods -l app=nginx +NAME READY STATUS RESTARTS AGE +my-nginx-2035384211-j5fhi 1/1 Running 0 30m +``` + +To have the system automatically choose the number of nginx replicas as needed, ranging from 1 to 3, do: + +```shell +$ kubectl autoscale deployment/my-nginx --min=1 --max=3 +deployment "my-nginx" autoscaled +``` + +Now your nginx replicas will be scaled up and down as needed, automatically. + +For more information, please see [kubectl scale](/docs/user-guide/kubectl/kubectl_scale/), [kubectl autoscale](/docs/user-guide/kubectl/kubectl_autoscale/) and [horizontal pod autoscaler](/docs/user-guide/horizontal-pod-autoscaler/) document. + + +## In-place updates of resources + +Sometimes it's necessary to make narrow, non-disruptive updates to resources you've created. + +### kubectl apply + +It is suggested to maintain a set of configuration files in source control (see [configuration as code](http://martinfowler.com/bliki/InfrastructureAsCode.html)), +so that they can be maintained and versioned along with the code for the resources they configure. +Then, you can use [`kubectl apply`](/docs/user-guide/kubectl/kubectl_apply/) to push your configuration changes to the cluster. + +This command will compare the version of the configuration that you're pushing with the previous version and apply the changes you've made, without overwriting any automated changes to properties you haven't specified. + +```shell +$ kubectl apply -f docs/user-guide/nginx/nginx-deployment.yaml +deployment "my-nginx" configured +``` + +Note that `kubectl apply` attaches an annotation to the resource in order to determine the changes to the configuration since the previous invocation. When it's invoked, `kubectl apply` does a three-way diff between the previous configuration, the provided input and the current configuration of the resource, in order to determine how to modify the resource. + +Currently, resources are created without this annotation, so the first invocation of `kubectl apply` will fall back to a two-way diff between the provided input and the current configuration of the resource. During this first invocation, it cannot detect the deletion of properties set when the resource was created. For this reason, it will not remove them. + +All subsequent calls to `kubectl apply`, and other commands that modify the configuration, such as `kubectl replace` and `kubectl edit`, will update the annotation, allowing subsequent calls to `kubectl apply` to detect and perform deletions using a three-way diff. + +**Note:** To use apply, always create resource initially with either `kubectl apply` or `kubectl create --save-config`. + +### kubectl edit + +Alternatively, you may also update resources with `kubectl edit`: + +```shell +$ kubectl edit deployment/my-nginx +``` + +This is equivalent to first `get` the resource, edit it in text editor, and then `apply` the resource with the updated version: + +```shell +$ kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml +$ vi /tmp/nginx.yaml +# do some edit, and then save the file +$ kubectl apply -f /tmp/nginx.yaml +deployment "my-nginx" configured +$ rm /tmp/nginx.yaml +``` + +This allows you to do more significant changes more easily. Note that you can specify the editor with your `EDITOR` or `KUBE_EDITOR` environment variables. + +For more information, please see [kubectl edit](/docs/user-guide/kubectl/kubectl_edit/) document. + +### kubectl patch + +Suppose you want to fix a typo of the container's image of a Deployment. One way to do that is with `kubectl patch`: + +```shell +# Suppose you have a Deployment with a container named "nginx" and its image "nignx" (typo), +# use container name "nginx" as a key to update the image from "nignx" (typo) to "nginx" +$ kubectl get deployment my-nginx -o yaml +``` + +```yaml +apiVersion: extensions/v1beta1 +kind: Deployment +... +spec: + template: + spec: + containers: + - image: nignx + name: nginx +... +``` + +```shell +$ kubectl patch deployment my-nginx -p'{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx"}]}}}}' +"my-nginx" patched +$ kubectl get pod my-nginx-1jgkf -o yaml +``` + +```yaml +apiVersion: extensions/v1beta1 +kind: Deployment +... +spec: + template: + spec: + containers: + - image: nginx + name: nginx +... +``` + +The patch is specified using json. + +The system ensures that you don't clobber changes made by other users or components by confirming that the `resourceVersion` doesn't differ from the version you edited. If you want to update regardless of other changes, remove the `resourceVersion` field when you edit the resource. However, if you do this, don't use your original configuration file as the source since additional fields most likely were set in the live state. + +For more information, please see [kubectl patch](/docs/user-guide/kubectl/kubectl_patch/) document. + +## Disruptive updates + +In some cases, you may need to update resource fields that cannot be updated once initialized, or you may just want to make a recursive change immediately, such as to fix broken pods created by a Deployment. To change such fields, use `replace --force`, which deletes and re-creates the resource. In this case, you can simply modify your original configuration file: + +```shell +$ kubectl replace -f docs/user-guide/nginx/nginx-deployment.yaml --force +deployment "my-nginx" deleted +deployment "my-nginx" replaced +``` + +## Updating your application without a service outage + +At some point, you'll eventually need to update your deployed application, typically by specifying a new image or image tag, as in the canary deployment scenario above. `kubectl` supports several update operations, each of which is applicable to different scenarios. + +We'll guide you through how to create and update applications with Deployments. If your deployed application is managed by Replication Controllers, +you should read [how to use `kubectl rolling-update`](/docs/tasks/run-application/rolling-update-replication-controller/) instead. + +Let's say you were running version 1.7.9 of nginx: + +```shell +$ kubectl run my-nginx --image=nginx:1.7.9 --replicas=3 +deployment "my-nginx" created +``` + +To update to version 1.9.1, simply change `.spec.template.spec.containers[0].image` from `nginx:1.7.9` to `nginx:1.9.1`, with the kubectl commands we learned above. + +```shell +$ kubectl edit deployment/my-nginx +``` + +That's it! The Deployment will declaratively update the deployed nginx application progressively behind the scene. It ensures that only a certain number of old replicas may be down while they are being updated, and only a certain number of new replicas may be created above the desired number of pods. To learn more details about it, visit [Deployment page](/docs/user-guide/deployments/). + +## What's next? + +- [Learn about how to use `kubectl` for application introspection and debugging.](/docs/user-guide/introspection-and-debugging/) +- [Configuration Best Practices and Tips](/docs/concepts/configuration/overview/) diff --git a/docs/concepts/cluster-administration/multiple-clusters.md b/docs/concepts/cluster-administration/multiple-clusters.md new file mode 100644 index 0000000000..085a9afa9f --- /dev/null +++ b/docs/concepts/cluster-administration/multiple-clusters.md @@ -0,0 +1,66 @@ +--- +assignees: +- davidopp +title: Using Multiple Clusters +--- + +You may want to set up multiple Kubernetes clusters, both to +have clusters in different regions to be nearer to your users, and to tolerate failures and/or invasive maintenance. +This document describes some of the issues to consider when making a decision about doing so. + +If you decide to have multiple clusters, Kubernetes provides a way to [federate them](/docs/admin/federation/). + +## Scope of a single cluster + +On IaaS providers such as Google Compute Engine or Amazon Web Services, a VM exists in a +[zone](https://cloud.google.com/compute/docs/zones) or [availability +zone](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). +We suggest that all the VMs in a Kubernetes cluster should be in the same availability zone, because: + + - compared to having a single global Kubernetes cluster, there are fewer single-points of failure + - compared to a cluster that spans availability zones, it is easier to reason about the availability properties of a + single-zone cluster. + - when the Kubernetes developers are designing the system (e.g. making assumptions about latency, bandwidth, or + correlated failures) they are assuming all the machines are in a single data center, or otherwise closely connected. + +It is okay to have multiple clusters per availability zone, though on balance we think fewer is better. +Reasons to prefer fewer clusters are: + + - improved bin packing of Pods in some cases with more nodes in one cluster (less resource fragmentation) + - reduced operational overhead (though the advantage is diminished as ops tooling and processes matures) + - reduced costs for per-cluster fixed resource costs, e.g. apiserver VMs (but small as a percentage + of overall cluster cost for medium to large clusters). + +Reasons to have multiple clusters include: + + - strict security policies requiring isolation of one class of work from another (but, see Partitioning Clusters + below). + - test clusters to canary new Kubernetes releases or other cluster software. + +## Selecting the right number of clusters + +The selection of the number of Kubernetes clusters may be a relatively static choice, only revisited occasionally. +By contrast, the number of nodes in a cluster and the number of pods in a service may change frequently according to +load and growth. + +To pick the number of clusters, first, decide which regions you need to be in to have adequate latency to all your end users, for services that will run +on Kubernetes (if you use a Content Distribution Network, the latency requirements for the CDN-hosted content need not +be considered). Legal issues might influence this as well. For example, a company with a global customer base might decide to have clusters in US, EU, AP, and SA regions. +Call the number of regions to be in `R`. + +Second, decide how many clusters should be able to be unavailable at the same time, while still being available. Call +the number that can be unavailable `U`. If you are not sure, then 1 is a fine choice. + +If it is allowable for load-balancing to direct traffic to any region in the event of a cluster failure, then +you need at least the larger of `R` or `U + 1` clusters. If it is not (e.g. you want to ensure low latency for all +users in the event of a cluster failure), then you need to have `R * (U + 1)` clusters +(`U + 1` in each of `R` regions). In any case, try to put each cluster in a different zone. + +Finally, if any of your clusters would need more than the maximum recommended number of nodes for a Kubernetes cluster, then +you may need even more clusters. Kubernetes v1.3 supports clusters up to 1000 nodes in size. + +## Working with multiple clusters + +When you have multiple clusters, you would typically create services with the same config in each cluster and put each of those +service instances behind a load balancer (AWS Elastic Load Balancer, GCE Forwarding Rule or HTTP Load Balancer) spanning all of them, so that +failures of a single cluster are not visible to end users. diff --git a/docs/concepts/cluster-administration/network-plugins.md b/docs/concepts/cluster-administration/network-plugins.md new file mode 100644 index 0000000000..f06d22fb87 --- /dev/null +++ b/docs/concepts/cluster-administration/network-plugins.md @@ -0,0 +1,73 @@ +--- +assignees: +- dcbw +- freehan +- thockin +title: Network Plugins +--- + +* TOC +{:toc} + +__Disclaimer__: Network plugins are in alpha. Its contents will change rapidly. + +Network plugins in Kubernetes come in a few flavors: + +* CNI plugins: adhere to the appc/CNI specification, designed for interoperability. +* Kubenet plugin: implements basic `cbr0` using the `bridge` and `host-local` CNI plugins + +## Installation + +The kubelet has a single default network plugin, and a default network common to the entire cluster. It probes for plugins when it starts up, remembers what it found, and executes the selected plugin at appropriate times in the pod lifecycle (this is only true for docker, as rkt manages its own CNI plugins). There are two Kubelet command line parameters to keep in mind when using plugins: + +* `network-plugin-dir`: Kubelet probes this directory for plugins on startup +* `network-plugin`: The network plugin to use from `network-plugin-dir`. It must match the name reported by a plugin probed from the plugin directory. For CNI plugins, this is simply "cni". + +## Network Plugin Requirements + +Besides providing the [`NetworkPlugin` interface](https://github.com/kubernetes/kubernetes/tree/{{page.version}}/pkg/kubelet/network/plugins.go) to configure and clean up pod networking, the plugin may also need specific support for kube-proxy. The iptables proxy obviously depends on iptables, and the plugin may need to ensure that container traffic is made available to iptables. For example, if the plugin connects containers to a Linux bridge, the plugin must set the `net/bridge/bridge-nf-call-iptables` sysctl to `1` to ensure that the iptables proxy functions correctly. If the plugin does not use a Linux bridge (but instead something like Open vSwitch or some other mechanism) it should ensure container traffic is appropriately routed for the proxy. + +By default if no kubelet network plugin is specified, the `noop` plugin is used, which sets `net/bridge/bridge-nf-call-iptables=1` to ensure simple configurations (like docker with a bridge) work correctly with the iptables proxy. + +### CNI + +The CNI plugin is selected by passing Kubelet the `--network-plugin=cni` command-line option. Kubelet reads a file from `--cni-conf-dir` (default `/etc/cni/net.d`) and uses the CNI configuration from that file to set up each pod's network. The CNI configuration file must match the [CNI specification](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration), and any required CNI plugins referenced by the configuration must be present in `--cni-bin-dir` (default `/opt/cni/bin`). + +If there are multiple CNI configuration files in the directory, the first one in lexicographic order of file name is used. + +In addition to the CNI plugin specified by the configuration file, Kubernetes requires the standard CNI [`lo`](https://github.com/containernetworking/cni/blob/master/plugins/main/loopback/loopback.go) plugin, at minimum version 0.2.0 + +Limitation: Due to [#31307](https://github.com/kubernetes/kubernetes/issues/31307), `HostPort` won't work with CNI networking plugin at the moment. That means all `hostPort` attribute in pod would be simply ignored. + +### kubenet + +Kubenet is a very basic, simple network plugin, on Linux only. It does not, of itself, implement more advanced features like cross-node networking or network policy. It is typically used together with a cloud provider that sets up routing rules for communication between nodes, or in single-node environments. + +Kubenet creates a Linux bridge named `cbr0` and creates a veth pair for each pod with the host end of each pair connected to `cbr0`. The pod end of the pair is assigned an IP address allocated from a range assigned to the node either through configuration or by the controller-manager. `cbr0` is assigned an MTU matching the smallest MTU of an enabled normal interface on the host. + +The plugin requires a few things: + +* The standard CNI `bridge`, `lo` and `host-local` plugins are required, at minimum version 0.2.0. Kubenet will first search for them in `/opt/cni/bin`. Specify `network-plugin-dir` to supply additional search path. The first found match will take effect. +* Kubelet must be run with the `--network-plugin=kubenet` argument to enable the plugin +* Kubelet should also be run with the `--non-masquerade-cidr=` argument to ensure traffic to IPs outside this range will use IP masquerade. +* The node must be assigned an IP subnet through either the `--pod-cidr` kubelet command-line option or the `--allocate-node-cidrs=true --cluster-cidr=` controller-manager command-line options. + +### Customizing the MTU (with kubenet) + +The MTU should always be configured correctly to get the best networking performance. Network plugins will usually try +to infer a sensible MTU, but sometimes the logic will not result in an optimal MTU. For example, if the +Docker bridge or another interface has a small MTU, kubenet will currently select that MTU. Or if you are +using IPSEC encapsulation, the MTU must be reduced, and this calculation is out-of-scope for +most network plugins. + +Where needed, you can specify the MTU explicitly with the `network-plugin-mtu` kubelet option. For example, +on AWS the `eth0` MTU is typically 9001, so you might specify `--network-plugin-mtu=9001`. If you're using IPSEC you +might reduce it to allow for encapsulation overhead e.g. `--network-plugin-mtu=8873`. + +This option is provided to the network-plugin; currently **only kubenet supports `network-plugin-mtu`**. + +## Usage Summary + +* `--network-plugin=cni` specifies that we use the `cni` network plugin with actual CNI plugin binaries located in `--cni-bin-dir` (default `/opt/cni/bin`) and CNI plugin configuration located in `--cni-conf-dir` (default `/etc/cni/net.d`). +* `--network-plugin=kubenet` specifies that we use the `kubenet` network plugin with CNI `bridge` and `host-local` plugins placed in `/opt/cni/bin` or `network-plugin-dir`. +* `--network-plugin-mtu=9001` specifies the MTU to use, currently only used by the `kubenet` network plugin. diff --git a/docs/concepts/cluster-administration/networking.md b/docs/concepts/cluster-administration/networking.md new file mode 100644 index 0000000000..533a9ee874 --- /dev/null +++ b/docs/concepts/cluster-administration/networking.md @@ -0,0 +1,215 @@ +--- +assignees: +- thockin +title: Cluster Networking +--- + +Kubernetes approaches networking somewhat differently than Docker does by +default. There are 4 distinct networking problems to solve: + +1. Highly-coupled container-to-container communications: this is solved by + [pods](/docs/user-guide/pods/) and `localhost` communications. +2. Pod-to-Pod communications: this is the primary focus of this document. +3. Pod-to-Service communications: this is covered by [services](/docs/user-guide/services/). +4. External-to-Service communications: this is covered by [services](/docs/user-guide/services/). + +* TOC +{:toc} + + +## Summary + +Kubernetes assumes that pods can communicate with other pods, regardless of +which host they land on. We give every pod its own IP address so you do not +need to explicitly create links between pods and you almost never need to deal +with mapping container ports to host ports. This creates a clean, +backwards-compatible model where pods can be treated much like VMs or physical +hosts from the perspectives of port allocation, naming, service discovery, load +balancing, application configuration, and migration. + +To achieve this we must impose some requirements on how you set up your cluster +networking. + +## Docker model + +Before discussing the Kubernetes approach to networking, it is worthwhile to +review the "normal" way that networking works with Docker. By default, Docker +uses host-private networking. It creates a virtual bridge, called `docker0` by +default, and allocates a subnet from one of the private address blocks defined +in [RFC1918](https://tools.ietf.org/html/rfc1918) for that bridge. For each +container that Docker creates, it allocates a virtual ethernet device (called +`veth`) which is attached to the bridge. The veth is mapped to appear as `eth0` +in the container, using Linux namespaces. The in-container `eth0` interface is +given an IP address from the bridge's address range. + +The result is that Docker containers can talk to other containers only if they +are on the same machine (and thus the same virtual bridge). Containers on +different machines can not reach each other - in fact they may end up with the +exact same network ranges and IP addresses. + +In order for Docker containers to communicate across nodes, they must be +allocated ports on the machine's own IP address, which are then forwarded or +proxied to the containers. This obviously means that containers must either +coordinate which ports they use very carefully or else be allocated ports +dynamically. + +## Kubernetes model + +Coordinating ports across multiple developers is very difficult to do at +scale and exposes users to cluster-level issues outside of their control. +Dynamic port allocation brings a lot of complications to the system - every +application has to take ports as flags, the API servers have to know how to +insert dynamic port numbers into configuration blocks, services have to know +how to find each other, etc. Rather than deal with this, Kubernetes takes a +different approach. + +Kubernetes imposes the following fundamental requirements on any networking +implementation (barring any intentional network segmentation policies): + + * all containers can communicate with all other containers without NAT + * all nodes can communicate with all containers (and vice-versa) without NAT + * the IP that a container sees itself as is the same IP that others see it as + +What this means in practice is that you can not just take two computers +running Docker and expect Kubernetes to work. You must ensure that the +fundamental requirements are met. + +This model is not only less complex overall, but it is principally compatible +with the desire for Kubernetes to enable low-friction porting of apps from VMs +to containers. If your job previously ran in a VM, your VM had an IP and could +talk to other VMs in your project. This is the same basic model. + +Until now this document has talked about containers. In reality, Kubernetes +applies IP addresses at the `Pod` scope - containers within a `Pod` share their +network namespaces - including their IP address. This means that containers +within a `Pod` can all reach each other's ports on `localhost`. This does imply +that containers within a `Pod` must coordinate port usage, but this is no +different than processes in a VM. We call this the "IP-per-pod" model. This +is implemented in Docker as a "pod container" which holds the network namespace +open while "app containers" (the things the user specified) join that namespace +with Docker's `--net=container:` function. + +As with Docker, it is possible to request host ports, but this is reduced to a +very niche operation. In this case a port will be allocated on the host `Node` +and traffic will be forwarded to the `Pod`. The `Pod` itself is blind to the +existence or non-existence of host ports. + +## How to achieve this + +There are a number of ways that this network model can be implemented. This +document is not an exhaustive study of the various methods, but hopefully serves +as an introduction to various technologies and serves as a jumping-off point. + +The following networking options are sorted alphabetically - the order does not +imply any preferential status. + +### 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. + +### Flannel + +[Flannel](https://github.com/coreos/flannel#flannel) is a very simple overlay +network that satisfies the Kubernetes requirements. Many +people have reported success with Flannel and Kubernetes. + +### Google Compute Engine (GCE) + +For the Google Compute Engine cluster configuration scripts, we use [advanced +routing](https://cloud.google.com/compute/docs/networking#routing) to +assign each VM a subnet (default is `/24` - 254 IPs). Any traffic bound for that +subnet will be routed directly to the VM by the GCE network fabric. This is in +addition to the "main" IP address assigned to the VM, which is NAT'ed for +outbound internet access. A linux bridge (called `cbr0`) is configured to exist +on that subnet, and is passed to docker's `--bridge` flag. + +We start Docker with: + +```shell +DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false" +``` + +This bridge is created by Kubelet (controlled by the `--network-plugin=kubenet` +flag) according to the `Node`'s `spec.podCIDR`. + +Docker will now allocate IPs from the `cbr-cidr` block. Containers can reach +each other and `Nodes` over the `cbr0` bridge. Those IPs are all routable +within the GCE project network. + +GCE itself does not know anything about these IPs, though, so it will not NAT +them for outbound internet traffic. To achieve that we use an iptables rule to +masquerade (aka SNAT - to make it seem as if packets came from the `Node` +itself) traffic that is bound for IPs outside the GCE project network +(10.0.0.0/8). + +```shell +iptables -t nat -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE +``` + +Lastly we enable IP forwarding in the kernel (so the kernel will process +packets for bridged containers): + +```shell +sysctl net.ipv4.ip_forward=1 +``` + +The result of all this is that all `Pods` can reach each other and can egress +traffic to the internet. + +### L2 networks and linux bridging + +If you have a "dumb" L2 network, such as a simple switch in a "bare-metal" +environment, you should be able to do something similar to the above GCE setup. +Note that these instructions have only been tried very casually - it seems to +work, but has not been thoroughly tested. If you use this technique and +perfect the process, please let us know. + +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. + +### Nuage Networks VCS (Virtualized Cloud Services) + +[Nuage](http://www.nuagenetworks.net) provides a highly scalable policy-based Software-Defined Networking (SDN) platform. Nuage uses the open source Open vSwitch for the data plane along with a feature rich SDN Controller built on open standards. + +The Nuage platform uses overlays to provide seamless policy-based networking between Kubernetes Pods and non-Kubernetes environments (VMs and bare metal servers). Nuage's policy abstraction model is designed with applications in mind and makes it easy to declare fine-grained policies for applications.The platform's real-time analytics engine enables visibility and security monitoring for Kubernetes applications. + +### OpenVSwitch + +[OpenVSwitch](/docs/admin/ovs-networking) is a somewhat more mature but also +complicated way to build an overlay network. This is endorsed by several of the +"Big Shops" for networking. + +### OVN (Open Virtual Networking) + +OVN is an opensource network virtualization solution developed by the +Open vSwitch community. It lets one create logical switches, logical routers, +stateful ACLs, load-balancers etc to build different virtual networking +topologies. The project has a specific Kubernetes plugin and documentation +at [ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes). + +### Project Calico + +[Project Calico](http://docs.projectcalico.org/) is an open source container networking provider and network policy engine. + +Calico provides a highly scalable networking and network policy solution for connecting Kubernetes pods based on the same IP networking principles as the internet. Calico can be deployed without encapsulation or overlays to provide high-performance, high-scale data center networking. Calico also provides fine-grained, intent based network security policy for Kubernetes pods via its distributed firewall. + +Calico can also be run in policy enforcement mode in conjunction with other networking solutions such as Flannel, aka [canal](https://github.com/tigera/canal), or native GCE networking. + +### Romana + +[Romana](http://romana.io) is an open source network and security automation solution that lets you deploy Kubernetes without an overlay network. Romana supports Kubernetes [Network Policy](/docs/user-guide/networkpolicies/) to provide isolation across network namespaces. + +### Weave Net from Weaveworks + +[Weave Net](https://www.weave.works/products/weave-net/) 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/docs/net/latest/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. + +## Other reading + +The early design of the networking model and its rationale, and some future +plans are described in more detail in the [networking design +document](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/networking.md). diff --git a/docs/concepts/cluster-administration/nginx-app.yaml b/docs/concepts/cluster-administration/nginx-app.yaml new file mode 100644 index 0000000000..8ae449d806 --- /dev/null +++ b/docs/concepts/cluster-administration/nginx-app.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Service +metadata: + name: my-nginx-svc + labels: + app: nginx +spec: + type: LoadBalancer + ports: + - port: 80 + selector: + app: nginx +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: my-nginx +spec: + replicas: 3 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 diff --git a/docs/concepts/cluster-administration/out-of-resource.md b/docs/concepts/cluster-administration/out-of-resource.md new file mode 100644 index 0000000000..76e7125e7e --- /dev/null +++ b/docs/concepts/cluster-administration/out-of-resource.md @@ -0,0 +1,368 @@ +--- +assignees: +- derekwaynecarr +- vishh +- timstclair +title: Configuring Out Of Resource Handling +--- + +* TOC +{:toc} + +The `kubelet` needs to preserve node stability when available compute resources are low. + +This is especially important when dealing with incompressible resources such as memory or disk. + +If either resource is exhausted, the node would become unstable. + +## Eviction Policy + +The `kubelet` can pro-actively monitor for and prevent against total starvation of a compute resource. In those cases, the `kubelet` can pro-actively fail one or more pods in order to reclaim +the starved resource. When the `kubelet` fails a pod, it terminates all containers in the pod, and the `PodPhase` +is transitioned to `Failed`. + +### Eviction Signals + +The `kubelet` can support the ability to trigger eviction decisions on the signals described in the +table below. The value of each signal is described in the description column based on the `kubelet` +summary API. + +| Eviction Signal | Description | +|----------------------------|-----------------------------------------------------------------------| +| `memory.available` | `memory.available` := `node.status.capacity[memory]` - `node.stats.memory.workingSet` | +| `nodefs.available` | `nodefs.available` := `node.stats.fs.available` | +| `nodefs.inodesFree` | `nodefs.inodesFree` := `node.stats.fs.inodesFree` | +| `imagefs.available` | `imagefs.available` := `node.stats.runtime.imagefs.available` | +| `imagefs.inodesFree` | `imagefs.inodesFree` := `node.stats.runtime.imagefs.inodesFree` | + +Each of the above signals supports either a literal or percentage based value. The percentage based value +is calculated relative to the total capacity associated with each signal. + +`kubelet` supports only two filesystem partitions. + +1. The `nodefs` filesystem that kubelet uses for volumes, daemon logs, etc. +1. The `imagefs` filesystem that container runtimes uses for storing images and container writable layers. + +`imagefs` is optional. `kubelet` auto-discovers these filesystems using cAdvisor. `kubelet` does not care about any +other filesystems. Any other types of configurations are not currently supported by the kubelet. For example, it is +*not OK* to store volumes and logs in a dedicated `filesystem`. + +In future releases, the `kubelet` will deprecate the existing [garbage collection](/docs/admin/garbage-collection/) +support in favor of eviction in response to disk pressure. + +### Eviction Thresholds + +The `kubelet` supports the ability to specify eviction thresholds that trigger the `kubelet` to reclaim resources. + +Each threshold is of the following form: + +`` + +* valid `eviction-signal` tokens as defined above. +* valid `operator` tokens are `<` +* valid `quantity` tokens must match the quantity representation used by Kubernetes +* an eviction threshold can be expressed as a percentage if ends with `%` token. + +For example, if a node has `10Gi` of memory, and the desire is to induce eviction +if available memory falls below `1Gi`, an eviction threshold can be specified as either +of the following (but not both). + +* `memory.available<10%` +* `memory.available<1Gi` + +#### Soft Eviction Thresholds + +A soft eviction threshold pairs an eviction threshold with a required +administrator specified grace period. No action is taken by the `kubelet` +to reclaim resources associated with the eviction signal until that grace +period has been exceeded. If no grace period is provided, the `kubelet` will +error on startup. + +In addition, if a soft eviction threshold has been met, an operator can +specify a maximum allowed pod termination grace period to use when evicting +pods from the node. If specified, the `kubelet` will use the lesser value among +the `pod.Spec.TerminationGracePeriodSeconds` and the max allowed grace period. +If not specified, the `kubelet` will kill pods immediately with no graceful +termination. + +To configure soft eviction thresholds, the following flags are supported: + +* `eviction-soft` describes a set of eviction thresholds (e.g. `memory.available<1.5Gi`) that if met over a +corresponding grace period would trigger a pod eviction. +* `eviction-soft-grace-period` describes a set of eviction grace periods (e.g. `memory.available=1m30s`) that +correspond to how long a soft eviction threshold must hold before triggering a pod eviction. +* `eviction-max-pod-grace-period` describes the maximum allowed grace period (in seconds) to use when terminating +pods in response to a soft eviction threshold being met. + +#### Hard Eviction Thresholds + +A hard eviction threshold has no grace period, and if observed, the `kubelet` +will take immediate action to reclaim the associated starved resource. If a +hard eviction threshold is met, the `kubelet` will kill the pod immediately +with no graceful termination. + +To configure hard eviction thresholds, the following flag is supported: + +* `eviction-hard` describes a set of eviction thresholds (e.g. `memory.available<1Gi`) that if met +would trigger a pod eviction. + +The `kubelet` has the following default hard eviction thresholds: + +* `--eviction-hard=memory.available<100Mi` + +### Eviction Monitoring Interval + +The `kubelet` evaluates eviction thresholds per its configured housekeeping interval. + +* `housekeeping-interval` is the interval between container housekeepings. + +### Node Conditions + +The `kubelet` will map one or more eviction signals to a corresponding node condition. + +If a hard eviction threshold has been met, or a soft eviction threshold has been met +independent of its associated grace period, the `kubelet` will report a condition that +reflects the node is under pressure. + +The following node conditions are defined that correspond to the specified eviction signal. + +| Node Condition | Eviction Signal | Description | +|-------------------------|-------------------------------|--------------------------------------------| +| `MemoryPressure` | `memory.available` | Available memory on the node has satisfied an eviction threshold | +| `DiskPressure` | `nodefs.available`, `nodefs.inodesFree`, `imagefs.available`, or `imagefs.inodesFree` | Available disk space and inodes on either the node's root filesytem or image filesystem has satisfied an eviction threshold | + +The `kubelet` will continue to report node status updates at the frequency specified by +`--node-status-update-frequency` which defaults to `10s`. + +### Oscillation of node conditions + +If a node is oscillating above and below a soft eviction threshold, but not exceeding +its associated grace period, it would cause the corresponding node condition to +constantly oscillate between true and false, and could cause poor scheduling decisions +as a consequence. + +To protect against this oscillation, the following flag is defined to control how +long the `kubelet` must wait before transitioning out of a pressure condition. + +* `eviction-pressure-transition-period` is the duration for which the `kubelet` has +to wait before transitioning out of an eviction pressure condition. + +The `kubelet` would ensure that it has not observed an eviction threshold being met +for the specified pressure condition for the period specified before toggling the +condition back to `false`. + +### Reclaiming node level resources + +If an eviction threshold has been met and the grace period has passed, +the `kubelet` will initiate the process of reclaiming the pressured resource +until it has observed the signal has gone below its defined threshold. + +The `kubelet` attempts to reclaim node level resources prior to evicting end-user pods. If +disk pressure is observed, the `kubelet` reclaims node level resources differently if the +machine has a dedicated `imagefs` configured for the container runtime. + +#### With Imagefs + +If `nodefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order: + +1. Delete dead pods/containers + +If `imagefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order: + +1. Delete all unused images + +#### Without Imagefs + +If `nodefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order: + +1. Delete dead pods/containers +1. Delete all unused images + +### Evicting end-user pods + +If the `kubelet` is unable to reclaim sufficient resource on the node, +it will begin evicting pods. + +The `kubelet` ranks pods for eviction as follows: + +* by their quality of service +* by the consumption of the starved compute resource relative to the pods scheduling request. + +As a result, pod eviction occurs in the following order: + +* `BestEffort` pods that consume the most of the starved resource are failed +first. +* `Burstable` pods that consume the greatest amount of the starved resource +relative to their request for that resource are killed first. If no pod +has exceeded its request, the strategy targets the largest consumer of the +starved resource. +* `Guaranteed` pods that consume the greatest amount of the starved resource +relative to their request are killed first. If no pod has exceeded its request, +the strategy targets the largest consumer of the starved resource. + +A `Guaranteed` pod is guaranteed to never be evicted because of another pod's +resource consumption. If a system daemon (i.e. `kubelet`, `docker`, `journald`, etc.) +is consuming more resources than were reserved via `system-reserved` or `kube-reserved` allocations, +and the node only has `Guaranteed` pod(s) remaining, then the node must choose to evict a +`Guaranteed` pod in order to preserve node stability, and to limit the impact +of the unexpected consumption to other `Guaranteed` pod(s). + +Local disk is a `BestEffort` resource. If necessary, `kubelet` will evict pods one at a time to reclaim +disk when `DiskPressure` is encountered. The `kubelet` will rank pods by quality of service. If the `kubelet` +is responding to `inode` starvation, it will reclaim `inodes` by evicting pods with the lowest quality of service +first. If the `kubelet` is responding to lack of available disk, it will rank pods within a quality of service +that consumes the largest amount of disk and kill those first. + +#### With Imagefs + +If `nodefs` is triggering evictions, `kubelet` will sort pods based on the usage on `nodefs` +- local volumes + logs of all its containers. + +If `imagefs` is triggering evictions, `kubelet` will sort pods based on the writable layer usage of all its containers. + +#### Without Imagefs + +If `nodefs` is triggering evictions, `kubelet` will sort pods based on their total disk usage +- local volumes + logs & writable layer of all its containers. + +### Minimum eviction reclaim + +In certain scenarios, eviction of pods could result in reclamation of small amount of resources. This can result in +`kubelet` hitting eviction thresholds in repeated successions. In addition to that, eviction of resources like `disk`, + is time consuming. + +To mitigate these issues, `kubelet` can have a per-resource `minimum-reclaim`. Whenever `kubelet` observes +resource pressure, `kubelet` will attempt to reclaim at least `minimum-reclaim` amount of resource below +the configured eviction threshold. + +For example, with the following configuration: + +``` +--eviction-hard=memory.available<500Mi,nodefs.available<1Gi,imagefs.available<100Gi +--eviction-minimum-reclaim="memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi"` +``` + +If an eviction threshold is triggered for `memory.available`, the `kubelet` will work to ensure +that `memory.available` is at least `500Mi`. For `nodefs.available`, the `kubelet` will work +to ensure that `nodefs.available` is at least `1.5Gi`, and for `imagefs.available` it will +work to ensure that `imagefs.available` is at least `102Gi` before no longer reporting pressure +on their associated resources. + +The default `eviction-minimum-reclaim` is `0` for all resources. + +### Scheduler + +The node will report a condition when a compute resource is under pressure. The +scheduler views that condition as a signal to dissuade placing additional +pods on the node. + +| Node Condition | Scheduler Behavior | +| ---------------- | ------------------------------------------------ | +| `MemoryPressure` | No new `BestEffort` pods are scheduled to the node. | +| `DiskPressure` | No new pods are scheduled to the node. | + +## Node OOM Behavior + +If the node experiences a system OOM (out of memory) event prior to the `kubelet` is able to reclaim memory, +the node depends on the [oom_killer](https://lwn.net/Articles/391222/) to respond. + +The `kubelet` sets a `oom_score_adj` value for each container based on the quality of service for the pod. + +| Quality of Service | oom_score_adj | +|----------------------------|-----------------------------------------------------------------------| +| `Guaranteed` | -998 | +| `BestEffort` | 1000 | +| `Burstable` | min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999) | + +If the `kubelet` is unable to reclaim memory prior to a node experiencing system OOM, the `oom_killer` will calculate +an `oom_score` based on the percentage of memory its using on the node, and then add the `oom_score_adj` to get an +effective `oom_score` for the container, and then kills the container with the highest score. + +The intended behavior should be that containers with the lowest quality of service that +are consuming the largest amount of memory relative to the scheduling request should be killed first in order +to reclaim memory. + +Unlike pod eviction, if a pod container is OOM killed, it may be restarted by the `kubelet` based on its `RestartPolicy`. + +## Best Practices + +### Schedulable resources and eviction policies + +Let's imagine the following scenario: + +* Node memory capacity: `10Gi` +* Operator wants to reserve 10% of memory capacity for system daemons (kernel, `kubelet`, etc.) +* Operator wants to evict pods at 95% memory utilization to reduce thrashing and incidence of system OOM. + +To facilitate this scenario, the `kubelet` would be launched as follows: + +``` +--eviction-hard=memory.available<500Mi +--system-reserved=memory=1.5Gi +``` + +Implicit in this configuration is the understanding that "System reserved" should include the amount of memory +covered by the eviction threshold. + +To reach that capacity, either some pod is using more than its request, or the system is using more than `500Mi`. + +This configuration will ensure that the scheduler does not place pods on a node that immediately induce memory pressure +and trigger eviction assuming those pods use less than their configured request. + +### DaemonSet + +It is never desired for a `kubelet` to evict a pod that was derived from +a `DaemonSet` since the pod will immediately be recreated and rescheduled +back to the same node. + +At the moment, the `kubelet` has no ability to distinguish a pod created +from `DaemonSet` versus any other object. If/when that information is +available, the `kubelet` could pro-actively filter those pods from the +candidate set of pods provided to the eviction strategy. + +In general, it is strongly recommended that `DaemonSet` not +create `BestEffort` pods to avoid being identified as a candidate pod +for eviction. Instead `DaemonSet` should ideally launch `Guaranteed` pods. + +## Deprecation of existing feature flags to reclaim disk + +`kubelet` has been freeing up disk space on demand to keep the node stable. + +As disk based eviction matures, the following `kubelet` flags will be marked for deprecation +in favor of the simpler configuration supported around eviction. + +| Existing Flag | New Flag | +| ------------- | -------- | +| `--image-gc-high-threshold` | `--eviction-hard` or `eviction-soft` | +| `--image-gc-low-threshold` | `--eviction-minimum-reclaim` | +| `--maximum-dead-containers` | deprecated | +| `--maximum-dead-containers-per-container` | deprecated | +| `--minimum-container-ttl-duration` | deprecated | +| `--low-diskspace-threshold-mb` | `--eviction-hard` or `eviction-soft` | +| `--outofdisk-transition-frequency` | `--eviction-pressure-transition-period` | + +## Known issues + +### kubelet may not observe memory pressure right away + +The `kubelet` currently polls `cAdvisor` to collect memory usage stats at a regular interval. If memory usage +increases within that window rapidly, the `kubelet` may not observe `MemoryPressure` fast enough, and the `OOMKiller` +will still be invoked. We intend to integrate with the `memcg` notification API in a future release to reduce this +latency, and instead have the kernel tell us when a threshold has been crossed immediately. + +If you are not trying to achieve extreme utilization, but a sensible measure of overcommit, a viable workaround for +this issue is to set eviction thresholds at approximately 75% capacity. This increases the ability of this feature +to prevent system OOMs, and promote eviction of workloads so cluster state can rebalance. + +### kubelet may evict more pods than needed + +The pod eviction may evict more pods than needed due to stats collection timing gap. This can be mitigated by adding +the ability to get root container stats on an on-demand basis (https://github.com/google/cadvisor/issues/1247) in the future. + +### How kubelet ranks pods for eviction in response to inode exhaustion + +At this time, it is not possible to know how many inodes were consumed by a particular container. If the `kubelet` observes +inode exhaustion, it will evict pods by ranking them by quality of service. The following issue has been opened in cadvisor +to track per container inode consumption (https://github.com/google/cadvisor/issues/1422) which would allow us to rank pods +by inode consumption. For example, this would let us identify a container that created large numbers of 0 byte files, and evict +that pod over others. diff --git a/docs/concepts/cluster-administration/static-pod.md b/docs/concepts/cluster-administration/static-pod.md new file mode 100644 index 0000000000..88aa78a212 --- /dev/null +++ b/docs/concepts/cluster-administration/static-pod.md @@ -0,0 +1,128 @@ +--- +assignees: +- jsafrane +title: Static Pods +--- + +**If you are running clustered Kubernetes and are using static pods to run a pod on every node, you should probably be using a [DaemonSet](/docs/admin/daemons/)!** + +*Static pods* are managed directly by kubelet daemon on a specific node, without API server observing it. It does not have associated any replication controller, kubelet daemon itself watches it and restarts it when it crashes. There is no health check though. Static pods are always bound to one kubelet daemon and always run on the same node with it. + +Kubelet automatically creates so-called *mirror pod* on Kubernetes API server for each static pod, so the pods are visible there, but they cannot be controlled from the API server. + +## Static pod creation + +Static pod can be created in two ways: either by using configuration file(s) or by HTTP. + +### Configuration files + +The configuration files are just standard pod definition in json or yaml format in specific directory. Use `kubelet --pod-manifest-path=` to start kubelet daemon, which periodically scans the directory and creates/deletes static pods as yaml/json files appear/disappear there. + +For example, this is how to start a simple web server as a static pod: + +1. Choose a node where we want to run the static pod. In this example, it's `my-node1`. + + ``` + [joe@host ~] $ ssh my-node1 + ``` + +2. Choose a directory, say `/etc/kubelet.d` and place a web server pod definition there, e.g. `/etc/kubelet.d/static-web.yaml`: + + ``` + [root@my-node1 ~] $ mkdir /etc/kubernetes.d/ + [root@my-node1 ~] $ cat </etc/kubernetes.d/static-web.yaml + apiVersion: v1 + kind: Pod + metadata: + name: static-web + labels: + role: myrole + spec: + containers: + - name: web + image: nginx + ports: + - name: web + containerPort: 80 + protocol: TCP + EOF + ``` + +3. Configure your kubelet daemon on the node to use this directory by running it with `--pod-manifest-path=/etc/kubelet.d/` argument. + On Fedora edit `/etc/kubernetes/kubelet` to include this line: + + ``` + KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/" + ``` + + Instructions for other distributions or Kubernetes installations may vary. + +4. Restart kubelet. On Fedora, this is: + + ``` + [root@my-node1 ~] $ systemctl restart kubelet + ``` + +## Pods created via HTTP + +Kubelet periodically downloads a file specified by `--manifest-url=` argument and interprets it as a json/yaml file with a pod definition. It works the same as `--pod-manifest-path=`, i.e. it's reloaded every now and then and changes are applied to running static pods (see below). + +## Behavior of static pods + +When kubelet starts, it automatically starts all pods defined in directory specified in `--pod-manifest-path=` or `--manifest-url=` arguments, i.e. our static-web. (It may take some time to pull nginx image, be patient…): + +```shell +[joe@my-node1 ~] $ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c +``` + +If we look at our Kubernetes API server (running on host `my-master`), we see that a new mirror-pod was created there too: + +```shell +[joe@host ~] $ ssh my-master +[joe@my-master ~] $ kubectl get pods +NAME READY STATUS RESTARTS AGE +static-web-my-node1 1/1 Running 0 2m + +``` + +Labels from the static pod are propagated into the mirror-pod and can be used as usual for filtering. + +Notice we cannot delete the pod with the API server (e.g. via [`kubectl`](/docs/user-guide/kubectl/) command), kubelet simply won't remove it. + +```shell +[joe@my-master ~] $ kubectl delete pod static-web-my-node1 +pods/static-web-my-node1 +[joe@my-master ~] $ kubectl get pods +NAME READY STATUS RESTARTS AGE +static-web-my-node1 1/1 Running 0 12s + +``` + +Back to our `my-node1` host, we can try to stop the container manually and see, that kubelet automatically restarts it in a while: + +```shell +[joe@host ~] $ ssh my-node1 +[joe@my-node1 ~] $ docker stop f6d05272b57e +[joe@my-node1 ~] $ sleep 20 +[joe@my-node1 ~] $ docker ps +CONTAINER ID IMAGE COMMAND CREATED ... +5b920cbaf8b1 nginx:latest "nginx -g 'daemon of 2 seconds ago ... +``` + +## Dynamic addition and removal of static pods + +Running kubelet periodically scans the configured directory (`/etc/kubelet.d` in our example) for changes and adds/removes pods as files appear/disappear in this directory. + +```shell +[joe@my-node1 ~] $ mv /etc/kubelet.d/static-web.yaml /tmp +[joe@my-node1 ~] $ sleep 20 +[joe@my-node1 ~] $ docker ps +// no nginx container is running +[joe@my-node1 ~] $ mv /tmp/static-web.yaml /etc/kubelet.d/ +[joe@my-node1 ~] $ sleep 20 +[joe@my-node1 ~] $ docker ps +CONTAINER ID IMAGE COMMAND CREATED ... +e7a62e3427f1 nginx:latest "nginx -g 'daemon of 27 seconds ago +``` diff --git a/docs/concepts/cluster-administration/sysctl-cluster.md b/docs/concepts/cluster-administration/sysctl-cluster.md new file mode 100644 index 0000000000..aa75c4df2a --- /dev/null +++ b/docs/concepts/cluster-administration/sysctl-cluster.md @@ -0,0 +1,122 @@ +--- +assignees: +- sttts +title: Using Sysctls in a Kubernetes Cluster +--- + +* TOC +{:toc} + +This document describes how sysctls are used within a Kubernetes cluster. + +## What is a Sysctl? + +In Linux, the sysctl interface allows an administrator to modify kernel +parameters at runtime. Parameters are available via the `/proc/sys/` virtual +process file system. The parameters cover various subsystems such as: + +- kernel (common prefix: `kernel.`) +- networking (common prefix: `net.`) +- virtual memory (common prefix: `vm.`) +- MDADM (common prefix: `dev.`) +- More subsystems are described in [Kernel docs](https://www.kernel.org/doc/Documentation/sysctl/README). + +To get a list of all parameters, you can run + +``` +$ sudo sysctl -a +``` + +## Namespaced vs. Node-Level Sysctls + +A number of sysctls are _namespaced_ in today's Linux kernels. This means that +they can be set independently for each pod on a node. Being namespaced is a +requirement for sysctls to be accessible in a pod context within Kubernetes. + +The following sysctls are known to be _namespaced_: + +- `kernel.shm*`, +- `kernel.msg*`, +- `kernel.sem`, +- `fs.mqueue.*`, +- `net.*`. + +Sysctls which are not namespaced are called _node-level_ and must be set +manually by the cluster admin, either by means of the underlying Linux +distribution of the nodes (e.g. via `/etc/sysctls.conf`) or using a DaemonSet +with privileged containers. + +**Note**: it is good practice to consider nodes with special sysctl settings as +_tainted_ within a cluster, and only schedule pods onto them which need those +sysctl settings. It is suggested to use the Kubernetes [_taints and toleration_ +feature](/docs/user-guide/kubectl/kubectl_taint.md) to implement this. + +## Safe vs. Unsafe Sysctls + +Sysctls are grouped into _safe_ and _unsafe_ sysctls. In addition to proper +namespacing a _safe_ sysctl must be properly _isolated_ between pods on the same +node. This means that setting a _safe_ sysctl for one pod + +- must not have any influence on any other pod on the node +- must not allow to harm the node's health +- must not allow to gain CPU or memory resources outside of the resource limits + of a pod. + +By far, most of the _namespaced_ sysctls are not necessarily considered _safe_. + +For Kubernetes 1.4, the following sysctls are supported in the _safe_ set: + +- `kernel.shm_rmid_forced`, +- `net.ipv4.ip_local_port_range`, +- `net.ipv4.tcp_syncookies`. + +This list will be extended in future Kubernetes versions when the kubelet +supports better isolation mechanisms. + +All _safe_ sysctls are enabled by default. + +All _unsafe_ sysctls are disabled by default and must be allowed manually by the +cluster admin on a per-node basis. Pods with disabled unsafe sysctls will be +scheduled, but will fail to launch. + +**Warning**: Due to their nature of being _unsafe_, the use of _unsafe_ sysctls +is at-your-own-risk and can lead to severe problems like wrong behavior of +containers, resource shortage or complete breakage of a node. + +## Enabling Unsafe Sysctls + +With the warning above in mind, the cluster admin can allow certain _unsafe_ +sysctls for very special situations like e.g. high-performance or real-time +application tuning. _Unsafe_ sysctls are enabled on a node-by-node basis with a +flag of the kubelet, e.g.: + +```shell +$ kubelet --experimental-allowed-unsafe-sysctls 'kernel.msg*,net.ipv4.route.min_pmtu' ... +``` + +Only _namespaced_ sysctls can be enabled this way. + +## Setting Sysctls for a Pod + +The sysctl feature is an alpha API in Kubernetes 1.4. Therefore, sysctls are set +using annotations on pods. They apply to all containers in the same pod. + +Here is an example, with different annotations for _safe_ and _unsafe_ sysctls: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: sysctl-example + annotations: + security.alpha.kubernetes.io/sysctls: kernel.shm_rmid_forced=1 + security.alpha.kubernetes.io/unsafe-sysctls: net.ipv4.route.min_pmtu=1000,kernel.msgmax=1 2 3 +spec: + ... +``` + +**Note**: a pod with the _unsafe_ sysctls specified above will fail to launch on +any node which has not enabled those two _unsafe_ sysctls explicitly. As with +_node-level_ sysctls it is recommended to use [_taints and toleration_ +feature](/docs/user-guide/kubectl/kubectl_taint.md) or [labels on nodes](/docs +/user-guide/labels.md) to schedule those pods onto the right nodes. diff --git a/docs/user-guide/logging/examples/two-files-counter-pod-agent-sidecar.yaml b/docs/concepts/cluster-administration/two-files-counter-pod-agent-sidecar.yaml similarity index 100% rename from docs/user-guide/logging/examples/two-files-counter-pod-agent-sidecar.yaml rename to docs/concepts/cluster-administration/two-files-counter-pod-agent-sidecar.yaml diff --git a/docs/user-guide/logging/examples/two-files-counter-pod-streaming-sidecar.yaml b/docs/concepts/cluster-administration/two-files-counter-pod-streaming-sidecar.yaml similarity index 100% rename from docs/user-guide/logging/examples/two-files-counter-pod-streaming-sidecar.yaml rename to docs/concepts/cluster-administration/two-files-counter-pod-streaming-sidecar.yaml diff --git a/docs/user-guide/logging/examples/two-files-counter-pod.yaml b/docs/concepts/cluster-administration/two-files-counter-pod.yaml similarity index 100% rename from docs/user-guide/logging/examples/two-files-counter-pod.yaml rename to docs/concepts/cluster-administration/two-files-counter-pod.yaml diff --git a/docs/concepts/configuration/container-command-args.md b/docs/concepts/configuration/container-command-args.md index 54fe3afcb9..c2dafaadfa 100644 --- a/docs/concepts/configuration/container-command-args.md +++ b/docs/concepts/configuration/container-command-args.md @@ -1,5 +1,8 @@ --- title: Container Command and Arguments +redirect_from: +- "/docs/user-guide/containers/" +- "/docs/user-guide/containers.html" --- {% capture overview %} @@ -13,7 +16,7 @@ fields to override the default Entrypoint and Cmd of the the Container's image. ## Container entry points and arguments -The configuration file for a Container has an `image` field that specifies the +The configuration file for a Container has an `image` field that specifies the Docker image to be run in the Container. A Docker image has metadata that includes a default Entrypoint and a default Cmd. @@ -66,6 +69,7 @@ Here are some examples: | `[/ep-1]` | `[foo bar]` | <not set> | <not set> | `[ep-1 foo bar]` | | `[/ep-1]` | `[foo bar]` | `[/ep-2]` | <not set> | `[ep-2]` | | `[/ep-1]` | `[foo bar]` | <not set> | `[zoo boo]` | `[ep-1 zoo boo]` | +| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | `[zoo boo]` | `[ep-2 zoo boo]` | {% endcapture %} diff --git a/docs/concepts/configuration/manage-compute-resources-container.md b/docs/concepts/configuration/manage-compute-resources-container.md new file mode 100644 index 0000000000..2754260d65 --- /dev/null +++ b/docs/concepts/configuration/manage-compute-resources-container.md @@ -0,0 +1,430 @@ +--- +title: Managing Compute Resources for Containers +--- + +{% capture overview %} + +When you specify a [Pod](/docs/user-guide/pods), you can optionally specify how +much CPU and memory (RAM) each Container needs. When Containers have resource +requests specified, the scheduler can make better decisions about which nodes to +place Pods on. And when Containers have their limits specified, contention for +resources on a node can be handled in a specified manner. For more details about +the difference between requests and limits, see +[Resource QoS](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resource-qos.md). + +{% endcapture %} + + +{% capture body %} + +## Resource types + +*CPU* and *memory* are each a *resource type*. A resource type has a base unit. +CPU is specified in units of cores, and memory is specified in units of bytes. + +CPU and memory are collectively referred to as *compute resources*, or just +*resources*. Compute +resources are measurable quantities that can be requested, allocated, and +consumed. They are distinct from +[API resources](/docs/api/). API resources, such as Pods and +[Services](/docs/user-guide/services) are objects that can be read and modified +through the Kubernetes API server. + +## Resource requests and limits of Pod and Container + +Each Container of a Pod can specify one or more of the following: + +* `spec.containers[].resources.limits.cpu` +* `spec.containers[].resources.limits.memory` +* `spec.containers[].resources.requests.cpu` +* `spec.containers[].resources.requests.memory` + +Although requests and limits can only be specified on individual Containers, it +is convenient to talk about Pod resource requests and limits. A +*Pod resource request/limit* for a particular resource type is the sum of the +resource requests/limits of that type for each Container in the Pod. + +## Meaning of CPU + +Limits and requests for CPU resources are measured in *cpu* units. +One cpu, in Kubernetes, is equivalent to: + +- 1 AWS vCPU +- 1 GCP Core +- 1 Azure vCore +- 1 *Hyperthread* on a bare-metal Intel processor with Hyperthreading + +Fractional requests are allowed. A Container with +`spec.containers[].resources.requests.cpu` of `0.5` is guaranteed half as much +CPU as one that asks for 1 CPU. The expression `0.1` is equivalent to the +expression `100m`, which can be read as "one hundred millicpu". Some people say +"one hundred millicores", and this is understood to mean the same thing. A +request with a decimal point, like `0.1`, is converted to `100m` by the API, and +precision finer than `1m` is not allowed. For this reason, the form `100m` might +be preferred. + +CPU is always requested as an absolute quantity, never as a relative quantity; +0.1 is the same amount of CPU on a single-core, dual-core, or 48-core machine. + +## Meaning of memory + +Limits and requests for `memory` are measured in bytes. You can express memory as +a plain integer or as a fixed-point integer using one of these SI suffixes: +E, P, T, G, M, K. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, +Mi, Ki. For example, the following represent roughly the same value: + +```shell +128974848, 129e6, 129M, 123Mi +``` + +Here's an example. +The following Pod has two Containers. Each Container has a request of 0.25 cpu +and 64MiB (226 bytes) of memory Each Container has a limit of 0.5 +cpu and 128MiB of memory. You can say the Pod has a request of 0.5 cpu and 128 +MiB of memory, and a limit of 1 core and 256MiB of memory. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: frontend +spec: + containers: + - name: db + image: mysql + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" + - name: wp + image: wordpress + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" +``` + +## How Pods with resource requests are scheduled + +When you create a Pod, the Kubernetes scheduler selects a node for the Pod to +run on. Each node has a maximum capacity for each of the resource types: the +amount of CPU and memory it can provide for Pods. The scheduler ensures that, +for each resource type, the sum of the resource requests of the scheduled +Containers is less than the capacity of the node. Note that although actual memory +or CPU resource usage on nodes is very low, the scheduler still refuses to place +a Pod on a node if the capacity check fails. This protects against a resource +shortage on a node when resource usage later increases, for example, during a +daily peak in request rate. + +## How Pods with resource limits are run + +When the kubelet starts a Container of a Pod, it passes the CPU and memory limits +to the container runtime. + +When using Docker: + +- The `spec.containers[].resources.requests.cpu` is converted to its core value, + which is potentially fractional, and multiplied by 1024. This number is used + as the value of the + [`--cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint) + flag in the `docker run` command. + +- The `spec.containers[].resources.limits.cpu` is converted to its millicore value, + multiplied by 100000, and then divided by 1000. This number is used as the value + of the [`--cpu-quota`](https://docs.docker.com/engine/reference/run/#/cpu-quota-constraint) + flag in the `docker run` command. he [`--cpu-period`] flag is set to 100000, + which represents the default 100ms period for measuring quota usage. The + kubelet enforces cpu limits if it is started with the + [`--cpu-cfs-quota`] flag set to true. As of Kubernetes version 1.2, this flag + defaults to true. + +- The `spec.containers[].resources.limits.memory` is converted to an integer, and + used as the value of the + [`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) + flag in the `docker run` command. + +If a Container exceeds its memory limit, it might be terminated. If it is +restartable, the kubelet will restart it, as with any other type of runtime +failure. + +If a Container exceeds its memory request, it is likely that its Pod will +be evicted whenever the node runs out of memory. + +A Container might or might not be allowed to exceed its CPU limit for extended +periods of time. However, it will not be killed for excessive CPU usage. + +To determine whether a Container cannot be scheduled or is being killed due to +resource limits, see the +[Troubleshooting](#troubleshooting) section. + +## Monitoring compute resource usage + +The resource usage of a Pod is reported as part of the Pod status. + +If [optional monitoring](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/cluster-monitoring/README.md) +is configured for your cluster, then Pod resource usage can be retrieved from +the monitoring system. + +## Troubleshooting + +### My Pods are pending with event message failedScheduling + +If the scheduler cannot find any node where a Pod can fit, the Pod remains +unscheduled until a place can be found. An event is produced each time the +scheduler fails to find a place for the Pod, like this: + +```shell +$ kubectl describe pod frontend | grep -A 3 Events +Events: + FirstSeen LastSeen Count From Subobject PathReason Message + 36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others +``` + +In the preceding example, the Pod named "frontend" fails to be scheduled due to +insufficient CPU resource on the node. Similar error messages can also suggest +failure due to insufficient memory (PodExceedsFreeMemory). In general, if a Pod +is pending with a message of this type, there are several things to try: + +- Add more nodes to the cluster. +- Terminate unneeded Pods to make room for pending Pods. +- Check that the Pod is not larger than all the nodes. For example, if all the + nodes have a capacity of `cpu: 1`, then a Pod with a limit of `cpu: 1.1` will + never be scheduled. + +You can check node capacities and amounts allocated with the +`kubectl describe nodes` command. For example: + +```shell +$ kubectl.sh describe nodes e2e-test-minion-group-4lw4 +Name: e2e-test-minion-group-4lw4 +[ ... lines removed for clarity ...] +Capacity: + alpha.kubernetes.io/nvidia-gpu: 0 + cpu: 2 + memory: 7679792Ki + pods: 110 +Allocatable: + alpha.kubernetes.io/nvidia-gpu: 0 + cpu: 1800m + memory: 7474992Ki + pods: 110 +[ ... lines removed for clarity ...] +Non-terminated Pods: (5 in total) + Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits + --------- ---- ------------ ---------- --------------- ------------- + kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%) + kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%) + kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%) + kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%) + kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%) +Allocated resources: + (Total limits may be over 100 percent, i.e., overcommitted.) + CPU Requests CPU Limits Memory Requests Memory Limits + ------------ ---------- --------------- ------------- + 680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%) +``` + +In the preceding output, you can see that if a Pod requests more than 1120m +CPUs or 6.23Gi of memory, it will not fit on the node. + +By looking at the `Pods` section, you can see which Pods are taking up space on +the node. + +The amount of resources available to Pods is less than the node capacity, because +system daemons use a portion of the available resources. The `allocatable` field +[NodeStatus](/docs/resources-reference/v1.5/#nodestatus-v1) +gives the amount of resources that are available to Pods. For more information, see +[Node Allocatable Resources](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node-allocatable.md). + +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. + +### My Container is terminated + +Your Container might get terminated because it is resource-starved. To check +whether a Container is being killed because it is hitting a resource limit, call +`kubectl describe pod` on the Pod of interest: + +```shell +[12:54:41] $ ./cluster/kubectl.sh describe pod simmemleak-hra99 +Name: simmemleak-hra99 +Namespace: default +Image(s): saadali/simmemleak +Node: kubernetes-node-tf0f/10.240.216.66 +Labels: name=simmemleak +Status: Running +Reason: +Message: +IP: 10.244.2.75 +Replication Controllers: simmemleak (1/1 replicas created) +Containers: + simmemleak: + Image: saadali/simmemleak + Limits: + cpu: 100m + memory: 50Mi + State: Running + Started: Tue, 07 Jul 2015 12:54:41 -0700 + Last Termination State: Terminated + Exit Code: 1 + Started: Fri, 07 Jul 2015 12:54:30 -0700 + Finished: Fri, 07 Jul 2015 12:54:33 -0700 + Ready: False + Restart Count: 5 +Conditions: + Type Status + Ready False +Events: + FirstSeen LastSeen Count From SubobjectPath Reason Message + Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f + Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "gcr.io/google_containers/pause:0.8.0" already present on machine + Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d + Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d + Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a +``` + +In the preceding example, the `Restart Count: 5` indicates that the `simmemleak` +Container in the Pod was terminated and restarted five times. + +You can call `get pod` with the `-o go-template=...` option to fetch the status +of previously terminated Containers: + +```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]]{% endraw %} +``` + +You can see that the Container was terminated because of `reason:OOM Killed`, +where `OOM` stands for Out Of Memory. + +## Opaque integer resources (Alpha feature) + +Kubernetes version 1.5 introduces Opaque integer resources. Opaque +integer resources allow cluster operators to advertise new node-level +resources that would be otherwise unknown to the system. + +Users can consume these resources in Pod specs just like CPU and memory. +The scheduler takes care of the resource accounting so that no more than the +available amount is simultaneously allocated to Pods. + +**Note:** Opaque integer resources are Alpha in Kubernetes version 1.5. +Only resource accounting is implemented; node-level isolation is still +under active development. + +Opaque integer resources are resources that begin with the prefix +`pod.alpha.kubernetes.io/opaque-int-resource-`. The API server +restricts quantities of these resources to whole numbers. Examples of +_valid_ quantities are `3`, `3000m` and `3Ki`. Examples of _invalid_ +quantities are `0.5` and `1500m`. + +There are two steps required to use opaque integer resources. First, the +cluster operator must advertise a per-node opaque resource on one or more +nodes. Second, users must request the opaque resource in Pods. + +To advertise a new opaque integer resource, the cluster operator should +submit a `PATCH` HTTP request to the API server to specify the available +quantity in the `status.capacity` for a node in the cluster. After this +operation, the node's `status.capacity` will include a new resource. The +`status.allocatable` field is updated automatically with the new resource +asynchronously by the kubelet. Note that because the scheduler uses the +node `status.allocatable` value when evaluating Pod fitness, there may +be a short delay between patching the node capacity with a new resource and the +first pod that requests the resource to be scheduled on that node. + +**Example:** + +Here is an HTTP request that advertises five "foo" resources on node `k8s-node-1`. + +```http +PATCH /api/v1/nodes/k8s-node-1/status HTTP/1.1 +Accept: application/json +Content-Type: application/json-patch+json +Host: k8s-master:8080 + +[ + { + "op": "add", + "path": "/status/capacity/pod.alpha.kubernetes.io~1opaque-int-resource-foo", + "value": "5" + } +] +``` + +**Note**: In the preceding request, `~1` is the encoding for the character `/` +in the patch path. The operation path value in JSON-Patch is interpreted as a +JSON-Pointer. For more details, see +[IETF RFC 6901, section 3](https://tools.ietf.org/html/rfc6901#section-3). + +To consume an opaque resource in a Pod, include the name of the opaque +resource as a key in the `spec.containers[].resources.requests` map. + +The Pod is scheduled only if all of the resource requests are +satisfied, including cpu, memory and any opaque resources. The Pod will +remain in the `PENDING` state as long as the resource request cannot be met by +any node. + +**Example:** + +The Pod below requests 2 cpus and 1 "foo" (an opaque resource.) + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: my-pod +spec: + containers: + - name: my-container + image: myimage + resources: + requests: + cpu: 2 + pod.alpha.kubernetes.io/opaque-int-resource-foo: 1 +``` + +## Planned Improvements + +Kubernetes version 1.5 only allows resource quantities to be specified on a +Container. It is planned to improve accounting for resources that are shared by +all Containers in a Pod, such as +[emptyDir volumes](/docs/user-guide/volumes/#emptydir). + +Kubernetes version 1.5 only supports Container requests and limits for CPU and +memory. It is planned to add new resource types, including a node disk space +resource, and a framework for adding custom +[resource types](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/resources.md). + +Kubernetes supports overcommitment of resources by supporting multiple levels of +[Quality of Service](http://issue.k8s.io/168). + +In Kubernetes version 1.5, one unit of CPU means different things on different +cloud providers, and on different 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. + +{% endcapture %} + + +{% capture whatsnext %} + +* Get hands-on experience +[assigning CPU and RAM resources to a container](/docs/tasks/configure-pod-container/assign-cpu-ram-container/). + +* [Container](/docs/api-reference/v1/definitions/#_v1_container) + +* [ResourceRequirements](/docs/resources-reference/v1.5/#resourcerequirements-v1) + +{% endcapture %} + +{% include templates/concept.md %} + diff --git a/docs/concepts/configuration/overview.md b/docs/concepts/configuration/overview.md new file mode 100644 index 0000000000..0ef55e7b5e --- /dev/null +++ b/docs/concepts/configuration/overview.md @@ -0,0 +1,119 @@ +--- +assignees: +- mikedanese +title: Configuration Best Practices +--- + +This document is meant to highlight and consolidate in one place configuration best practices that are introduced throughout the user-guide and getting-started documentation and examples. This is a living document so if you think of something that is not on this list but might be useful to others, please don't hesitate to file an issue or submit a PR. + +## General Config Tips + +- When defining configurations, specify the latest stable API version (currently v1). + +- Configuration files should be stored in version control before being pushed to the cluster. This allows a configuration to be quickly rolled back if needed, and will aid with cluster re-creation and restoration if necessary. + +- Write your configuration files using YAML rather than JSON. They can be used interchangeably in almost all scenarios, but YAML tends to be more user-friendly for config. + +- Group related objects together in a single file where this makes sense. This format is often easier to manage than separate files. See the [guestbook-all-in-one.yaml](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/all-in-one/guestbook-all-in-one.yaml) file as an example of this syntax. +(Note also that many `kubectl` commands can be called on a directory, and so you can also call +`kubectl create` on a directory of config files— see below for more detail). + +- Don't specify default values unnecessarily, in order to simplify and minimize configs, and to + reduce error. For example, omit the selector and labels in a `ReplicationController` if you want + them to be the same as the labels in its `podTemplate`, since those fields are populated from the + `podTemplate` labels by default. See the [guestbook app's](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) .yaml files for some [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/frontend-deployment.yaml) of this. + +- Put an object description in an annotation to allow better introspection. + + +## "Naked" Pods vs Replication Controllers and Jobs + +- If there is a viable alternative to naked pods (i.e., pods not bound to a [replication controller + ](/docs/user-guide/replication-controller)), go with the alternative. Naked pods will not be rescheduled in the + event of node failure. + + Replication controllers are almost always preferable to creating pods, except for some explicit + [`restartPolicy: Never`](/docs/user-guide/pod-states/#restartpolicy) scenarios. A + [Job](/docs/user-guide/jobs/) object (currently in Beta), may also be appropriate. + + +## Services + +- It's typically best to create a [service](/docs/user-guide/services/) before corresponding [replication + controllers](/docs/user-guide/replication-controller/), so that the scheduler can spread the pods comprising the + service. You can also create a replication controller without specifying replicas (this will set + replicas=1), create a service, then scale up the replication controller. This can be useful in + ensuring that one replica works before creating lots of them. + +- Don't use `hostPort` (which specifies the port number to expose on the host) unless absolutely + necessary, e.g., for a node daemon. When you bind a Pod to a `hostPort`, there are a limited + number of places that pod can be scheduled, due to port conflicts— you can only schedule as many + such Pods as there are nodes in your Kubernetes cluster. + + If you only need access to the port for debugging purposes, you can use the [kubectl proxy and apiserver proxy](/docs/user-guide/connecting-to-applications-proxy/) or [kubectl port-forward](/docs/user-guide/connecting-to-applications-port-forward/). + You can use a [Service](/docs/user-guide/services/) object for external service access. + If you do need to expose a pod's port on the host machine, consider using a [NodePort](/docs/user-guide/services/#type-nodeport) service before resorting to `hostPort`. + +- Avoid using `hostNetwork`, for the same reasons as `hostPort`. + +- Use _headless services_ for easy service discovery when you don't need kube-proxy load balancing. + See [headless services](/docs/user-guide/services/#headless-services). + +## Using Labels + +- Define and use [labels](/docs/user-guide/labels/) that identify __semantic attributes__ of your application or + deployment. For example, instead of attaching a label to a set of pods to explicitly represent + some service (e.g., `service: myservice`), or explicitly representing the replication + controller managing the pods (e.g., `controller: mycontroller`), attach labels that identify + semantic attributes, such as `{ app: myapp, tier: frontend, phase: test, deployment: v3 }`. This + will let you select the object groups appropriate to the context— e.g., a service for all "tier: + frontend" pods, or all "test" phase components of app "myapp". See the + [guestbook](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) app for an example of this approach. + + A service can be made to span multiple deployments, such as is done across [rolling updates](/docs/user-guide/kubectl/kubectl_rolling-update/), by simply omitting release-specific labels from its selector, rather than updating a service's selector to match the replication controller's selector fully. + +- To facilitate rolling updates, include version info in replication controller names, e.g. as a + suffix to the name. It is useful to set a 'version' label as well. The rolling update creates a + new controller as opposed to modifying the existing controller. So, there will be issues with + version-agnostic controller names. See the [documentation](/docs/user-guide/kubectl/kubectl_rolling-update/) on + the rolling-update command for more detail. + + Note that the [Deployment](/docs/user-guide/deployments/) object obviates the need to manage replication + 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).) + +- 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 + controller, or served traffic by a service, by removing the relevant selector labels. If you + remove the labels of an existing pod, its controller will create a new pod to take its place. + This is a useful way to debug a previously "live" pod in a quarantine environment. See the + [`kubectl label`](/docs/user-guide/kubectl/kubectl_label/) command. + +## Container Images + +- The [default container image pull policy](/docs/user-guide/images/) is `IfNotPresent`, which causes the + [Kubelet](/docs/admin/kubelet/) to not pull an image if it already exists. If you would like to + always force a pull, you must specify a pull image policy of `Always` in your .yaml file + (`imagePullPolicy: Always`) or specify a `:latest` tag on your image. + + That is, if you're specifying an image with other than the `:latest` tag, e.g. `myimage:v1`, and + there is an image update to that same tag, the Kubelet won't pull the updated image. You can + 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 ` where possible. This looks for config objects in all `.yaml`, `.yml`, and `.json` files in `` and passes them to `create`. + +- Use `kubectl delete` rather than `stop`. `Delete` has a superset of the functionality of `stop`, and `stop` is deprecated. + +- 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/concepts/cluster-administration/manage-deployment/#using-labels-effectively). + +- 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. + + diff --git a/docs/concepts/index.md b/docs/concepts/index.md index 3f131c6358..39e44fbc97 100644 --- a/docs/concepts/index.md +++ b/docs/concepts/index.md @@ -8,7 +8,7 @@ The Concepts section helps you learn about the parts of the Kubernetes system an To work with Kubernetes, you use *Kubernetes API objects* to describe your cluster's *desired state*: what applications or other workloads you want to run, what container images they use, the number of replicas, what network and disk resources you want to make available, and more. You set your desired state by creating objects using the Kubernetes API, typically via the command-line interface, `kubectl`. You can also use the Kubernetes API directly to interact with the cluster and set or modify your desired state. -Once you've set your desired state, the *Kubernetes Control Plane* works to make the cluster's current state match the desired state. To do so, Kuberentes performs a variety of tasks automatically--such as starting or restarting containers, scaling the number of replicas of a given application, and more. The Kubernetes Control Plane consists of a collection processes running on your cluster: +Once you've set your desired state, the *Kubernetes Control Plane* works to make the cluster's current state match the desired state. To do so, Kuberentes performs a variety of tasks automatically--such as starting or restarting containers, scaling the number of replicas of a given application, and more. The Kubernetes Control Plane consists of a collection of processes running on your cluster: * The **Kubernetes Master** is a collection of four processes that run on a single node in your cluster, which is designated as the master node. * Each individual non-master node in your cluster runs two processes: @@ -17,7 +17,7 @@ Once you've set your desired state, the *Kubernetes Control Plane* works to make ## Kubernetes Objects -Kubernetes contains a number of abstractions that represent your the state of your system: deployed containerized applications and workloads, their associated network and disk resources, and other information about what your cluster is doing. These abstractions are represented by objects in the Kubernetes API; see the [Kubernetes Objects overview](/docs/concepts/abstractions/overview/) for more details. +Kubernetes contains a number of abstractions that represent the state of your system: deployed containerized applications and workloads, their associated network and disk resources, and other information about what your cluster is doing. These abstractions are represented by objects in the Kubernetes API; see the [Kubernetes Objects overview](/docs/concepts/abstractions/overview/) for more details. The basic Kubernetes objects include: @@ -44,7 +44,7 @@ For example, when you use the Kubernetes API to create a Deployment object, you The Kubernetes master is responsible for maintaining the desired state for your cluster. When you interact with Kubernetes, such as by using the `kubectl` command-line interface, you're communicating with your cluster's Kubernetes master. -> The "master" refers to a collection of processes managing the cluster state. Typically these processes are all run on a single node in the cluster, and this node is also referred to as the master. The master can also be replicated for availability and redundnacy. +> The "master" refers to a collection of processes managing the cluster state. Typically these processes are all run on a single node in the cluster, and this node is also referred to as the master. The master can also be replicated for availability and redundancy. ### Kubernetes Nodes diff --git a/docs/concepts/jobs/job.yaml b/docs/concepts/jobs/job.yaml new file mode 100644 index 0000000000..ece4512a8a --- /dev/null +++ b/docs/concepts/jobs/job.yaml @@ -0,0 +1,15 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: pi +spec: + template: + metadata: + name: pi + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + diff --git a/docs/concepts/jobs/run-to-completion-finite-workloads.md b/docs/concepts/jobs/run-to-completion-finite-workloads.md new file mode 100644 index 0000000000..fe17bb32e6 --- /dev/null +++ b/docs/concepts/jobs/run-to-completion-finite-workloads.md @@ -0,0 +1,385 @@ +--- +assignees: +- erictune +- soltysh +title: Run to Completion Finite Workloads +--- + +* TOC +{:toc} + +## What is a Job? + +A _job_ creates one or more pods and ensures that a specified number of them successfully terminate. +As pods successfully complete, the _job_ tracks the successful completions. When a specified number +of successful completions is reached, the job itself is complete. Deleting a Job will cleanup the +pods it created. + +A simple case is to create one Job object in order to reliably run one Pod to completion. +The Job object will start a new Pod if the first pod fails or is deleted (for example +due to a node hardware failure or a node reboot). + +A Job can also be used to run multiple pods in parallel. + +### extensions/v1beta1.Job is deprecated + +Starting from version 1.5 `extensions/v1beta1.Job` is being deprecated, with a plan to be removed in +version 1.6 of Kubernetes (see this [issue](https://github.com/kubernetes/kubernetes/issues/32763)). +Please use `batch/v1.Job` instead. + +## Running an example Job + +Here is an example Job config. It computes π to 2000 places and prints it out. +It takes around 10s to complete. + +{% include code.html language="yaml" file="job.yaml" ghlink="/docs/user-guide/job.yaml" %} + +Run the example job by downloading the example file and then running this command: + +```shell +$ kubectl create -f ./job.yaml +job "pi" created +``` + +Check on the status of the job using this command: + +```shell +$ kubectl describe jobs/pi +Name: pi +Namespace: default +Image(s): perl +Selector: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495 +Parallelism: 1 +Completions: 1 +Start Time: Tue, 07 Jun 2016 10:56:16 +0200 +Labels: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495,job-name=pi +Pods Statuses: 0 Running / 1 Succeeded / 0 Failed +No volumes. +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: pi-dtn4q +``` + +To view completed pods of a job, use `kubectl get pods --show-all`. The `--show-all` will show completed pods too. + +To list all the pods that belong to a job in a machine readable form, you can use a command like this: + +```shell +$ pods=$(kubectl get pods --show-all --selector=job-name=pi --output=jsonpath={.items..metadata.name}) +echo $pods +pi-aiw0a +``` + +Here, the selector is the same as the selector for the job. The `--output=jsonpath` option specifies an expression +that just gets the name from each pod in the returned list. + +View the standard output of one of the pods: + +```shell +$ kubectl logs $pods +3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901 +``` + +## Writing a Job Spec + +As with all other Kubernetes config, a Job needs `apiVersion`, `kind`, and `metadata` fields. For +general information about working with config files, see [here](/docs/user-guide/simple-yaml), +[here](/docs/user-guide/configuring-containers), and [here](/docs/user-guide/working-with-resources). + +A Job also needs a [`.spec` section](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status). + +### Pod Template + +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 `apiVersion` or +`kind`. + +In addition to required fields for a Pod, a pod template in a job must specify appropriate +labels (see [pod selector](#pod-selector)) and an appropriate restart policy. + +Only a [`RestartPolicy`](/docs/user-guide/pod-states/#restartpolicy) equal to `Never` or `OnFailure` is allowed. + +### Pod Selector + +The `.spec.selector` field is optional. In almost all cases you should not specify it. +See section [specifying your own pod selector](#specifying-your-own-pod-selector). + + +### Parallel Jobs + +There are three main types of jobs: + +1. Non-parallel Jobs + - normally only one pod is started, unless the pod fails. + - job is complete as soon as Pod terminates successfully. +1. Parallel Jobs with a *fixed completion count*: + - specify a non-zero positive value for `.spec.completions` + - the job is complete when there is one successful pod for each value in the range 1 to `.spec.completions`. + - **not implemented yet:** each pod passed a different index in the range 1 to `.spec.completions`. +1. Parallel Jobs with a *work queue*: + - do not specify `.spec.completions`, default to `.spec.Parallelism` + - the pods must coordinate with themselves or an external service to determine what each should work on + - each pod is independently capable of determining whether or not all its peers are done, thus the entire Job is done. + - when _any_ pod terminates with success, no new pods are created. + - once at least one pod has terminated with success and all pods are terminated, then the job is completed with success. + - once any pod has exited with success, no other pod should still be doing any work or writing any output. They should all be + in the process of exiting. + +For a Non-parallel job, you can leave both `.spec.completions` and `.spec.parallelism` unset. When both are +unset, both are defaulted to 1. + +For a Fixed Completion Count job, you should set `.spec.completions` to the number of completions needed. +You can set `.spec.parallelism`, or leave it unset and it will default to 1. + +For a Work Queue Job, you must leave `.spec.completions` unset, and set `.spec.parallelism` to +a non-negative integer. + +For more information about how to make use of the different types of job, see the [job patterns](#job-patterns) section. + + +#### Controlling Parallelism + +The requested parallelism (`.spec.parallelism`) can be set to any non-negative value. +If it is unspecified, it defaults to 1. +If it is specified as 0, then the Job is effectively paused until it is increased. + +A job can be scaled up using the `kubectl scale` command. For example, the following +command sets `.spec.parallelism` of a job called `myjob` to 10: + +```shell +$ kubectl scale --replicas=$N jobs/myjob +job "myjob" scaled +``` + +You can also use the `scale` subresource of the Job resource. + +Actual parallelism (number of pods running at any instant) may be more or less than requested +parallelism, for a variety or reasons: + +- For Fixed Completion Count jobs, the actual number of pods running in parallel will not exceed the number of + remaining completions. Higher values of `.spec.parallelism` are effectively ignored. +- For work queue jobs, no new pods are started after any pod has succeeded -- remaining pods are allowed to complete, however. +- If the controller has not had time to react. +- If the controller failed to create pods for any reason (lack of ResourceQuota, lack of permission, etc.), + then there may be fewer pods than requested. +- The controller may throttle new pod creation due to excessive previous pod failures in the same Job. +- When a pod is gracefully shutdown, it takes time to stop. + +## Handling Pod and Container Failures + +A Container in a Pod may fail for a number of reasons, such as because the process in it exited with +a non-zero exit code, or the Container was killed for exceeding a memory limit, etc. If this +happens, and the `.spec.template.spec.restartPolicy = "OnFailure"`, then the Pod stays +on the node, but the Container is re-run. Therefore, your program needs to handle the case when it is +restarted locally, or else specify `.spec.template.spec.restartPolicy = "Never"`. +See [pods-states](/docs/user-guide/pod-states) for more information on `restartPolicy`. + +An entire Pod can also fail, for a number of reasons, such as when the pod is kicked off the node +(node is upgraded, rebooted, deleted, etc.), or if a container of the Pod fails and the +`.spec.template.spec.restartPolicy = "Never"`. When a Pod fails, then the Job controller +starts a new Pod. Therefore, your program needs to handle the case when it is restarted in a new +pod. In particular, it needs to handle temporary files, locks, incomplete output and the like +caused by previous runs. + +Note that even if you specify `.spec.parallelism = 1` and `.spec.completions = 1` and +`.spec.template.spec.restartPolicy = "Never"`, the same program may +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 +designed to support closely-communicating parallel processes, as commonly found in scientific +computing. It does support parallel processing of a set of independent but related *work items*. +These might be emails to be sent, frames to be rendered, files to be transcoded, ranges of keys in a +NoSQL database to scan, and so on. + +In a complex system, there may be multiple different sets of work items. Here we are just +considering one set of work items that the user wants to manage together — a *batch job*. + +There are several different patterns for parallel computation, each with strengths and weaknesses. +The tradeoffs are: + +- One Job object for each work item, vs. a single Job object for all work items. The latter is + better for large numbers of work items. The former creates some overhead for the user and for the + system to manage large numbers of Job objects. Also, with the latter, the resource usage of the job + (number of concurrently running pods) can be easily adjusted using the `kubectl scale` command. +- Number of pods created equals number of work items, vs. each pod can process multiple work items. + The former typically requires less modification to existing code and containers. The latter + is better for large numbers of work items, for similar reasons to the previous bullet. +- Several approaches use a work queue. This requires running a queue service, + and modifications to the existing program or container to make it use the work queue. + Other approaches are easier to adapt to an existing containerised application. + + +The tradeoffs are summarized here, with columns 2 to 4 corresponding to the above tradeoffs. +The pattern names are also links to examples and more detailed description. + +| Pattern | Single Job object | Fewer pods than work items? | Use app unmodified? | Works in Kube 1.1? | +| -------------------------------------------------------------------- |:-----------------:|:---------------------------:|:-------------------:|:-------------------:| +| [Job Template Expansion](/docs/user-guide/jobs/expansions) | | | ✓ | ✓ | +| [Queue with Pod Per Work Item](/docs/user-guide/jobs/work-queue-1/) | ✓ | | sometimes | ✓ | +| [Queue with Variable Pod Count](/docs/user-guide/jobs/work-queue-2/) | ✓ | ✓ | | ✓ | +| Single Job with Static Work Assignment | ✓ | | ✓ | | + +When you specify completions with `.spec.completions`, each Pod created by the Job controller +has an identical [`spec`](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status). This means that +all pods will have the same command line and the same +image, the same volumes, and (almost) the same environment variables. These patterns +are different ways to arrange for pods to work on different things. + +This table shows the required settings for `.spec.parallelism` and `.spec.completions` for each of the patterns. +Here, `W` is the number of work items. + +| Pattern | `.spec.completions` | `.spec.parallelism` | +| -------------------------------------------------------------------- |:-------------------:|:--------------------:| +| [Job Template Expansion](/docs/user-guide/jobs/expansions/) | 1 | should be 1 | +| [Queue with Pod Per Work Item](/docs/user-guide/jobs/work-queue-1/) | W | any | +| [Queue with Variable Pod Count](/docs/user-guide/jobs/work-queue-2/) | 1 | any | +| Single Job with Static Work Assignment | W | any | + + +## Advanced Usage + +### Specifying your own pod selector + +Normally, when you create a job object, you do not specify `spec.selector`. +The system defaulting logic adds this field when the job is created. +It picks a selector value that will not overlap with any other jobs. + +However, in some cases, you might need to override this automatically set selector. +To do this, you can specify the `spec.selector` of the job. + +Be very careful when doing this. If you specify a label selector which is not +unique to the pods of that job, and which matches unrelated pods, then pods of the unrelated +job may be deleted, or this job may count other pods as completing it, or one or both +of the jobs may refuse to create pods or run to completion. If a non-unique selector is +chosen, then other controllers (e.g. ReplicationController) and their pods may behave +in unpredicatable ways too. Kubernetes will not stop you from making a mistake when +specifying `spec.selector`. + +Here is an example of a case when you might want to use this feature. + +Say job `old` is already running. You want existing pods +to keep running, but you want the rest of the pods it creates +to use a different pod template and for the job to have a new name. +You cannot update the job because these fields are not updatable. +Therefore, you delete job `old` but leave its pods +running, using `kubectl delete jobs/old-one --cascade=false`. +Before deleting it, you make a note of what selector it uses: + +``` +kind: Job +metadata: + name: old + ... +spec: + selector: + matchLabels: + job-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002 + ... +``` + +Then you create a new job with name `new` and you explicitly specify the same selector. +Since the existing pods have label `job-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`, +they are controlled by job `new` as well. + +You need to specify `manualSelector: true` in the new job since you are not using +the selector that the system normally generates for you automatically. + +``` +kind: Job +metadata: + name: new + ... +spec: + manualSelector: true + selector: + matchLabels: + job-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002 + ... +``` + +The new Job itself will have a different uid from `a8f3d00d-c6d2-11e5-9f87-42010af00002`. Setting +`manualSelector: true` tells the system to that you know what you are doing and to allow this +mismatch. + +## Alternatives + +### Bare Pods + +When the node that a pod is running on reboots or fails, the pod is terminated +and will not be restarted. However, a Job will create new pods to replace terminated ones. +For this reason, we recommend that you use a job rather than a bare pod, even if your application +requires only a single pod. + +### Replication Controller + +Jobs are complementary to [Replication Controllers](/docs/user-guide/replication-controller). +A Replication Controller manages pods which are not expected to terminate (e.g. web servers), and a Job +manages pods that are expected to terminate (e.g. batch jobs). + +As discussed in [life of a pod](/docs/user-guide/pod-states), `Job` is *only* appropriate for pods with +`RestartPolicy` equal to `OnFailure` or `Never`. (Note: If `RestartPolicy` is not set, the default +value is `Always`.) + +### Single Job starts Controller Pod + +Another pattern is for a single Job to create a pod which then creates other pods, acting as a sort +of custom controller for those pods. This allows the most flexibility, but may be somewhat +complicated to get started with and offers less integration with Kubernetes. + +One example of this pattern would be a Job which starts a Pod which runs a script that in turn +starts a Spark master controller (see [spark example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/spark/README.md)), runs a spark +driver, and then cleans up. + +An advantage of this approach is that the overall process gets the completion guarantee of a Job +object, but complete control over what pods are created and how work is assigned to them. + +## Cron Jobs + +Support for creating Jobs at specified times/dates (i.e. cron) is available in Kubernetes [1.4](https://github.com/kubernetes/kubernetes/pull/11980). More information is available in the [cron job documents](http://kubernetes.io/docs/user-guide/cron-jobs/) diff --git a/docs/concepts/overview/components.md b/docs/concepts/overview/components.md new file mode 100644 index 0000000000..280b9b1f2c --- /dev/null +++ b/docs/concepts/overview/components.md @@ -0,0 +1,136 @@ +--- +assignees: +- lavalamp +title: Kubernetes Components +--- + +This document outlines the various binary components that need to run to +deliver a functioning Kubernetes cluster. + +## Master Components + +Master components are those that provide the cluster's control plane. For +example, master components are responsible for making global decisions about the +cluster (e.g., scheduling), and detecting and responding to cluster events +(e.g., starting up a new pod when a replication controller's 'replicas' field is +unsatisfied). + +In theory, Master components can be run on any node in the cluster. However, +for simplicity, current set up scripts typically start all master components on +the same VM, and does not run user containers on this VM. See +[high-availability.md](/docs/admin/high-availability) for an example multi-master-VM setup. + +Even in the future, when Kubernetes is fully self-hosting, it will probably be +wise to only allow master components to schedule on a subset of nodes, to limit +co-running with user-run pods, reducing the possible scope of a +node-compromising security exploit. + +### kube-apiserver + +[kube-apiserver](/docs/admin/kube-apiserver) exposes the Kubernetes API; it is the front-end for the +Kubernetes control plane. It is designed to scale horizontally (i.e., one scales +it by running more of them-- [high-availability.md](/docs/admin/high-availability)). + +### etcd + +[etcd](/docs/admin/etcd) is used as Kubernetes' backing store. All cluster data is stored here. +Proper administration of a Kubernetes cluster includes a backup plan for etcd's +data. + +### kube-controller-manager + +[kube-controller-manager](/docs/admin/kube-controller-manager) is a binary that runs controllers, which are the +background threads that handle routine tasks in the cluster. Logically, each +controller is a separate process, but to reduce the number of moving pieces in +the system, they are all compiled into a single binary and run in a single +process. + +These controllers include: + +* Node Controller: Responsible for noticing & responding when nodes go down. +* Replication Controller: Responsible for maintaining the correct number of pods for every replication + controller object in the system. +* Endpoints Controller: Populates the Endpoints object (i.e., join Services & Pods). +* Service Account & Token Controllers: Create default accounts and API access tokens for new namespaces. +* ... and others. + +### kube-scheduler + +[kube-scheduler](/docs/admin/kube-scheduler) watches newly created pods that have no node assigned, and +selects a node for them to run on. + +### addons + +Addons are pods and services that implement cluster features. The pods may be managed +by Deployments, ReplicationContollers, etc. Namespaced addon objects are created in +the "kube-system" namespace. + +Addon manager takes the responsibility for creating and maintaining addon resources. +See [here](http://releases.k8s.io/HEAD/cluster/addons) for more details. + +#### DNS + +While the other addons are not strictly required, all Kubernetes +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. + +Containers started by Kubernetes automatically include this DNS server +in their DNS searches. + +#### User interface + +The kube-ui provides a read-only overview of the cluster state. Access +[the UI using kubectl proxy](/docs/user-guide/connecting-to-applications-proxy/#connecting-to-the-kube-ui-service-from-your-local-workstation) + +#### Container Resource Monitoring + +[Container Resource Monitoring](/docs/user-guide/monitoring) records generic time-series metrics +about containers in a central database, and provides a UI for browsing that data. + +#### Cluster-level Logging + +A [Cluster-level logging](/docs/user-guide/logging/overview) mechanism is responsible for +saving container logs to a central log store with search/browsing interface. + +## Node components + +Node components run on every node, maintaining running pods and providing them +the Kubernetes runtime environment. + +### kubelet + +[kubelet](/docs/admin/kubelet) is the primary node agent. It: + +* Watches for pods that have been assigned to its node (either by apiserver + or via local configuration file) and: +* Mounts the pod's required volumes +* Downloads the pod's secrets +* Runs the pod's containers via docker (or, experimentally, rkt). +* Periodically executes any requested container liveness probes. +* Reports the status of the pod back to the rest of the system, by creating a + "mirror pod" if necessary. +* Reports the status of the node back to the rest of the system. + +### kube-proxy + +[kube-proxy](/docs/admin/kube-proxy) enables the Kubernetes service abstraction by maintaining +network rules on the host and performing connection forwarding. + +### docker + +`docker` is of course used for actually running containers. + +### rkt + +`rkt` is supported experimentally as an alternative to docker. + +### supervisord + +`supervisord` is a lightweight process babysitting system for keeping kubelet and docker +running. + +### fluentd + +`fluentd` is a daemon which helps provide [cluster-level logging](#cluster-level-logging). diff --git a/docs/concepts/overview/kubernetes-api.md b/docs/concepts/overview/kubernetes-api.md new file mode 100644 index 0000000000..e3cd940ed0 --- /dev/null +++ b/docs/concepts/overview/kubernetes-api.md @@ -0,0 +1,109 @@ +--- +assignees: +- bgrant0607 +- erictune +- lavalamp +title: The Kubernetes API +--- + +Primary system and API concepts are documented in the [User guide](/docs/user-guide/). + +Overall API conventions are described in the [API conventions doc](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md). + +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) command-line tool can be used to create, update, delete, and get API objects. + +Kubernetes also stores its serialized state (currently in [etcd](https://coreos.com/docs/distributed-configuration/getting-started-with-etcd/)) in terms of the API resources. + +Kubernetes itself is decomposed into multiple components, which interact through its API. + +## API changes + +In our experience, any system that is successful needs to grow and change as new use cases emerge or existing ones change. Therefore, we expect the Kubernetes API to continuously change and grow. However, we intend to not break compatibility with existing clients, for an extended period of time. In general, new API resources and new resource fields can be expected to be added frequently. Elimination of resources or fields will require following a deprecation process. The precise deprecation policy for eliminating features is TBD, but once we reach our 1.0 milestone, there will be a specific policy. + +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). + +## OpenAPI and Swagger definitions + +Complete API details are documented using [Swagger v1.2](http://swagger.io/) and [OpenAPI](https://www.openapis.org/). The Kubernetes apiserver (aka "master") exposes an API that can be used to retrieve the Swagger v1.2 Kubernetes API spec located at `/swaggerapi`. You can also enable a UI to browse the API documentation at `/swagger-ui` by passing the `--enable-swagger-ui=true` flag to apiserver. + +We also host a version of the [latest v1.2 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. + +Starting with kubernetes 1.4, OpenAPI spec is also available at `/swagger.json`. While we are transitioning from Swagger v1.2 to OpenAPI (aka Swagger v2.0), some of the tools such as kubectl and swagger-ui are still using v1.2 spec. OpenAPI spec is in Beta as of Kubernetes 1.5. + +Kubernetes implements an alternative Protobuf based serialization format for the API that is primarily intended for intra-cluster communication, documented in the [design proposal](https://github.com/kubernetes/kubernetes/blob/{{ page.githubbranch }}/docs/proposals/protobuf.md) and the IDL files for each schema are located in the Go packages that define the API objects. + +## API versioning + +To make it easier to eliminate fields or restructure resource representations, Kubernetes supports +multiple API versions, each at a different API path, such as `/api/v1` or +`/apis/extensions/v1beta1`. + +We chose to version at the API level rather than at the resource or field level to ensure that the API presents a clear, consistent view of system resources and behavior, and to enable controlling access to end-of-lifed and/or experimental APIs. The JSON and Protobuf serialization schemas follow the same guidelines for schema changes - all descriptions below cover both formats. + +Note that API versioning and Software versioning are only indirectly related. The [API and release +versioning proposal](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/versioning.md) describes the relationship between API versioning and +software versioning. + + +Different API versions imply different levels of stability and support. The criteria for each level are described +in more detail in the [API Changes documentation](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api_changes.md#alpha-beta-and-stable-versions). They are summarized here: + +- Alpha level: + - The version names contain `alpha` (e.g. `v1alpha1`). + - May be buggy. Enabling the feature may expose bugs. Disabled by default. + - Support for feature may be dropped at any time without notice. + - The API may change in incompatible ways in a later software release without notice. + - Recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support. +- Beta level: + - The version names contain `beta` (e.g. `v2beta3`). + - Code is well tested. Enabling the feature is considered safe. Enabled by default. + - Support for the overall feature will not be dropped, though details may change. + - The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, + we will provide instructions for migrating to the next version. This may require deleting, editing, and re-creating + API objects. The editing process may require some thought. This may require downtime for applications that rely on the feature. + - Recommended for only non-business-critical uses because of potential for incompatible changes in subsequent releases. If you have + multiple clusters which can be upgraded independently, you may be able to relax this restriction. + - **Please do try our beta features and give feedback on them! Once they exit beta, it may not be practical for us to make more changes.** +- Stable level: + - The version name is `vX` where `X` is an integer. + - Stable versions of features will appear in released software for many subsequent versions. + +## API groups + +To make it easier to extend the Kubernetes API, we implemented [*API groups*](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-group.md). +The API group is specified in a REST path and in the `apiVersion` field of a serialized object. + +Currently there are several API groups in use: + +1. the "core" (oftentimes called "legacy", due to not having explicit group name) group, which is at + REST path `/api/v1` and is not specified as part of the `apiVersion` field, e.g. `apiVersion: v1`. +1. the named groups are at REST path `/apis/$GROUP_NAME/$VERSION`, and use `apiVersion: $GROUP_NAME/$VERSION` + (e.g. `apiVersion: batch/v1`). Full list of supported API groups can be seen in [Kubernetes API reference](/docs/reference/). + + +There are two supported paths to extending the API. +1. [Third Party Resources](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/extending-api.md) + are for users with very basic CRUD needs. +1. Coming soon: users needing the full set of Kubernetes API semantics can implement their own apiserver + and use the [aggregator](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/aggregated-api-servers.md) + to make it seamless for clients. + + +## Enabling API groups + +Certain resources and API groups are enabled by default. They can be enabled or disabled by setting `--runtime-config` +on apiserver. `--runtime-config` accepts comma separated values. For ex: to disable batch/v1, set +`--runtime-config=batch/v1=false`, to enable batch/v2alpha1, set `--runtime-config=batch/v2alpha1`. +The flag accepts comma separated set of key=value pairs describing runtime configuration of the apiserver. + +IMPORTANT: Enabling or disabling groups or resources requires restarting apiserver and controller-manager +to pick up the `--runtime-config` changes. + +## Enabling resources in the groups + +DaemonSets, Deployments, HorizontalPodAutoscalers, Ingress, Jobs and ReplicaSets are enabled by default. +Other extensions resources can be enabled by setting `--runtime-config` on +apiserver. `--runtime-config` accepts comma separated values. For ex: to disable deployments and jobs, set +`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/jobs=false` diff --git a/docs/concepts/overview/what-is-kubernetes.md b/docs/concepts/overview/what-is-kubernetes.md new file mode 100644 index 0000000000..378a1f2c47 --- /dev/null +++ b/docs/concepts/overview/what-is-kubernetes.md @@ -0,0 +1,117 @@ +--- +assignees: +- bgrant0607 +- mikedanese +title: What is Kubernetes? +--- + +Kubernetes is an [open-source platform for automating deployment, scaling, and operations of application containers](http://www.slideshare.net/BrianGrant11/wso2con-us-2015-kubernetes-a-platform-for-automating-deployment-scaling-and-operations) across clusters of hosts, providing container-centric infrastructure. + +With Kubernetes, you are able to quickly and efficiently respond to customer demand: + + - Deploy your applications quickly and predictably. + - Scale your applications on the fly. + - Seamlessly roll out new features. + - Optimize use of your hardware by using only the resources you need. + +Our goal is to foster an ecosystem of components and tools that relieve the burden of running applications in public and private clouds. + +#### Kubernetes is: + +* **portable**: public, private, hybrid, multi-cloud +* **extensible**: modular, pluggable, hookable, composable +* **self-healing**: auto-placement, auto-restart, auto-replication, auto-scaling + +The Kubernetes project was started by Google in 2014. Kubernetes builds upon a [decade and a half of experience that Google has with running production workloads at scale](https://research.google.com/pubs/pub43438.html), combined with best-of-breed ideas and practices from the community. + +##### Ready to [Get Started](/docs/getting-started-guides/)? + +## Why containers? + +Looking for reasons why you should be using [containers](http://aucouranton.com/2014/06/13/linux-containers-parallels-lxc-openvz-docker-and-more/)? + +![Why Containers?](/images/docs/why_containers.svg) + +The *Old Way* to deploy applications was to install the applications on a host using the operating system package manager. This had the disadvantage of entangling the applications' executables, configuration, libraries, and lifecycles with each other and with the host OS. One could build immutable virtual-machine images in order to achieve predictable rollouts and rollbacks, but VMs are heavyweight and non-portable. + +The *New Way* is to deploy containers based on operating-system-level virtualization rather than hardware virtualization. These containers are isolated from each other and from the host: they have their own filesystems, they can't see each others' processes, and their computational resource usage can be bounded. They are easier to build than VMs, and because they are decoupled from the underlying infrastructure and from the host filesystem, they are portable across clouds and OS distributions. + +Because containers are small and fast, one application can be packed in each container image. This one-to-one application-to-image relationship unlocks the full benefits of containers. With containers, immutable container images can be created at build/release time rather than deployment time, since each application doesn't need to be composed with the rest of the application stack, nor married to the production infrastructure environment. Generating container images at build/release time enables a consistent environment to be carried from development into production. +Similarly, containers are vastly more transparent than VMs, which facilitates monitoring and management. This is especially true when the containers' process lifecycles are managed by the infrastructure rather than hidden by a process supervisor inside the container. Finally, with a single application per container, managing the containers becomes tantamount to managing deployment of the application. + +Summary of container benefits: + +* **Agile application creation and deployment**: + Increased ease and efficiency of container image creation compared to VM image use. +* **Continuous development, integration, and deployment**: + Provides for reliable and frequent container image build and deployment with quick and easy rollbacks (due to image immutability). +* **Dev and Ops separation of concerns**: + Create application container images at build/release time rather than deployment time, thereby decoupling applications from infrastructure. +* **Environmental consistency across development, testing, and production**: + Runs the same on a laptop as it does in the cloud. +* **Cloud and OS distribution portability**: + Runs on Ubuntu, RHEL, CoreOS, on-prem, Google Container Engine, and anywhere else. +* **Application-centric management**: + Raises the level of abstraction from running an OS on virtual hardware to run an application on an OS using logical resources. +* **Loosely coupled, distributed, elastic, liberated [micro-services](http://martinfowler.com/articles/microservices.html)**: + Applications are broken into smaller, independent pieces and can be deployed and managed dynamically -- not a fat monolithic stack running on one big single-purpose machine. +* **Resource isolation**: + Predictable application performance. +* **Resource utilization**: + High efficiency and density. + +#### Why do I need Kubernetes and what can it do? + +At a minimum, Kubernetes can schedule and run application containers on clusters of physical or virtual machines. However, Kubernetes also allows developers to 'cut the cord' to physical and virtual machines, moving from a **host-centric** infrastructure to a **container-centric** infrastructure, which provides the full advantages and benefits inherent to containers. Kubernetes provides the infrastructure to build a truly **container-centric** development environment. + +Kubernetes satisfies a number of common needs of applications running in production, such as: + +* [co-locating helper processes](/docs/user-guide/pods/), facilitating composite applications and preserving the one-application-per-container model, +* [mounting storage systems](/docs/user-guide/volumes/), +* [distributing secrets](/docs/user-guide/secrets/), +* [application health checking](/docs/user-guide/production-pods/#liveness-and-readiness-probes-aka-health-checks), +* [replicating application instances](/docs/user-guide/replication-controller/), +* [horizontal auto-scaling](/docs/user-guide/horizontal-pod-autoscaling/), +* [naming and discovery](/docs/user-guide/connecting-applications/), +* [load balancing](/docs/user-guide/services/), +* [rolling updates](/docs/tasks/run-application/rolling-update-replication-controller/), +* [resource monitoring](/docs/user-guide/monitoring/), +* [log access and ingestion](/docs/user-guide/logging/overview/), +* [support for introspection and debugging](/docs/user-guide/introspection-and-debugging/), and +* [identity and authorization](/docs/admin/authorization/). + +This provides the simplicity of Platform as a Service (PaaS) with the flexibility of Infrastructure as a Service (IaaS), and facilitates portability across infrastructure providers. + +For more details, see the [user guide](/docs/user-guide/). + +#### Why and how is Kubernetes a platform? + +Even though Kubernetes provides a lot of functionality, there are always new scenarios that would benefit from new features. Application-specific workflows can be streamlined to accelerate developer velocity. Ad hoc orchestration that is acceptable initially often requires robust automation at scale. This is why Kubernetes was also designed to serve as a platform for building an ecosystem of components and tools to make it easier to deploy, scale, and manage applications. + +[Labels](/docs/user-guide/labels/) empower users to organize their resources however they please. [Annotations](/docs/user-guide/annotations/) enable users to decorate resources with custom information to facilitate their workflows and provide an easy way for management tools to checkpoint state. + +Additionally, the [Kubernetes control plane](/docs/admin/cluster-components) is built upon the same [APIs](/docs/api/) that are available to developers and users. Users can write their own controllers, [schedulers](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/scheduler.md), etc., if they choose, with [their own APIs](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/extending-api.md) that can be targeted by a general-purpose [command-line tool](/docs/user-guide/kubectl-overview/). + +This [design](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/principles.md) has enabled a number of other systems to build atop Kubernetes. + +#### Kubernetes is not: + +Kubernetes is not a traditional, all-inclusive PaaS (Platform as a Service) system. We preserve user choice where it is important. + +* Kubernetes does not limit the types of applications supported. It does not dictate application frameworks (e.g., [Wildfly](http://wildfly.org/)), restrict the set of supported language runtimes (e.g., Java, Python, Ruby), cater to only [12-factor applications](http://12factor.net/), nor distinguish "apps" from "services". Kubernetes aims to support an extremely diverse variety of workloads, including stateless, stateful, and data-processing workloads. If an application can run in a container, it should run great on Kubernetes. +* Kubernetes does not provide middleware (e.g., message buses), data-processing frameworks (e.g., Spark), databases (e.g., mysql), nor cluster storage systems (e.g., Ceph) as built-in services. Such applications run on Kubernetes. +* Kubernetes does not have a click-to-deploy service marketplace. +* Kubernetes is unopinionated in the source-to-image space. It does not deploy source code and does not build your application. Continuous Integration (CI) workflow is an area where different users and projects have their own requirements and preferences, so we support layering CI workflows on Kubernetes but don't dictate how it should work. +* Kubernetes allows users to choose the logging, monitoring, and alerting systems of their choice. (Though we do provide some integrations as proof of concept.) +* Kubernetes does not provide nor mandate a comprehensive application configuration language/system (e.g., [jsonnet](https://github.com/google/jsonnet)). +* Kubernetes does not provide nor adopt any comprehensive machine configuration, maintenance, management, or self-healing systems. + +On the other hand, a number of PaaS systems run *on* Kubernetes, such as [Openshift](https://github.com/openshift/origin), [Deis](http://deis.io/), and [Eldarion](http://eldarion.cloud/). You could also roll your own custom PaaS, integrate with a CI system of your choice, or get along just fine with just Kubernetes: bring your container images and deploy them on Kubernetes. + +Since Kubernetes operates at the application level rather than at just the hardware level, it provides some generally applicable features common to PaaS offerings, such as deployment, scaling, load balancing, logging, monitoring, etc. However, Kubernetes is not monolithic, and these default solutions are optional and pluggable. + +Additionally, Kubernetes is not a mere "orchestration system"; it eliminates the need for orchestration. The technical definition of "orchestration" is execution of a defined workflow: do A, then B, then C. In contrast, Kubernetes is comprised of a set of independent, composable control processes that continuously drive current state towards the provided desired state. It shouldn't matter how you get from A to C: make it so. Centralized control is also not required; the approach is more akin to "choreography". This results in a system that is easier to use and more powerful, robust, resilient, and extensible. + +#### What does *Kubernetes* mean? K8s? + +The name **Kubernetes** originates from Greek, meaning "helmsman" or "pilot", and is the root of "governor" and ["cybernetic"](http://www.etymonline.com/index.php?term=cybernetics). **K8s** is an abbreviation derived by replacing the 8 letters "ubernete" with 8. diff --git a/docs/concepts/object-metadata/annotations.md b/docs/concepts/overview/working-with-objects/annotations.md similarity index 100% rename from docs/concepts/object-metadata/annotations.md rename to docs/concepts/overview/working-with-objects/annotations.md diff --git a/docs/concepts/abstractions/overview.md b/docs/concepts/overview/working-with-objects/kubernetes-objects.md similarity index 90% rename from docs/concepts/abstractions/overview.md rename to docs/concepts/overview/working-with-objects/kubernetes-objects.md index dc2e8cf7ab..3e24b810f4 100644 --- a/docs/concepts/abstractions/overview.md +++ b/docs/concepts/overview/working-with-objects/kubernetes-objects.md @@ -1,5 +1,9 @@ --- -title: Kubernetes Objects +title: Understanding Kubernetes Objects + +redirect_from: +- "/docs/concepts/abstractions/overview/" +- "/docs/concepts/abstractions/overview.html" --- {% capture overview %} @@ -9,7 +13,7 @@ This page explains how Kubernetes objects are represented in the Kubernetes API, {% capture body %} ## Understanding Kubernetes Objects -*Kubernetes Objects* are persistent entities in the Kubernetes system. Kubenetes uses these entities to represent the state of your cluster. Specifically, they can describe: +*Kubernetes Objects* are persistent entities in the Kubernetes system. Kubernetes uses these entities to represent the state of your cluster. Specifically, they can describe: * What containerized applications are running (and on which nodes) * The resources available to those applications @@ -17,15 +21,16 @@ This page explains how Kubernetes objects are represented in the Kubernetes API, A Kubernetes object is a "record of intent"--once you create the object, the Kubernetes system will constantly work to ensure that that object exists. By creating an object, you're effectively telling the Kubernetes system what you want your cluster's workload to look like; this is your cluster's **desired state**. -To work with Kubernetes objects--whether to create, modify, or delete them--you'll need to use the [Kubernetes API](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/api-conventions.md). When you use the `kubectl` comamnd-line interface, for example, the CLI makes the necessary Kubernetes API calls for you; you can also use the Kubernetes API directly in your own programs. Kubernetes currently provides a `golang` [client library](https://github.com/kubernetes/client-go) for this purpose, and other language libraries (such as [Python](https://github.com/kubernetes-incubator/client-python)) are being developed. +To work with Kubernetes objects--whether to create, modify, or delete them--you'll need to use the [Kubernetes API](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/api-conventions.md). When you use the `kubectl` command-line interface, for example, the CLI makes the necessary Kubernetes API calls for you; you can also use the Kubernetes API directly in your own programs. Kubernetes currently provides a `golang` [client library](https://github.com/kubernetes/client-go) for this purpose, and other language libraries (such as [Python](https://github.com/kubernetes-incubator/client-python)) are being developed. ### Object Spec and Status Every Kubernetes object includes two nested object fields that govern the object's configuration: the object *spec* and the object *status*. The *spec*, which you must provide, describes your *desired state* for the object--the characteristics that you want the object to have. The *status* describes the *actual state* for the object, and is supplied and updated by the Kubernetes system. At any given time, the Kubernetes Control Plane actively manages an object's actual state to match the desired state you supplied. + For example, a Kubernetes Deployment is an object that can represent an application running on your cluster. When you create the Deployment, you might set the Deployment spec to specify that you want three replicas of the application to be running. The Kubernetes system reads the Deployment spec and starts three instances of your desired application--updating the status to match your spec. If any of those instances should fail (a status change), the Kubernetes system responds to the difference between spec and status by making a correction--in this case, starting a replacement instance. -For more information on the object spec, status, and metadata, see the [Kubernetes API Conventions](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/api-conventions.md#spec-and-status). +For more information on the object spec, status, and metadata, see the [Kubernetes API Conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md). ### Describing a Kubernetes Object @@ -33,7 +38,7 @@ When you create an object in Kubernetes, you must provide the object spec that d Here's an example `.yaml` file that shows the required fields and object spec for a Kubernetes Deployment: -{% include code.html language="yaml" file="nginx-deployment.yaml" ghlink="/docs/concepts/abstractions/nginx-deployment.yaml" %} +{% include code.html language="yaml" file="nginx-deployment.yaml" ghlink="/docs/concepts/overview/working-with-objects/nginx-deployment.yaml" %} One way to create a Deployment using a `.yaml` file like the one above is to use the []`kubectl create`]() command in the `kubectl` command-line interface, passing the `.yaml` file as an argument. Here's an example: diff --git a/docs/user-guide/labels.md b/docs/concepts/overview/working-with-objects/labels.md similarity index 99% rename from docs/user-guide/labels.md rename to docs/concepts/overview/working-with-objects/labels.md index a13e160089..af99f0c364 100644 --- a/docs/user-guide/labels.md +++ b/docs/concepts/overview/working-with-objects/labels.md @@ -2,6 +2,9 @@ assignees: - mikedanese title: Labels and Selectors +redirect_from: +- "/docs/user-guide/labels/" +- "/docs/user-guide/labels.html" --- _Labels_ are key/value pairs that are attached to objects, such as pods. diff --git a/docs/concepts/overview/working-with-objects/nginx-deployment.yaml b/docs/concepts/overview/working-with-objects/nginx-deployment.yaml new file mode 100644 index 0000000000..7a0dd431ef --- /dev/null +++ b/docs/concepts/overview/working-with-objects/nginx-deployment.yaml @@ -0,0 +1,16 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: nginx-deployment +spec: + replicas: 3 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 diff --git a/docs/concepts/policy/resource-quotas.md b/docs/concepts/policy/resource-quotas.md new file mode 100644 index 0000000000..24d7a09246 --- /dev/null +++ b/docs/concepts/policy/resource-quotas.md @@ -0,0 +1,240 @@ +--- +assignees: +- derekwaynecarr +title: Resource Quotas +--- + +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. + +A resource quota, defined by a `ResourceQuota` object, provides constraints that limit +aggregate resource consumption per namespace. It can limit the quantity of objects that can +be created in a namespace by type, as well as the total amount of compute resources that may +be consumed by resources in that project. + +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 one or more Resource Quota objects for each namespace. +- Users create resources (pods, services, etc.) in the namespace, and the quota system + tracks usage to ensure it does not exceed hard resource limits defined in a Resource Quota. +- If creating or updating a resource violates a quota constraint, the request will fail with HTTP + status code `403 FORBIDDEN` with a message explaining the constraint that would have been violated. +- If quota is enabled in a namespace for compute resources like `cpu` and `memory`, users must specify + requests or limits for those values; otherwise, the quota system may reject pod creation. Hint: Use + the LimitRange admission controller to force defaults for pods that make no compute resource requirements. + See the [walkthrough](/docs/admin/resourcequota/walkthrough/) for an example 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 created resources. + +## 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 + +You can limit the total sum of [compute resources](/docs/user-guide/compute-resources) that can be requested in a given namespace. + +The following resource types are supported: + +| Resource Name | Description | +| --------------------- | ----------------------------------------------------------- | +| `cpu` | Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. | +| `limits.cpu` | Across all pods in a non-terminal state, the sum of CPU limits cannot exceed this value. | +| `limits.memory` | Across all pods in a non-terminal state, the sum of memory limits cannot exceed this value. | +| `memory` | Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. | +| `requests.cpu` | Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. | +| `requests.memory` | Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. | + +## Storage Resource Quota + +You can limit the total sum of [storage resources](/docs/user-guide/persistent-volumes) that can be requested in a given namespace. + +In addition, you can limit consumption of storage resources based on associated storage-class. + +| Resource Name | Description | +| --------------------- | ----------------------------------------------------------- | +| `requests.storage` | Across all persistent volume claims, the sum of storage requests cannot exceed this value. | +| `persistentvolumeclaims` | The total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. | +| `.storageclass.storage.k8s.io/requests.storage` | Across all persistent volume claims associated with the storage-class-name, the sum of storage requests cannot exceed this value. | +| `.storageclass.storage.k8s.io/persistentvolumeclaims` | Across all persistent volume claims associated with the storage-class-name, the total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. | + +For example, if an operator wants to quota storage with `gold` storage class separate from `bronze` storage class, the operator can +define a quota as follows: + +* `gold.storageclass.storage.k8s.io/requests.storage: 500Gi` +* `bronze.storageclass.storage.k8s.io/requests.storage: 100Gi` + +## Object Count Quota + +The number of objects of a given type can be restricted. The following types +are supported: + +| Resource Name | Description | +| ------------------------------- | ------------------------------------------------- | +| `configmaps` | The total number of config maps that can exist in the namespace. | +| `persistentvolumeclaims` | The total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. | +| `pods` | The total number of pods in a non-terminal state that can exist in the namespace. A pod is in a terminal state if `status.phase in (Failed, Succeeded)` is true. | +| `replicationcontrollers` | The total number of replication controllers that can exist in the namespace. | +| `resourcequotas` | The total number of [resource quotas](/docs/admin/admission-controllers/#resourcequota) that can exist in the namespace. | +| `services` | The total number of services that can exist in the namespace. | +| `services.loadbalancers` | The total number of services of type load balancer that can exist in the namespace. | +| `services.nodeports` | The total number of services of type node port that can exist in the namespace. | +| `secrets` | The total number of secrets that can exist in the namespace. | + +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. + +## Quota Scopes + +Each quota can have an associated set of scopes. A quota will only measure usage for a resource if it matches +the intersection of enumerated scopes. + +When a scope is added to the quota, it limits the number of resources it supports to those that pertain to the scope. +Resources specified on the quota outside of the allowed set results in a validation error. + +| Scope | Description | +| ----- | ----------- | +| `Terminating` | Match pods where `spec.activeDeadlineSeconds >= 0` | +| `NotTerminating` | Match pods where `spec.activeDeadlineSeconds is nil` | +| `BestEffort` | Match pods that have best effort quality of service. | +| `NotBestEffort` | Match pods that do not have best effort quality of service. | + +The `BestEffort` scope restricts a quota to tracking the following resource: `pods` + +The `Terminating`, `NotTerminating`, and `NotBestEffort` scopes restrict a quota to tracking the following resources: + +* `cpu` +* `limits.cpu` +* `limits.memory` +* `memory` +* `pods` +* `requests.cpu` +* `requests.memory` + +## Requests vs Limits + +When allocating compute resources, each container may specify a request and a limit value for either CPU or memory. +The quota can be configured to quota either value. + +If the quota has a value specified for `requests.cpu` or `requests.memory`, then it requires that every incoming +container makes an explicit request for those resources. If the quota has a value specified for `limits.cpu` or `limits.memory`, +then it requires that every incoming container specifies an explicit limit for those resources. + +## Viewing and Setting Quotas + +Kubectl supports creating, updating, and viewing quotas: + +```shell +$ kubectl create namespace myspace + +$ cat < compute-resources.yaml +apiVersion: v1 +kind: ResourceQuota +metadata: + name: compute-resources +spec: + hard: + pods: "4" + requests.cpu: "1" + requests.memory: 1Gi + limits.cpu: "2" + limits.memory: 2Gi +EOF +$ kubectl create -f ./compute-resources.yaml --namespace=myspace + +$ cat < object-counts.yaml +apiVersion: v1 +kind: ResourceQuota +metadata: + name: object-counts +spec: + hard: + configmaps: "10" + persistentvolumeclaims: "4" + replicationcontrollers: "20" + secrets: "10" + services: "10" + services.loadbalancers: "2" +EOF +$ kubectl create -f ./object-counts.yaml --namespace=myspace + +$ kubectl get quota --namespace=myspace +NAME AGE +compute-resources 30s +object-counts 32s + +$ kubectl describe quota compute-resources --namespace=myspace +Name: compute-resources +Namespace: myspace +Resource Used Hard +-------- ---- ---- +limits.cpu 0 2 +limits.memory 0 2Gi +pods 0 4 +requests.cpu 0 1 +requests.memory 0 1Gi + +$ kubectl describe quota object-counts --namespace=myspace +Name: object-counts +Namespace: myspace +Resource Used Hard +-------- ---- ---- +configmaps 0 10 +persistentvolumeclaims 0 4 +replicationcontrollers 0 20 +secrets 1 10 +services 0 10 +services.loadbalancers 0 2 +``` + +## 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. diff --git a/docs/concepts/services-networking/dns-pod-service.md b/docs/concepts/services-networking/dns-pod-service.md new file mode 100644 index 0000000000..ada734830d --- /dev/null +++ b/docs/concepts/services-networking/dns-pod-service.md @@ -0,0 +1,389 @@ +--- +assignees: +- davidopp +- thockin +title: DNS Pods and Services +--- + +## Introduction + +As of Kubernetes 1.3, DNS is a built-in service launched automatically using the addon manager [cluster add-on](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/README.md). + +Kubernetes DNS schedules a DNS Pod and Service on the cluster, and configures +the kubelets to tell individual containers to use the DNS Service's IP to +resolve DNS names. + +## What things get DNS names? + +Every Service defined in the cluster (including the DNS server itself) is +assigned a DNS name. By default, a client Pod's DNS search list will +include the Pod's own namespace and the cluster's default domain. This is best +illustrated by example: + +Assume a Service named `foo` in the Kubernetes namespace `bar`. A Pod running +in namespace `bar` can look up this service by simply doing a DNS query for +`foo`. A Pod running in namespace `quux` can look up this service by doing a +DNS query for `foo.bar`. + +## Supported DNS schema + +The following sections detail the supported record types and layout that is +supported. Any other layout or names or queries that happen to work are +considered implementation details and are subject to change without warning. + +### Services + +#### A records + +"Normal" (not headless) Services are assigned a DNS A record for a name of the +form `my-svc.my-namespace.svc.cluster.local`. This resolves to the cluster IP +of the Service. + +"Headless" (without a cluster IP) Services are also assigned a DNS A record for +a name of the form `my-svc.my-namespace.svc.cluster.local`. Unlike normal +Services, this resolves to the set of IPs of the pods selected by the Service. +Clients are expected to consume the set or else use standard round-robin +selection from the set. + +### SRV records + +SRV Records are created for named ports that are part of normal or [Headless +Services](http://releases.k8s.io/docs/user-guide/services/#headless-services). +For each named port, the SRV record would have the form +`_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local`. +For a regular service, this resolves to the port number and the CNAME: +`my-svc.my-namespace.svc.cluster.local`. +For a headless service, this resolves to multiple answers, one for each pod +that is backing the service, and contains the port number and a CNAME of the pod +of the form `auto-generated-name.my-svc.my-namespace.svc.cluster.local`. + +### Backwards compatibility + +Previous versions of kube-dns made names of the form +`my-svc.my-namespace.cluster.local` (the 'svc' level was added later). This +is no longer supported. + +### Pods + +#### A Records + +When enabled, pods are assigned a DNS A record in the form of `pod-ip-address.my-namespace.pod.cluster.local`. + +For example, a pod with IP `1.2.3.4` in the namespace `default` with a DNS name of `cluster.local` would have an entry: `1-2-3-4.default.pod.cluster.local`. + +#### A Records and hostname based on Pod's hostname and subdomain fields + +Currently when a pod is created, its hostname is the Pod's `metadata.name` value. + +With v1.2, users can specify a Pod annotation, `pod.beta.kubernetes.io/hostname`, to specify what the Pod's hostname should be. +The Pod annotation, if specified, takes precedence over the Pod's name, to be the hostname of the pod. +For example, given a Pod with annotation `pod.beta.kubernetes.io/hostname: my-pod-name`, the Pod will have its hostname set to "my-pod-name". + +With v1.3, the PodSpec has a `hostname` field, which can be used to specify the Pod's hostname. This field value takes precedence over the +`pod.beta.kubernetes.io/hostname` annotation value. + +v1.2 introduces a beta feature where the user can specify a Pod annotation, `pod.beta.kubernetes.io/subdomain`, to specify the Pod's subdomain. +The final domain will be "...svc.". +For example, a Pod with the hostname annotation set to "foo", and the subdomain annotation set to "bar", in namespace "my-namespace", will have the FQDN "foo.bar.my-namespace.svc.cluster.local" + +With v1.3, the PodSpec has a `subdomain` field, which can be used to specify the Pod's subdomain. This field value takes precedence over the +`pod.beta.kubernetes.io/subdomain` annotation value. + +Example: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: default-subdomain +spec: + selector: + name: busybox + clusterIP: None + ports: + - name: foo # Actually, no port is needed. + port: 1234 + targetPort: 1234 +--- +apiVersion: v1 +kind: Pod +metadata: + name: busybox1 + labels: + name: busybox +spec: + hostname: busybox-1 + subdomain: default-subdomain + containers: + - image: busybox + command: + - sleep + - "3600" + name: busybox +--- +apiVersion: v1 +kind: Pod +metadata: + name: busybox2 + labels: + name: busybox +spec: + hostname: busybox-2 + subdomain: default-subdomain + containers: + - image: busybox + command: + - sleep + - "3600" + name: busybox +``` + +If there exists a headless service in the same namespace as the pod and with the same name as the subdomain, the cluster's KubeDNS Server also returns an A record for the Pod's fully qualified hostname. +Given a Pod with the hostname set to "busybox-1" and the subdomain set to "default-subdomain", and a headless Service named "default-subdomain" in the same namespace, the pod will see it's own FQDN as "busybox-1.default-subdomain.my-namespace.svc.cluster.local". DNS serves an A record at that name, pointing to the Pod's IP. Both pods "busybox1" and "busybox2" can have their distinct A records. + +As of Kubernetes v1.2, the Endpoints object also has the annotation `endpoints.beta.kubernetes.io/hostnames-map`. Its value is the json representation of map[string(IP)][endpoints.HostRecord], for example: '{"10.245.1.6":{HostName: "my-webserver"}}'. +If the Endpoints are for a headless service, an A record is created with the format ...svc. +For the example json, if endpoints are for a headless service named "bar", and one of the endpoints has IP "10.245.1.6", an A record is created with the name "my-webserver.bar.my-namespace.svc.cluster.local" and the A record lookup would return "10.245.1.6". +This endpoints annotation generally does not need to be specified by end-users, but can used by the internal service controller to deliver the aforementioned feature. + +With v1.3, The Endpoints object can specify the `hostname` for any endpoint, along with its IP. The hostname field takes precedence over the hostname value +that might have been specified via the `endpoints.beta.kubernetes.io/hostnames-map` annotation. + +With v1.3, the following annotations are deprecated: `pod.beta.kubernetes.io/hostname`, `pod.beta.kubernetes.io/subdomain`, `endpoints.beta.kubernetes.io/hostnames-map` + +## How do I test if it is working? + +### Create a simple Pod to use as a test environment + +Create a file named busybox.yaml with the +following contents: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: busybox + namespace: default +spec: + containers: + - image: busybox + command: + - sleep + - "3600" + imagePullPolicy: IfNotPresent + name: busybox + restartPolicy: Always +``` + +Then create a pod using this file: + +``` +kubectl create -f busybox.yaml +``` + +### Wait for this pod to go into the running state + +You can get its status with: +``` +kubectl get pods busybox +``` + +You should see: + +``` +NAME READY STATUS RESTARTS AGE +busybox 1/1 Running 0 +``` + +### Validate that DNS is working + +Once that pod is running, you can exec nslookup in that environment: + +``` +kubectl exec -ti busybox -- nslookup kubernetes.default +``` + +You should see something like: + +``` +Server: 10.0.0.10 +Address 1: 10.0.0.10 + +Name: kubernetes.default +Address 1: 10.0.0.1 +``` + +If you see that, DNS is working correctly. + +### Troubleshooting Tips + +If the nslookup command fails, check the following: + +#### Check the local DNS configuration first +Take a look inside the resolv.conf file. (See "Inheriting DNS from the node" and "Known issues" below for more information) + +``` +kubectl exec busybox cat /etc/resolv.conf +``` + +Verify that the search path and name server are set up like the following (note that search path may vary for different cloud providers): + +``` +search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal +nameserver 10.0.0.10 +options ndots:5 +``` + +#### Quick diagnosis + +Errors such as the following indicate a problem with the kube-dns add-on or associated Services: + +``` +$ kubectl exec -ti busybox -- nslookup kubernetes.default +Server: 10.0.0.10 +Address 1: 10.0.0.10 + +nslookup: can't resolve 'kubernetes.default' +``` + +or + +``` +$ kubectl exec -ti busybox -- nslookup kubernetes.default +Server: 10.0.0.10 +Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local + +nslookup: can't resolve 'kubernetes.default' +``` + +#### Check if the DNS pod is running + +Use the kubectl get pods command to verify that the DNS pod is running. + +``` +kubectl get pods --namespace=kube-system -l k8s-app=kube-dns +``` + +You should see something like: + +``` +NAME READY STATUS RESTARTS AGE +... +kube-dns-v19-ezo1y 3/3 Running 0 1h +... +``` + +If you see that no pod is running or that the pod has failed/completed, the DNS add-on may not be deployed by default in your current environment and you will have to deploy it manually. + +#### Check for Errors in the DNS pod + +Use `kubectl logs` command to see logs for the DNS daemons. + +``` +kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns +kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq +kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c healthz +``` + +See if there is any suspicious log. W, E, F letter at the beginning represent Warning, Error and Failure. Please search for entries that have these as the logging level and use [kubernetes issues](https://github.com/kubernetes/kubernetes/issues) to report unexpected errors. + +#### Is DNS service up? + +Verify that the DNS service is up by using the `kubectl get service` command. + +``` +kubectl get svc --namespace=kube-system +``` + +You should see: + +``` +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +... +kube-dns 10.0.0.10 53/UDP,53/TCP 1h +... +``` + +If you have created the service or in the case it should be created by default but it does not appear, see this [debugging services page](http://kubernetes.io/docs/user-guide/debugging-services/) for more information. + +#### Are DNS endpoints exposed? + +You can verify that DNS endpoints are exposed by using the `kubectl get endpoints` command. + +``` +kubectl get ep kube-dns --namespace=kube-system +``` + +You should see something like: +``` +NAME ENDPOINTS AGE +kube-dns 10.180.3.17:53,10.180.3.17:53 1h +``` + +If you do not see the endpoints, see endpoints section in the [debugging services documentation](http://kubernetes.io/docs/user-guide/debugging-services/). + +For additional Kubernetes DNS examples, see the [cluster-dns examples](https://github.com/kubernetes/kubernetes/tree/master/examples/cluster-dns) in the Kubernetes GitHub repository. + +## Kubernetes Federation (Multiple Zone support) + +Release 1.3 introduced Cluster Federation support for multi-site +Kubernetes installations. This required some minor +(backward-compatible) changes to the way +the Kubernetes cluster DNS server processes DNS queries, to facilitate +the lookup of federated services (which span multiple Kubernetes clusters). +See the [Cluster Federation Administrators' Guide](/docs/admin/federation) for more +details on Cluster Federation and multi-site support. + +## How it Works + +The running Kubernetes DNS pod holds 3 containers - kubedns, dnsmasq and a health check called healthz. +The kubedns process watches the Kubernetes master for changes in Services and Endpoints, and maintains +in-memory lookup structures to service DNS requests. The dnsmasq container adds DNS caching to improve +performance. The healthz container provides a single health check endpoint while performing dual healthchecks +(for dnsmasq and kubedns). + +The DNS pod is exposed as a Kubernetes Service with a static IP. Once assigned the +kubelet passes DNS configured using the `--cluster-dns=10.0.0.10` flag to each +container. + +DNS names also need domains. The local domain is configurable, in the kubelet using +the flag `--cluster-domain=` + +The Kubernetes cluster DNS server (based off the [SkyDNS](https://github.com/skynetservices/skydns) library) +supports forward lookups (A records), service lookups (SRV records) and reverse IP address lookups (PTR records). + +## Inheriting DNS from the node +When running a pod, kubelet will prepend the cluster DNS server and search +paths to the node's own DNS settings. If the node is able to resolve DNS names +specific to the larger environment, pods should be able to, also. See "Known +issues" below for a caveat. + +If you don't want this, or if you want a different DNS config for pods, you can +use the kubelet's `--resolv-conf` flag. Setting it to "" means that pods will +not inherit DNS. Setting it to a valid file path means that kubelet will use +this file instead of `/etc/resolv.conf` for DNS inheritance. + +## Known issues +Kubernetes installs do not configure the nodes' resolv.conf files to use the +cluster DNS by default, because that process is inherently distro-specific. +This should probably be implemented eventually. + +Linux's libc is impossibly stuck ([see this bug from +2005](https://bugzilla.redhat.com/show_bug.cgi?id=168253)) with limits of just +3 DNS `nameserver` records and 6 DNS `search` records. Kubernetes needs to +consume 1 `nameserver` record and 3 `search` records. This means that if a +local installation already uses 3 `nameserver`s or uses more than 3 `search`es, +some of those settings will be lost. As a partial workaround, the node can run +`dnsmasq` which will provide more `nameserver` entries, but not more `search` +entries. You can also use kubelet's `--resolv-conf` flag. + +If you are using Alpine version 3.3 or earlier as your base image, DNS may not +work properly owing to a known issue with Alpine. Check [here](https://github.com/kubernetes/kubernetes/issues/30215) +for more information. + +## References + +- [Docs for the DNS cluster addon](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md) + +## What's next +- [Autoscaling the DNS Service in a Cluster](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/). diff --git a/docs/concepts/workloads/pods/pod-lifecycle.md b/docs/concepts/workloads/pods/pod-lifecycle.md new file mode 100644 index 0000000000..540ba506fc --- /dev/null +++ b/docs/concepts/workloads/pods/pod-lifecycle.md @@ -0,0 +1,282 @@ +--- +title: Pod Lifecycle +--- + +{% capture overview %} + +{% comment %}Updated: 4/14/2015{% endcomment %} +{% comment %}Edited and moved to Concepts section: 2/2/17{% endcomment %} + +This page describes the lifecycle of a Pod. + +{% endcapture %} + + +{% capture body %} + +## Pod phase + +A Pod's `status` field is a +[PodStatus](/docs/resources-reference/v1.5/#podstatus-v1) +object, which has a `phase` field. + +The phase of a Pod is a simple, high-level summary of where the Pod is in its +lifecycle. The phase is not intended to be a comprehensive rollup of observations +of Container or Pod state, nor is it intended to be a comprehensive state machine. + +The number and meanings of Pod phase values are tightly guarded. +Other than what is documented here, nothing should be assumed about Pods that +have a given `phase` value. + +Here are the possible values for `phase`: + +* Pending: The Pod has been accepted by the Kubernetes system, but one or more of + the Container images has not been created. This includes time before being + scheduled as well as time spent downloading images over the network, + which could take a while. + +* Running: The Pod has been bound to a node, and all of the Containers have been + created. At least one Container is still running, or is in the process of + starting or restarting. + +* Succeeded: All Containers in the Pod have terminated in success, and will not + be restarted. + +* Failed: All Containers in the Pod have terminated, and at least one Container + has terminated in failure. That is, the Container either exited with non-zero + status or was terminated by the system. + +* Unknown: For some reason the state of the Pod could not be obtained, typically + due to an error in communicating with the host of the Pod. + +## Pod conditions + +A Pod has a PodStatus, which has an array of +[PodConditions](docs/resources-reference/v1.5/#podcondition). Each element +of the PodCondition array has a `type` field and a `status` field. The `type` +field is a string, with possible values PodScheduled, Ready, Initialized, and +Unschedulable. The `status` field is a string, with possible values True, False, +and Unknown. + +## Container probes + +A [Probe](/docs/resources-reference/v1.5/#probe-v1) is a diagnostic +performed periodically by the [kubelet](/docs/admin/kubelet/) +on a Container. To perform a diagnostic, +the kublet calls a +[Handler](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#Handler) implemented by +the Container. There are three types of handlers: + +* [ExecAction](/docs/resources-reference/v1.5/#execaction-v1): + Executes a specified command inside the Container. The diagnostic + is considered successful if the command exits with a status code of 0. + +* [TCPSocketAction](/docs/resources-reference/v1.5/#tcpsocketaction-v1): + Performs a TCP check against the Container's IP address on + a specified port. The diagnostic is considered successful if the port is open. + +* [HTTPGetAction](/docs/resources-reference/v1.5/#httpgetaction-v1): + Performs an HTTP Get request against the Container's IP + address on a specified port and path. The diagnostic is considered successful + if the response has a status code greater than or equal to 200 and less than 400. + +Each probe has one of three results: + +* Success: The Container passed the diagnostic. +* Failure: The Container failed the diagnostic. +* Unknown: The diagnostic failed, so no action should be taken. + +The kubelet can optionally perform and react to two kinds of probes on running +Containers: + +* `livenessProbe`: Indicates whether the Container is running. If + the liveness probe fails, the kubelet kills the Container, and the Container + is subjected to its [restart policy](#restart-policy). If a Container does not + provide a liveness probe, the default state is `Success`. + +* `readinessProbe`: Indicates whether the Container is ready to service requests. + If the readiness probe fails, the endpoints controller removes the Pod's IP + address from the endpoints of all Services that match the Pod. The default + state of readiness before the initial delay is `Failure`. If a Container does + not provide a readiness probe, the default state is `Success`. + +### When should you use liveness or readiness probes? + +If the process in your Container is able to crash on its own whenever it +encounters an issue or becomes unhealthy, you do not necessarily need a liveness +probe; the kubelet will automatically perform the correct action in accordance +with the Pod's `restartPolicy`. + +If you'd like your Container to be killed and restarted if a probe fails, then +specify a liveness probe, and specify a `restartPolicy` of Always or OnFailure. + +If you'd like to start sending traffic to a Pod only when a probe succeeds, +specify a readiness probe. In this case, the readiness probe might be the same +as the liveness probe, but the existence of the readiness probe in the spec means +that the Pod will start without receiving any traffic and only start receiving +traffic after the probe starts succeeding. + +If you want your Container to be able to take itself down for maintenance, you +can specify a readiness probe that checks an endpoint specific to readiness that +is different from the liveness probe. + +Note that if you just want to be able to drain requests when the Pod is deleted, +you do not necessarily need a readiness probe; on deletion, the Pod automatically +puts itself into an unready state regardless of whether the readiness probe exists. +The Pod remains in the unready state while it waits for the Containers in the Pod +to stop. + +## Pod and Container status + +For detailed information about Pod Container status, see +[PodStatus](/docs/resources-reference/v1.5/#podstatus-v1) +and +[ContainerStatus](/docs/resources-reference/v1.5/#containerstatus-v1). +Note that the information reported as Pod status depends on the current +[ContainerState](/docs/resources-reference/v1.5/#containerstate-v1). + +## Restart policy + +A PodSpec has a `restartPolicy` field with possible values Always, OnFailure, +and Never. The default value is Always. +`restartPolicy` applies to all Containers in the Pod. `restartPolicy` only +refers to restarts of the Containers by the kubelet on the same node. Failed +Containers that are restarted by the kubelet are restarted with an exponential +back-off delay (10s, 20s, 40s ...) capped at five minutes, and is reset after ten +minutes of successful execution. As discussed in the +[Pods document](/docs/user-guide/pods/#durability-of-pods-or-lack-thereof), +once bound to a node, a Pod will never be rebound to another node. + + + +## Pod lifetime + +In general, Pods do not disappear until someone destroys them. This might be a +human or a controller. The only exception to +this rule is that Pods with a `phase` of Succeeded or Failed for more than some +duration (determined by the master) will expire and be automatically destroyed. + +Three types of controllers are available: + +- Use a [Job](/docs/user-guide/jobs/) for Pods that are expected to terminate, + for example, batch computations. Jobs are appropriate only for Pods with + `restartPolicy` equal to OnFailure or Never. + +- Use a [ReplicationController](/docs/user-guide/replication-controller/), + [ReplicaSet](/docs/user-guide/replicasets/), or + [Deployment](/docs/user-guide/deployments/) + for Pods that are not expected to terminate, for example, web servers. + ReplicationControllers are appropriate only for Pods with a `restartPolicy` of + Always. + +- Use a [DaemonSet](/docs/admin/daemons/) for Pods that need to run one per + machine, because they provide a machine-specific system service. + +All three types of controllers contain a PodTemplate. It +is recommended to create the appropriate controller and let +it create Pods, rather than directly create Pods yourself. That is because Pods +alone are not resilient to machine failures, but controllers are. + +If a node dies or is disconnected from the rest of the cluster, Kubernetes +applies a policy for setting the `phase` of all Pods on the lost node to Failed. + +## Examples + +### Advanced liveness probe example + +Liveness probes are executed by the kubelet, so all requests are made in the +kubelet network namespace. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + test: liveness + name: liveness-http +spec: + containers: + - args: + - /server + image: gcr.io/google_containers/liveness + livenessProbe: + httpGet: + # when "host" is not defined, "PodIP" will be used + # host: my-host + # when "scheme" is not defined, "HTTP" scheme will be used. Only "HTTP" and "HTTPS" are allowed + # scheme: HTTPS + path: /healthz + port: 8080 + httpHeaders: + - name: X-Custom-Header + value: Awesome + initialDelaySeconds: 15 + timeoutSeconds: 1 + name: liveness +``` + +### Example states + + * Pod is running and has one Container. Container exits with success. + * Log completion event. + * If `restartPolicy` is: + * Always: Restart Container; Pod `phase` stays Running. + * OnFailure: Pod `phase` becomes Succeeded. + * Never: Pod `phase` becomes Succeeded. + + * Pod is running and has one Container. Container exits with failure. + * Log failure event. + * If `restartPolicy` is: + * Always: Restart Container; Pod `phase` stays Running. + * OnFailure: Restart Container; Pod `phase` stays Running. + * Never: Pod `phase` becomes Failed. + + * Pod is running and has two Containers. Container 1 exits with failure. + * Log failure event. + * If `restartPolicy` is: + * Always: Restart Container; Pod `phase` stays Running. + * OnFailure: Restart Container; Pod `phase` stays Running. + * Never: Do not restart Container; Pod `phase` stays Running. + * If Container 1 is not running, and Container 2 exits: + * Log failure event. + * If `restartPolicy` is: + * Always: Restart Container; Pod `phase` stays Running. + * OnFailure: Restart Container; Pod `phase` stays Running. + * Never: Pod `phase` becomes Failed. + + * Pod is running and has one Container. Container runs out of memory. + * Container terminates in failure. + * Log OOM event. + * If `restartPolicy` is: + * Always: Restart Container; Pod `phase` stays Running. + * OnFailure: Restart Container; Pod `phase` stays Running. + * Never: Log failure event; Pod `phase` becomes Failed. + + * Pod is running, and a disk dies. + * Kill all Containers. + * Log appropriate event. + * Pod `phase` becomes Failed. + * If running under a controller, Pod is recreated elsewhere. + + * Pod is running, and its node is segmented out. + * Node controller waits for timeout. + * Node controller sets Pod `phase` to Failed. + * If running under a controller, Pod is recreated elsewhere. + +{% endcapture %} + + +{% capture whatsnext %} + +* Get hands-on experience + [attaching handlers to Container lifecycle events](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/). + +* Get hands-on experience + [configuring liveness and readiness probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/). + +* [Container Lifecycle Hooks](/docs/user-guide/container-environment/) + +{% endcapture %} + +{% include templates/concept.md %} + diff --git a/docs/contribute/review-issues.md b/docs/contribute/review-issues.md index f5430d0b11..1353620e81 100644 --- a/docs/contribute/review-issues.md +++ b/docs/contribute/review-issues.md @@ -12,6 +12,8 @@ This page explains how documentation issues are reviewed and prioritized for the ## Categorizing issues Issues should be sorted into different buckets of work using the following labels and definitions. If an issue doesn't have enough information to identify a problem that can be researched, reviewed, or worked on (i.e. the issue doesn't fit into any of the categories below) you should close the issue with a comment explaining why it is being closed. +### Needs Clarification +* Issues that need more information from the original submitter to make them actionable. Issues with this label that aren't followed up within a week may be closed. ### Actionable * Issues that can be worked on with current information (or may need a comment to explain what needs to be done to make it more clear) @@ -26,8 +28,9 @@ Issues should be sorted into different buckets of work using the following label * Issues that are suggestions for better processes or site improvements that require community agreement to be implemented * Topics can be brought to SIG meetings as agenda items -#### Needs UX Review -* Issues that are suggestions for improving the user interface of the site or fixing a broken UX. +### Needs UX Review +* Issues that are suggestions for improving the user interface of the site. +* Fixing broken site elements. ## Prioritizing Issues diff --git a/docs/contribute/stage-documentation-changes.md b/docs/contribute/stage-documentation-changes.md index 452c38170c..48d28aad15 100644 --- a/docs/contribute/stage-documentation-changes.md +++ b/docs/contribute/stage-documentation-changes.md @@ -90,6 +90,14 @@ web server: 1. View your staged content at [http://localhost:4000](http://localhost:4000){: target="_blank"}. +NOTE: If you do not want Jekyll to interfere with your other globally installed gems, you can use `bundler`: + + gem install bundler + bundle install + bundler exec jekyll serve + + Regardless of whether you use `bundler` or not, your copy of the site will then be viewable at: [http://localhost:4000](http://localhost:4000) + {% endcapture %} {% capture whatsnext %} diff --git a/docs/contribute/style-guide.md b/docs/contribute/style-guide.md index 6bb1aa5837..d44cab2ea4 100644 --- a/docs/contribute/style-guide.md +++ b/docs/contribute/style-guide.md @@ -17,7 +17,7 @@ docs, follow the instructions on ## Documentation formatting standards -### Use Camel Case for API objects +### Use camel case for API objects When you refer to an API object, use the same uppercase and lowercase letters that are used in the actual object name. Typically, the names of API @@ -75,7 +75,7 @@ represents. Open the /_data/concepts.yaml file.Open the /_data/concepts.yaml file. -## Code snippet formatting +## Inline code formatting ### Use code style for inline code and commands @@ -84,10 +84,31 @@ document, use the backtick (`). - +
    DoDon't
    Set the value of the replicas field in the configuration file.Set the value of the "replicas" field in the configuration file.
    The kubectl run command creates a Deployment.The "kubectl run" command creates a Deployment.
    For declarative management, use kubectl apply.For declarative management, use "kubectl apply".
    +### Use code style for object field names + + + + + +
    DoDon't
    Set the value of the replicas field in the configuration file.Set the value of the "replicas" field in the configuration file.
    The value of the exec field is an ExecAction object.The value of the "exec" field is an ExecAction object.
    + +### Use normal style for string and integer field values + +For field values of type string or integer, use normal style without quotation marks. + + + + + + +
    DoDon't
    Set the value of imagePullPolicy to Always.Set the value of imagePullPolicy to "Always".
    Set the value of image to nginx:1.8.Set the value of image to nginx:1.8.
    Set the value of the replicas field to 2.Set the value of the replicas field to 2.
    + +## Code snippet formatting + ### Don't include the command prompt diff --git a/docs/deprecation-policy.md b/docs/deprecation-policy.md index c51326bbc5..cdc0bb0102 100644 --- a/docs/deprecation-policy.md +++ b/docs/deprecation-policy.md @@ -233,7 +233,7 @@ after their announced deprecation for no less than:** * **Beta: 3 months or 1 release (whichever is longer)** * **Alpha: 0 releases** -**Rule #6: Deprecated CLI elements must emit warnings (optionally disableable) +**Rule #6: Deprecated CLI elements must emit warnings (optionally disable) when used.** ## Deprecating a feature or behavior diff --git a/docs/federation/api-reference/extensions/v1beta1/definitions.html b/docs/federation/api-reference/extensions/v1beta1/definitions.html index 897ab5aca8..28b2883fc2 100755 --- a/docs/federation/api-reference/extensions/v1beta1/definitions.html +++ b/docs/federation/api-reference/extensions/v1beta1/definitions.html @@ -3073,7 +3073,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i - + diff --git a/docs/getting-started-guides/centos/centos_manual_config.md b/docs/getting-started-guides/centos/centos_manual_config.md index 031a5bb3f5..b64af60475 100644 --- a/docs/getting-started-guides/centos/centos_manual_config.md +++ b/docs/getting-started-guides/centos/centos_manual_config.md @@ -61,9 +61,6 @@ echo "192.168.121.9 centos-master * Edit /etc/kubernetes/config which will be the same on all hosts to contain: ```shell -# Comma separated list of nodes in the etcd cluster -KUBE_ETCD_SERVERS="--etcd-servers=http://centos-master:2379" - # logging to stderr means we get it in the systemd journal KUBE_LOGTOSTDERR="--logtostderr=true" @@ -111,6 +108,9 @@ KUBE_API_PORT="--port=8080" # Port kubelets listen on KUBELET_PORT="--kubelet-port=10250" +# Comma separated list of nodes in the etcd cluster +KUBE_ETCD_SERVERS="--etcd-servers=http://centos-master:2379" + # Address range to use for services KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" diff --git a/docs/getting-started-guides/gce.md b/docs/getting-started-guides/gce.md index 245de295f9..109dcb8d95 100644 --- a/docs/getting-started-guides/gce.md +++ b/docs/getting-started-guides/gce.md @@ -134,10 +134,10 @@ $ kubectl get --all-namespaces services should show a set of [services](/docs/user-guide/services) that look something like this: ```shell -NAMESPACE NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE -default kubernetes 10.0.0.1 443/TCP 1d -kube-system kube-dns 10.0.0.2 53/TCP,53/UDP k8s-app=kube-dns 1d -kube-system kube-ui 10.0.0.3 80/TCP k8s-app=kube-ui 1d +NAMESPACE NAME CLUSTER_IP EXTERNAL_IP PORT(S) AGE +default kubernetes 10.0.0.1 443/TCP 1d +kube-system kube-dns 10.0.0.2 53/TCP,53/UDP 1d +kube-system kube-ui 10.0.0.3 80/TCP 1d ... ``` diff --git a/docs/getting-started-guides/index.md b/docs/getting-started-guides/index.md index 9ee9e01301..2d3d18cd57 100644 --- a/docs/getting-started-guides/index.md +++ b/docs/getting-started-guides/index.md @@ -47,6 +47,8 @@ clusters. [KCluster.io](https://kcluster.io) provides highly available and scalable managed Kubernetes clusters for AWS. +[KUBE2GO.io](https://kube2go.io) get started with highly available Kubernetes clusters on multiple public clouds along with useful tools for development, debugging, monitoring. + [Platform9](https://platform9.com/products/kubernetes/) offers managed Kubernetes on-premises or any public cloud, and provides 24/7 health monitoring and alerting. [OpenShift Dedicated](https://www.openshift.com/dedicated/) offers managed Kubernetes clusters powered by OpenShift and [OpenShift Online](https://www.openshift.com/features/) provides free hosted access for Kubernetes applications. @@ -59,9 +61,11 @@ few commands, and have active community support. - [GCE](/docs/getting-started-guides/gce) - [AWS](/docs/getting-started-guides/aws) - [Azure](/docs/getting-started-guides/azure) +- [Tectonic by CoreOS](https://coreos.com/tectonic) - [CenturyLink Cloud](/docs/getting-started-guides/clc) - [IBM SoftLayer](https://github.com/patrocinio/kubernetes-softlayer) - [Stackpoint.io](/docs/getting-started-guides/stackpoint/) +- [KUBE2GO.io](https://kube2go.io/) ### Custom Solutions @@ -131,6 +135,7 @@ GKE | | | GCE | [docs](https://clou Stackpoint.io | | multi-support | multi-support | [docs](http://www.stackpointcloud.com) | Commercial AppsCode.com | Saltstack | Debian | multi-support | [docs](https://appscode.com/products/cloud-deployment/) | Commercial KCluster.io | | multi-support | multi-support | [docs](https://kcluster.io) | Commercial +KUBE2GO.io | | multi-support | multi-support | [docs](https://kube2go.io) | Commercial Platform9 | | multi-support | multi-support | [docs](https://platform9.com/products/kubernetes/) | Commercial GCE | Saltstack | Debian | GCE | [docs](/docs/getting-started-guides/gce) | Project Azure Container Service | | Ubuntu | Azure | [docs](https://azure.microsoft.com/en-us/services/container-service/) | Commercial diff --git a/docs/getting-started-guides/kubeadm.md b/docs/getting-started-guides/kubeadm.md index a005ed0c56..03cf546eaa 100644 --- a/docs/getting-started-guides/kubeadm.md +++ b/docs/getting-started-guides/kubeadm.md @@ -69,6 +69,7 @@ For each host in turn: * SSH into the machine and become `root` if you are not already (for example, run `sudo su -`). * If the machine is running Ubuntu or HypriotOS, run: + apt-get update && apt-get install -y apt-transport-https curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - cat < /etc/apt/sources.list.d/kubernetes.list deb http://apt.kubernetes.io/ kubernetes-xenial main @@ -102,7 +103,15 @@ Note: Disabling SELinux by running `setenforce 0` is required in order to allow ### (2/4) Initializing your master The master is the machine where the "control plane" components run, including `etcd` (the cluster database) and the API server (which the `kubectl` CLI communicates with). -All of these components run in pods started by `kubelet`. +All of these components run in pods started by `kubelet` and the following images are required and will be automatically pulled by `kubelet` if they are absent while `kubeadm init` is initializing your master: + + gcr.io/google_containers/kube-proxy-amd64 v1.5.3 + gcr.io/google_containers/kube-controller-manager-amd64 v1.5.3 + gcr.io/google_containers/kube-scheduler-amd64 v1.5.3 + gcr.io/google_containers/kube-apiserver-amd64 v1.5.3 + gcr.io/google_containers/etcd-amd64 3.0.14-kubeadm + gcr.io/google_containers/kube-discovery-amd64 1.0 + gcr.io/google_containers/pause-amd64 3.0 Right now you can't run `kubeadm init` twice without tearing down the cluster in between, see [Tear down](#tear-down). @@ -194,6 +203,46 @@ Once a pod network has been installed, you can confirm that it is working by che And once the `kube-dns` pod is up and running, you can continue by joining your nodes. + +You may have trouble in the configuration if you see the following statuses + +``` +NAMESPACE NAME READY STATUS RESTARTS AGE +kube-system canal-node-f0lqp 2/3 RunContainerError 2 48s +kube-system canal-node-77d0h 2/3 CrashLoopBackOff 3 3m +kube-system kube-dns-2924299975-7q1vq 0/4 ContainerCreating 0 15m +``` + +The three statuses ```RunContainerError``` and ```CrashLoopBackOff``` and ```ContainerCreating``` are very common. + +To help diagnose what happened, you can use the following command to check what is in the logs: + +```bash +kubectl describe -n kube-system po {YOUR_POD_NAME} +``` + +Do not using kubectl logs. You will got the following error: + +``` +# kubectl logs -n kube-system canal-node-f0lqp +Error from server (BadRequest): the server rejected our request for an unknown reason (get pods canal-node-f0lqp) +``` + +The ```kubectl describe``` comand gives you more details about the logs + +``` +# kubectl describe -n kube-system po kube-dns-2924299975-1l2t7 + 2m 2m 1 {kubelet nac} spec.containers{flannel} Warning Failed Failed to start container with docker id 927e7ccdc32b with error: Error response from daemon: {"message":"chown /etc/resolv.conf: operation not permitted"} + +``` + +Or +``` + 6m 1m 191 {kubelet nac} Warning FailedSync Error syncing pod, skipping: failed to "SetupNetwork" for "kube-dns-2924299975-1l2t7_kube-system" with SetupNetworkError: "Failed to setup network for pod \"kube-dns-2924299975-1l2t7_kube-system(dee8ef21-fbcb-11e6-ba19-38d547e0006a)\" using network plugins \"cni\": open /run/flannel/subnet.env: no such file or directory; Skipping pod" +``` + +You can then do some Google searches on the error messages, which may help you to find some solutions. + ### (4/4) Joining your nodes The nodes are where your workloads (containers and pods, etc) run. @@ -269,7 +318,7 @@ It takes several minutes to download and start all the containers, watch the out Then go to the IP address of your cluster's master node in your browser, and specify the given port. So for example, `http://:`. -In the example above, this was `31869`, but it is a different port for you. +In the example above, this was `30001`, but it is a different port for you. If there is a firewall, make sure it exposes this port to the internet before you try to access it. @@ -352,11 +401,11 @@ Please note: `kubeadm` is a work in progress and these limitations will be addre 1. There is no built-in way of fetching the token easily once the cluster is up and running, but here is a `kubectl` command you can copy and paste that will print out the token for you: ```console - # kubectl -n kube-system get secret clusterinfo -o yaml | grep token-map | awk '{print $2}' | base64 -D | sed "s|{||g;s|}||g;s|:|.|g;s/\"//g;" | xargs echo + # kubectl -n kube-system get secret clusterinfo -o yaml | grep token-map | awk '{print $2}' | base64 --decode | sed "s|{||g;s|}||g;s|:|.|g;s/\"//g;" | xargs echo ``` 1. If you are using VirtualBox (directly or via Vagrant), you will need to ensure that `hostname -i` returns a routable IP address (i.e. one on the second network interface, not the first one). By default, it doesn't do this and kubelet ends-up using first non-loopback network interface, which is usually NATed. - Workaround: Modify `/etc/hosts`, take a look at this [`Vagrantfile`][ubuntu-vagrantfile] for how you this can be achieved. + Workaround: Modify `/etc/hosts`, take a look at this [`Vagrantfile`][ubuntu-vagrantfile] for how this can be achieved. [ubuntu-vagrantfile]: https://github.com/errordeveloper/k8s-playground/blob/22dd39dfc06111235620e6c4404a96ae146f26fd/Vagrantfile#L11), diff --git a/docs/getting-started-guides/minikube.md b/docs/getting-started-guides/minikube.md index 4f4a432185..e0e79364cf 100644 --- a/docs/getting-started-guides/minikube.md +++ b/docs/getting-started-guides/minikube.md @@ -40,7 +40,7 @@ See the installation instructions for the [latest release](https://github.com/ku ## Quickstart Here's a brief demo of minikube usage. -If you want to change the VM driver add the appropriate `--vm-driver=xxx` flag to `minikube start`. Minikube Supports +If you want to change the VM driver add the appropriate `--vm-driver=xxx` flag to `minikube start`. Minikube supports the following drivers: * virtualbox @@ -106,7 +106,7 @@ plugins, if required. When using a single VM of Kubernetes, it's really handy to reuse the minikube's built-in Docker daemon; as this means you don't have to build a docker registry on your host machine and push the image into it - you can just build inside the same docker daemon as minikube which speeds up local experiments. Just make sure you tag your Docker image with something other than 'latest' and use that tag while you pull the image. Otherwise, if you do not specify version of your image, it will be assumed as `:latest`, with pull image policy of `Always` correspondingly, which may eventually result in `ErrImagePull` as you may not have any versions of your Docker image out there in the default docker registry (usually DockerHub) yet. -To be able to work with the docker daemon on your mac/linux host use the [docker-env command](./docs/minikube_docker-env.md) in your shell: +To be able to work with the docker daemon on your mac/linux host use the [docker-env command](https://github.com/kubernetes/minikube/blob/master/docs/minikube_docker-env.md) in your shell: ``` eval $(minikube docker-env) diff --git a/docs/getting-started-guides/network-policy/walkthrough.md b/docs/getting-started-guides/network-policy/walkthrough.md index 21a74278c5..ef722f9ddc 100644 --- a/docs/getting-started-guides/network-policy/walkthrough.md +++ b/docs/getting-started-guides/network-policy/walkthrough.md @@ -31,12 +31,13 @@ This will run two nginx Pods in the default Namespace, and expose them through a ```console $ kubectl get svc,pod -NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE -kubernetes 10.100.0.1 443/TCP 46m -nginx 10.100.0.16 80/TCP 33s -NAME READY STATUS RESTARTS AGE -nginx-701339712-e0qfq 1/1 Running 0 35s -nginx-701339712-o00ef 1/1 Running 0 35s +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc/kubernetes 10.100.0.1 443/TCP 46m +svc/nginx 10.100.0.16 80/TCP 33s + +NAME READY STATUS RESTARTS AGE +po/nginx-701339712-e0qfq 1/1 Running 0 35s +po/nginx-701339712-o00ef 1/1 Running 0 35s ``` We should be able to access our new nginx Service from other Pods. Let's try to access it from another Pod @@ -49,7 +50,7 @@ Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending Hit enter for command prompt -/ # wget -s --timeout=1 nginx +/ # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) / # ``` @@ -95,7 +96,7 @@ Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending Hit enter for command prompt -/ # wget -s --timeout=1 nginx +/ # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) wget: download timed out / # @@ -109,7 +110,7 @@ Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending Hit enter for command prompt -/ # wget -s --timeout=1 nginx +/ # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) / # ``` diff --git a/docs/getting-started-guides/network-policy/weave.md b/docs/getting-started-guides/network-policy/weave.md index d26634e8d9..02224b7425 100644 --- a/docs/getting-started-guides/network-policy/weave.md +++ b/docs/getting-started-guides/network-policy/weave.md @@ -1,7 +1,7 @@ --- assignees: - bboreham -title: Weave Net Addon +title: Using Weave Net for NetworkPolicy --- The [Weave Net Addon](https://www.weave.works/docs/net/latest/kube-addon/) for Kubernetes comes with a Network Policy Controller. diff --git a/docs/getting-started-guides/openstack-heat.md b/docs/getting-started-guides/openstack-heat.md index e4fb7c277d..8a2fd52d11 100644 --- a/docs/getting-started-guides/openstack-heat.md +++ b/docs/getting-started-guides/openstack-heat.md @@ -23,7 +23,7 @@ This guide assumes you have access to a working OpenStack cluster with the follo - 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. +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. @@ -92,7 +92,7 @@ Please see the contents of these files for documentation regarding each variable ## Starting a cluster -Once Kubernetes version 1.3 is released, and you've installed the OpenStack CLI tools and have set your OpenStack environment variables, issue this command: +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 @@ -194,6 +194,11 @@ nova list --name=$STACK_NAME See the [OpenStack CLI Reference](http://docs.openstack.org/cli-reference/) for more details. +### Salt + +The OpenStack-Heat provider uses a [standalone Salt configuration](/docs/admin/salt/#standalone-salt-configuration-on-gce-and-others). +It only uses Salt for bootstraping the machines and creates no salt-master and does not auto-start the salt-minion service on the nodes. + ## SSHing to your nodes Your public key was added during the cluster turn-up, so you can easily ssh to them for troubleshooting purposes. diff --git a/docs/getting-started-guides/ubuntu/backups.md b/docs/getting-started-guides/ubuntu/backups.md index 9c0c741d9b..8617c557ad 100644 --- a/docs/getting-started-guides/ubuntu/backups.md +++ b/docs/getting-started-guides/ubuntu/backups.md @@ -3,13 +3,14 @@ title: Backups --- {% capture overview %} -This pages shows you how to backup and restore data from the different deployed services in a given cluster. +This page shows you how to backup and restore data from the different deployed services in a given cluster. {% endcapture %} {% capture prerequisites %} This page assumes you have a working Juju deployed cluster. {% endcapture %} +{% capture steps %} ## Exporting cluster data Exporting of cluster data is not supported at this time. @@ -18,7 +19,6 @@ Exporting of cluster data is not supported at this time. Importing of cluster data is not supported at this time. -{% capture steps %} ## Exporting etcd data Migrating etcd is a fairly easy task. diff --git a/docs/getting-started-guides/ubuntu/calico.md b/docs/getting-started-guides/ubuntu/calico.md index 631d2cdaac..ccd66093a4 100644 --- a/docs/getting-started-guides/ubuntu/calico.md +++ b/docs/getting-started-guides/ubuntu/calico.md @@ -80,7 +80,7 @@ The master requires the root CA public key, `ca.pem`; the apiserver certificate, Calico needs its own etcd cluster to store its state. In this guide we install a single-node cluster on the master server. -> Note: In a production deployment we recommend running a distributed etcd cluster for redundancy. In this guide, we use a single etcd for simplicitly. +> Note: In a production deployment we recommend running a distributed etcd cluster for redundancy. In this guide, we use a single etcd for simplicity. 1. Download the template manifest file: diff --git a/docs/getting-started-guides/ubuntu/decommissioning.md b/docs/getting-started-guides/ubuntu/decommissioning.md index 0da845236e..2d1b42c7e4 100644 --- a/docs/getting-started-guides/ubuntu/decommissioning.md +++ b/docs/getting-started-guides/ubuntu/decommissioning.md @@ -13,7 +13,7 @@ This page assumes you have a working Juju deployed cluster. {% endcapture %} {% capture steps %} -It is recommended to deploy individual Kubernetes clusters in their own models, so that there is a clean seperation between environments. To remove a cluster first find out which model it's in with `juju list-models`. The controller reserves an `admin` model for itself. If you have chosen to not name your model it might show up as `default`. +It is recommended to deploy individual Kubernetes clusters in their own models, so that there is a clean separation between environments. To remove a cluster first find out which model it's in with `juju list-models`. The controller reserves an `admin` model for itself. If you have chosen to not name your model it might show up as `default`. ``` $ juju list-models diff --git a/docs/getting-started-guides/ubuntu/glossary.md b/docs/getting-started-guides/ubuntu/glossary.md index 1c8b2ec99b..2afe083a82 100644 --- a/docs/getting-started-guides/ubuntu/glossary.md +++ b/docs/getting-started-guides/ubuntu/glossary.md @@ -16,7 +16,7 @@ This page assumes you have a working Juju deployed cluster. controller - The management node of a cloud environment. Typically you have one controller per cloud region, or more in HA environments. The controller is responsible for managing all subsequent models in a given environment. It contains the Juju API server and its underlying database. -model - A collection of charms and their relationships that define a deployment. This includes machines and units. A controller can host multiple models. It is recommended to seperate Kubernetes clusters into individual models for management and isolation reasons. +model - A collection of charms and their relationships that define a deployment. This includes machines and units. A controller can host multiple models. It is recommended to separate Kubernetes clusters into individual models for management and isolation reasons. charm - The definition of a service, including its metadata, dependencies with other services, required packages, and application management logic. It contains all the operational knowledge of deploying a Kubernetes cluster. Included charm examples are `kubernetes-core`, `easy-rsa`, `kibana`, and `etcd`. @@ -25,4 +25,4 @@ unit - A given instance of a service. These may or may not use up a whole machin machine - A physical node, these can either be bare metal nodes, or virtual machines provided by a cloud. {% endcapture %} -{% include templates/task.md %} \ No newline at end of file +{% include templates/task.md %} diff --git a/docs/getting-started-guides/ubuntu/index.md b/docs/getting-started-guides/ubuntu/index.md index d54b94a88c..e5a5125f2f 100644 --- a/docs/getting-started-guides/ubuntu/index.md +++ b/docs/getting-started-guides/ubuntu/index.md @@ -15,16 +15,13 @@ Supports AWS, GCE, Azure, Joyent, OpenStack, Bare Metal and local workstation de ### Quick Start -[conjure-up](http://conjure-up.io/) provides quick wasy to deploy Kubernetes on multiple clouds and bare metal. It provides a user-friendly UI that prompts you for cloud credentials and configuration options: +[conjure-up](http://conjure-up.io/) provides a quick way to deploy Kubernetes on multiple clouds and bare metal. It provides a user-friendly UI that prompts you for cloud credentials and configuration options: Available for Ubuntu 16.04 and newer: ``` -sudo apt-add-repository ppa:juju/stable -sudo apt-add-repository ppa:conjure-up/next -sudo apt update -sudo apt install conjure-up -conjure-up +sudo snap install conjure-up --classic +conjure-up kubernetes ``` ### Operational Guides diff --git a/docs/getting-started-guides/ubuntu/installation.md b/docs/getting-started-guides/ubuntu/installation.md index cc93995144..9e3bdd8b2b 100644 --- a/docs/getting-started-guides/ubuntu/installation.md +++ b/docs/getting-started-guides/ubuntu/installation.md @@ -159,15 +159,17 @@ juju scp kubernetes-master/0:config ~/.kube/config Fetch a binary for the architecture you have deployed. If your client is a different architecture you will need to get the appropriate `kubectl` binary -through other means. +through other means. In this example we copy kubectl to `~/bin` for convenience, +by default this should be in your $PATH. ``` -juju scp kubernetes-master/0:kubectl ./kubectl +mkdir -p ~/bin +juju scp kubernetes-master/0:kubectl ~/bin/kubectl ``` Query the cluster: - ./kubectl cluster-info + kubectl cluster-info Output: diff --git a/docs/getting-started-guides/ubuntu/local.md b/docs/getting-started-guides/ubuntu/local.md index 854a34fa5d..767e867680 100644 --- a/docs/getting-started-guides/ubuntu/local.md +++ b/docs/getting-started-guides/ubuntu/local.md @@ -42,14 +42,11 @@ Next, apply those kernel parameters (you should see the above options echoed bac Now you're ready to install conjure-up and deploy Kubernetes. ``` - sudo apt-add-repository ppa:juju/stable - sudo apt-add-repository ppa:conjure-up/next - sudo apt update - sudo apt install conjure-up - + sudo snap install conjure-up --classic + conjure-up kubernetes ``` -Note: During this set up phase cojure-up will ask you to "Setup an ipv6 subnet" with LXD, ensure you answer NO. ipv6 with Juju/LXD is currently unsupported. +Note: During this set up phase conjure-up will ask you to "Setup an ipv6 subnet" with LXD, ensure you answer NO. ipv6 with Juju/LXD is currently unsupported. ### Walkthrough diff --git a/docs/getting-started-guides/ubuntu/monitoring.md b/docs/getting-started-guides/ubuntu/monitoring.md index ee6b102f43..7ac97ea4e9 100644 --- a/docs/getting-started-guides/ubuntu/monitoring.md +++ b/docs/getting-started-guides/ubuntu/monitoring.md @@ -28,7 +28,7 @@ Configure Datadog with your api-key, found in the [Datadog dashboard](). Replace juju configure datadog api-key=XXXX ``` -Finally, attach `datadog` to all applications you wish to montior. For example, kubernetes-master, kubernetes-worker, and etcd: +Finally, attach `datadog` to all applications you wish to monitor. For example, kubernetes-master, kubernetes-worker, and etcd: ``` juju add-relation datadog kubernetes-worker @@ -74,7 +74,7 @@ juju add-relation kubernetes-worker filebeat ### Existing ElasticSearch cluster -In the event an ElasticSearch cluster already exists, the following can be used to connect and leverage it instead of creating a new, seprate, cluster. First deploy the two beats, filebeat and topbeat +In the event an ElasticSearch cluster already exists, the following can be used to connect and leverage it instead of creating a new, separate, cluster. First deploy the two beats, filebeat and topbeat ``` juju deploy filebeat @@ -122,7 +122,7 @@ juju add-relation nrpe kubeapi-load-balancer ### Existing install of Nagios -If you already have an exisiting Nagios installation, the `nrpe-external-master` charm can be used instead. This will allow you to supply configuration options that map your exisiting external Nagios installation to NRPE. Replace `255.255.255.255` with the IP address of the nagios instance. +If you already have an existing Nagios installation, the `nrpe-external-master` charm can be used instead. This will allow you to supply configuration options that map your existing external Nagios installation to NRPE. Replace `255.255.255.255` with the IP address of the nagios instance. ``` juju deploy nrpe-external-master diff --git a/docs/getting-started-guides/ubuntu/networking.md b/docs/getting-started-guides/ubuntu/networking.md index 54ca15c6ad..bb16491e2b 100644 --- a/docs/getting-started-guides/ubuntu/networking.md +++ b/docs/getting-started-guides/ubuntu/networking.md @@ -45,7 +45,7 @@ $ route | grep default | head -n 1 | awk {'print $8'} establishing networking setup with etcd. Ensure this network range is not active on layers 2/3 you're deploying to, as it will cause collisions and odd behavior if care is not taken when selecting a good CIDR range to assign to flannel. It's -also good practice to ensure you alot yourself a large enough IP range to support +also good practice to ensure you allot yourself a large enough IP range to support how large your cluster will potentially scale. Class A IP ranges with /24 are a good option. {% endcapture %} diff --git a/docs/getting-started-guides/ubuntu/storage.md b/docs/getting-started-guides/ubuntu/storage.md index 104dd588a4..9d193fa81b 100644 --- a/docs/getting-started-guides/ubuntu/storage.md +++ b/docs/getting-started-guides/ubuntu/storage.md @@ -83,8 +83,8 @@ test 50M RWO Available 10s ``` To consume these Persistent Volumes, your pods will need an associated -Persistant Volume Claim with them, and is outside the scope of this README. See the -[Persistant Volumes](http://kubernetes.io/docs/user-guide/persistent-volumes/) +Persistent Volume Claim with them, and is outside the scope of this README. See the +[Persistent Volumes](http://kubernetes.io/docs/user-guide/persistent-volumes/) documentation for more information. {% endcapture %} diff --git a/docs/getting-started-guides/ubuntu/troubleshooting.md b/docs/getting-started-guides/ubuntu/troubleshooting.md index 44b3a34346..b371e1af0c 100644 --- a/docs/getting-started-guides/ubuntu/troubleshooting.md +++ b/docs/getting-started-guides/ubuntu/troubleshooting.md @@ -42,9 +42,9 @@ Machine State DNS Inst id Series AZ In this example we can glean some information. The `Workload` column will show the status of a given service. The `Message` section will show you the health of a given service in the cluster. During deployment and maintenance these workload statuses will update to reflect what a given node is doing. For example the workload my say `maintenance` while message will describe this maintenance as `Installing docker`. -During normal oprtation the Workload should read `active`, the Agent column (which reflects what the Juju agent is doing) should read `idle`, and the messages will either say `Ready` or another descriptive term. `juju status --color` will also return all green results when a cluster's deployment is healthy. +During normal operation the Workload should read `active`, the Agent column (which reflects what the Juju agent is doing) should read `idle`, and the messages will either say `Ready` or another descriptive term. `juju status --color` will also return all green results when a cluster's deployment is healthy. -Status can become unweildly for large clusters, it is then recommended to check status on individual services, for example to check the status on the workers only: +Status can become unwieldy for large clusters, it is then recommended to check status on individual services, for example to check the status on the workers only: juju status kubernetes-workers diff --git a/docs/getting-started-guides/ubuntu/validation.md b/docs/getting-started-guides/ubuntu/validation.md index 51b265a722..e881ab9fa6 100644 --- a/docs/getting-started-guides/ubuntu/validation.md +++ b/docs/getting-started-guides/ubuntu/validation.md @@ -31,7 +31,7 @@ users do, when unit and integration tests are insufficient. To deploy the end-to-end test suite, you need to relate the `kubernetes-e2e` charm to your existing kubernetes-master nodes and easyrsa: ``` -juju deploy kubernetes-e2e +juju deploy cs:~containers/kubernetes-e2e juju add-relation kubernetes-e2e kubernetes-master juju add-relation kubernetes-e2e easyrsa ``` @@ -83,7 +83,7 @@ As an example, you can run a more limited set of tests for rapid validation of a deployed cluster. The following example will skip the `Flaky`, `Slow`, and `Feature` labeled tests: - juju run-action kubernetes-e2e/0 skip='\[(Flaky|Slow|Feature:.*)\]' + juju run-action kubernetes-e2e/0 test skip='\[(Flaky|Slow|Feature:.*)\]' > Note: the escaping of the regex due to how bash handles brackets. @@ -120,13 +120,13 @@ Output: Action queued with id: 4ceed33a-d96d-465a-8f31-20d63442e51b -Copy output to your local machine +Copy output to your local machine: juju scp kubernetes-e2e/0:4ceed33a-d96d-465a-8f31-20d63442e51b.log . ##### Action result output -Or you can just show the output inline:: +Or you can just show the output inline: juju run-action kubernetes-e2e/0 test diff --git a/docs/getting-started-guides/vsphere.md b/docs/getting-started-guides/vsphere.md index ba07d14890..a22d38609f 100644 --- a/docs/getting-started-guides/vsphere.md +++ b/docs/getting-started-guides/vsphere.md @@ -69,6 +69,7 @@ Sample Config: datacenter = datastore = working-dir = + vm-uuid = [Disk] scsicontrollertype = pvscsi ``` @@ -78,8 +79,7 @@ Sample Config: #### Known issues -* [Volumes are not removed from a VM configuration if the VM is down](https://github.com/kubernetes/kubernetes/issues/33061). The workaround is to manually remove the disk from VM settings before powering it up. -* [FS groups are not supported in 1.4.7](https://github.com/kubernetes/kubernetes/issues/34039) - This issue is fixed in 1.4.8 +* [Unable to execute command on pod container using kubectl exec](https://github.com/kubernetes/kubernetes-anywhere/issues/337) ### Kube-up (Deprecated) @@ -215,7 +215,7 @@ going on (find yourself authorized with your SSH key, or use the password IaaS Provider | Config. Mgmt | OS | Networking | Docs | Conforms | Support Level -------------------- | ------------ | ------ | ---------- | --------------------------------------------- | ---------| ---------------------------- -Vmware vSphere | Kube-anywhere | Photon OS | Flannel | [docs](/docs/getting-started-guides/vsphere) | | Community ([@abrarshivani](https://github.com/abrarshivani)), ([@kerneltime](https://github.com/kerneltime)), ([@BaluDontu](https://github.com/BaluDontu))([@luomiao](https://github.com/luomiao)) +Vmware vSphere | Kube-anywhere | Photon OS | Flannel | [docs](/docs/getting-started-guides/vsphere) | | Community ([@abrarshivani](https://github.com/abrarshivani)), ([@kerneltime](https://github.com/kerneltime)), ([@BaluDontu](https://github.com/BaluDontu)), ([@luomiao](https://github.com/luomiao)), ([@divyenpatel](https://github.com/divyenpatel)) For support level information on all solutions, see the [Table of solutions](/docs/getting-started-guides/#table-of-solutions) chart. diff --git a/docs/resources-reference/v1.5/index.html b/docs/resources-reference/v1.5/index.html index c3902110de..8b5c05ec19 100644 --- a/docs/resources-reference/v1.5/index.html +++ b/docs/resources-reference/v1.5/index.html @@ -1062,7 +1062,7 @@ Appears In Pod PodTemplateSp - + diff --git a/docs/tasks/administer-cluster/dns-horizontal-autoscaling.md b/docs/tasks/administer-cluster/dns-horizontal-autoscaling.md index 069409058a..3d80cc77b2 100644 --- a/docs/tasks/administer-cluster/dns-horizontal-autoscaling.md +++ b/docs/tasks/administer-cluster/dns-horizontal-autoscaling.md @@ -156,7 +156,7 @@ The output is: Verify that the replica count is zero: - kubectl get deployment --namespace-kube-system + kubectl get deployment --namespace=kube-system The output displays 0 in the DESIRED and CURRENT columns: diff --git a/docs/tasks/administer-cluster/limit-storage-consumption.md b/docs/tasks/administer-cluster/limit-storage-consumption.md new file mode 100644 index 0000000000..bde00eb2e7 --- /dev/null +++ b/docs/tasks/administer-cluster/limit-storage-consumption.md @@ -0,0 +1,76 @@ +--- +title: Limiting Storage Consumption +--- + +This example demonstrates an easy way to limit the amount of storage consumed in a namespace. + +The following resources are used in the demonstration: + +* [Resource Quota](/docs/admin/resourcequota/) +* [Limit Range](/docs/admin/limitrange/) +* [Persistent Volume Claim](/docs/user-guide/persistent-volumes/) + +This example assumes you have a functional Kubernetes setup. + +## Limiting Storage Consumption + +The cluster-admin is operating a cluster on behalf of a user population and the admin wants to control +how much storage a single namespace can consume in order to control cost. + +The admin would like to limit: + +1. The number of persistent volume claims in a namespace +2. The amount of storage each claim can request +3. The amount of cumulative storage the namespace can have + + +## LimitRange to limit requests for storage + +Adding a `LimitRange` to a namespace enforces storage request sizes to a minimum and maximum. Storage is requested +via `PersistentVolumeClaim`. The admission controller that enforces limit ranges will reject any PVC that is above or below +the values set by the admin. + +In this example, a PVC requesting 10Gi of storage would be rejected because it exceeds the 2Gi max. + +``` +apiVersion: v1 +kind: LimitRange +metadata: + name: storagelimits +spec: + limits: + - type: PersistentVolumeClaim + max: + storage: 2Gi + min: + storage: 1Gi +``` + +Minimum storage requests are used when the underlying storage provider requires certain minimums. For example, +AWS EBS volumes have a 1Gi minimum requirement. + +## StorageQuota to limit PVC count and cumulative storage capacity + +Admins can limit the number of PVCs in a namespace as well as the cumulative capacity of those PVCs. New PVCs that exceed +either maximum value will be rejected. + +In this example, a 6th PVC in the namespace would be rejected because it exceeds the maximum count of 5. Alternatively, +a 5Gi maximum quota when combined with the 2Gi max limit above, cannot have 3 PVCs where each has 2Gi. That would be 6Gi requested + for a namespace capped at 5Gi. + +``` +apiVersion: v1 +kind: ResourceQuota +metadata: + name: storagequota +spec: + hard: + persistentvolumeclaims: "5" + requests.storage: "5Gi" +``` + +## Summary + +A limit range can put a ceiling on how much storage is requested while a resource quota can effectively cap the storage +consumed by a namespace through claim counts and cumulative storage capacity. The allows a cluster-admin to plan their +cluster's storage budget without risk of any one project going over their allotment. diff --git a/docs/tasks/administer-federation/configmap.md b/docs/tasks/administer-federation/configmap.md new file mode 100644 index 0000000000..b36cf7d8d6 --- /dev/null +++ b/docs/tasks/administer-federation/configmap.md @@ -0,0 +1,87 @@ +--- +title: Federated ConfigMap +--- + +This guide explains how to use ConfigMaps in a Federation control plane. + +* TOC +{:toc} + +## Prerequisites + +This guide assumes that you have a running Kubernetes Cluster +Federation installation. If not, then head over to the +[federation admin guide](/docs/admin/federation/) to learn how to +bring up a cluster federation (or have your cluster administrator do +this for you). +Other tutorials, such as Kelsey Hightower's +[Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation), +might also help you create a Federated Kubernetes cluster. + +You should also have a basic +[working knowledge of Kubernetes](/docs/getting-started-guides/) in +general and [ConfigMaps](/docs/user-guide/configmap/) in particular. + +## Overview + +Federated ConfigMaps are very similar to the traditional [Kubernetes +ConfigMaps](/docs/user-guide/configmap/) and provide the same functionality. +Creating them in the federation control plane ensures that they are synchronized +across all the clusters in federation. + + +## Creating a Federated ConfigMap + +The API for Federated ConfigMap is 100% compatible with the +API for traditional Kubernetes ConfigMap. You can create a ConfigMap by sending +a request to the federation apiserver. + +You can do that using [kubectl](/docs/user-guide/kubectl/) by running: + +``` shell +kubectl --context=federation-cluster create -f myconfigmap.yaml +``` + +The `--context=federation-cluster` flag tells kubectl to submit the +request to the Federation apiserver instead of sending it to a Kubernetes +cluster. + +Once a Federated ConfigMap is created, the federation control plane will create +a matching ConfigMap in all underlying Kubernetes clusters. +You can verify this by checking each of the underlying clusters, for example: + +``` shell +kubectl --context=gce-asia-east1a get configmap myconfigmap +``` + +The above assumes that you have a context named 'gce-asia-east1a' +configured in your client for your cluster in that zone. + +These ConfigMaps in underlying clusters will match the Federated ConfigMap. + + +## Updating a Federated ConfigMap + +You can update a Federated ConfigMap as you would update a Kubernetes +ConfigMap; however, for a Federated ConfigMap, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. +The federation control plane ensures that whenever the Federated ConfigMap is +updated, it updates the corresponding ConfigMaps in all underlying clusters to +match it. + +## Deleting a Federated ConfigMap + +You can delete a Federated ConfigMap as you would delete a Kubernetes +ConfigMap; however, for a Federated ConfigMap, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. + +For example, you can do that using kubectl by running: + +```shell +kubectl --context=federation-cluster delete configmap +``` + +Note that at this point, deleting a Federated ConfigMap will not delete the +corresponding ConfigMaps from underlying clusters. +You must delete the underlying ConfigMaps manually. +We intend to fix this in the future. diff --git a/docs/tasks/administer-federation/daemonset.md b/docs/tasks/administer-federation/daemonset.md new file mode 100644 index 0000000000..a6f1d92e42 --- /dev/null +++ b/docs/tasks/administer-federation/daemonset.md @@ -0,0 +1,83 @@ +--- +title: Federated DaemonSet +--- + +This guide explains how to use DaemonSets in a federation control plane. + +* TOC +{:toc} + +## Prerequisites + +This guide assumes that you have a running Kubernetes Cluster +Federation installation. If not, then head over to the +[federation admin guide](/docs/admin/federation/) to learn how to +bring up a cluster federation (or have your cluster administrator do +this for you). +Other tutorials, such as Kelsey Hightower's +[Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation), +might also help you create a Federated Kubernetes cluster. + +You should also have a basic +[working knowledge of Kubernetes](/docs/getting-started-guides/) in +general and DaemonSets in particular. + +## Overview + +DaemonSets in federation control plane ("Federated Daemonsets" in +this guide) are very similar to the traditional Kubernetes +DaemonSets and provide the same functionality. +Creating them in the federation control plane ensures that they are synchronized +across all the clusters in federation. + + +## Creating a Federated Daemonset + +The API for Federated Daemonset is 100% compatible with the +API for traditional Kubernetes DaemonSet. You can create a DaemonSet by sending +a request to the federation apiserver. + +You can do that using [kubectl](/docs/user-guide/kubectl/) by running: + +``` shell +kubectl --context=federation-cluster create -f mydaemonset.yaml +``` + +The `--context=federation-cluster` flag tells kubectl to submit the +request to the Federation apiserver instead of sending it to a Kubernetes +cluster. + +Once a Federated Daemonset is created, the federation control plane will create +a matching DaemonSet in all underlying Kubernetes clusters. +You can verify this by checking each of the underlying clusters, for example: + +``` shell +kubectl --context=gce-asia-east1a get daemonset mydaemonset +``` + +The above assumes that you have a context named 'gce-asia-east1a' +configured in your client for your cluster in that zone. + +These DaemonSets in underlying clusters will match the Federated Daemonset. + + +## Updating a Federated Daemonset + +You can update a Federated Daemonset as you would update a Kubernetes +DaemonSet; however, for a Federated Daemonset, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. +The federation control plane ensures that whenever the Federated Daemonset is +updated, it updates the corresponding DaemonSets in all underlying clusters to +match it. + +## Deleting a Federated Daemonset + +You can delete a Federated Daemonset as you would delete a Kubernetes +DaemonSet; however, for a Federated Daemonset, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. + +For example, you can do that using kubectl by running: + +```shell +kubectl --context=federation-cluster delete daemonset mydaemonset +``` diff --git a/docs/tasks/administer-federation/deployment.md b/docs/tasks/administer-federation/deployment.md new file mode 100644 index 0000000000..51b092971d --- /dev/null +++ b/docs/tasks/administer-federation/deployment.md @@ -0,0 +1,108 @@ +--- +title: Federated Deployment +--- + +This guide explains how to use Deployments in the Federation control plane. + +* TOC +{:toc} + +## Prerequisites + +This guide assumes that you have a running Kubernetes Cluster +Federation installation. If not, then head over to the +[federation admin guide](/docs/admin/federation/) to learn how to +bring up a cluster federation (or have your cluster administrator do +this for you). +Other tutorials, such as Kelsey Hightower's +[Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation), +might also help you create a Federated Kubernetes cluster. + +You should also have a basic +[working knowledge of Kubernetes](/docs/getting-started-guides/) in +general and [Deployment](/docs/user-guide/deployments) in particular. + +## Overview + +Deployments in federation control plane (referred to as "Federated Deployments" in +this guide) are very similar to the traditional [Kubernetes +Deployment](/docs/user-guide/deployments/), and provide the same functionality. +Creating them in the federation control plane ensures that the desired number of +replicas exist across the registered clusters. + +**As of Kubernetes version 1.5, Federated Deployment is an Alpha feature. The core +functionality of Deployment is present, but some features +(such as full rollout compatibility) are still in development.** + +## Creating a Federated Deployment + +The API for Federated Deployment is compatible with the +API for traditional Kubernetes Deployment. You can create a Deployment by sending +a request to the federation apiserver. + +You can do that using [kubectl](/docs/user-guide/kubectl/) by running: + +``` shell +kubectl --context=federation-cluster create -f mydeployment.yaml +``` + +The '--context=federation-cluster' flag tells kubectl to submit the +request to the Federation apiserver instead of sending it to a Kubernetes +cluster. + +Once a Federated Deployment is created, the federation control plane will create +a Deployment in all underlying Kubernetes clusters. +You can verify this by checking each of the underlying clusters, for example: + +``` shell +kubectl --context=gce-asia-east1a get deployment mydep +``` + +The above assumes that you have a context named 'gce-asia-east1a' +configured in your client for your cluster in that zone. + +These Deployments in underlying clusters will match the federation Deployment +_except_ in the number of replicas and revision-related annotations. +Federation control plane ensures that the +sum of replicas in each cluster combined matches the desired number of replicas in the +Federated Deployment. + +### Spreading Replicas in Underlying Clusters + +By default, replicas are spread equally in all the underlying clusters. For ex: +if you have 3 registered clusters and you create a Federated Deployment with +`spec.replicas = 9`, then each Deployment in the 3 clusters will have +`spec.replicas=3`. +To modify the number of replicas in each cluster, you can specify +[FederatedReplicaSetPreference](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/federation/apis/federation/types.go) +as an annotation with key `federation.kubernetes.io/deployment-preferences` +on Federated Deployment. + + +## Updating a Federated Deployment + +You can update a Federated Deployment as you would update a Kubernetes +Deployment; however, for a Federated Deployment, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. +The federation control plane ensures that whenever the Federated Deployment is +updated, it updates the corresponding Deployments in all underlying clusters to +match it. So if the rolling update strategy was chosen then the underlying +cluster will do the rolling update independently and `maxSurge` and `maxUnavailable` +will apply only to individual clusters. This behavior may change in the future. + +If your update includes a change in number of replicas, the federation +control plane will change the number of replicas in underlying clusters to +ensure that their sum remains equal to the number of desired replicas in +Federated Deployment. + +## Deleting a Federated Deployment + +You can delete a Federated Deployment as you would delete a Kubernetes +Deployment; however, for a Federated Deployment, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. + +For example, you can do that using kubectl by running: + +```shell +kubectl --context=federation-cluster delete deployment mydep +``` diff --git a/docs/tasks/administer-federation/events.md b/docs/tasks/administer-federation/events.md new file mode 100644 index 0000000000..1d9f72ea0e --- /dev/null +++ b/docs/tasks/administer-federation/events.md @@ -0,0 +1,40 @@ +--- +title: Federated Events +--- + +This guide explains how to use events in federation control plane to help in debugging. + + +* TOC +{:toc} + +## Prerequisites + +This guide assumes that you have a running Kubernetes Cluster +Federation installation. If not, then head over to the +[federation admin guide](/docs/admin/federation/) to learn how to +bring up a cluster federation (or have your cluster administrator do +this for you). Other tutorials, for example +[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) +by Kelsey Hightower, are also available to help you. + +You are also expected to have a basic +[working knowledge of Kubernetes](/docs/getting-started-guides/) in +general. + +## Overview + +Events in federation control plane (referred to as "federation events" in +this guide) are very similar to the traditional Kubernetes +Events providing the same functionality. +Federation Events are stored only in federation control plane and are not passed on to the underlying Kubernetes clusters. + +Federation controllers create events as they process API resources to surface to the +user, the state that they are in. +You can get all events from federation apiserver by running: + +```shell +kubectl --context=federation-cluster get events +``` + +The standard kubectl get, update, delete commands will all work. diff --git a/docs/tasks/administer-federation/ingress.md b/docs/tasks/administer-federation/ingress.md new file mode 100644 index 0000000000..410f49d541 --- /dev/null +++ b/docs/tasks/administer-federation/ingress.md @@ -0,0 +1,355 @@ +--- +title: Federated Ingress +--- + +This guide explains how to use Kubernetes Federated Ingress to deploy +a common HTTP(S) virtual IP load balancer across a federated service running in +multiple Kubernetes clusters. As of v1.4, clusters hosted in Google +Cloud (both GKE and GCE, or both) are supported. This makes it +easy to deploy a service that reliably serves HTTP(S) traffic +originating from web clients around the globe on a single, static IP +address. Low +network latency, high fault tolerance and easy administration are +ensured through intelligent request routing and automatic replica +relocation (using [Federated ReplicaSets](/docs/tasks/administer-federation/replicaset/). +Clients are automatically routed, via the shortest network path, to +the cluster closest to them with available capacity (despite the fact +that all clients use exactly the same static IP address). The load balancer +automatically checks the health of the pods comprising the service, +and avoids sending requests to unresponsive or slow pods (or entire +unresponsive clusters). + +Federated Ingress is released as an alpha feature, and supports Google Cloud Platform (GKE, +GCE and hybrid scenarios involving both) in Kubernetes v1.4. Work is under way to support other cloud +providers such as AWS, and other hybrid cloud scenarios (e.g. services +spanning private on-premise as well as public cloud Kubernetes +clusters). We welcome your feedback. + +* TOC +{:toc} + +## Prerequisites + +This guide assumes that you have a running Kubernetes Cluster +Federation installation. If not, then head over to the +[federation admin guide](/docs/admin/federation/) to learn how to +bring up a cluster federation (or have your cluster administrator do +this for you). Other tutorials, for example +[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) +by Kelsey Hightower, are also available to help you. + +You are also expected to have a basic +[working knowledge of Kubernetes](/docs/getting-started-guides/) in +general, and [Ingress](/docs/user-guide/ingress/) in particular. + +## Overview + +Federated Ingresses are created in much that same way as traditional +[Kubernetes Ingresses](/docs/user-guide/ingress/): by making an API +call which specifies the desired properties of your logical ingress point. In the +case of Federated Ingress, this API call is directed to the +Federation API endpoint, rather than a Kubernetes cluster API +endpoint. The API for Federated Ingress is 100% compatible with the +API for traditional Kubernetes Services. + +Once created, the Federated Ingress automatically: + +1. creates matching Kubernetes Ingress objects in every cluster +underlying your Cluster Federation, +2. ensures that all of these in-cluster ingress objects share the same + logical global L7 (i.e. HTTP(S)) load balancer and IP address. +3. monitors the health and capacity of the service "shards" (i.e. your + pods) behind this ingress in each cluster +4. ensures that all client connections are routed to an appropriate +healthy backend service endpoint at all times, even in the event of +pod, cluster, +availability zone or regional outages. + +Note that in the case of Google Cloud, the logical L7 load balancer is +not a single physical device (which would present both a single point +of failure, and a single global network routing choke point), but +rather a +[truly global, highly available load balancing managed service](https://cloud.google.com/load-balancing/), +globally reachable via a single, static IP address. + +Clients inside your federated Kubernetes clusters (i.e. Pods) will be +automatically routed to the cluster-local shard of the Federated Service +backing the Ingress in their +cluster if it exists and is healthy, or the closest healthy shard in a +different cluster if it does not. Note that this involves a network +trip to the HTTP(s) load balancer, which resides outside your local +Kubernetes cluster but inside the same GCP region. + +## Creating a federated ingress + +You can create a federated ingress in any of the usual ways, for example using kubectl: + +``` shell +kubectl --context=federation-cluster create -f myingress.yaml +``` +For example ingress YAML configurations, see the [Ingress User Guide](/docs/user-guide/ingress/) +The '--context=federation-cluster' flag tells kubectl to submit the +request to the Federation API endpoint, with the appropriate +credentials. If you have not yet configured such a context, visit the +[federation admin guide](/docs/admin/federation/) or one of the +[administration tutorials](https://github.com/kelseyhightower/kubernetes-cluster-federation) +to find out how to do so. + +As described above, the Federated Ingress will automatically create +and maintain matching Kubernetes ingresses in all of the clusters +underlying your federation. These cluster-specific ingresses (and +their associated ingress controllers) configure and manage the load +balancing and health checking infrastructure that ensures that traffic +is load balanced to each cluster appropriately. + +You can verify this by checking in each of the underlying clusters, for example: + +``` shell +kubectl --context=gce-asia-east1a get ingress myingress +NAME HOSTS ADDRESS PORTS AGE +myingress * 130.211.5.194 80, 443 1m +``` + +The above assumes that you have a context named 'gce-asia-east1a' +configured in your client for your cluster in that zone. The name and +namespace of the underlying ingress will automatically match those of +the Federated Ingress that you created above (and if you happen to +have had ingresses of the same name and namespace already existing in +any of those clusters, they will be automatically adopted by the +Federation and updated to conform with the specification of your +Federated Ingress - either way, the end result will be the same). + +The status of your Federated Ingress will automatically reflect the +real-time status of the underlying Kubernetes ingresses, for example: + +``` shell +$kubectl --context=federation-cluster describe ingress myingress + +Name: myingress +Namespace: default +Address: 130.211.5.194 +TLS: + tls-secret terminates +Rules: + Host Path Backends + ---- ---- -------- + * * echoheaders-https:80 (10.152.1.3:8080,10.152.2.4:8080) +Annotations: + https-target-proxy: k8s-tps-default-myingress--ff1107f83ed600c0 + target-proxy: k8s-tp-default-myingress--ff1107f83ed600c0 + url-map: k8s-um-default-myingress--ff1107f83ed600c0 + backends: {"k8s-be-30301--ff1107f83ed600c0":"Unknown"} + forwarding-rule: k8s-fw-default-myingress--ff1107f83ed600c0 + https-forwarding-rule: k8s-fws-default-myingress--ff1107f83ed600c0 +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 3m 3m 1 {loadbalancer-controller } Normal ADD default/myingress + 2m 2m 1 {loadbalancer-controller } Normal CREATE ip: 130.211.5.194 +``` + +Note that: + +1. the address of your Federated Ingress +corresponds with the address of all of the +underlying Kubernetes ingresses (once these have been allocated - this +may take up to a few minutes). +2. we have not yet provisioned any backend Pods to receive +the network traffic directed to this ingress (i.e. 'Service +Endpoints' behind the service backing the Ingress), so the Federated Ingress does not yet consider these to +be healthy shards and will not direct traffic to any of these clusters. +3. the federation control system will +automatically reconfigure the load balancer controllers in all of the +clusters in your federation to make them consistent, and allow +them to share global load balancers. But this reconfiguration can +only complete successfully if there are no pre-existing Ingresses in +those clusters (this is a safety feature to prevent accidental +breakage of existing ingresses). So to ensure that your federated +ingresses function correctly, either start with new, empty clusters, or make +sure that you delete (and recreate if necessary) all pre-existing +Ingresses in the clusters comprising your federation. + +#Adding backend services and pods + +To render the underlying ingress shards healthy, we need to add +backend Pods behind the service upon which the Ingress is based. There are several ways to achieve this, but +the easiest is to create a Federated Service and +Federated Replicaset. Details of how those +work are covered in the aforementioned user guides - here we'll simply use them, to +create appropriately labelled pods and services in the 13 underlying clusters of +our federation: + +``` shell +kubectl --context=federation-cluster create -f services/nginx.yaml +``` + +``` shell + kubectl --context=federation-cluster create -f myreplicaset.yaml +``` + +Note that in order for your federated ingress to work correctly on +Google Cloud, the node ports of all of the underlying cluster-local +services need to be identical. If you're using a federated service +this is easy to do. Simply pick a node port that is not already +being used in any of your clusters, and add that to the spec of your +federated service. If you do not specify a node port for your +federated service, each cluster will choose it's own node port for +its cluster-local shard of the service, and these will probably end +up being different, which is not what you want. + +You can verify this by checking in each of the underlying clusters, for example: + +``` shell +kubectl --context=gce-asia-east1a get services nginx +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +nginx 10.63.250.98 104.199.136.89 80/TCP 9m +``` + + +## Hybrid cloud capabilities + +Federations of Kubernetes Clusters can include clusters running in +different cloud providers (e.g. Google Cloud, AWS), and on-premises +(e.g. on OpenStack). However, in Kubernetes v1.4, Federated Ingress is only +supported across Google Cloud clusters. In future versions we intend +to support hybrid cloud Ingress-based deployments. + +## Discovering a federated ingress + +Ingress objects (in both plain Kubernets clusters, and in federations +of clusters) expose one or more IP addresses (via +the Status.Loadbalancer.Ingress field) that remains static for the lifetime +of the Ingress object (in future, automatically managed DNS names +might also be added). All clients (whether internal to your cluster, +or on the external network or internet) should connect to one of these IP +or DNS addresses. As mentioned above, all client requests are automatically +routed, via the shortest network path, to a healthy pod in the +closest cluster to the origin of the request. So for example, HTTP(S) +requests from internet +users in Europe will be routed directly to the closest cluster in +Europe that has available capacity. If there are no such clusters in +Europe, the request will be routed to the next closest cluster +(typically in the U.S.). + +## Handling failures of backend pods and whole clusters + +Ingresses are backed by Services, which are typically (but not always) +backed by one or more ReplicaSets. For Federated Ingresses, it is +common practise to use the federated variants of Services and +ReplicaSets for this purpose, as +described above. + +In particular, Federated ReplicaSets ensure that the desired number of +pods are kept running in each cluster, even in the event of node +failures. In the event of entire cluster or availability zone +failures, Federated ReplicaSets automatically place additional +replacas in the other available clusters in the federation to accommodate the +traffic which was previously being served by the now unavailable +cluster. While the Federated ReplicaSet ensures that sufficient replicas are +kept running, the Federated Ingress ensures that user traffic is +automatically redirected away from the failed cluster to other +available clusters. + +## Known issue + +GCE L7 load balancer back-ends and health checks are known to "flap"; this is due +to conflicting firewall rules in the federation's underlying clusters, which might override one another. To work around this problem, you can +install the firewall rules manually to expose the targets of all the +underlying clusters in your federation for each Federated Ingress +object. This way, the health checks can consistently pass and the GCE L7 load balancer +can remain stable. You install the rules using the +[`gcloud`](https://cloud.google.com/sdk/gcloud/) command line tool, +[Google Cloud Console](https://console.cloud.google.com) or the +[Google Compute Engine APIs](https://cloud.google.com/compute/docs/reference/latest/). + +You can install these rules using +[`gcloud`](https://cloud.google.com/sdk/gcloud/) as follows: + +```shell +gcloud compute firewall-rules create \ + --source-ranges 130.211.0.0/22 --allow [] \ + --target-tags [] \ + --network +``` + +where: + +1. `firewall-rule-name` can be any name. +2. `[]` is the comma separated list of node ports corresponding to the services that back the Federated Ingress. +3. [] is the comma separated list of the target tags assigned to the nodes in a Kubernetes cluster. +4. is the name of the network where the firewall rule must be installed. + +Example: +```shell +gcloud compute firewall-rules create my-federated-ingress-firewall-rule \ + --source-ranges 130.211.0.0/22 --allow tcp:30301, tcp:30061, tcp:34564 \ + --target-tags my-cluster-1-minion, my-cluster-2-minion \ + --network default +``` + + +## Troubleshooting + +#### I cannot connect to my cluster federation API +Check that your + +1. Client (typically kubectl) is correctly configured (including API endpoints and login credentials), and +2. Cluster Federation API server is running and network-reachable. + +See the [federation admin guide](/docs/admin/federation/) to learn +how to bring up a cluster federation correctly (or have your cluster administrator do this for you), and how to correctly configure your client. + +#### I can create a federated ingress/service/replicaset successfully against the cluster federation API, but no matching ingresses/services/replicasets are created in my underlying clusters + +Check that: + +1. Your clusters are correctly registered in the Cluster Federation API (`kubectl describe clusters`) +2. Your clusters are all 'Active'. This means that the cluster + Federation system was able to connect and authenticate against the + clusters' endpoints. If not, consult the event logs of the federation-controller-manager pod to ascertain what the failure might be. (`kubectl --namespace=federation logs $(kubectl get pods --namespace=federation -l module=federation-controller-manager -oname`) +3. That the login credentials provided to the Cluster Federation API + for the clusters have the correct authorization and quota to create + ingresses/services/replicasets in the relevant namespace in the + clusters. Again you should see associated error messages providing + more detail in the above event log file if this is not the case. +4. Whether any other error is preventing the service creation + operation from succeeding (look for `ingress-controller`, + `service-controller` or `replicaset-controller`, + errors in the output of `kubectl logs federation-controller-manager --namespace federation`). + +#### I can create a federated ingress successfully, but request load is not correctly distributed across the underlying clusters + +Check that: + +1. the services underlying your federated ingress in each cluster have + identical node ports. See [above](#creating_a_federated_ingress) for further explanation. +2. the load balancer controllers in each of your clusters are of the + correct type ("GLBC") and have been correctly reconfigured by the + federation control plane to share a global GCE load balancer (this + should happen automatically). If they of the correct type, and + have been correctly reconfigured, the UID data item in the GLBC + configmap in each cluster will be identical across all clusters. + See + [the GLBC docs](https://github.com/kubernetes/ingress/blob/7dcb4ae17d5def23d3e9c878f3146ac6df61b09d/controllers/gce/README.md) + for further details. + If this is not the case, check the logs of your federation + controller manager to determine why this automated reconfiguration + might be failing. +3. no ingresses have been manually created in any of your clusters before the above + reconfiguration of the load balancer controller completed + successfully. Ingresses created before the reconfiguration of + your GLBC will interfere with the behavior of your federated + ingresses created after the reconfiguration (see + [the GLBC docs](https://github.com/kubernetes/ingress/blob/7dcb4ae17d5def23d3e9c878f3146ac6df61b09d/controllers/gce/README.md) + for further information. To remedy this, + delete any ingresses created before the cluster joined the + federation (and had it's GLBC reconfigured), and recreate them if + necessary. + +#### This troubleshooting guide did not help me solve my problem + +Please use one of our [support channels](http://kubernetes.io/docs/troubleshooting/) to seek assistance. + +## For more information + + * [Federation proposal](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/proposals/federation.md) details use cases that motivated this work. diff --git a/docs/tasks/administer-federation/namespaces.md b/docs/tasks/administer-federation/namespaces.md new file mode 100644 index 0000000000..5ed3ffafec --- /dev/null +++ b/docs/tasks/administer-federation/namespaces.md @@ -0,0 +1,90 @@ +--- +title: Federated Namespaces +--- + +This guide explains how to use namespaces in Federation control plane. + +* TOC +{:toc} + +## Prerequisites + +This guide assumes that you have a running Kubernetes Cluster +Federation installation. If not, then head over to the +[federation admin guide](/docs/admin/federation/) to learn how to +bring up a cluster federation (or have your cluster administrator do +this for you). Other tutorials, for example +[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) +by Kelsey Hightower, are also available to help you. + +You are also expected to have a basic +[working knowledge of Kubernetes](/docs/getting-started-guides/) in +general and [Namespaces](/docs/user-guide/namespaces/) in particular. + +## Overview + +Namespaces in federation control plane (referred to as "federated namespaces" in +this guide) are very similar to the traditional [Kubernetes +Namespaces](/docs/user-guide/namespaces/) providing the same functionality. +Creating them in the federation control plane ensures that they are synchronized +across all the clusters in federation. + + +## Creating a Federated Namespace + +The API for Federated Namespaces is 100% compatible with the +API for traditional Kubernetes Namespaces. You can create a namespace by sending +a request to the federation apiserver. + +You can do that using kubectl by running: + +``` shell +kubectl --context=federation-cluster create -f myns.yaml +``` + +The '--context=federation-cluster' flag tells kubectl to submit the +request to the Federation apiserver instead of sending it to a Kubernetes +cluster. + +Once a federated namespace is created, the federation control plane will create +a matching namespace in all underlying Kubernetes clusters. +You can verify this by checking each of the underlying clusters, for example: + +``` shell +kubectl --context=gce-asia-east1a get namespaces myns +``` + +The above assumes that you have a context named 'gce-asia-east1a' +configured in your client for your cluster in that zone. The name and +spec of the underlying namespace will match those of +the Federated Namespace that you created above. + + +## Updating a Federated Namespace + +You can update a federated namespace as you would update a Kubernetes +namespace, just send the request to federation apiserver instead of sending it +to a specific Kubernetes cluster. +Federation control plan will ensure that whenever the federated namespace is +updated, it updates the corresponding namespaces in all underlying clusters to +match it. + +## Deleting a Federated Namespace + +You can delete a federated namespace as you would delete a Kubernetes +namespace, just send the request to federation apiserver instead of sending it +to a specific Kubernetes cluster. + +For example, you can do that using kubectl by running: + +```shell +kubectl --context=federation-cluster delete ns myns +``` + +As in Kubernetes, deleting a federated namespace will delete all resources in that +namespace from the federation control plane. + +Note that at this point, deleting a federated namespace will not delete the +corresponding namespaces and resources in those namespaces from underlying clusters. +Users are expected to delete them manually. +We intend to fix this in the future. diff --git a/docs/tasks/administer-federation/replicaset.md b/docs/tasks/administer-federation/replicaset.md new file mode 100644 index 0000000000..c173a38996 --- /dev/null +++ b/docs/tasks/administer-federation/replicaset.md @@ -0,0 +1,105 @@ +--- +title: Federated ReplicaSets +--- + +This guide explains how to use replica sets in the Federation control plane. + +* TOC +{:toc} + +## Prerequisites + +This guide assumes that you have a running Kubernetes Cluster +Federation installation. If not, then head over to the +[federation admin guide](/docs/admin/federation/) to learn how to +bring up a cluster federation (or have your cluster administrator do +this for you). Other tutorials, for example +[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) +by Kelsey Hightower, are also available to help you. + +You are also expected to have a basic +[working knowledge of Kubernetes](/docs/getting-started-guides/) in +general and [ReplicaSets](/docs/user-guide/replicasets/) in particular. + +## Overview + +Replica Sets in federation control plane (referred to as "federated replica sets" in +this guide) are very similar to the traditional [Kubernetes +ReplicaSets](/docs/user-guide/replicasets/), and provide the same functionality. +Creating them in the federation control plane ensures that the desired number of +replicas exist across the registered clusters. + + +## Creating a Federated Replica Set + +The API for Federated Replica Set is 100% compatible with the +API for traditional Kubernetes Replica Set. You can create a replica set by sending +a request to the federation apiserver. + +You can do that using [kubectl](/docs/user-guide/kubectl/) by running: + +``` shell +kubectl --context=federation-cluster create -f myrs.yaml +``` + +The '--context=federation-cluster' flag tells kubectl to submit the +request to the Federation apiserver instead of sending it to a Kubernetes +cluster. + +Once a federated replica set is created, the federation control plane will create +a replica set in all underlying Kubernetes clusters. +You can verify this by checking each of the underlying clusters, for example: + +``` shell +kubectl --context=gce-asia-east1a get rs myrs +``` + +The above assumes that you have a context named 'gce-asia-east1a' +configured in your client for your cluster in that zone. + +These replica sets in underlying clusters will match the federation replica set +except in the number of replicas. Federation control plane will ensure that the +sum of replicas in each cluster match the desired number of replicas in the +federation replica set. + +### Spreading Replicas in Underlying Clusters + +By default, replicas are spread equally in all the underlying clusters. For ex: +if you have 3 registered clusters and you create a federated replica set with +`spec.replicas = 9`, then each replica set in the 3 clusters will have +`spec.replicas=3`. +To modify the number of replicas in each cluster, you can specify +[FederatedReplicaSetPreference](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/federation/apis/federation/types.go) +as an annotation with key `federation.kubernetes.io/replica-set-preferences` +on federated replica set. + + +## Updating a Federated Replica Set + +You can update a federated replica set as you would update a Kubernetes +replica set; however, for a federated replica set, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. +The Federation control plan ensures that whenever the federated replica set is +updated, it updates the corresponding replica sets in all underlying clusters to +match it. +If your update includes a change in number of replicas, the federation +control plane will change the number of replicas in underlying clusters to +ensure that their sum remains equal to the number of desired replicas in +federated replica set. + +## Deleting a Federated Replica Set + +You can delete a federated replica set as you would delete a Kubernetes +replica set; however, for a federated replica set, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. + +For example, you can do that using kubectl by running: + +```shell +kubectl --context=federation-cluster delete rs myrs +``` + +Note that at this point, deleting a federated replica set will not delete the +corresponding replica sets from underlying clusters. +You must delete the underlying Replica Sets manually. +We intend to fix this in the future. diff --git a/docs/tasks/administer-federation/secret.md b/docs/tasks/administer-federation/secret.md new file mode 100644 index 0000000000..2c5eac6dba --- /dev/null +++ b/docs/tasks/administer-federation/secret.md @@ -0,0 +1,87 @@ +--- +title: Federated Secrets +--- + +This guide explains how to use secrets in Federation control plane. + +* TOC +{:toc} + +## Prerequisites + +This guide assumes that you have a running Kubernetes Cluster +Federation installation. If not, then head over to the +[federation admin guide](/docs/admin/federation/) to learn how to +bring up a cluster federation (or have your cluster administrator do +this for you). Other tutorials, for example +[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) +by Kelsey Hightower, are also available to help you. + +You are also expected to have a basic +[working knowledge of Kubernetes](/docs/getting-started-guides/) in +general and [Secrets](/docs/user-guide/secrets/) in particular. + +## Overview + +Secrets in federation control plane (referred to as "federated secrets" in +this guide) are very similar to the traditional [Kubernetes +Secrets](/docs/user-guide/secrets/) providing the same functionality. +Creating them in the federation control plane ensures that they are synchronized +across all the clusters in federation. + + +## Creating a Federated Secret + +The API for Federated Secret is 100% compatible with the +API for traditional Kubernetes Secret. You can create a secret by sending +a request to the federation apiserver. + +You can do that using [kubectl](/docs/user-guide/kubectl/) by running: + +``` shell +kubectl --context=federation-cluster create -f mysecret.yaml +``` + +The '--context=federation-cluster' flag tells kubectl to submit the +request to the Federation apiserver instead of sending it to a Kubernetes +cluster. + +Once a federated secret is created, the federation control plane will create +a matching secret in all underlying Kubernetes clusters. +You can verify this by checking each of the underlying clusters, for example: + +``` shell +kubectl --context=gce-asia-east1a get secret mysecret +``` + +The above assumes that you have a context named 'gce-asia-east1a' +configured in your client for your cluster in that zone. + +These secrets in underlying clusters will match the federated secret. + + +## Updating a Federated Secret + +You can update a federated secret as you would update a Kubernetes +secret; however, for a federated secret, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. +The Federation control plan ensures that whenever the federated secret is +updated, it updates the corresponding secrets in all underlying clusters to +match it. + +## Deleting a Federated Secret + +You can delete a federated secret as you would delete a Kubernetes +secret; however, for a federated secret, you must send the request to +the federation apiserver instead of sending it to a specific Kubernetes cluster. + +For example, you can do that using kubectl by running: + +```shell +kubectl --context=federation-cluster delete secret mysecret +``` + +Note that at this point, deleting a federated secret will not delete the +corresponding secrets from underlying clusters. +You must delete the underlying secrets manually. +We intend to fix this in the future. diff --git a/docs/tasks/configure-pod-container/apply-resource-quota-limit.md b/docs/tasks/configure-pod-container/apply-resource-quota-limit.md new file mode 100644 index 0000000000..1120e7550d --- /dev/null +++ b/docs/tasks/configure-pod-container/apply-resource-quota-limit.md @@ -0,0 +1,366 @@ +--- +assignees: +- derekwaynecarr +- janetkuo +title: Applying Resource Quotas and Limits +--- + +This example demonstrates a typical setup to control for resource usage in a namespace. + +It demonstrates using the following resources: + +* [Namespace](/docs/admin/namespaces) +* [Resource Quota](/docs/admin/resourcequota/) +* [Limit Range](/docs/admin/limitrange/) + +This example assumes you have a functional Kubernetes setup. + +## Scenario + +The cluster-admin is operating a cluster on behalf of a user population and the cluster-admin +wants to control the amount of resources that can be consumed in a particular namespace to promote +fair sharing of the cluster and control cost. + +The cluster-admin has the following goals: + +* Limit the amount of compute resource for running pods +* Limit the number of persistent volume claims to control access to storage +* Limit the number of load balancers to control cost +* Prevent the use of node ports to preserve scarce resources +* Provide default compute resource requests to enable better scheduling decisions + +## 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 STATUS AGE +default Active 2m +kube-system Active 2m +quota-example Active 39s +``` + +## Step 2: Apply an object-count quota to the namespace + +The cluster-admin wants to control the following resources: + +* persistent volume claims +* load balancers +* node ports + +Let's create a simple quota that controls object counts for those resource types in this namespace. + +```shell +$ kubectl create -f docs/admin/resourcequota/object-counts.yaml --namespace=quota-example +resourcequota "object-counts" created +``` + +The quota system will observe that a quota has been created, and will calculate consumption +in the namespace in response. This should happen quickly. + +Let's describe the quota to see what is currently being consumed in this namespace: + +```shell +$ kubectl describe quota object-counts --namespace=quota-example +Name: object-counts +Namespace: quota-example +Resource Used Hard +-------- ---- ---- +persistentvolumeclaims 0 2 +services.loadbalancers 0 2 +services.nodeports 0 0 +``` + +The quota system will now prevent users from creating more than the specified amount for each resource. + + +## Step 3: Apply a compute-resource quota to the namespace + +To limit the amount of compute resource that can be consumed in this namespace, +let's create a quota that tracks compute resources. + +```shell +$ kubectl create -f docs/admin/resourcequota/compute-resources.yaml --namespace=quota-example +resourcequota "compute-resources" created +``` + +Let's describe the quota to see what is currently being consumed in this namespace: + +```shell +$ kubectl describe quota compute-resources --namespace=quota-example +Name: compute-resources +Namespace: quota-example +Resource Used Hard +-------- ---- ---- +limits.cpu 0 2 +limits.memory 0 2Gi +pods 0 4 +requests.cpu 0 1 +requests.memory 0 1Gi +``` + +The quota system will now prevent the namespace from having more than 4 non-terminal pods. In +addition, it will enforce that each container in a pod makes a `request` and defines a `limit` for +`cpu` and `memory`. + +## Step 4: 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 +``` + +Now let's look at the pods that were created. + +```shell +$ kubectl get pods --namespace=quota-example +``` + +What happened? I have no pods! Let's describe the deployment to get a view of what is happening. + +```shell +$ kubectl describe deployment nginx --namespace=quota-example +Name: nginx +Namespace: quota-example +CreationTimestamp: Mon, 06 Jun 2016 16:11:37 -0400 +Labels: run=nginx +Selector: run=nginx +Replicas: 0 updated | 1 total | 0 available | 1 unavailable +StrategyType: RollingUpdate +MinReadySeconds: 0 +RollingUpdateStrategy: 1 max unavailable, 1 max surge +OldReplicaSets: +NewReplicaSet: nginx-3137573019 (0/1 replicas created) +... +``` + +A deployment created a corresponding replica set and attempted to size it to create a single pod. + +Let's look at the replica set to get more detail. + +```shell +$ kubectl describe rs nginx-3137573019 --namespace=quota-example +Name: nginx-3137573019 +Namespace: quota-example +Image(s): nginx +Selector: pod-template-hash=3137573019,run=nginx +Labels: pod-template-hash=3137573019 + 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 + --------- -------- ----- ---- ------------- -------- ------ ------- + 4m 7s 11 {replicaset-controller } Warning FailedCreate Error creating: pods "nginx-3137573019-" is forbidden: Failed quota: compute-resources: must specify limits.cpu,limits.memory,requests.cpu,requests.memory +``` + +The Kubernetes API server is rejecting the replica set requests to create a pod because our pods +do not specify `requests` or `limits` for `cpu` and `memory`. + +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 memory - - 256Mi 512Mi - +Container cpu - - 100m 200m - +``` + +If the Kubernetes API server observes a request to create a pod in this namespace, and the containers +in that pod do not make any compute resource requests, a default request and default limit will be applied +as part of admission control. + +In this example, each pod created will have compute resources equivalent to the following: + +```shell +$ kubectl run nginx \ + --image=nginx \ + --replicas=1 \ + --requests=cpu=100m,memory=256Mi \ + --limits=cpu=200m,memory=512Mi \ + --namespace=quota-example +``` + +Now that we have applied default compute resources for our namespace, our replica set should be able to create +its pods. + +```shell +$ kubectl get pods --namespace=quota-example +NAME READY STATUS RESTARTS AGE +nginx-3137573019-fvrig 1/1 Running 0 6m +``` + +And if we print out our quota usage in the namespace: + +```shell +$ kubectl describe quota --namespace=quota-example +Name: compute-resources +Namespace: quota-example +Resource Used Hard +-------- ---- ---- +limits.cpu 200m 2 +limits.memory 512Mi 2Gi +pods 1 4 +requests.cpu 100m 1 +requests.memory 256Mi 1Gi + + +Name: object-counts +Namespace: quota-example +Resource Used Hard +-------- ---- ---- +persistentvolumeclaims 0 2 +services.loadbalancers 0 2 +services.nodeports 0 0 +``` + +As you can see, the pod that was created is consuming explicit amounts of compute resources, and the usage is being +tracked by Kubernetes properly. + +## Step 5: Advanced quota scopes + +Let's imagine you did not want to specify default compute resource consumption in your namespace. + +Instead, you want to let users run a specific number of `BestEffort` pods in their namespace to take +advantage of slack compute resources, and then require that users make an explicit resource request for +pods that require a higher quality of service. + +Let's create a new namespace with two quotas to demonstrate this behavior: + +```shell +$ kubectl create namespace quota-scopes +namespace "quota-scopes" created +$ kubectl create -f docs/admin/resourcequota/best-effort.yaml --namespace=quota-scopes +resourcequota "best-effort" created +$ kubectl create -f docs/admin/resourcequota/not-best-effort.yaml --namespace=quota-scopes +resourcequota "not-best-effort" created +$ kubectl describe quota --namespace=quota-scopes +Name: best-effort +Namespace: quota-scopes +Scopes: BestEffort + * Matches all pods that have best effort quality of service. +Resource Used Hard +-------- ---- ---- +pods 0 10 + + +Name: not-best-effort +Namespace: quota-scopes +Scopes: NotBestEffort + * Matches all pods that do not have best effort quality of service. +Resource Used Hard +-------- ---- ---- +limits.cpu 0 2 +limits.memory 0 2Gi +pods 0 4 +requests.cpu 0 1 +requests.memory 0 1Gi +``` + +In this scenario, a pod that makes no compute resource requests will be tracked by the `best-effort` quota. + +A pod that does make compute resource requests will be tracked by the `not-best-effort` quota. + +Let's demonstrate this by creating two deployments: + +```shell +$ kubectl run best-effort-nginx --image=nginx --replicas=8 --namespace=quota-scopes +deployment "best-effort-nginx" created +$ kubectl run not-best-effort-nginx \ + --image=nginx \ + --replicas=2 \ + --requests=cpu=100m,memory=256Mi \ + --limits=cpu=200m,memory=512Mi \ + --namespace=quota-scopes +deployment "not-best-effort-nginx" created +``` + +Even though no default limits were specified, the `best-effort-nginx` deployment will create +all 8 pods. This is because it is tracked by the `best-effort` quota, and the `not-best-effort` +quota will just ignore it. The `not-best-effort` quota will track the `not-best-effort-nginx` +deployment since it creates pods with `Burstable` quality of service. + +Let's list the pods in the namespace: + +```shell +$ kubectl get pods --namespace=quota-scopes +NAME READY STATUS RESTARTS AGE +best-effort-nginx-3488455095-2qb41 1/1 Running 0 51s +best-effort-nginx-3488455095-3go7n 1/1 Running 0 51s +best-effort-nginx-3488455095-9o2xg 1/1 Running 0 51s +best-effort-nginx-3488455095-eyg40 1/1 Running 0 51s +best-effort-nginx-3488455095-gcs3v 1/1 Running 0 51s +best-effort-nginx-3488455095-rq8p1 1/1 Running 0 51s +best-effort-nginx-3488455095-udhhd 1/1 Running 0 51s +best-effort-nginx-3488455095-zmk12 1/1 Running 0 51s +not-best-effort-nginx-2204666826-7sl61 1/1 Running 0 23s +not-best-effort-nginx-2204666826-ke746 1/1 Running 0 23s +``` + +As you can see, all 10 pods have been allowed to be created. + +Let's describe current quota usage in the namespace: + +```shell +$ kubectl describe quota --namespace=quota-scopes +Name: best-effort +Namespace: quota-scopes +Scopes: BestEffort + * Matches all pods that have best effort quality of service. +Resource Used Hard +-------- ---- ---- +pods 8 10 + + +Name: not-best-effort +Namespace: quota-scopes +Scopes: NotBestEffort + * Matches all pods that do not have best effort quality of service. +Resource Used Hard +-------- ---- ---- +limits.cpu 400m 2 +limits.memory 1Gi 2Gi +pods 2 4 +requests.cpu 200m 1 +requests.memory 512Mi 1Gi +``` + +As you can see, the `best-effort` quota has tracked the usage for the 8 pods we created in +the `best-effort-nginx` deployment, and the `not-best-effort` quota has tracked the usage for +the 2 pods we created in the `not-best-effort-nginx` quota. + +Scopes provide a mechanism to subdivide the set of resources that are tracked by +any quota document to allow greater flexibility in how operators deploy and track resource +consumption. + +In addition to `BestEffort` and `NotBestEffort` scopes, there are scopes to restrict +long-running versus time-bound pods. The `Terminating` scope will match any pod +where `spec.activeDeadlineSeconds is not nil`. The `NotTerminating` scope will match any pod +where `spec.activeDeadlineSeconds is nil`. These scopes allow you to quota pods based on their +anticipated permanence on a node in your cluster. + +## Summary + +Actions that consume node resources for cpu and memory can be subject to hard quota limits defined by the namespace quota. + +Any action that consumes those resources can be tweaked, or can pick up namespace level defaults to meet your end goal. + +Quota can be apportioned based on quality of service and anticipated permanence on a node in your cluster. diff --git a/docs/tasks/configure-pod-container/assign-cpu-ram-container.md b/docs/tasks/configure-pod-container/assign-cpu-ram-container.md index 24cca3eca5..fc62af79d9 100644 --- a/docs/tasks/configure-pod-container/assign-cpu-ram-container.md +++ b/docs/tasks/configure-pod-container/assign-cpu-ram-container.md @@ -4,7 +4,7 @@ title: Assigning CPU and RAM Resources to a Container {% capture overview %} -This page shows how assign CPU and RAM resources to containers running +This page shows how to assign CPU and RAM resources to containers running in a Kubernetes Pod. {% endcapture %} diff --git a/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md b/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md index 8c877ac16c..a5c3d8ee56 100644 --- a/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md +++ b/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md @@ -84,7 +84,7 @@ FirstSeen LastSeen Count From SubobjectPath Type 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e ``` -After 30 seconds, view the Pod events again: +After 35 seconds, view the Pod events again: ```shell kubectl describe pod liveness-exec @@ -247,7 +247,7 @@ where you would set it. Suppose the Container listens on 127.0.0.1 and the Pod's If your pod relies on virtual hosts, which is probably the more common case, you should not use `host`, but rather set the `Host` header in `httpHeaders`. -In addition to command probes and HTTP probes, Kubenetes supports +In addition to command probes and HTTP probes, Kubernetes supports [TCP probes](/docs/api-reference/v1/definitions/#_v1_tcpsocketaction). {% endcapture %} @@ -255,7 +255,7 @@ In addition to command probes and HTTP probes, Kubenetes supports {% capture whatsnext %} * Learn more about -[Container Probes](/docs/user-guide/pod-states/#container-probes). +[Container Probes](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). * Learn more about [Health Checking section](/docs/user-guide/walkthrough/k8s201/#health-checking). diff --git a/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md b/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md index 27b5249138..f5be254f2e 100644 --- a/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md +++ b/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md @@ -1,5 +1,8 @@ --- title: Configuring a Pod to Use a PersistentVolume for Storage +redirect_from: +- "/docs/user-guide/persistent-volumes/walkthrough/" +- "/docs/user-guide/persistent-volumes/walkthrough.html" --- {% capture overview %} diff --git a/docs/tasks/configure-pod-container/configure-pod-disruption-budget.md b/docs/tasks/configure-pod-container/configure-pod-disruption-budget.md new file mode 100644 index 0000000000..489f5e0f4c --- /dev/null +++ b/docs/tasks/configure-pod-container/configure-pod-disruption-budget.md @@ -0,0 +1,95 @@ +--- +assignees: +- davidopp +title: Configuring a Pod Disruption Budget +--- +This guide is for anyone wishing to specify safety constraints on pods or anyone +wishing to write software (typically automation software) that respects those +constraints. + +* TOC +{:toc} + +## Rationale + +Various cluster management operations may voluntarily evict pods. "Voluntary" +means an eviction can be safely delayed for a reasonable period of time. The +principal examples today are draining a node for maintenance or upgrade +(`kubectl drain`), and cluster autoscaling down. In the future the +[rescheduler](https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/rescheduling.md) +may also perform voluntary evictions. By contrast, something like evicting pods +because a node has become unreachable or reports `NotReady`, is not "voluntary." + +For voluntary evictions, it can be useful for applications to be able to limit +the number of pods that are down simultaneously. For example, a quorum-based application would +like to ensure that the number of replicas running is never brought below the +number needed for a quorum, even temporarily. Or a web front end might want to +ensure that the number of replicas serving load never falls below a certain +percentage of the total, even briefly. `PodDisruptionBudget` is an API object +that specifies the minimum number or percentage of replicas of a collection that +must be up at a time. Components that wish to evict a pod subject to disruption +budget use the `/eviction` subresource; unlike a regular pod deletion, this +operation may be rejected by the API server if the eviction would cause a +disruption budget to be violated. + +## Specifying a PodDisruptionBudget + +A `PodDisruptionBudget` has two components: a label selector `selector` to specify the set of +pods to which it applies, and `minAvailable` which is a description of the number of pods from that +set that must still be available after the eviction, i.e. even in the absence +of the evicted pod. `minAvailable` can be either an absolute number or a percentage. +So for example, 100% means no voluntary evictions from the set are permitted. In +typical usage, a single budget would be used for a collection of pods managed by +a controller—for example, the pods in a single ReplicaSet. + +Note that a disruption budget does not truly guarantee that the specified +number/percentage of pods will always be up. For example, a node that hosts a +pod from the collection may fail when the collection is at the minimum size +specified in the budget, thus bringing the number of available pods from the +collection below the specified size. The budget can only protect against +voluntary evictions, not all causes of unavailability. + +## Requesting an eviction + +If you are writing infrastructure software that wants to produce these voluntary +evictions, you will need to use the eviction API. The eviction subresource of a +pod can be thought of as a kind of policy-controlled DELETE operation on the pod +itself. To attempt an eviction (perhaps more REST-precisely, to attempt to +*create* an eviction), you POST an attempted operation. Here's an example: + +```json +{ + "apiVersion": "policy/v1beta1", + "kind": "Eviction", + "metadata": { + "name": "quux", + "namespace": "default" + } +} +``` + +You can attempt an eviction using `curl`: + +```bash +$ curl -v -H 'Content-type: application/json' http://127.0.0.1:8080/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json +``` + +The API can respond in one of three ways. + + 1. If the eviction is granted, then the pod is deleted just as if you had sent + a `DELETE` request to the pod's URL and you get back `200 OK`. + 2. If the current state of affairs wouldn't allow an eviction by the rules set + forth in the budget, you get back `429 Too Many Requests`. This is + typically used for generic rate limiting of *any* requests, but here we mean + that this request isn't allowed *right now* but it may be allowed later. + Currently, callers do not get any `Retry-After` advice, but they may in + future versions. + 3. If there is some kind of misconfiguration, like multiple budgets pointing at + the same pod, you will get `500 Internal Server Error`. + +For a given eviction request, there are two cases. + + 1. There is no budget that matches this pod. In this case, the server always + returns `200 OK`. + 2. There is at least one budget. In this case, any of the three above responses may + apply. diff --git a/docs/tasks/configure-pod-container/dapi-envars-container.yaml b/docs/tasks/configure-pod-container/dapi-envars-container.yaml new file mode 100644 index 0000000000..8b3b3a39d3 --- /dev/null +++ b/docs/tasks/configure-pod-container/dapi-envars-container.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dapi-envars-resourcefieldref +spec: + containers: + - name: test-container + image: gcr.io/google_containers/busybox:1.24 + command: [ "sh", "-c"] + args: + - while true; do + echo -en '\n'; + printenv MY_CPU_REQUEST MY_CPU_LIMIT; + printenv MY_MEM_REQUEST MY_MEM_LIMIT; + sleep 10; + done; + resources: + requests: + memory: "32Mi" + cpu: "125m" + limits: + memory: "64Mi" + cpu: "250m" + env: + - name: MY_CPU_REQUEST + valueFrom: + resourceFieldRef: + containerName: test-container + resource: requests.cpu + - name: MY_CPU_LIMIT + valueFrom: + resourceFieldRef: + containerName: test-container + resource: limits.cpu + - name: MY_MEM_REQUEST + valueFrom: + resourceFieldRef: + containerName: test-container + resource: requests.memory + - name: MY_MEM_LIMIT + valueFrom: + resourceFieldRef: + containerName: test-container + resource: limits.memory + restartPolicy: Never diff --git a/docs/tasks/configure-pod-container/dapi-envars-pod.yaml b/docs/tasks/configure-pod-container/dapi-envars-pod.yaml new file mode 100644 index 0000000000..00762373b3 --- /dev/null +++ b/docs/tasks/configure-pod-container/dapi-envars-pod.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dapi-envars-fieldref +spec: + containers: + - name: test-container + image: gcr.io/google_containers/busybox + command: [ "sh", "-c"] + args: + - while true; do + echo -en '\n'; + printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE; + printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT; + sleep 10; + done; + env: + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: MY_POD_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + restartPolicy: Never diff --git a/docs/tasks/configure-pod-container/dapi-volume-resources.yaml b/docs/tasks/configure-pod-container/dapi-volume-resources.yaml new file mode 100644 index 0000000000..65770f283f --- /dev/null +++ b/docs/tasks/configure-pod-container/dapi-volume-resources.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: Pod +metadata: + name: kubernetes-downwardapi-volume-example-2 +spec: + containers: + - name: client-container + image: gcr.io/google_containers/busybox:1.24 + command: ["sh", "-c"] + args: + - while true; do + echo -en '\n'; + if [[ -e /etc/cpu_limit ]]; then + echo -en '\n'; cat /etc/cpu_limit; fi; + if [[ -e /etc/cpu_request ]]; then + echo -en '\n'; cat /etc/cpu_request; fi; + if [[ -e /etc/mem_limit ]]; then + echo -en '\n'; cat /etc/mem_limit; fi; + if [[ -e /etc/mem_request ]]; then + echo -en '\n'; cat /etc/mem_request; fi; + sleep 5; + done; + resources: + requests: + memory: "32Mi" + cpu: "125m" + limits: + memory: "64Mi" + cpu: "250m" + volumeMounts: + - name: podinfo + mountPath: /etc + readOnly: false + volumes: + - name: podinfo + downwardAPI: + items: + - path: "cpu_limit" + resourceFieldRef: + containerName: client-container + resource: limits.cpu + - path: "cpu_request" + resourceFieldRef: + containerName: client-container + resource: requests.cpu + - path: "mem_limit" + resourceFieldRef: + containerName: client-container + resource: limits.memory + - path: "mem_request" + resourceFieldRef: + containerName: client-container + resource: requests.memory + diff --git a/docs/tasks/configure-pod-container/dapi-volume.yaml b/docs/tasks/configure-pod-container/dapi-volume.yaml new file mode 100644 index 0000000000..7126cefae5 --- /dev/null +++ b/docs/tasks/configure-pod-container/dapi-volume.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: Pod +metadata: + name: kubernetes-downwardapi-volume-example + labels: + zone: us-est-coast + cluster: test-cluster1 + rack: rack-22 + annotations: + build: two + builder: john-doe +spec: + containers: + - name: client-container + image: gcr.io/google_containers/busybox + command: ["sh", "-c"] + args: + - while true; do + if [[ -e /etc/labels ]]; then + echo -en '\n\n'; cat /etc/labels; fi; + if [[ -e /etc/annotations ]]; then + echo -en '\n\n'; cat /etc/annotations; fi; + sleep 5; + done; + volumeMounts: + - name: podinfo + mountPath: /etc + readOnly: false + volumes: + - name: podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + diff --git a/docs/tasks/configure-pod-container/distribute-credentials-secure.md b/docs/tasks/configure-pod-container/distribute-credentials-secure.md index 69d5d37890..6dcd642262 100644 --- a/docs/tasks/configure-pod-container/distribute-credentials-secure.md +++ b/docs/tasks/configure-pod-container/distribute-credentials-secure.md @@ -1,5 +1,8 @@ --- title: Distributing Credentials Securely +redirect_from: +- "/docs/user-guide/secrets/walkthrough/" +- "/docs/user-guide/secrets/walkthrough.html" --- {% capture overview %} @@ -22,11 +25,11 @@ Suppose you want to have two pieces of secret data: a username `my-app` and a pa convert your username and password to a base-64 representation. Here's a Linux example: - echo 'my-app' | base64 - echo '39528$vdg7Jb' | base64 + echo -n 'my-app' | base64 + echo -n '39528$vdg7Jb' | base64 -The output shows that the base-64 representation of your username is `bXktYXBwCg==`, -and the base-64 representation of your password is `Mzk1MjgkdmRnN0piCg==`. +The output shows that the base-64 representation of your username is `bXktYXBw`, +and the base-64 representation of your password is `Mzk1MjgkdmRnN0pi`. ## Creating a Secret @@ -37,12 +40,12 @@ username and password: 1. Create the Secret - kubectl create -f http://k8s.io/docs/tasks/administer-cluster/secret.yaml + kubectl create -f secret.yaml **Note:** If you want to skip the Base64 encoding step, you can create a Secret by using the `kubectl create secret` command: - kubectl create secret generic test-secret --from-literal=username="my-app",password="39528$vdg7Jb" + kubectl create secret generic test-secret --from-literal=username='my-app',password='39528$vdg7Jb' 1. View information about the Secret: @@ -69,8 +72,8 @@ username and password: Data ==== - password: 13 bytes - username: 7 bytes + password: 12 bytes + username: 6 bytes ## Creating a Pod that has access to the secret data through a Volume @@ -80,7 +83,7 @@ Here is a configuration file you can use to create a Pod: 1. Create the Pod: - kubectl create -f http://k8s.io/docs/tasks/administer-cluster/secret-pod.yaml + kubectl create -f secret-pod.yaml 1. Verify that your Pod is running: @@ -112,7 +115,7 @@ is exposed: 1. In your shell, display the contents of the `username` and `password` files: - root@secret-test-pod:/etc/secret-volume# cat username password + root@secret-test-pod:/etc/secret-volume# cat username; echo; cat password; echo The output is your username and password: @@ -127,7 +130,7 @@ Here is a configuration file you can use to create a Pod: 1. Create the Pod: - kubectl create -f http://k8s.io/docs/tasks/administer-cluster/secret-envars-pod.yaml + kubectl create -f secret-envars-pod.yaml 1. Verify that your Pod is running: diff --git a/docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information.md b/docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information.md new file mode 100644 index 0000000000..a55d22f387 --- /dev/null +++ b/docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information.md @@ -0,0 +1,242 @@ +--- +title: Exposing Pod Information to Containers Using a DownwardApiVolumeFile +--- + +{% capture overview %} + +This page shows how a Pod can use a DownwardAPIVolumeFile to expose information +about itself to Containers running in the Pod. A DownwardAPIVolumeFile can expose +Pod fields and Container fields. + +{% endcapture %} + + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + +{% capture steps %} + +## The Downward API + +There are two ways to expose Pod and Container fields to a running Container: + +* [Environment variables](/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/) +* DownwardAPIVolumeFiles + +Together, these two ways of exposing Pod and Container fields are called the +*Downward API*. + +## Storing Pod fields + +In this exercise, you create a Pod that has one Container. +Here is the configuration file for the Pod: + +{% include code.html language="yaml" file="dapi-volume.yaml" ghlink="/docs/tasks/configure-pod-container/dapi-volume.yaml" %} + +In the configuration file, you can see that the Pod has a `downwardAPI` Volume, +and the Container mounts the Volume at `/etc`. + +Look at the `items` array under `downwardAPI`. Each element of the array is a +[DownwardAPIVolumeFile](/docs/resources-reference/v1.5/#downwardapivolumefile-v1). +The first element specifies that the value of the Pod's +`metadata.labels` field should be stored in a file named `labels`. +The second element specifies that the value of the Pod's `annotations` +field should be stored in a file named `annotations`. + +**Note**: The fields in this example are Pod fields. They are not +fields of the Container in the Pod. + +Create the Pod: + +```shell +kubectl create -f http://k8s.io/docs/tasks/configure-pod-container/dapi-volume.yaml +``` + +Verify that Container in the Pod is running: + +```shell +kubectl get pods +``` + +View the Container's logs: + +```shell +kubectl logs kubernetes-downwardapi-volume-example +``` + +The output shows the contents of the `labels` file and the `annotations` file: + +```shell +cluster="test-cluster1" +rack="rack-22" +zone="us-est-coast" + +build="two" +builder="john-doe" +``` + +Get a shell into the Container that is running in your Pod: + +``` +kubectl exec -it kubernetes-downwardapi-volume-example -- sh +``` + +In your shell, view the `labels` file: + +```shell +/# cat /etc/labels +``` + +The output shows that all of the Pod's labels have been written +to the `labels` file: + +```shell +cluster="test-cluster1" +rack="rack-22" +zone="us-est-coast" +``` + +Similarly, view the `annotations` file: + +```shell +/# cat /etc/annotations +``` + +View the files in the `/etc` directory: + +```shell +/# ls -laR /etc +``` + +In the output, you can see that the `labels` and `annotations` files +are in a temporary subdirectory: in this example, +`..2982_06_02_21_47_53.299460680`. In the `/etc` directory, `..data` is +a symbolic link to the temporary subdirectory. Also in the `/etc` directory, +`labels` and `annotations` are symbolic links. + +``` +drwxr-xr-x ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680 +lrwxrwxrwx ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680 +lrwxrwxrwx ... Feb 6 21:47 annotations -> ..data/annotations +lrwxrwxrwx ... Feb 6 21:47 labels -> ..data/labels + +/etc/..2982_06_02_21_47_53.299460680: +total 8 +-rw-r--r-- ... Feb 6 21:47 annotations +-rw-r--r-- ... Feb 6 21:47 labels +``` + +Using symbolic links enables dynamic atomic refresh of the metadata; updates are +written to a new temporary directory, and the `..data` symlink is updated +atomically using +[rename(2)](http://man7.org/linux/man-pages/man2/rename.2.html). + +Exit the shell: + +```shell +/# exit +``` + +## Storing Container fields + +The preceding exercise, you stored Pod fields in a DownwardAPIVolumeFile. +In this next exercise, you store Container fields. Here is the configuration +file for a Pod that has one Container: + +{% include code.html language="yaml" file="dapi-volume-resources.yaml" ghlink="/docs/tasks/configure-pod-container/dapi-volume-resources.yaml" %} + +In the configuration file, you can see that the Pod has a `downwardAPI` Volume, +and the Container mounts the Volume at `/etc`. + +Look at the `items` array under `downwardAPI`. Each element of the array is a +DownwardAPIVolumeFile. + +The first element specifies that in the Container named `client-container`, +the value of the `limits.cpu` field +`metadata.labels` field should be stored in a file named `cpu_limit`. + +Create the Pod: + +```shell +kubectl create -f http://k8s.io/docs/tasks/configure-pod-container/dapi-volume-resources.yaml +``` + +Get a shell into the Container that is running in your Pod: + +``` +kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh +``` + +In your shell, view the `cpu_limit` file: + +```shell +/# cat /etc/cpu_limit +``` +You can use similar commands to view the `cpu_request`, `mem_limit` and +`mem_request` files. + +{% endcapture %} + +{% capture discussion %} + +## Capabilities of the Downward API + +The following information is available to Containers through environment +variables and DownwardAPIVolumeFiles: + +* The node’s name +* The Pod’s name +* The Pod’s namespace +* The Pod’s IP address +* The Pod’s service account name +* A Container’s CPU limit +* A container’s CPU request +* A Container’s memory limit +* A Container’s memory request + +In addition, the following information is available through +DownwardAPIVolumeFiles. + +* The Pod's labels +* The Pod's annotations + +**Note**: If CPU and memory limits are not specified for a Container, the +Downward API defaults to the node allocatable value for CPU and memory. + +## Projecting keys to specific paths and file permissions + +You can project keys to specific paths and specific permissions on a per-file +basis. For more information, see +[Secrets](/docs/user-guide/secrets/). + +## Motivation for the Downward API + +It is sometimes useful for a Container to have information about itself, without +being overly coupled to Kubernetes. The Downward API allows containers to consume +information about themselves or the cluster without using the Kubernetes client +or API server. + +An example is an existing application that assumes a particular well-known +environment variable holds a unique identifier. One possibility is to wrap the +application, but that is tedious and error prone, and it violates the goal of low +coupling. A better option would be to use the Pod's name as an identifier, and +inject the Pod's name into the well-known environment variable. + +{% endcapture %} + + +{% capture whatsnext %} + +* [PodSpec](/docs/resources-reference/v1.5/#podspec-v1) +* [Volume](/docs/resources-reference/v1.5/#volume-v1) +* [DownwardAPIVolumeSource](/docs/resources-reference/v1.5/#downwardapivolumesource-v1) +* [DownwardAPIVolumeFile](/docs/resources-reference/v1.5/#downwardapivolumefile-v1) +* [ResourceFieldSelector](/docs/resources-reference/v1.5/#resourcefieldselector-v1) + +{% endcapture %} + +{% include templates/task.md %} + diff --git a/docs/tasks/configure-pod-container/environment-variable-expose-pod-information.md b/docs/tasks/configure-pod-container/environment-variable-expose-pod-information.md new file mode 100644 index 0000000000..10ac238c5e --- /dev/null +++ b/docs/tasks/configure-pod-container/environment-variable-expose-pod-information.md @@ -0,0 +1,175 @@ +--- +title: Exposing Pod Information to Containers Through Environment Variables +--- + +{% capture overview %} + +This page shows how a Pod can use environment variables to expose information +about itself to Containers running in the Pod. Environment variables can expose +Pod fields and Container fields. + +There are two ways to expose Pod and Container fields to a running Container: +environment variables and +[DownwardAPIVolumeFiles](/docs/resources-reference/v1.5/#downwardapivolumefile-v1). +Together, these two ways of exposing Pod and Container fields are called the +*Downward API*. + +{% endcapture %} + + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + + +{% capture steps %} + +## The Downward API + +There are two ways to expose Pod and Container fields to a running Container: + +* Environment variables +* [DownwardAPIVolumeFiles](/docs/resources-reference/v1.5/#downwardapivolumefile-v1) + +Together, these two ways of exposing Pod and Container fields are called the +*Downward API*. + + +## Using Pod fields as values for environment variables + +In this exercise, you create a Pod that has one Container. Here is the +configuration file for the Pod: + +{% include code.html language="yaml" file="dapi-envars-pod.yaml" ghlink="/docs/tasks/configure-pod-container/dapi-envars-pod.yaml" %} + +In the configuration file, you can see five environment variables. The `env` +field is an array of +[EnvVars](/docs/resources-reference/v1.5/#envvar-v1). +The first element in the array specifies that the `MY_NODE_NAME` environment +variable gets its value from the Pod's `spec.nodeName` field. Similarly, the +other environment variables get their names from Pod fields. + +**Note**: The fields in this example are Pod fields. They are not fields of the +Container in the Pod. + +Create the Pod: + +```shell +kubectl create -f http://k8s.io/docs/tasks/configure-pod-container/dapi-envars-pod.yaml +``` + +Verify that the Container in the Pod is running: + +``` +kubectl get pods +``` + +View the Container's logs: + +``` +kubectl logs dapi-envars-fieldref +``` + +The output shows the values of selected environment variables: + +``` +minikube +dapi-envars-fieldref +default +172.17.0.4 +default +``` + +To see why these values are in the log, look at the `command` and `args` fields +in the configuration file. When the Container starts, it writes the values of +five environment variables to stdout. It repeats this every ten seconds. + +Next, get a shell into the Container that is running in your Pod: + +``` +kubectl exec -it dapi-envars-fieldref -- sh +``` + +In your shell, view the environment variables: + +``` +/# printenv +``` + +The output shows that certain environment variables have been assigned the +values of Pod fields: + +``` +MY_POD_SERVICE_ACCOUNT=default +... +MY_POD_NAMESPACE=default +MY_POD_IP=172.17.0.4 +... +MY_NODE_NAME=minikube +... +MY_POD_NAME=dapi-envars-fieldref +``` + +## Using Container fields as values for environment variables + +In the preceding exercise, you used Pod fields as the values for environment +variables. In this next exercise, you use Container fields as the values for +environment variables. Here is the configuration file for a Pod that has one +container: + +{% include code.html language="yaml" file="dapi-envars-container.yaml" ghlink="/docs/tasks/configure-pod-container/dapi-envars-container.yaml" %} + +In the configuration file, you can see four environment variables. The `env` +field is an array of +[EnvVars](/docs/resources-reference/v1.5/#envvar-v1). +The first element in the array specifies that the `MY_CPU_REQUEST` environment +variable gets its value from the `requests.cpu` field of a Container named +`test-container`. Similarly, the other environment variables get their values +from Container fields. + +Create the Pod: + +```shell +kubectl create -f http://k8s.io/docs/tasks/configure-pod-container/dapi-envars-container.yaml +``` + +Verify that the Container in the Pod is running: + +``` +kubectl get pods +``` + +View the Container's logs: + +``` +kubectl logs dapi-envars-resourcefieldref +``` + +The output shows the values of selected environment variables: + +``` +1 +1 +33554432 +67108864 +``` + +{% endcapture %} + +{% capture whatsnext %} + +* [Defining Environment Variables for a Container](/docs/tasks/configure-pod-container/define-environment-variable-container/) +* [PodSpec](/docs/resources-reference/v1.5/#podspec-v1) +* [Container](/docs/resources-reference/v1.5/#container-v1) +* [EnvVar](/docs/resources-reference/v1.5/#envvar-v1) +* [EnvVarSource](/docs/resources-reference/v1.5/#envvarsource-v1) +* [ObjectFieldSelector](/docs/resources-reference/v1.5/#objectfieldselector-v1) +* [ResourceFieldSelector](/docs/resources-reference/v1.5/#resourcefieldselector-v1) + +{% endcapture %} + + +{% include templates/task.md %} + diff --git a/docs/tasks/configure-pod-container/limit-range.md b/docs/tasks/configure-pod-container/limit-range.md new file mode 100644 index 0000000000..1791f14f4d --- /dev/null +++ b/docs/tasks/configure-pod-container/limit-range.md @@ -0,0 +1,214 @@ +--- +assignees: +- derekwaynecarr +- janetkuo +title: Setting Pod CPU and Memory Limits +--- + +By default, pods run with unbounded CPU and memory 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 impose restrictions on the amount of resources a single pod in the system may consume +for a variety of reasons. + +For example: + +1. Each node in the cluster has 2GB of memory. The cluster operator does not want to accept pods +that require more than 2GB of memory since no node in the cluster can support the requirement. To prevent a +pod from being permanently unscheduled to a node, the operator instead chooses to reject pods that exceed 2GB +of memory as part of admission control. +2. A cluster is shared by two communities in an organization that runs production and development workloads +respectively. Production workloads may consume up to 8GB of memory, but development workloads may consume up +to 512MB of memory. The cluster operator creates a separate namespace for each workload, and applies limits to +each namespace. +3. Users may create a pod which consumes resources just below the capacity of a machine. The left over space +may be too small to be useful, but big enough for the waste to be costly over the entire cluster. As a result, +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 limit waste. + +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. + +See [LimitRange design doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/admission_control_limit_range.md) for more information. For a detailed description of the Kubernetes resource model, see [Resources](/docs/user-guide/compute-resources/) + +## Step 0: Prerequisites + +This example requires a running Kubernetes cluster. See the [Getting Started guides](/docs/getting-started-guides/) for how to get started. + +Change to the `` directory if you're not already there. + +## 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 limit-example: + +```shell +$ 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 STATUS AGE +default Active 51s +limit-example Active 45s +``` + +## Step 2: Apply a limit to the namespace + +Let's create a simple limit in our namespace. + +```shell +$ kubectl create -f docs/admin/limitrange/limits.yaml --namespace=limit-example +limitrange "mylimits" created +``` + +Let's describe the limits that we have imposed in our namespace. + +```shell +$ kubectl describe limits mylimits --namespace=limit-example +Name: mylimits +Namespace: limit-example +Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio +---- -------- --- --- --------------- ------------- ----------------------- +Pod cpu 200m 2 - - - +Pod memory 6Mi 1Gi - - - +Container cpu 100m 2 200m 300m - +Container memory 3Mi 1Gi 100Mi 200Mi - +``` + +In this scenario, we have said the following: + +1. If a max constraint is specified for a resource (2 CPU and 1Gi memory in this case), then a limit +must be specified for that resource across all containers. Failure to specify a limit will result in +a validation error when attempting to create the pod. Note that a default value of limit is set by +*default* in file `limits.yaml` (300m CPU and 200Mi memory). +2. If a min constraint is specified for a resource (100m CPU and 3Mi memory in this case), then a +request must be specified for that resource across all containers. Failure to specify a request will +result in a validation error when attempting to create the pod. Note that a default value of request is +set by *defaultRequest* in file `limits.yaml` (200m CPU and 100Mi memory). +3. For any pod, the sum of all containers memory requests must be >= 6Mi and the sum of all containers +memory limits must be <= 1Gi; the sum of all containers CPU requests must be >= 200m and the sum of all +containers CPU limits must be <= 2. + +## Step 3: Enforcing limits at point of creation + +The limits enumerated in a namespace are only enforced when a pod is created or updated in +the cluster. If you change the limits to a different value range, it does not affect pods that +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 [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 +deployment "nginx" created +``` + +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*. + +Let's create a pod that exceeds our allowed limits by having it have a container that requests 3 CPU cores. + +```shell +$ kubectl create -f docs/admin/limitrange/invalid-pod.yaml --namespace=limit-example +Error from server: error when creating "docs/admin/limitrange/invalid-pod.yaml": Pod "invalid-pod" is forbidden: [Maximum cpu usage per Pod is 2, but limit is 3., Maximum cpu usage per Container is 2, but limit is 3.] +``` + +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 +``` + +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 enforced in the default Kubernetes setup on the physical node +that runs the container unless the administrator deploys the kubelet with the following flag: + +```shell +$ kubelet --help +Usage of kubelet +.... + --cpu-cfs-quota[=true]: Enable CPU CFS quota enforcement for containers that specify CPU limits +$ kubelet --cpu-cfs-quota=false ... +``` + +## Step 4: Cleanup + +To remove the resources used by this example, you can just delete the limit-example namespace. + +```shell +$ kubectl delete namespace limit-example +namespace "limit-example" deleted +$ kubectl get namespaces +NAME STATUS AGE +default Active 12m +``` + +## Summary + +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. diff --git a/docs/tasks/configure-pod-container/pull-image-private-registry.md b/docs/tasks/configure-pod-container/pull-image-private-registry.md index e9b640873a..f54d881178 100644 --- a/docs/tasks/configure-pod-container/pull-image-private-registry.md +++ b/docs/tasks/configure-pod-container/pull-image-private-registry.md @@ -80,7 +80,7 @@ Copy the base64 representation of the secret data into a file named `secret64`. **Important**: Make sure there are no line breaks in your `secret64` file. -To understand what is in the `dockercfg` field, convert the secret data to a +To understand what is in the `.dockercfg` field, convert the secret data to a readable format: base64 -d secret64 diff --git a/docs/tasks/debug-application-cluster/counter-pod.yaml b/docs/tasks/debug-application-cluster/counter-pod.yaml new file mode 100644 index 0000000000..f997886386 --- /dev/null +++ b/docs/tasks/debug-application-cluster/counter-pod.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: counter +spec: + containers: + - name: count + image: busybox + args: [/bin/sh, -c, + 'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done'] diff --git a/docs/tasks/troubleshoot/debug-init-containers.md b/docs/tasks/debug-application-cluster/debug-init-containers.md similarity index 96% rename from docs/tasks/troubleshoot/debug-init-containers.md rename to docs/tasks/debug-application-cluster/debug-init-containers.md index 3c362c5072..77abef0a84 100644 --- a/docs/tasks/troubleshoot/debug-init-containers.md +++ b/docs/tasks/debug-application-cluster/debug-init-containers.md @@ -8,6 +8,9 @@ assignees: - kow3ns - smarterclayton title: Debugging Init Containers +redirect_from: +- "/docs/tasks/troubleshoot/debug-init-containers/" +- "/docs/tasks/troubleshoot/debug-init-containers.html" --- {% capture overview %} diff --git a/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md b/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md new file mode 100644 index 0000000000..4441067d60 --- /dev/null +++ b/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md @@ -0,0 +1,104 @@ +--- +assignees: +- crassirostris +- piosz +title: Logging Using Elasticsearch and Kibana +--- + +On the Google Compute Engine (GCE) platform, the default logging support targets +[Stackdriver Logging](https://cloud.google.com/logging/), which is described in detail +in the [Logging With Stackdriver Logging](/docs/user-guide/logging/stackdriver). + +This article describes how to set up a cluster to ingest logs into +[Elasticsearch](https://www.elastic.co/products/elasticsearch), and view +them using [Kibana](https://www.elastic.co/products/kibana), as an alternative to +Stackdriver Logging when running on GCE. Note that Elasticsearch and Kibana do not work with Kubernetes clusters hosted on Google Container Engine. + +To use Elasticsearch and Kibana for cluster logging, you should set the +following environment variable as shown below when creating your cluster with +kube-up.sh: + +```shell +KUBE_LOGGING_DESTINATION=elasticsearch +``` + +You should also ensure that `KUBE_ENABLE_NODE_LOGGING=true` (which is the default for the GCE platform). + +Now, when you create a cluster, a message will indicate that the Fluentd log +collection daemons that run on each node will target Elasticsearch: + +```shell +$ cluster/kube-up.sh +... +Project: kubernetes-satnam +Zone: us-central1-b +... calling kube-up +Project: kubernetes-satnam +Zone: us-central1-b ++++ Staging server tars to Google Storage: gs://kubernetes-staging-e6d0e81793/devel ++++ kubernetes-server-linux-amd64.tar.gz uploaded (sha1 = 6987c098277871b6d69623141276924ab687f89d) ++++ kubernetes-salt.tar.gz uploaded (sha1 = bdfc83ed6b60fa9e3bff9004b542cfc643464cd0) +Looking for already existing resources +Starting master and configuring firewalls +Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/zones/us-central1-b/disks/kubernetes-master-pd]. +NAME ZONE SIZE_GB TYPE STATUS +kubernetes-master-pd us-central1-b 20 pd-ssd READY +Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/regions/us-central1/addresses/kubernetes-master-ip]. ++++ Logging using Fluentd to elasticsearch +``` + +The per-node Fluentd pods, the Elasticsearch pods, and the Kibana pods should +all be running in the kube-system namespace soon after the cluster comes to +life. + +```shell +$ kubectl get pods --namespace=kube-system +NAME READY REASON RESTARTS AGE +elasticsearch-logging-v1-78nog 1/1 Running 0 2h +elasticsearch-logging-v1-nj2nb 1/1 Running 0 2h +fluentd-elasticsearch-kubernetes-node-5oq0 1/1 Running 0 2h +fluentd-elasticsearch-kubernetes-node-6896 1/1 Running 0 2h +fluentd-elasticsearch-kubernetes-node-l1ds 1/1 Running 0 2h +fluentd-elasticsearch-kubernetes-node-lz9j 1/1 Running 0 2h +kibana-logging-v1-bhpo8 1/1 Running 0 2h +kube-dns-v3-7r1l9 3/3 Running 0 2h +monitoring-heapster-v4-yl332 1/1 Running 1 2h +monitoring-influx-grafana-v1-o79xf 2/2 Running 0 2h +``` + +The `fluentd-elasticsearch` pods gather logs from each node and send them to +the `elasticsearch-logging` pods, which are part of a +[service](/docs/user-guide/services/) named `elasticsearch-logging`. These +Elasticsearch pods store the logs and expose them via a REST API. +The `kibana-logging` pod provides a web UI for reading the logs stored in +Elasticsearch, and is part of a service named `kibana-logging`. + +The Elasticsearch and Kibana services are both in the `kube-system` namespace +and are not directly exposed via a publicly reachable IP address. To reach them, +follow the instructions for [Accessing services running in a cluster](/docs/user-guide/accessing-the-cluster/#accessing-services-running-on-the-cluster). + +If you try accessing the `elasticsearch-logging` service in your browser, you'll +see a status page that looks something like this: + +![Elasticsearch Status](/images/docs/es-browser.png) + +You can now type Elasticsearch queries directly into the browser, if you'd +like. See [Elasticsearch's documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html) +for more details on how to do so. + +Alternatively, you can view your cluster's logs using Kibana (again using the +[instructions for accessing a service running in the cluster](/docs/user-guide/accessing-the-cluster/#accessing-services-running-on-the-cluster)). +The first time you visit the Kibana URL you will be presented with a page that +asks you to configure your view of the ingested logs. Select the option for +timeseries values and select `@timestamp`. On the following page select the +`Discover` tab and then you should be able to see the ingested logs. +You can set the refresh interval to 5 seconds to have the logs +regularly refreshed. + +Here is a typical view of ingested logs from the Kibana viewer: + +![Kibana logs](/images/docs/kibana-logs.png) + +Kibana opens up all sorts of powerful options for exploring your logs! For some +ideas on how to dig into it, check out [Kibana's documentation](https://www.elastic.co/guide/en/kibana/current/discover.html). + diff --git a/docs/tasks/debug-application-cluster/logging-stackdriver.md b/docs/tasks/debug-application-cluster/logging-stackdriver.md new file mode 100644 index 0000000000..b382d0faf7 --- /dev/null +++ b/docs/tasks/debug-application-cluster/logging-stackdriver.md @@ -0,0 +1,148 @@ +--- +assignees: +- crassirostris +- piosz +title: Logging Using Stackdriver +--- + +Before reading this page, it's highly recommended to familiasrize yourself with the [overview of logging in Kubernetes](/docs/user-guide/logging/overview). + +This article assumes that you have created a Kubernetes cluster with cluster-level logging support for sending logs to Stackdriver Logging. You can do this either by selecting the **Enable Stackdriver Logging** checkbox in the create cluster dialogue in [GKE](https://cloud.google.com/container-engine/), or by setting the `KUBE_LOGGING_DESTINATION` flag to `gcp` when manually starting a cluster using `kube-up.sh`. + +The following guide describes gathering a container's standard output and standard error. To gather logs written by an application to a file, you can use [a sidecar approach](https://github.com/kubernetes/contrib/blob/master/logging/fluentd-sidecar-gcp/README.md). + +## Overview + +After creation, you can discover logging agent pods in the `kube-system` namespace, +one per node, by running the following command: + +```shell +$ kubectl get pods --namespace=kube-system +NAME READY STATUS RESTARTS AGE +... +fluentd-gcp-v1.30-50gnc 1/1 Running 0 5d +fluentd-gcp-v1.30-v255c 1/1 Running 0 5d +fluentd-gcp-v1.30-f02l5 1/1 Running 0 5d +... +``` + +To understand how logging with Stackdriver works, consider the following +synthetic log generator pod specification [counter-pod.yaml](/docs/tasks/debug-application-cluster/counter-pod.yaml): + +{% include code.html language="yaml" file="counter-pod.yaml" ghlink="/docs/tasks/debug-application-cluster/counter-pod.yaml" %} + +This pod specification has one container that runs a bash script +that writes out the value of a counter and the date once per +second, and runs indefinitely. Let's create this pod in the default namespace. + +```shell +$ kubectl create -f http://k8s.io/docs/user-guide/logging/examples/counter-pod.yaml +pod "counter" created +``` + +You can observe the running pod: + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +counter 1/1 Running 0 5m +``` + +For a short period of time you can observe the 'Pending' pod status, because the kubelet +has to download the container image first. When the pod status changes to `Running` +you can use the `kubectl logs` command to view the output of this counter pod. + +```shell +$ kubectl logs counter +0: Mon Jan 1 00:00:00 UTC 2001 +1: Mon Jan 1 00:00:01 UTC 2001 +2: Mon Jan 1 00:00:02 UTC 2001 +... +``` + +As described in the logging overview, this command fetches log entries +from the container log file. If the container is killed and then restarted by +Kubernetes, you can still access logs from the previous container. However, +if the pod is evicted from the node, log files are lost. Let's demonstrate this +by deleting the currently running counter container: + +```shell +$ kubectl delete pod counter +pod "counter" deleted +``` + +and then recreating it: + +```shell +$ kubectl create -f http://k8s.io/docs/user-guide/logging/examples/counter-pod.yaml +pod "counter" created +``` + +After some time, you can access logs from the counter pod again: + +```shell +$ kubectl logs counter +0: Mon Jan 1 00:01:00 UTC 2001 +1: Mon Jan 1 00:01:01 UTC 2001 +2: Mon Jan 1 00:01:02 UTC 2001 +... +``` + +As expected, only recent log lines are present. However, for a real-world +application you will likely want to be able to access logs from all containers, +especially for the debug purposes. This is exactly when the previously enabled +Stackdriver Logging can help. + +## Viewing logs + +Stackdriver Logging agent attaches metadata to each log entry, for you to use later +in queries to select only the messages you're interested in: for example, +the messages from a particular pod. + +The most important pieces of metadata are the resource type and log name. +The resource type of a container log is `container`, which is named +`GKE Containers` in the UI (even if the Kubernetes cluster is not on GKE). +The log name is the name of the container, so that if you have a pod with +two containers, named `container_1` and `container_2` in the spec, their logs +will have log names `container_1` and `container_2` respectively. + +System components have resource type `compute`, which is named +`GCE VM Instance` in the interface. Log names for system components are fixed. +For a GKE node, every log entry from a system component has one the following +log names: + +* docker +* kubelet +* kube-proxy + +You can learn more about viewing logs on [the dedicated Stackdriver page](https://cloud.google.com/logging/docs/view/logs_viewer). + +One of the possible ways to view logs is using the +[`gcloud logging`](https://cloud.google.com/logging/docs/api/gcloud-logging) +command line interface from the [Google Cloud SDK](https://cloud.google.com/sdk/). +It uses Stackdriver Logging [filtering syntax](https://cloud.google.com/logging/docs/view/advanced_filters) +to query specific logs. For example, you can run the following command: + +```shell +$ gcloud beta logging read 'logName="projects/$YOUR_PROJECT_ID/logs/count"' --format json | jq '.[].textPayload' +... +"2: Mon Jan 1 00:01:02 UTC 2001\n" +"1: Mon Jan 1 00:01:01 UTC 2001\n" +"0: Mon Jan 1 00:01:00 UTC 2001\n" +... +"2: Mon Jan 1 00:00:02 UTC 2001\n" +"1: Mon Jan 1 00:00:01 UTC 2001\n" +"0: Mon Jan 1 00:00:00 UTC 2001\n" +``` + +As you can see, it outputs messages for the count container from both +the first and second runs, despite the fact that the kubelet already deleted +the logs for the first container. + +### Exporting logs + +You can export logs to [Google Cloud Storage](https://cloud.google.com/storage/) +or to [BigQuery](https://cloud.google.com/bigquery/) to run further +analysis. Stackdriver Logging offers the concept of sinks, where you can +specify the destination of log entries. More information is available on +the Stackdriver [Exporting Logs page](https://cloud.google.com/logging/docs/export/configure_export_v2). diff --git a/docs/tasks/debug-application-cluster/monitor-node-health.md b/docs/tasks/debug-application-cluster/monitor-node-health.md new file mode 100644 index 0000000000..08ca3208dd --- /dev/null +++ b/docs/tasks/debug-application-cluster/monitor-node-health.md @@ -0,0 +1,248 @@ +--- +assignees: +- Random-Liu +- dchen1107 +title: Monitoring Node Health +--- + +* TOC +{:toc} + +## Node Problem Detector + +*Node problem detector* is a [DaemonSet](/docs/admin/daemons/) monitoring the +node health. It collects node problems from various daemons and reports them +to the apiserver as [NodeCondition](/docs/admin/node/#node-condition) and +[Event](/docs/api-reference/v1/definitions/#_v1_event). + +It supports some known kernel issue detection now, and will detect more and +more node problems over time. + +Currently Kubernetes won't take any action on the node conditions and events +generated by node problem detector. In the future, a remedy system could be +introduced to deal with node problems. + +See more information +[here](https://github.com/kubernetes/node-problem-detector). + +## Limitations + +* The kernel issue detection of node problem detector only supports file based +kernel log now. It doesn't support log tools like journald. + +* The kernel issue detection of node problem detector has assumption on kernel +log format, and now it only works on Ubuntu and Debian. However, it is easy to extend +it to [support other log format](/docs/admin/node-problem/#support-other-log-format). + +## Enable/Disable in GCE cluster + +Node problem detector is [running as a cluster addon](cluster-large.md/#addon-resources) enabled by default in the +gce cluster. + +You can enable/disable it by setting the environment variable +`KUBE_ENABLE_NODE_PROBLEM_DETECTOR` before `kube-up.sh`. + +## Use in Other Environment + +To enable node problem detector in other environment outside of GCE, you can use +either `kubectl` or addon pod. + +### Kubectl + +This is the recommended way to start node problem detector outside of GCE. It +provides more flexible management, such as overwriting the default +configuration to fit it into your environment or detect +customized node problems. + +* **Step 1:** Create `node-problem-detector.yaml`: + +```yaml +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: node-problem-detector-v0.1 + namespace: kube-system + labels: + k8s-app: node-problem-detector + version: v0.1 + kubernetes.io/cluster-service: "true" +spec: + template: + metadata: + labels: + k8s-app: node-problem-detector + version: v0.1 + kubernetes.io/cluster-service: "true" + spec: + hostNetwork: true + containers: + - name: node-problem-detector + image: gcr.io/google_containers/node-problem-detector:v0.1 + securityContext: + privileged: true + resources: + limits: + cpu: "200m" + memory: "100Mi" + requests: + cpu: "20m" + memory: "20Mi" + volumeMounts: + - name: log + mountPath: /log + readOnly: true + volumes: + - name: log + hostPath: + path: /var/log/ +``` + +***Notice that you should make sure the system log directory is right for your +OS distro.*** + +* **Step 2:** Start node problem detector with `kubectl`: + +```shell +kubectl create -f node-problem-detector.yaml +``` + +### Addon Pod + +This is for those who have their own cluster bootstrap solution, and don't need +to overwrite the default configuration. They could leverage the addon pod to +further automate the deployment. + +Just create `node-problem-detector.yaml`, and put it under the addon pods directory +`/etc/kubernetes/addons/node-problem-detector` on master node. + +## Overwrite the Configuration + +The [default configuration](https://github.com/kubernetes/node-problem-detector/tree/v0.1/config) +is embedded when building the docker image of node problem detector. + +However, you can use [ConfigMap](/docs/user-guide/configmap/) to overwrite it +following the steps: + +* **Step 1:** Change the config files in `config/`. +* **Step 2:** Create the ConfigMap `node-problem-detector-config` with `kubectl create configmap +node-problem-detector-config --from-file=config/`. +* **Step 3:** Change the `node-problem-detector.yaml` to use the ConfigMap: + +```yaml +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: node-problem-detector-v0.1 + namespace: kube-system + labels: + k8s-app: node-problem-detector + version: v0.1 + kubernetes.io/cluster-service: "true" +spec: + template: + metadata: + labels: + k8s-app: node-problem-detector + version: v0.1 + kubernetes.io/cluster-service: "true" + spec: + hostNetwork: true + containers: + - name: node-problem-detector + image: gcr.io/google_containers/node-problem-detector:v0.1 + securityContext: + privileged: true + resources: + limits: + cpu: "200m" + memory: "100Mi" + requests: + cpu: "20m" + memory: "20Mi" + volumeMounts: + - name: log + mountPath: /log + readOnly: true + - name: config # Overwrite the config/ directory with ConfigMap volume + mountPath: /config + readOnly: true + volumes: + - name: log + hostPath: + path: /var/log/ + - name: config # Define ConfigMap volume + configMap: + name: node-problem-detector-config +``` + +* **Step 4:** Re-create the node problem detector with the new yaml file: + +```shell +kubectl delete -f node-problem-detector.yaml # If you have a node-problem-detector running +kubectl create -f node-problem-detector.yaml +``` + +***Notice that this approach only applies to node problem detector started with `kubectl`.*** + +For node problem detector running as cluster addon, because addon manager doesn't support +ConfigMap, configuration overwriting is not supported now. + +## Kernel Monitor + +*Kernel Monitor* is a problem daemon in node problem detector. It monitors kernel log +and detects known kernel issues following predefined rules. + +The Kernel Monitor matches kernel issues according to a set of predefined rule list in +[`config/kernel-monitor.json`](https://github.com/kubernetes/node-problem-detector/blob/v0.1/config/kernel-monitor.json). +The rule list is extensible, and you can always extend it by [overwriting the +configuration](/docs/admin/node-problem/#overwrite-the-configuration). + +### Add New NodeConditions + +To support new node conditions, you can extend the `conditions` field in +`config/kernel-monitor.json` with new condition definition: + +```json +{ + "type": "NodeConditionType", + "reason": "CamelCaseDefaultNodeConditionReason", + "message": "arbitrary default node condition message" +} +``` + +### Detect New Problems + +To detect new problems, you can extend the `rules` field in `config/kernel-monitor.json` +with new rule definition: + +```json +{ + "type": "temporary/permanent", + "condition": "NodeConditionOfPermanentIssue", + "reason": "CamelCaseShortReason", + "message": "regexp matching the issue in the kernel log" +} +``` + +### Change Log Path + +Kernel log in different OS distros may locate in different path. The `log` +field in `config/kernel-monitor.json` is the log path inside the container. +You can always configure it to match your OS distro. + +### Support Other Log Format + +Kernel monitor uses [`Translator`](https://github.com/kubernetes/node-problem-detector/blob/v0.1/pkg/kernelmonitor/translator/translator.go) +plugin to translate kernel log the internal data structure. It is easy to +implement a new translator for a new log format. + +## Caveats + +It is recommended to run the node problem detector in your cluster to monitor +the node health. However, you should be aware that this will introduce extra +resource overhead on each node. Usually this is fine, because: + +* The kernel log is generated relatively slowly. +* Resource limit is set for node problem detector. +* Even under high load, the resource usage is acceptable. +(see [benchmark result](https://github.com/kubernetes/node-problem-detector/issues/2#issuecomment-220255629)) diff --git a/docs/tasks/index.md b/docs/tasks/index.md index 39f81c6751..4572ca077b 100644 --- a/docs/tasks/index.md +++ b/docs/tasks/index.md @@ -1,17 +1,30 @@ --- title: Tasks +redirect_from: +- "/docs/user-guide/configuring-containers/" +- "/docs/user-guide/configuring-containers.html" +- "/docs/user-guide/production-pods/" +- "/docs/user-guide/production-pods.html" --- This section of the Kubernetes documentation contains pages that show how to do individual tasks. A task page shows how to do a single thing, typically by giving a short sequence of steps. +#### Using the kubectl Command Line + +* [Listing Alll Container Images Running in a Cluster](/docs/tasks/kubectl/list-all-running-container-images/) +* [Getting a Shell to a Running Container](/docs/tasks/kubectl/get-shell-running-container/) + #### Configuring Pods and Containers * [Defining Environment Variables for a Container](/docs/tasks/configure-pod-container/define-environment-variable-container/) * [Defining a Command and Arguments for a Container](/docs/tasks/configure-pod-container/define-command-argument-container/) * [Assigning CPU and RAM Resources to a Container](/docs/tasks/configure-pod-container/assign-cpu-ram-container/) * [Configuring a Pod to Use a Volume for Storage](/docs/tasks/configure-pod-container/configure-volume-storage/) +* [Configuring a Pod to Use a PersistentVolume for Storage](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/) +* [Exposing Pod Information to Containers Through Environment Variables](/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/) +* [Exposing Pod Information to Containers Using a DownwardAPIVolumeFile](/docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information/) * [Distributing Credentials Securely](/docs/tasks/configure-pod-container/distribute-credentials-secure/) * [Pulling an Image from a Private Registry](/docs/tasks/configure-pod-container/pull-image-private-registry/) * [Configuring Liveness and Readiness Probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) @@ -24,9 +37,12 @@ single thing, typically by giving a short sequence of steps. * [Using Port Forwarding to Access Applications in a Cluster](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) * [Providing Load-Balanced Access to an Application in a Cluster](/docs/tasks/access-application-cluster/load-balance-access-application-cluster/) -#### Debugging Applications in a Cluster +#### Monitoring, Logging, and Debugging * [Determining the Reason for Pod Failure](/docs/tasks/debug-application-cluster/determine-reason-pod-failure/) +* [Debugging Init Containers](/docs/tasks/debug-application-cluster/debug-init-containers/) +* [Logging Using Stackdriver](/docs/tasks/debug-application-cluster/logging-stackdriver/) +* [Logging Using ElasticSearch and Kibana](/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana/) #### Accessing the Kubernetes API @@ -47,11 +63,8 @@ single thing, typically by giving a short sequence of steps. * [Debugging a StatefulSet](/docs/tasks/manage-stateful-set/debugging-a-statefulset/) * [Force Deleting StatefulSet Pods](/docs/tasks/manage-stateful-set/delete-pods/) -#### Troubleshooting - -* [Debugging Init Containers](/docs/tasks/troubleshoot/debug-init-containers/) - ### What's next If you would like to write a task page, see [Creating a Documentation Pull Request](/docs/contribute/create-pull-request/). + diff --git a/docs/tasks/kubectl/get-shell-running-container.md b/docs/tasks/kubectl/get-shell-running-container.md new file mode 100644 index 0000000000..a005f3e0fe --- /dev/null +++ b/docs/tasks/kubectl/get-shell-running-container.md @@ -0,0 +1,148 @@ +--- +assignees: +- caesarxuchao +- mikedanese +title: Getting a Shell to a Running Container +--- + +{% capture overview %} + +This page shows how to use `kubectl exec` to get a shell to a +running Container. + +{% endcapture %} + + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + + +{% capture steps %} + +## Getting a shell to a Container + +In this exercise, you create a Pod that has one Container. The Container +runs the nginx image. Here is the configuration file for the Pod: + +{% include code.html language="yaml" file="shell-demo.yaml" ghlink="/docs/tasks/kubectl/shell-demo.yaml" %} + +Create the Pod: + +```shell +kubectl create -f https://k8s.io/docs/tasks/kubectl/shell-demo.yaml +``` + +Verify that the Container is running: + +```shell +kubectl get pod shell-demo +``` + +Get a shell to the running Container: + +```shell +kubectl exec -it shell-demo -- /bin/bash +``` + +In your shell, list the running processes: + +```shell +root@shell-demo:/# ps aux +``` + +In your shell, list the nginx processes: + +```shell +root@shell-demo:/# ps aux | grep nginx +``` + +In your shell, experiment with other commands. Here are +some examples: + +```shell +root@shell-demo:/# ls / +root@shell-demo:/# cat /proc/mounts +root@shell-demo:/# cat /proc/1/maps +root@shell-demo:/# apt-get update +root@shell-demo:/# apt-get install tcpdump +root@shell-demo:/# tcpdump +root@shell-demo:/# apt-get install lsof +root@shell-demo:/# lsof +``` + +## Writing the root page for nginx + +Look again at the configuration file for your Pod. The Pod +has an `emptyDir` volume, and the Container mounts the volume +at `/usr/share/nginx/html`. + +In your shell, create an `index.html` file in the `/usr/share/nginx/html` +directory: + +```shell +root@shell-demo:/# echo Hello shell demo > /usr/share/nginx/html/index.html +``` + +In your shell, send a GET request to the nginx server: + +```shell +root@shell-demo:/# apt-get update +root@shell-demo:/# apt-get install curl +root@shell-demo:/# curl localhost +``` + +The output shows the text that you wrote to the `index.html` file: + +```shell +Hello shell demo +``` + +When you are finished with your shell, enter `exit`. + +## Running individual commands in a Container + +In an ordinary command window, not your shell, list the environment +variables in the running Container: + +```shell +kubectl exec shell-demo env +``` + +Experiment running other commands. Here are some examples: + +```shell +kubectl exec shell-demo ps aux +kubectl exec shell-demo ls / +kubectl exec shell-demo cat /proc/1/mounts +``` + +{% endcapture %} + +{% capture discussion %} + +## Opening a shell when a Pod has more than one Container + +If a Pod has more than one Container, use `--container` or `-c` to +specify a Container in the `kubectl exec` command. For example, +suppose you have a Pod named my-pod, and the Pod has two containers +named main-app and helper-app. The following command would open a +shell to the main-app Container. + +```shell +kubectl exec -it my-pod --container main-app -- /bin/bash +``` + +{% endcapture %} + + +{% capture whatsnext %} + +* [kubectl exec](/docs/user-guide/kubectl/v1.5/#exec) + +{% endcapture %} + + +{% include templates/task.md %} diff --git a/docs/tasks/kubectl/list-all-running-container-images.md b/docs/tasks/kubectl/list-all-running-container-images.md new file mode 100644 index 0000000000..070de69004 --- /dev/null +++ b/docs/tasks/kubectl/list-all-running-container-images.md @@ -0,0 +1,122 @@ +--- +title: Listing All Container Images Running in a Cluster +--- + +{% capture overview %} + +This page shows how to use kubectl to list all of the Container images +for Pods running in a cluster. + +{% endcapture %} + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + +{% capture steps %} + +In this exercise you will use kubectl to fetch all of the Pods +running in a cluster, and format the output to pull out the list +of Containers for each. + +## List all Containers in all namespaces + +- Fetch all Pods in all namespaces using `kubectl get pods --all-namespaces` +- Format the output to include only the list of Container image names + using `-o jsonpath={..image}`. This will recursively parse out the + `image` field from the returned json. + - See the [jsonpath reference](/docs/user-guide/jsonpath/) + for further information on how to use jsonpath. +- Format the output using standard tools: `tr`, `sort`, `uniq` + - Use `tr` to replace spaces with newlines + - Use `sort` to sort the results + - Use `uniq` to aggregate image counts + +```sh +kubectl get pods --all-namespaces -o jsonpath="{..image}" |\ +tr -s '[[:space:]]' '\n' |\ +sort |\ +uniq -c +``` + +The above command will recursively return all fields named `image` +for all items returned. + +As an alternative, it is possible to use the absolute path to the image +field within the Pod. This ensures the correct field is retrieved +in the even the field name is repeated, +e.g. many fields are called `name` within a given item: + +```sh +kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" +``` + +The jsonpath is interpreted as follows: + +- `.items[*]`: for each returned value +- `.spec`: get the spec +- `.containers[*]`: for each container +- `.image`: get the image + +**Note:** When fetching a single Pod by name, e.g. `kubect get pod nginx`, +the `.items[*]` portion of the path should be omitted because a single +Pod is returned instead of a list of items. + +## List Containers by Pod + +The formatting can be controlled further by using the `range` operation to +iterate over elements individually. + +```sh +kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\ +sort +``` + +## List Containers filtering by Pod label + +To target only Pods matching a specific label, use the -l flag. The +following matches only Pods with labels matching `app=nginx`. + +```sh +kubectl get pods --all-namespaces -o=jsonpath="{..image}" -l app=nginx +``` + +## List Containers filtering by Pod namespace + +To target only pods in a specific namespace, use the namespace flag. The +following matches only Pods in the `kube-system` namespace. + +```sh +kubectl get pods --namespace kube-system -o jsonpath="{..image}" +``` + +## List Containers using a go-template instead of jsonpath + +As an alternative to jsonpath, Kubectl supports using [go-templates](https://golang.org/pkg/text/template/) +for formatting the output: + +{% raw %} +```sh +kubectl get pods --all-namespaces -o go-template --template="{{range .items}}{{range .spec.containers}}{{.image}} {{end}}{{end}}" +``` +{% endraw %} + + +{% endcapture %} + +{% capture discussion %} + +{% endcapture %} + +{% capture whatsnext %} + +### Reference + +* [Jsonpath](/docs/user-guide/jsonpath/) reference guide +* [Go template](https://golang.org/pkg/text/template/) reference guide + +{% endcapture %} + +{% include templates/task.md %} diff --git a/docs/tasks/kubectl/shell-demo.yaml b/docs/tasks/kubectl/shell-demo.yaml new file mode 100644 index 0000000000..2a7d274a64 --- /dev/null +++ b/docs/tasks/kubectl/shell-demo.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: shell-demo +spec: + volumes: + - name: shared-data + emptyDir: {} + containers: + - name: nginx + image: nginx + volumeMounts: + - name: shared-data + mountPath: /usr/share/nginx/html diff --git a/docs/tasks/manage-stateful-set/scale-stateful-set.md b/docs/tasks/manage-stateful-set/scale-stateful-set.md index eda728efdd..b79f188e6f 100644 --- a/docs/tasks/manage-stateful-set/scale-stateful-set.md +++ b/docs/tasks/manage-stateful-set/scale-stateful-set.md @@ -47,7 +47,7 @@ kubectl scale statefulsets --replicas= ### Alternative: `kubectl apply` / `kubectl edit` / `kubectl patch` -Alternatively, you can do [in-place updates](/docs/user-guide/managing-deployments/#in-place-updates-of-resources) on your StatefulSets. +Alternatively, you can do [in-place updates](/docs/concepts/cluster-administration/manage-deployment/#in-place-updates-of-resources) on your StatefulSets. If your StatefulSet was initially created with `kubectl apply` or `kubectl create --save-config`, update `.spec.replicas` of the StatefulSet manifests, and then do a `kubectl apply`: diff --git a/docs/tasks/run-application/rolling-update-replication-controller.md b/docs/tasks/run-application/rolling-update-replication-controller.md new file mode 100644 index 0000000000..97b6f0bbd0 --- /dev/null +++ b/docs/tasks/run-application/rolling-update-replication-controller.md @@ -0,0 +1,256 @@ +--- +assignees: +- janetkuo +title: Rolling Update Replication Controller +--- + +* TOC +{:toc} + +## Overview + +To update a service without an outage, `kubectl` supports what is called ['rolling update'](/docs/user-guide/kubectl/kubectl_rolling-update), which updates one pod at a time, rather than taking down the entire service at the same time. See the [rolling update design document](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/simple-rolling-update.md) and the [example of rolling update](/docs/tasks/run-application/rolling-update-replication-controller/) for more information. + +Note that `kubectl rolling-update` only supports Replication Controllers. However, if you deploy applications with Replication Controllers, +consider switching them to [Deployments](/docs/user-guide/deployments/). A Deployment is a higher-level controller that automates rolling updates +of applications declaratively, and therefore is recommended. If you still want to keep your Replication Controllers and use `kubectl rolling-update`, keep reading: + +A rolling update applies changes to the configuration of pods being managed by +a replication controller. The changes can be passed as a new replication +controller configuration file; or, if only updating the image, a new container +image can be specified directly. + +A rolling update works by: + +1. Creating a new replication controller with the updated configuration. +2. Increasing/decreasing the replica count on the new and old controllers until + the correct number of replicas is reached. +3. Deleting the original replication controller. + +Rolling updates are initiated with the `kubectl rolling-update` command: + + $ kubectl rolling-update NAME \ + ([NEW_NAME] --image=IMAGE | -f FILE) + +## Passing a configuration file + +To initiate a rolling update using a configuration file, pass the new file to +`kubectl rolling-update`: + + $ kubectl rolling-update NAME -f FILE + +The configuration file must: + +* Specify a different `metadata.name` value. + +* Overwrite at least one common label in its `spec.selector` field. + +* Use the same `metadata.namespace`. + +Replication controller configuration files are described in +[Creating Replication Controllers](/docs/user-guide/replication-controller/operations/). + +### Examples + + // Update pods of frontend-v1 using new replication controller data in frontend-v2.json. + $ kubectl rolling-update frontend-v1 -f frontend-v2.json + + // Update pods of frontend-v1 using JSON data passed into stdin. + $ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f - + +## Updating the container image + +To update only the container image, pass a new image name and tag with the +`--image` flag and (optionally) a new controller name: + + $ kubectl rolling-update NAME [NEW_NAME] --image=IMAGE:TAG + +The `--image` flag is only supported for single-container pods. Specifying +`--image` with multi-container pods returns an error. + +If no `NEW_NAME` is specified, a new replication controller is created with +a temporary name. Once the rollout is complete, the old controller is deleted, +and the new controller is updated to use the original name. + +The update will fail if `IMAGE:TAG` is identical to the +current value. For this reason, we recommend the use of versioned tags as +opposed to values such as `:latest`. Doing a rolling update from `image:latest` +to a new `image:latest` will fail, even if the image at that tag has changed. +Moreover, the use of `:latest` is not recommended, see +[Best Practices for Configuration](/docs/concepts/configuration/overview/#container-images) for more information. + +### Examples + + // Update the pods of frontend-v1 to frontend-v2 + $ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 + + // Update the pods of frontend, keeping the replication controller name + $ kubectl rolling-update frontend --image=image:v2 + +## Required and optional fields + +Required fields are: + +* `NAME`: The name of the replication controller to update. + +as well as either: + +* `-f FILE`: A replication controller configuration file, in either JSON or + YAML format. The configuration file must specify a new top-level `id` value + and include at least one of the existing `spec.selector` key:value pairs. + See the + [Run Stateless AP Replication Controller](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/#replication-controller-configuration-file) + page for details. +
    +
    + or: +
    +
    +* `--image IMAGE:TAG`: The name and tag of the image to update to. Must be + different than the current image:tag currently specified. + +Optional fields are: + +* `NEW_NAME`: Only used in conjunction with `--image` (not with `-f FILE`). The + name to assign to the new replication controller. +* `--poll-interval DURATION`: The time between polling the controller status + after update. Valid units are `ns` (nanoseconds), `us` or `µs` (microseconds), + `ms` (milliseconds), `s` (seconds), `m` (minutes), or `h` (hours). Units can + be combined (e.g. `1m30s`). The default is `3s`. +* `--timeout DURATION`: The maximum time to wait for the controller to update a + pod before exiting. Default is `5m0s`. Valid units are as described for + `--poll-interval` above. +* `--update-period DURATION`: The time to wait between updating pods. Default + is `1m0s`. Valid units are as described for `--poll-interval` above. + +Additional information about the `kubectl rolling-update` command is available +from the [`kubectl` reference](/docs/user-guide/kubectl/kubectl_rolling-update/). + +## Walkthrough + +Let's say you were running version 1.7.9 of nginx: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: my-nginx +spec: + replicas: 5 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 +``` + +To update to version 1.9.1, you can use [`kubectl rolling-update --image`](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/simple-rolling-update.md) to specify the new image: + +```shell +$ kubectl rolling-update my-nginx --image=nginx:1.9.1 +Created my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 +``` + +In another window, you can see that `kubectl` added a `deployment` label to the pods, whose value is a hash of the configuration, to distinguish the new pods from the old: + +```shell +$ kubectl get pods -l app=nginx -L deployment +NAME READY STATUS RESTARTS AGE DEPLOYMENT +my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-k156z 1/1 Running 0 1m ccba8fbd8cc8160970f63f9a2696fc46 +my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-v95yh 1/1 Running 0 35s ccba8fbd8cc8160970f63f9a2696fc46 +my-nginx-divi2 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e +my-nginx-o0ef1 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e +my-nginx-q6all 1/1 Running 0 8m 2d1d7a8f682934a254002b56404b813e +``` + +`kubectl rolling-update` reports progress as it progresses: + +``` +Scaling up my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 0 to 3, scaling down my-nginx from 3 to 0 (keep 3 pods available, don't exceed 4 pods) +Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 1 +Scaling my-nginx down to 2 +Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 2 +Scaling my-nginx down to 1 +Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 3 +Scaling my-nginx down to 0 +Update succeeded. Deleting old controller: my-nginx +Renaming my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 to my-nginx +replicationcontroller "my-nginx" rolling updated +``` + +If you encounter a problem, you can stop the rolling update midway and revert to the previous version using `--rollback`: + +```shell +$ kubectl rolling-update my-nginx --rollback +Setting "my-nginx" replicas to 1 +Continuing update with existing controller my-nginx. +Scaling up nginx from 1 to 1, scaling down my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 1 to 0 (keep 1 pods available, don't exceed 2 pods) +Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 down to 0 +Update succeeded. Deleting my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 +replicationcontroller "my-nginx" rolling updated +``` + +This is one example where the immutability of containers is a huge asset. + +If you need to update more than just the image (e.g., command arguments, environment variables), you can create a new replication controller, with a new name and distinguishing label value, such as: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: my-nginx-v4 +spec: + replicas: 5 + selector: + app: nginx + deployment: v4 + template: + metadata: + labels: + app: nginx + deployment: v4 + spec: + containers: + - name: nginx + image: nginx:1.9.2 + args: ["nginx", "-T"] + ports: + - containerPort: 80 +``` + +and roll it out: + +```shell +$ kubectl rolling-update my-nginx -f ./nginx-rc.yaml +Created my-nginx-v4 +Scaling up my-nginx-v4 from 0 to 5, scaling down my-nginx from 4 to 0 (keep 4 pods available, don't exceed 5 pods) +Scaling my-nginx-v4 up to 1 +Scaling my-nginx down to 3 +Scaling my-nginx-v4 up to 2 +Scaling my-nginx down to 2 +Scaling my-nginx-v4 up to 3 +Scaling my-nginx down to 1 +Scaling my-nginx-v4 up to 4 +Scaling my-nginx down to 0 +Scaling my-nginx-v4 up to 5 +Update succeeded. Deleting old controller: my-nginx +replicationcontroller "my-nginx-v4" rolling updated +``` + +You can also run the [update demo](/docs/tasks/run-application/rolling-update-replication-controller/) to see a visual representation of the rolling update process. + +## Troubleshooting + +If the `timeout` duration is reached during a rolling update, the operation will +fail with some pods belonging to the new replication controller, and some to the +original controller. + +To continue the update from where it failed, retry using the same command. + +To roll back to the original state before the attempted update, append the +`--rollback=true` flag to the original command. This will revert all changes. diff --git a/docs/tutorials/clusters/apparmor.md b/docs/tutorials/clusters/apparmor.md new file mode 100644 index 0000000000..881c2e72a6 --- /dev/null +++ b/docs/tutorials/clusters/apparmor.md @@ -0,0 +1,393 @@ +--- +assignees: +- stclair +title: AppArmor +--- + +AppArmor is a Linux kernel enhancement that can reduce the potential attack surface of an +application and provide greater defense in depth for Applications. Beta support for AppArmor was +added in Kubernetes v1.4. + +* TOC +{:toc} + +## What is AppArmor + +AppArmor is a Linux kernel security module that supplements the standard Linux user and group based +permissions to confine programs to a limited set of resources. AppArmor can be configured for any +application to reduce its potential attack surface and provide greater defense in depth. It is +configured through profiles tuned to whitelist the access needed by a specific program or container, +such as Linux capabilities, network access, file permissions, etc. Each profile can be run in either +enforcing mode, which blocks access to disallowed resources, or complain mode, which only reports +violations. + +AppArmor can help you to run a more secure deployment by restricting what containers are allowed to +do, and /or providing better auditing through system logs. However, it is important to keep in mind +that AppArmor is not a silver bullet, and can only do so much to protect against exploits in your +application code. It is important to provide good, restrictive profiles, and harden your +applications and cluster from other angles as well. + +AppArmor support in Kubernetes is currently in beta. + +## Prerequisites + +1. **Kubernetes version is at least v1.4**. Kubernetes support for AppArmor was added in + v1.4. Kubernetes components older than v1.4 are not aware of the new AppArmor annotations, and + will **silently ignore** any AppArmor settings that are provided. To ensure that your Pods are + receiving the expected protections, it is important to verify the Kubelet version of your nodes: + + $ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.kubeletVersion}\n{end}' + gke-test-default-pool-239f5d02-gyn2: v1.4.0 + gke-test-default-pool-239f5d02-x1kf: v1.4.0 + gke-test-default-pool-239f5d02-xwux: v1.4.0 + +2. **AppArmor kernel module is enabled**. For the Linux kernel to enforce an AppArmor profile, the + AppArmor kernel module must be installed and enabled. Several distributions enable the module by + default, such as Ubuntu and SUSE, and many others provide optional support. To check whether the + module is enabled, check the `/sys/module/apparmor/parameters/enabled` file: + + $ cat /sys/module/apparmor/parameters/enabled + Y + + If the Kubelet contains AppArmor support (>= v1.4), it will refuse to run a Pod with AppArmor + options if the kernel module is not enabled. + + *Note: Ubuntu carries many AppArmor patches that have not been merged into the upstream Linux + kernel, including patches that add additional hooks and features. Kubernetes has only been + tested with the upstream version, and does not promise support for other features.* + +3. **Container runtime is Docker**. Currently the only Kubernetes-supported container runtime that + also supports AppArmor is Docker. As more runtimes add AppArmor support, the options will be + expanded. You can verify that your nodes are running docker with: + + $ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.containerRuntimeVersion}\n{end}' + gke-test-default-pool-239f5d02-gyn2: docker://1.11.2 + gke-test-default-pool-239f5d02-x1kf: docker://1.11.2 + gke-test-default-pool-239f5d02-xwux: docker://1.11.2 + + If the Kubelet contains AppArmor support (>= v1.4), it will refuse to run a Pod with AppArmor + options if the runtime is not Docker. + +4. **Profile is loaded**. AppArmor is applied to a Pod by specifying an AppArmor profile that each + container should be run with. If any of the specified profiles is not already loaded in the + kernel, the Kubelet (>= v1.4) will reject the Pod. You can view which profiles are loaded on a + node by checking the `/sys/kernel/security/apparmor/profiles` file. For example: + + $ ssh gke-test-default-pool-239f5d02-gyn2 "sudo cat /sys/kernel/security/apparmor/profiles | sort" + apparmor-test-deny-write (enforce) + apparmor-test-audit-write (enforce) + docker-default (enforce) + k8s-nginx (enforce) + + For more details on loading profiles on nodes, see + [Setting up nodes with profiles](#setting-up-nodes-with-profiles). + +As long as the Kubelet version includes AppArmor support (>= v1.4), the Kubelet will reject a Pod +with AppArmor options if any of the prerequisites are not met. You can also verify AppArmor support +on nodes by checking the node ready condition message (though this is likely to be removed in a +later release): + + $ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {.status.conditions[?(@.reason=="KubeletReady")].message}\n{end}' + gke-test-default-pool-239f5d02-gyn2: kubelet is posting ready status. AppArmor enabled + gke-test-default-pool-239f5d02-x1kf: kubelet is posting ready status. AppArmor enabled + gke-test-default-pool-239f5d02-xwux: kubelet is posting ready status. AppArmor enabled + +## Securing a Pod + +*Note: AppArmor is currently in beta, so options are specified as annotations. Once support graduates to +general availability, the annotations will be replaced with first-class fields (more details in +[Upgrade path to GA](#upgrade-path-to-general-availability)).* + +AppArmor profiles are specified *per-container*. To specify the AppArmor profile to run a Pod +container with, add an annotation to the Pod's metadata: + + container.apparmor.security.beta.kubernetes.io/: + +Where `` is the name of the container to apply the profile to, and `` +specifies the profile to apply. The `profile_ref` can be one of: + +- `runtime/default` to apply the runtime's default profile. +- `localhost/` to apply the profile loaded on the host with the name `` + +See the [API Reference](#api-reference) for the full details on the annotation and profile name formats. + +The Kubernetes AppArmor enforcement works by first checking that all the prerequisites have been +met, and then forwarding the profile selection to the container runtime for enforcement. If the +prerequisites have not been met, the Pod will be rejected, and will not run. + +To verify that the profile was applied, you can expect to see the AppArmor security option listed in the container created event: + + $ kubectl get events | grep Created + 22s 22s 1 hello-apparmor Pod spec.containers{hello} Normal Created {kubelet e2e-test-stclair-minion-group-31nt} Created container with docker id 269a53b202d3; Security:[seccomp=unconfined apparmor=k8s-apparmor-example-deny-write] + +You can also verify directly that the container's root process is running with the correct profile by checking its proc attr: + + $ kubectl exec cat /proc/1/attr/current + k8s-apparmor-example-deny-write (enforce) + +## Example + +In this example you'll see: + +- One way to load a profile on a node +- How to enforce the profile on a Pod +- How to check that the profile is loaded +- What happens when a profile is violated +- What happens when a profile cannot be loaded + +*This example assumes you have already set up a cluster with AppArmor support.* + +First, we need to load the profile we want to use onto our nodes. The profile we'll use simply +denies all file writes: + + +{% include code.html language="text" file="deny-write.profile" ghlink="/docs/tutorials/clusters/deny-write.profile" %} + +Since we don't know where the Pod will be scheduled, we'll need to load the profile on all our +nodes. For this example we'll just use SSH to install the profiles, but other approaches are +discussed in [Setting up nodes with profiles](#setting-up-nodes-with-profiles). + + $ NODES=( + # The SSH-accessible domain names of your nodes + gke-test-default-pool-239f5d02-gyn2.us-central1-a.my-k8s + gke-test-default-pool-239f5d02-x1kf.us-central1-a.my-k8s + gke-test-default-pool-239f5d02-xwux.us-central1-a.my-k8s) + $ for NODE in ${NODES[*]}; do ssh $NODE 'sudo apparmor_parser -q < + + profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { + #include + + file, + + # Deny all file writes. + deny /** w, + } + EOF' + done + +Next, we'll run a simple "Hello AppArmor" pod with the deny-write profile: + +{% include code.html language="yaml" file="hello-apparmor-pod.yaml" ghlink="/docs/tutorials/clusters/hello-apparmor-pod.yaml" %} + + $ kubectl create -f /dev/stdin < + Status: Failed + Reason: AppArmor + Message: Pod Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded + IP: + Controllers: + Containers: + hello: + Image: busybox + Port: + Command: + sh + -c + echo 'Hello AppArmor!' && sleep 1h + Requests: + cpu: 100m + Environment Variables: + Volumes: + default-token-dnz7v: + Type: Secret (a volume populated by a Secret) + SecretName: default-token-dnz7v + QoS Tier: Burstable + Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 23s 23s 1 {default-scheduler } Normal Scheduled Successfully assigned hello-apparmor-2 to e2e-test-stclair-minion-group-t1f5 + 23s 23s 1 {kubelet e2e-test-stclair-minion-group-t1f5} Warning AppArmor Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded + +Note the pod status is Failed, with a helpful error message: `Pod Cannot enforce AppArmor: profile +"k8s-apparmor-example-allow-write" is not loaded`. An event was also recorded with the same message. + +## Administration + +### Setting up nodes with profiles + +Kubernetes does not currently provide any native mechanisms for loading AppArmor profiles onto +nodes. There are lots of ways to setup the profiles though, such as: + +- Through a [DaemonSet](../daemons/) that runs a Pod on each node to + ensure the correct profiles are loaded. An example implementation can be found + [here](https://github.com/kubernetes/contrib/tree/master/apparmor/loader). +- At node initialization time, using your node initialization scripts (e.g. Salt, Ansible, etc.) or + image. +- By copying the profiles to each node and loading them through SSH, as demonstrated in the + [Example](#example). + +The scheduler is not aware of which profiles are loaded onto which node, so the full set of profiles +must be loaded onto every node. An alternative approach is to add a node label for each profile (or +class of profiles) on the node, and use a +[node selector](../../user-guide/node-selection/) to ensure the Pod is run on a +node with the required profile. + +### Restricting profiles with the PodSecurityPolicy + +If the PodSecurityPolicy extension is enabled, cluster-wide AppArmor restrictions can be applied. To +enable the PodSecurityPolicy, two flags must be set on the `apiserver`: + + --admission-control=PodSecurityPolicy[,others...] + --runtime-config=extensions/v1beta1/podsecuritypolicy[,others...] + +With the extension enabled, the AppArmor options can be specified as annotations on the PodSecurityPolicy: + + apparmor.security.beta.kubernetes.io/defaultProfileName: + apparmor.security.beta.kubernetes.io/allowedProfileNames: [,others...] + +The default profile name option specifies the profile to apply to containers by default when none is +specified. The allowed profile names option specifies a list of profiles that Pod containers are +allowed to be run with. If both options are provided, the default must be allowed. The profiles are +specified in the same format as on containers. See the [API Reference](#api-reference) for the full +specification. + +### Disabling AppArmor + +If you do not want AppArmor to be available on your cluster, it can be disabled by a command-line flag: + + --feature-gates=AppArmor=false + +When disabled, any Pod that includes an AppArmor profile will fail validation with a "Forbidden" +error. Note that by default docker always enables the "docker-default" profile on non-privileged +pods (if the AppArmor kernel module is enabled), and will continue to do so even if the feature-gate +is disabled. The option to disable AppArmor will be removed when AppArmor graduates to general +availability (GA). + +### Upgrading to Kubernetes v1.4 with AppArmor + +No action is required with respect to AppArmor to upgrade your cluster to v1.4. However, if any +existing pods had an AppArmor annotation, they will not go through validation (or PodSecurityPolicy +admission). If permissive profiles are loaded on the nodes, a malicious user could pre-apply a +permissive profile to escalate the pod privileges above the docker-default. If this is a concern, it +is recommended to scrub the cluster of any pods containing an annotation with +`apparmor.security.beta.kubernetes.io`. + +### Upgrade path to General Availability + +When AppArmor is ready to be graduated to general availability (GA), the options currently specified +through annotations will be converted to fields. Supporting all the upgrade and downgrade paths +through the transition is very nuanced, and will be explained in detail when the transition +occurs. We will commit to supporting both fields and annotations for at least 2 releases, and will +explicitly reject the annotations for at least 2 releases after that. + +## Authoring Profiles + +Getting AppArmor profiles specified correctly can be a tricky business. Fortunately there are some +tools to help with that: + +- `aa-genprof` and `aa-logprof` generate profile rules by monitoring an application's activity and + logs, and admitting the actions it takes. Further instructions are provided by the + [AppArmor documentation](http://wiki.apparmor.net/index.php/Profiling_with_tools). +- [bane](https://github.com/jfrazelle/bane) is an AppArmor profile generator for Docker that uses a + simplified profile language. + +It is recommended to run your application through Docker on a development workstation to generate +the profiles, but there is nothing preventing running the tools on the Kubernetes node where your +Pod is running. + +To debug problems with AppArmor, you can check the system logs to see what, specifically, was +denied. AppArmor logs verbose messages to `dmesg`, and errors can usually be found in the system +logs or through `journalctl`. More information is provided in +[AppArmor failures](http://wiki.apparmor.net/index.php/AppArmor_Failures). + +Additional resources: + +- [Quick guide to the AppArmor profile language](http://wiki.apparmor.net/index.php/QuickProfileLanguage) +- [AppArmor core policy reference](http://wiki.apparmor.net/index.php/ProfileLanguage) + +## API Reference + +**Pod Annotation**: + +Specifying the profile a container will run with: + +- **key**: `container.apparmor.security.beta.kubernetes.io/` + Where `` matches the name of a container in the Pod. + A separate profile can be specified for each container in the Pod. +- **value**: a profile reference, described below + +**Profile Reference**: + +- `runtime/default`: Refers to the default runtime profile. + - Equivalent to not specifying a profile (without a PodSecurityPolicy default), except it still + requires AppArmor to be enabled. + - For Docker, this resolves to the + [`docker-default`](https://docs.docker.com/engine/security/apparmor/) profile for non-privileged + containers, and unconfined (no profile) for privileged containers. +- `localhost/`: Refers to a profile loaded on the node (localhost) by name. + - The possible profile names are detailed in the + [core policy reference](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#Profile_names_and_attachment_specifications) + +Any other profile reference format is invalid. + +**PodSecurityPolicy Annotations** + +Specifying the default profile to apply to containers when none is provided: + +- **key**: `apparmor.security.beta.kubernetes.io/defaultProfileName` +- **value**: a profile reference, described above + +Specifying the list of profiles Pod containers is allowed to specify: + +- **key**: `apparmor.security.beta.kubernetes.io/allowedProfileNames` +- **value**: a comma-separated list of profile references (described above) + - Although an escaped comma is a legal character in a profile name, it cannot be explicitly + allowed here diff --git a/docs/tutorials/clusters/deny-write.profile b/docs/tutorials/clusters/deny-write.profile new file mode 100644 index 0000000000..c2653c7112 --- /dev/null +++ b/docs/tutorials/clusters/deny-write.profile @@ -0,0 +1,10 @@ +#include + +profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { + #include + + file, + + # Deny all file writes. + deny /** w, +} diff --git a/docs/tutorials/clusters/hello-apparmor-pod.yaml b/docs/tutorials/clusters/hello-apparmor-pod.yaml new file mode 100644 index 0000000000..3e9b3b2a9c --- /dev/null +++ b/docs/tutorials/clusters/hello-apparmor-pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: hello-apparmor + annotations: + # Tell Kubernetes to apply the AppArmor profile "k8s-apparmor-example-deny-write". + # Note that this is ignored if the Kubernetes node is not running version 1.4 or greater. + container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write +spec: + containers: + - name: hello + image: busybox + command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ] diff --git a/docs/tutorials/federation/set-up-cluster-federation-kubefed.md b/docs/tutorials/federation/set-up-cluster-federation-kubefed.md new file mode 100644 index 0000000000..4af8db60b5 --- /dev/null +++ b/docs/tutorials/federation/set-up-cluster-federation-kubefed.md @@ -0,0 +1,208 @@ +--- +assignees: +- madhusudancs +title: Setting up Cluster Federation with Kubefed +--- + +* TOC +{:toc} + +Kubernetes version 1.5 includes a new command line tool called +`kubefed` to help you administrate your federated clusters. +`kubefed` helps you to deploy a new Kubernetes cluster federation +control plane, and to add clusters to or remove clusters from an +existing federation control plane. + +This guide explains how to administer a Kubernetes Cluster Federation +using `kubefed`. + +> Note: `kubefed` is an alpha feature in Kubernetes 1.5. + +## Prerequisites + +This guide assumes that you have a running Kubernetes cluster. Please +see one of the [getting started](/docs/getting-started-guides/) guides +for installation instructions for your platform. + + +## Getting `kubefed` + +Download the client tarball corresponding to Kubernetes version 1.5 +or later +[from the release page](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md), +extract the binaries in the tarball to one of the directories +in your `$PATH` and set the executable permission on those binaries. + +Note: The URL in the curl command below downloads the binaries for +Linux amd64. If you are on a different platform, please use the URL +for the binaries appropriate for your platform. You can find the list +of available binaries on the [release page](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md#client-binaries-1). + + +```shell +curl -O https://storage.googleapis.com/kubernetes-release/release/v1.5.2/kubernetes-client-linux-amd64.tar.gz +tar -xzvf kubernetes-client-linux-amd64.tar.gz +sudo cp kubernetes/client/bin/kubefed /usr/local/bin +sudo chmod +x /usr/local/bin/kubefed +sudo cp kubernetes/client/bin/kubectl /usr/local/bin +sudo chmod +x /usr/local/bin/kubectl +``` + + +## Choosing a host cluster. + +You'll need to choose one of your Kubernetes clusters to be the +*host cluster*. The host cluster hosts the components that make up +your federation control plane. Ensure that you have a `kubeconfig` +entry in your local `kubeconfig` that corresponds to the host cluster. +You can verify that you have the required `kubeconfig` entry by +running: + +```shell +kubectl config get-contexts +``` + +The output should contain an entry corresponding to your host cluster, +similar to the following: + +``` +CURRENT NAME CLUSTER AUTHINFO NAMESPACE + gke_myproject_asia-east1-b_gce-asia-east1 gke_myproject_asia-east1-b_gce-asia-east1 gke_myproject_asia-east1-b_gce-asia-east1 +``` + + +You'll need to provide the `kubeconfig` context (called name in the +entry above) for your host cluster when you deploy your federation +control plane. + + +## Deploying a federation control plane. + +To deploy a federation control plane on your host cluster, run +`kubefed init` command. When you use `kubefed init`, you must provide +the following: + +* Federation name +* `--host-cluster-context`, the `kubeconfig` context for the host cluster +* `--dns-zone-name`, a domain name suffix for your federated services + +The following example command deploys a federation control plane with +the name `fellowship`, a host cluster context `rivendell`, and the +domain suffix `example.com`: + +```shell +kubefed init fellowship --host-cluster-context=rivendell --dns-zone-name="example.com" +``` + +The domain suffix specified in `--dns-zone-name` must be an existing +domain that you control, and that is programmable by your DNS provider. + +`kubefed init` sets up the federation control plane in the host +cluster and also adds an entry for the federation API server in your +local kubeconfig. Note that in the alpha release in Kubernetes 1.5, +`kubefed init` does not automatically set the current context to the +newly deployed federation. You can set the current context manually by +running: + +```shell +kubectl config use-context fellowship +``` + +where `fellowship` is the name of your federation. + + +## Adding a cluster to a federation + +Once you've deployed a federation control plane, you'll need to make +that control plane aware of the clusters it should manage. You can add +a cluster to your federation by using the `kubefed join` command. + +To use `kubefed join`, you'll need to provide the name of the cluster +you want to add to the federation, and the `--host-cluster-context` +for the federation control plane's host cluster. + +The following example command adds the cluster `gondor` to the +federation with host cluster `rivendell`: + +``` +kubefed join gondor --host-cluster-context=rivendell +``` + +> Note: Kubernetes requires that you manually join clusters to a +federation because the federation control plane manages only those +clusters that it is responsible for managing. Adding a cluster tells +the federation control plane that it is responsible for managing that +cluster. + +### Naming rules and customization + +The cluster name you supply to `kubefed join` must be a valid RFC 1035 +label. + +Furthermore, federation control plane requires credentials of the +joined clusters to operate on them. These credentials are obtained +from the local kubeconfig. `kubefed join` uses the cluster name +specified as the argument to look for the cluster's context in the +local kubeconfig. If it fails to find a matching context, it exits +with an error. + +This might cause issues in cases where context names for each cluster +in the federation don't follow +[RFC 1035](https://www.ietf.org/rfc/rfc1035.txt) label naming rules. +In such cases, you can specify a cluster name that conforms to the +[RFC 1035](https://www.ietf.org/rfc/rfc1035.txt) label naming rules +and specify the cluster context using the `--cluster-context` flag. +For example, if context of the cluster your are joining is +`gondor_needs-no_king`, then you can join the cluster by running: + +```shell +kubefed join gondor --host-cluster-context=rivendell --cluster-context=gondor_needs-no_king +``` + +#### Secret name + +Cluster credentials required by the federation control plane as +described above are stored as a secret in the host cluster. The name +of the secret is also derived from the cluster name. + +However, the name of a secret object in Kubernetes should conform +to the DNS subdomain name specification described in +[RFC 1123](https://tools.ietf.org/html/rfc1123). If this isn't the +case, you can pass the secret name to `kubefed join` using the +`--secret-name` flag. For example, if the cluster name is `noldor` and +the secret name is `11kingdom`, you can join the cluster by +running: + +```shell +kubefed join noldor --host-cluster-context=rivendell --secret-name=11kingdom +``` + +Note: If your cluster name does not conform to the DNS subdomain name +specification, all you need to do is supply the secret name via the +`--secret-name` flag. `kubefed join` automatically creates the secret +for you. + + +## Removing a cluster from a federation + +To remove a cluster from a federation, run the `kubefed unjoin` +command with the cluster name and the federation's +`--host-cluster-context`: + +``` +kubefed unjoin gondor --host-cluster-context=rivendell +``` + + +## Turning down the federation control plane: + +Proper cleanup of federation control plane is not fully implemented in +this alpha release of `kubefed`. However, for the time being, deleting +the federation system namespace should remove all the resources except +the persistent storage volume dynamically provisioned for the +federation control plane's etcd. You can delete the federation +namespace by running the following command: + +``` +$ kubectl delete ns federation-system +``` diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md index 76e42570b1..25b8cca32e 100644 --- a/docs/tutorials/index.md +++ b/docs/tutorials/index.md @@ -7,14 +7,14 @@ A tutorial shows how to accomplish a goal that is larger than a single [task](/docs/tasks/). Typically a tutorial has several sections, each of which has a sequence of steps. -#### Kubernetes Basics - * [Kubernetes Basics](/docs/tutorials/kubernetes-basics/) is an in-depth interactive tutorial that helps you understand the Kubernetes system and try out some basic Kubernetes features. -#### Stateless Applications +* [Online Training Course](https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615) * [Hello Minikube](/docs/tutorials/stateless-application/hello-minikube/) +#### Stateless Applications + * [Running a Stateless Application Using a Deployment](/docs/tutorials/stateless-application/run-stateless-application-deployment/) * [Using a Service to Access an Application in a Cluster](/docs/tutorials/stateless-application/expose-external-ip-address-service/) diff --git a/docs/tutorials/kubernetes-basics/cluster-intro.html b/docs/tutorials/kubernetes-basics/cluster-intro.html index 830b651594..1041f1af36 100644 --- a/docs/tutorials/kubernetes-basics/cluster-intro.html +++ b/docs/tutorials/kubernetes-basics/cluster-intro.html @@ -74,7 +74,7 @@ title: Using Minikube to Create a Cluster
    diff --git a/docs/tutorials/kubernetes-basics/expose-intro.html b/docs/tutorials/kubernetes-basics/expose-intro.html index 9ee7a4117a..ad4394b0e4 100644 --- a/docs/tutorials/kubernetes-basics/expose-intro.html +++ b/docs/tutorials/kubernetes-basics/expose-intro.html @@ -28,7 +28,7 @@ title: Using a Service to Expose Your App

    Kubernetes Services

    -

    While Pods do have their own unique IP across the cluster, those IP's are not exposed outside Kubernetes. Taking into account that over time Pods may be terminated, deleted or replaced by other Pods, we need a way to let other Pods and applications automatically discover each other. Kubernetes addresses this by grouping Pods in Services. A Kubernetes Service is an abstraction layer which defines a logical set of Pods and enables external traffic exposure, load balancing and service discovery for those Pods.

    +

    While Pods do have their own unique IP across the cluster, those IPs are not exposed outside Kubernetes. Taking into account that over time Pods may be terminated, deleted or replaced by other Pods, we need a way to let other Pods and applications automatically discover each other. Kubernetes addresses this by grouping Pods in Services. A Kubernetes Service is an abstraction layer which defines a logical set of Pods and enables external traffic exposure, load balancing and service discovery for those Pods.

    This abstraction will allow us to expose Pods to traffic originating from outside the cluster. Services have their own unique cluster-private IP address and expose a port to receive traffic. If you choose to expose the service outside the cluster, the options are:

      diff --git a/docs/concepts/tools/kubectl/object-management-using-declarative-config.md b/docs/tutorials/object-management-kubectl/declarative-object-management-configuration.md similarity index 98% rename from docs/concepts/tools/kubectl/object-management-using-declarative-config.md rename to docs/tutorials/object-management-kubectl/declarative-object-management-configuration.md index 5033bbac8c..f0e1fea561 100644 --- a/docs/concepts/tools/kubectl/object-management-using-declarative-config.md +++ b/docs/tutorials/object-management-kubectl/declarative-object-management-configuration.md @@ -1,5 +1,8 @@ --- title: Declarative Management of Kubernetes Objects Using Configuration Files +redirect_from: +- "/docs/concepts/tools/kubectl/object-management-using-declarative-config/" +- "/docs/concepts/tools/kubectl/object-management-using-declarative-config.html" --- {% capture overview %} @@ -382,7 +385,7 @@ is used to identify fields that have been removed from the configuration file and need to be cleared from the live configuration. Here are the steps used to caluculate which fields should be deleted or set: -1. Calculate the fields to delete. Thes are the fields present in `last-applied-configuration` and missing from the configuration file. +1. Calculate the fields to delete. These are the fields present in `last-applied-configuration` and missing from the configuration file. 2. Calculate the fields to add or set. These are the fields present in the configuration file whose values don't match the live configuration. Here's an example. Suppose this is the configuration file for a Deployment object: @@ -949,8 +952,8 @@ The recommended approach for ThirdPartyResources is to use [imperative object co {% endcapture %} {% capture whatsnext %} -- [Managing Kubernetes Objects Using Imperative Commands](/docs/concepts/tools/kubectl/object-management-using-imperative-commands/) -- [Imperative Management of Kubernetes Objects Using Configuration Files](/docs/concepts/tools/kubectl/object-management-using-imperative-config/) +- [Managing Kubernetes Objects Using Imperative Commands](/docs/tutorials/object-management-kubectl/imperative-object-management-command/) +- [Imperative Management of Kubernetes Objects Using Configuration Files](/docs/tutorials/object-management-kubectl/imperative-object-management-configuration/) - [Kubectl Command Reference](/docs/user-guide/kubectl/v1.5/) - [Kubernetes Object Schema Reference](/docs/resources-reference/v1.5/) {% endcapture %} diff --git a/docs/concepts/tools/kubectl/object-management-using-imperative-commands.md b/docs/tutorials/object-management-kubectl/imperative-object-management-command.md similarity index 94% rename from docs/concepts/tools/kubectl/object-management-using-imperative-commands.md rename to docs/tutorials/object-management-kubectl/imperative-object-management-command.md index 372e5c0584..e658b0dcda 100644 --- a/docs/concepts/tools/kubectl/object-management-using-imperative-commands.md +++ b/docs/tutorials/object-management-kubectl/imperative-object-management-command.md @@ -1,5 +1,8 @@ --- title: Managing Kubernetes Objects Using Imperative Commands +redirect_from: +- "/docs/concepts/tools/kubectl/object-management-using-imperative-commands/" +- "/docs/concepts/tools/kubectl/object-management-using-imperative-commands.html" --- {% capture overview %} @@ -150,8 +153,8 @@ kubectl create --edit -f /tmp/srv.yaml {% endcapture %} {% capture whatsnext %} -- [Managing Kubernetes Objects Using Object Configuration (Imperative)](/docs/concepts/tools/kubectl/object-management-using-imperative-config/) -- [Managing Kubernetes Objects Using Object Configuration (Declarative)](/docs/concepts/tools/kubectl/object-management-using-declarative-config/) +- [Managing Kubernetes Objects Using Object Configuration (Imperative)](/docs/tutorials/object-management-kubectl/imperative-object-management-configuration/) +- [Managing Kubernetes Objects Using Object Configuration (Declarative)](/docs/tutorials/object-management-kubectl/declarative-object-management-configuration/) - [Kubectl Command Reference](/docs/user-guide/kubectl/v1.5/) - [Kubernetes Object Schema Reference](/docs/resources-reference/v1.5/) {% endcapture %} diff --git a/docs/concepts/tools/kubectl/object-management-using-imperative-config.md b/docs/tutorials/object-management-kubectl/imperative-object-management-configuration.md similarity index 92% rename from docs/concepts/tools/kubectl/object-management-using-imperative-config.md rename to docs/tutorials/object-management-kubectl/imperative-object-management-configuration.md index 065e27c6dd..196d26fa8a 100644 --- a/docs/concepts/tools/kubectl/object-management-using-imperative-config.md +++ b/docs/tutorials/object-management-kubectl/imperative-object-management-configuration.md @@ -1,5 +1,8 @@ --- title: Imperative Management of Kubernetes Objects Using Configuration Files +redirect_from: +- "/docs/concepts/tools/kubectl/object-management-using-imperative-config/" +- "/docs/concepts/tools/kubectl/object-management-using-imperative-config.html" --- {% capture overview %} @@ -120,8 +123,8 @@ template: {% endcapture %} {% capture whatsnext %} -- [Managing Kubernetes Objects Using Imperative Commands](/docs/concepts/tools/kubectl/object-management-using-imperative-commands/) -- [Managing Kubernetes Objects Using Object Configuration (Declarative)](/docs/concepts/tools/kubectl/object-management-using-declarative-config/) +- [Managing Kubernetes Objects Using Imperative Commands](/docs/tutorials/object-management-kubectl/imperative-object-management-command/) +- [Managing Kubernetes Objects Using Object Configuration (Declarative)](/docs/tutorials/object-management-kubectl/declarative-object-management-configuration/) - [Kubectl Command Reference](/docs/user-guide/kubectl/v1.5/) - [Kubernetes Object Schema Reference](/docs/resources-reference/v1.5/) {% endcapture %} diff --git a/docs/concepts/tools/kubectl/object-management-overview.md b/docs/tutorials/object-management-kubectl/object-management.md similarity index 93% rename from docs/concepts/tools/kubectl/object-management-overview.md rename to docs/tutorials/object-management-kubectl/object-management.md index 2604a50468..96804ef109 100644 --- a/docs/concepts/tools/kubectl/object-management-overview.md +++ b/docs/tutorials/object-management-kubectl/object-management.md @@ -1,5 +1,8 @@ --- title: Kubernetes Object Management +redirect_from: +- "/docs/concepts/tools/kubectl/object-management-overview/" +- "/docs/concepts/tools/kubectl/object-management-overview.html" --- {% capture overview %} @@ -162,9 +165,9 @@ Disadvantages compared to imperative object configuration: {% endcapture %} {% capture whatsnext %} -- [Managing Kubernetes Objects Using Imperative Commands](/docs/concepts/tools/kubectl/object-management-using-imperative-commands/) -- [Managing Kubernetes Objects Using Object Configuration (Imperative)](/docs/concepts/tools/kubectl/object-management-using-imperative-config/) -- [Managing Kubernetes Objects Using Object Configuration (Declarative)](/docs/concepts/tools/kubectl/object-management-using-declarative-config/) +- [Managing Kubernetes Objects Using Imperative Commands](/docs/tutorials/object-management-kubectl/imperative-object-management-command/) +- [Managing Kubernetes Objects Using Object Configuration (Imperative)](/docs/tutorials/object-management-kubectl/imperative-object-management-configuration/) +- [Managing Kubernetes Objects Using Object Configuration (Declarative)](/docs/tutorials/object-management-kubectl/declarative-object-management-configuration/) - [Kubectl Command Reference](/docs/user-guide/kubectl/v1.5/) - [Kubernetes Object Schema Reference](/docs/resources-reference/v1.5/) diff --git a/docs/concepts/tools/kubectl/simple_deployment.yaml b/docs/tutorials/object-management-kubectl/simple_deployment.yaml similarity index 100% rename from docs/concepts/tools/kubectl/simple_deployment.yaml rename to docs/tutorials/object-management-kubectl/simple_deployment.yaml diff --git a/docs/concepts/tools/kubectl/update_deployment.yaml b/docs/tutorials/object-management-kubectl/update_deployment.yaml similarity index 100% rename from docs/concepts/tools/kubectl/update_deployment.yaml rename to docs/tutorials/object-management-kubectl/update_deployment.yaml diff --git a/docs/tutorials/services/source-ip.md b/docs/tutorials/services/source-ip.md index 56daa8b345..0df6c11f58 100644 --- a/docs/tutorials/services/source-ip.md +++ b/docs/tutorials/services/source-ip.md @@ -20,8 +20,8 @@ of Services, and how you can toggle this behavior according to your needs. This document makes use of the following terms: * [NAT](https://en.wikipedia.org/wiki/Network_address_translation): network address translation -* [Source NAT](/docs/user-guide/services/#ips-and-vips): replacing the source IP on a packet, usually with a node's IP -* [Destination NAT](/docs/user-guide/services/#ips-and-vips): replacing the destination IP on a packet, usually with a pod IP +* [Source NAT](https://en.wikipedia.org/wiki/Network_address_translation#SNAT): replacing the source IP on a packet, usually with a node's IP +* [Destination NAT](https://en.wikipedia.org/wiki/Network_address_translation#DNAT): replacing the destination IP on a packet, usually with a pod IP * [VIP](/docs/user-guide/services/#ips-and-vips): a virtual IP, such as the one assigned to every Kubernetes Service * [Kube-proxy](/docs/user-guide/services/#virtual-ips-and-service-proxies): a network daemon that orchestrates Service VIP management on every node @@ -132,7 +132,7 @@ client_address=10.240.0.5 client_address=10.240.0.3 ``` -Note that these are not your IPs, they're cluster internal IPs. This is what happens: +Note that these are not the correct client IPs, they're cluster internal IPs. This is what happens: * Client sends packet to `node2:nodePort` * `node2` replaces the source IP address (SNAT) in the packet with its own IP address @@ -174,7 +174,7 @@ service "nodeport" annotated Now, re-run the test: ```console -$ for node in $NODES; do curl --connect-timeout 1 -s $node:$NODEPORT | grep -i client_address; do +$ for node in $NODES; do curl --connect-timeout 1 -s $node:$NODEPORT | grep -i client_address; done client_address=104.132.1.79 ``` diff --git a/docs/tutorials/stateful-application/zookeeper.md b/docs/tutorials/stateful-application/zookeeper.md index ba2bb219d6..e31d8e280b 100644 --- a/docs/tutorials/stateful-application/zookeeper.md +++ b/docs/tutorials/stateful-application/zookeeper.md @@ -580,7 +580,7 @@ env: key: purge.interval ``` -The entry point of the container invokes a bash script, `zkConfig.sh`, prior to +The entry point of the container invokes a bash script, `zkGenConfig.sh`, prior to launching the ZooKeeper server process. This bash script generates the ZooKeeper configuration files from the supplied environment variables. @@ -653,7 +653,7 @@ ZK_LOG_DIR=/var/log/zookeeper ### Configuring Logging -One of the files generated by the `zkConfigGen.sh` script controls ZooKeeper's logging. +One of the files generated by the `zkGenConfig.sh` script controls ZooKeeper's logging. ZooKeeper uses [Log4j](http://logging.apache.org/log4j/2.x/), and, by default, it uses a time and size based rolling file appender for its logging configuration. Get the logging configuration from one of Pods in the `zk` StatefulSet. diff --git a/docs/tutorials/stateless-application/deployment-scale.yaml b/docs/tutorials/stateless-application/deployment-scale.yaml index 2968b88360..7259c97603 100644 --- a/docs/tutorials/stateless-application/deployment-scale.yaml +++ b/docs/tutorials/stateless-application/deployment-scale.yaml @@ -3,7 +3,7 @@ kind: Deployment metadata: name: nginx-deployment spec: - replicas: 4 + replicas: 4 # Update the replicas from 2 to 4 template: metadata: labels: @@ -11,6 +11,6 @@ spec: spec: containers: - name: nginx - image: nginx:1.8 # Update the version of nginx from 1.7.9 to 1.8 + image: nginx:1.8 ports: - containerPort: 80 diff --git a/docs/tutorials/stateless-application/expose-external-ip-address-service.md b/docs/tutorials/stateless-application/expose-external-ip-address-service.md index f4a63b1e31..8564ed7d72 100644 --- a/docs/tutorials/stateless-application/expose-external-ip-address-service.md +++ b/docs/tutorials/stateless-application/expose-external-ip-address-service.md @@ -1,5 +1,8 @@ --- title: Using a Service to Access an Application in a Cluster +redirect_from: +- "/docs/user-guide/quick-start/" +- "/docs/user-guide/quick-start.html" --- {% capture overview %} diff --git a/docs/tutorials/stateless-application/hello-minikube.md b/docs/tutorials/stateless-application/hello-minikube.md index 6f2a47b897..70fed7db16 100644 --- a/docs/tutorials/stateless-application/hello-minikube.md +++ b/docs/tutorials/stateless-application/hello-minikube.md @@ -74,10 +74,9 @@ chmod +x ./kubectl sudo mv ./kubectl /usr/local/bin/kubectl ``` Determine whether you can access sites like [https://cloud.google.com/container-registry/](https://cloud.google.com/container-registry/) directly without a proxy, by opening a new terminal and using + ```shell -export http_proxy="" -export https_proxy="" -curl https://cloud.google.com/container-registry/ +curl --proxy "" https://cloud.google.com/container-registry/ ``` If NO proxy is required, start the Minikube cluster: diff --git a/docs/tutorials/stateless-application/run-stateless-ap-replication-controller.md b/docs/tutorials/stateless-application/run-stateless-ap-replication-controller.md new file mode 100644 index 0000000000..6e33fce6e1 --- /dev/null +++ b/docs/tutorials/stateless-application/run-stateless-ap-replication-controller.md @@ -0,0 +1,258 @@ +--- +assignees: +- bprashanth +title: Run Stateless AP Replication Controller +--- + +* TOC +{:toc} + +A replication controller ensures that a specified number of pod "replicas" are +running at any one time. If there are too many, it will kill some. If there are +too few, it will start more. + +## Creating a replication controller + +Replication controllers are created with `kubectl create`: + +```shell +$ kubectl create -f FILE +``` + +Where: + +* `-f FILE` or `--filename FILE` is a relative path to a + [configuration file](#replication_controller_configuration_file) in + either JSON or YAML format. + +You can use the [sample file](#sample_file) below to try a create request. + +A successful create request returns the name of the replication controller. To +view more details about the controller, see +[Viewing replication controllers](#viewing_replication_controllers) below. + +### Replication controller configuration file + +When creating a replication controller, you must point to a configuration file +as the value of the `-f` flag. The configuration +file can be formatted as YAML or as JSON, and supports the following fields: + +```json +{ + "apiVersion": "v1", + "kind": "ReplicationController", + "metadata": { + "name": "", + "labels": "", + "namespace": "" + }, + "spec": { + "replicas": int, + "selector": { + "":"" + }, + "template": { + "metadata": { + "labels": { + "":"" + } + }, + "spec": { + // See 'The spec schema' below + } + } + } +} +``` + +Required fields are: + +* `kind`: Always `ReplicationController`. +* `apiVersion`: Currently `v1`. +* `metadata`: An object containing: + * `name`: Required if `generateName` is not specified. The name of this + replication controller. It must be an + [RFC1035](https://www.ietf.org/rfc/rfc1035.txt) compatible value and be + unique within the namespace. + * `labels`: Optional. Labels are arbitrary key:value pairs that can be used + for grouping and targeting by other resources and services. + * `generateName`: Required if `name` is not set. A prefix to use to generate + a unique name. Has the same validation rules as `name`. + * `namespace`: Optional. The namespace of the replication controller. + * `annotations`: Optional. A map of string keys and values that can be used + by external tooling to store and retrieve arbitrary metadata about + objects. +* `spec`: The configuration for this replication controller. It must + contain: + * `replicas`: The number of pods to create and maintain. + * `selector`: A map of key:value pairs assigned to the set of pods that + this replication controller is responsible for managing. **This must** + **match the key:value pairs in the `template`'s `labels` field**. + * `template` contains: + * A `metadata` object with `labels` for the pod. + * The [`spec` schema](#the_spec_schema) that defines the pod + configuration. + +### The `spec` schema + +The `spec` schema (that is a child of `template`) is described in the locations +below: + +* The [`spec` schema](/docs/user-guide/pods/multi-container/#the_spec_schema) + section of the Creating Multi-Container Pods page covers required and + frequently-used fields. +* The entire `spec` schema is documented in the + [Kubernetes API reference](/docs/api-reference/v1/definitions/#_v1_podspec). + +### Sample file + +The following sample file creates 2 pods, each containing a single container +using the `redis` image. Port 80 on each container is opened. The replication +controller is tagged with the `serving` label. The pods are given the label +`frontend` and the `selector` is set to `frontend`, to indicate that the +controller should manage pods with the `frontend` label. + +```json +{ + "kind": "ReplicationController", + "apiVersion": "v1", + "metadata": { + "name": "frontend-controller", + "labels": { + "state": "serving" + } + }, + "spec": { + "replicas": 2, + "selector": { + "app": "frontend" + }, + "template": { + "metadata": { + "labels": { + "app": "frontend" + } + }, + "spec": { + "volumes": null, + "containers": [ + { + "name": "php-redis", + "image": "redis", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "dnsPolicy": "ClusterFirst" + } + } + } +} +``` + +## Updating replication controller pods + +See [Rolling Updates](/docs/tasks/run-application/rolling-update-replication-controller/). + +## Resizing a replication controller + +To increase or decrease the number of pods under a replication controller's +control, use the `kubectl scale` command: + + $ kubectl scale rc NAME --replicas=COUNT \ + [--current-replicas=COUNT] \ + [--resource-version=VERSION] + +Tip: You can use the `rc` alias in your commands in place of +`replicationcontroller`. + +Required fields are: + +* `NAME`: The name of the replication controller to update. +* `--replicas=COUNT`: The desired number of replicas. + +Optional fields are: + +* `--current-replicas=COUNT`: A precondition for current size. If specified, + the resize will only take place if the current number of replicas matches + this value. +* `--resource-version=VERSION`: A precondition for resource version. If + specified, the resize will only take place if the current replication + controller version matches this value. Versions are specified in the + `labels` field of the replication controller's configuration file, as a + key:value pair with a key of `version`. For example, + `--resource-version test` matches: + + "labels": { + "version": "test" + } + +## Viewing replication controllers + +To list replication controllers on a cluster, use the `kubectl get` command: + +```shell +$ kubectl get rc +``` + +A successful get command returns all replication controllers on the cluster in +the specified or default namespace. For example: + +```shell +CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS +frontend php-redis redis name=frontend 2 +``` + +You can also use `get rc NAME` to return information about a specific +replication controller. + +To view detailed information about a specific replication controller, use the +`kubectl describe` command: + +```shell +$ kubectl describe rc NAME +``` + +A successful describe request returns details about the replication controller +including number and status of pods managed, and recent events: + +```conf +Name: frontend +Namespace: default +Image(s): gcr.io/google_samples/gb-frontend:v3 +Selector: name=frontend +Labels: name=frontend +Replicas: 2 current / 2 desired +Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed +Events: + FirstSeen LastSeen Count From SubobjectPath Reason Message + Fri, 06 Nov 2015 16:52:50 -0800 Fri, 06 Nov 2015 16:52:50 -0800 1 {replication-controller } SuccessfulCreate Created pod: frontend-gyx2h + Fri, 06 Nov 2015 16:52:50 -0800 Fri, 06 Nov 2015 16:52:50 -0800 1 {replication-controller } SuccessfulCreate Created pod: frontend-vc9w4 +``` + +## Deleting replication controllers + +To delete a replication controller as well as the pods that it controls, use +`kubectl delete`: + +```shell +$ kubectl delete rc NAME +``` + +By default, `kubectl delete rc` will resize the controller to zero (effectively +deleting all pods) before deleting it. + +To delete a replication controller without deleting its pods, use +`kubectl delete` and specify `--cascade=false`: + +```shell +$ kubectl delete rc NAME --cascade=false +``` + +A successful delete request returns the name of the deleted resource. diff --git a/docs/tutorials/stateless-application/run-stateless-application-deployment.md b/docs/tutorials/stateless-application/run-stateless-application-deployment.md index 8e3d725752..831ed6bb45 100644 --- a/docs/tutorials/stateless-application/run-stateless-application-deployment.md +++ b/docs/tutorials/stateless-application/run-stateless-application-deployment.md @@ -1,5 +1,12 @@ --- title: Running a Stateless Application Using a Deployment +redirect_from: +- "/docs/user-guide/simple-nginx/" +- "/docs/user-guide/simple-nginx.html" +- "/docs/user-guide/pods/single-container/" +- "/docs/user-guide/pods/single-container.html" +- "/docs/user-guide/deploying-applications/" +- "/docs/user-guide/deploying-applications.html" --- {% capture overview %} diff --git a/docs/user-guide/accessing-the-cluster.md b/docs/user-guide/accessing-the-cluster.md index 8fb9e6b0b4..1f5a65aa61 100644 --- a/docs/user-guide/accessing-the-cluster.md +++ b/docs/user-guide/accessing-the-cluster.md @@ -1,10 +1,10 @@ ---- -assignees: -- lavalamp -- mikedanese -title: Accessing Clusters ---- - +--- +assignees: +- lavalamp +- mikedanese +title: Accessing Clusters +--- + * TOC {:toc} @@ -125,6 +125,7 @@ with future high-availability support. The Kubernetes project-supported Go client library is at [https://github.com/kubernetes/client-go](https://github.com/kubernetes/client-go). To use it, + * To get the library, run the following command: `go get k8s.io/client-go//kubernetes` See [https://github.com/kubernetes/client-go](https://github.com/kubernetes/client-go) to see which versions are supported. * Write an application atop of the client-go clients. Note that client-go defines its own API objects, so if needed, please import API definitions from client-go rather than from the main repository, e.g., `import "k8s.io/client-go/1.4/pkg/api/v1"` is correct. diff --git a/docs/user-guide/compute-resources.md b/docs/user-guide/compute-resources.md index d2856f50aa..51fcaafa9d 100644 --- a/docs/user-guide/compute-resources.md +++ b/docs/user-guide/compute-resources.md @@ -5,368 +5,6 @@ assignees: title: Managing Compute Resources --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -When specifying a [pod](/docs/user-guide/pods), you can optionally specify how much CPU and memory (RAM) each -container needs. When containers have their resource requests specified, the scheduler is -able to make better decisions about which nodes to place pods on; and when containers have their -limits specified, contention for resources on a node can be handled in a specified manner. For -more details about the difference between requests and limits, please refer to -[Resource QoS](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/resource-qos.md). - -*CPU* and *memory* are each a *resource type*. A resource type has a base unit. CPU is specified -in units of cores. Memory is specified in units of bytes. - -CPU and RAM are collectively referred to as *compute resources*, or just *resources*. Compute -resources are measureable quantities which can be requested, allocated, and consumed. They are -distinct from [API resources](/docs/user-guide/working-with-resources). API resources, such as pods and -[services](/docs/user-guide/services) are objects that can be written to and retrieved from the Kubernetes API -server. - -## Resource Requests and Limits of Pod and Container - -Each container of a pod can optionally specify one or more of the following: - -* `spec.containers[].resources.limits.cpu` -* `spec.containers[].resources.limits.memory` -* `spec.containers[].resources.requests.cpu` -* `spec.containers[].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 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 -about pod resource requests/limits. A *pod resource request/limit* for a particular resource -type is the sum of the resource requests/limits of that type for each container in the pod, with -unset values treated as zero (or equal to default values in some cluster configurations). - -### Meaning of CPU -Limits and requests for `cpu` are measured in cpus. -One cpu, in Kubernetes, is equivalent to: - -- 1 AWS vCPU -- 1 GCP Core -- 1 Azure vCore -- 1 *Hyperthread* on a bare-metal Intel processor with Hyperthreading - -Fractional requests are allowed. A container with `spec.containers[].resources.requests.cpu` of `0.5` will -be guaranteed half as much CPU as one that asks for `1`. The expression `0.1` is equivalent to the expression -`100m`, which can be read as "one hundred millicpu" (some may say "one hundred millicores", and this is understood -to mean the same thing when talking about Kubernetes). A request with a decimal point, like `0.1` is converted to -`100m` by the API, and precision finer than `1m` is not allowed. For this reason, the form `100m` may be preferred. - -CPU is always requested as an absolute quantity, never as a relative quantity; 0.1 is the same amount of cpu on a single -core, dual core, or 48 core machine. - -# Meaning of Memory - -Limits and requests for `memory` are measured in bytes. -Memory can be expressed a plain integer or as fixed-point integers with one of these SI suffixes (E, P, T, G, M, K) -or their power-of-two equivalents (Ei, Pi, Ti, Gi, Mi, Ki). For example, the following represent roughly the same value: -`128974848`, `129e6`, `129M` , `123Mi`. - -### Example -The following pod has two containers. Each has a request of 0.25 core of cpu and 64MiB -(226 bytes) of memory and a limit of 0.5 core of cpu and 128MiB of memory. The pod can -be said to have a request of 0.5 core and 128 MiB of memory and a limit of 1 core and 256MiB of -memory. - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: frontend -spec: - containers: - - name: db - image: mysql - resources: - requests: - memory: "64Mi" - cpu: "250m" - limits: - memory: "128Mi" - cpu: "500m" - - name: wp - image: wordpress - resources: - requests: - memory: "64Mi" - cpu: "250m" - limits: - memory: "128Mi" - cpu: "500m" -``` - -## How Pods with Resource Requests are Scheduled - -When a pod is created, the Kubernetes scheduler selects a node for the pod to -run on. Each node has a maximum capacity for each of the resource types: the -amount of CPU and memory it can provide for pods. The scheduler ensures that, -for each resource type (CPU and memory), the sum of the resource requests of the -containers scheduled to the node is less than the capacity of the node. Note -that although actual memory or CPU resource usage on nodes is very low, the -scheduler will still refuse to place pods onto nodes if the capacity check -fails. This protects against a resource shortage on a node when resource usage -later increases, such as due to a daily peak in request rate. - -## How Pods with Resource Limits are Run - -When kubelet starts a container of a pod, it passes the CPU and memory limits to the container -runner (Docker or rkt). - -When using Docker: - -- The `spec.containers[].resources.requests.cpu` is converted to its core value (potentially fractional), - and multiplied by 1024, and used as the value of the [`--cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint) - flag to the `docker run` command. -- The `spec.containers[].resources.limits.cpu` is converted to its millicore value, - multiplied by 100000, and then divided by 1000, and used as the value of the [`--cpu-quota`]( - https://docs.docker.com/engine/reference/run/#/cpu-quota-constraint) flag to the `docker run` - command. The [`--cpu-period`] flag is set to 100000 which represents the default 100ms period - for measuring quota usage. The kubelet enforces cpu limits if it was started with the - [`--cpu-cfs-quota`] flag set to true. As of version 1.2, this flag will now default to true. -- The `spec.containers[].resources.limits.memory` is converted to an integer, and used as the value - of the [`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) flag - to the `docker run` command. - -**TODO: document behavior for rkt** - -If a container exceeds its memory limit, it may be terminated. If it is restartable, it will be -restarted by kubelet, as will any other type of runtime failure. - -A container may or may not be allowed to exceed its CPU limit for extended periods of time. -However, it will not be killed for excessive CPU usage. - -To determine if a container cannot be scheduled or is being killed due to resource limits, see the -"Troubleshooting" section below. - -## Monitoring Compute Resource Usage - -The resource usage of a pod is reported as part of the Pod status. - -If [optional monitoring](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/cluster-monitoring/README.md) is configured for your cluster, -then pod resource usage can be retrieved from the monitoring system. - -## Troubleshooting - -### My pods are pending with event message failedScheduling - -If the scheduler cannot find any node where a pod can fit, then the pod will remain unscheduled -until a place can be found. An event will be produced each time the scheduler fails to find a -place for the pod, like this: - -```shell -$ kubectl describe pod frontend | grep -A 3 Events -Events: - FirstSeen LastSeen Count From Subobject PathReason Message - 36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others -``` - -In the case shown above, the pod "frontend" fails to be scheduled due to insufficient -CPU resource on the node. Similar error messages can also suggest failure due to insufficient -memory (PodExceedsFreeMemory). In general, if a pod or pods are pending with this message and -alike, then there are several things to try: - -- Add more nodes to the cluster. -- Terminate unneeded pods to make room for pending pods. -- Check that the pod is not larger than all the nodes. For example, if all the nodes -have a capacity of `cpu: 1`, then a pod with a limit of `cpu: 1.1` will never be scheduled. - -You can check node capacities and amounts allocated with the `kubectl describe nodes` command. -For example: - -```shell -$ kubectl describe nodes gke-cluster-4-386701dd-node-ww4p -Name: gke-cluster-4-386701dd-node-ww4p -[ ... lines removed for clarity ...] -Capacity: - cpu: 1 - memory: 464Mi - pods: 40 -Allocated resources (total requests): - cpu: 910m - memory: 2370Mi - pods: 4 -[ ... lines removed for clarity ...] -Pods: (4 in total) - Namespace Name CPU(milliCPU) Memory(bytes) - frontend webserver-ffj8j 500 (50% of total) 2097152000 (50% of total) - kube-system fluentd-cloud-logging-gke-cluster-4-386701dd-node-ww4p 100 (10% of total) 209715200 (5% of total) - kube-system kube-dns-v8-qopgw 310 (31% of total) 178257920 (4% of total) -TotalResourceLimits: - CPU(milliCPU): 910 (91% of total) - Memory(bytes): 2485125120 (59% of total) -[ ... lines removed for clarity ...] -``` - -Here you can see from the `Allocated resources` section that that a pod which ask for more than -90 millicpus or more than 1341MiB of memory will not be able to fit on this node. - -Looking at the `Pods` section, you can see which pods are taking up space on the node. - -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. - -### My container is terminated - -Your container may be terminated because it's resource-starved. To check if a container is being killed because it is hitting a resource limit, call `kubectl describe pod` -on the pod you are interested in: - -```shell -[12:54:41] $ ./cluster/kubectl.sh describe pod simmemleak-hra99 -Name: simmemleak-hra99 -Namespace: default -Image(s): saadali/simmemleak -Node: kubernetes-node-tf0f/10.240.216.66 -Labels: name=simmemleak -Status: Running -Reason: -Message: -IP: 10.244.2.75 -Replication Controllers: simmemleak (1/1 replicas created) -Containers: - simmemleak: - Image: saadali/simmemleak - Limits: - cpu: 100m - memory: 50Mi - State: Running - Started: Tue, 07 Jul 2015 12:54:41 -0700 - Last Termination State: Terminated - Exit Code: 1 - Started: Fri, 07 Jul 2015 12:54:30 -0700 - Finished: Fri, 07 Jul 2015 12:54:33 -0700 - Ready: False - Restart Count: 5 -Conditions: - Type Status - Ready False -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "gcr.io/google_containers/pause:0.8.0" already present on machine - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a -``` - -The `Restart Count: 5` indicates that the `simmemleak` container in this pod was terminated and restarted 5 times. - -You can call `get pod` with the `-o go-template=...` option to fetch the status of previously terminated containers: - -```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]]{% endraw %} -``` - -We can see that this container was terminated because `reason:OOM Killed`, where *OOM* stands for Out Of Memory. - -## Opaque Integer Resources (Alpha Feature) - -Kubernetes version 1.5 introduces Opaque integer resources. Opaque -integer resources allow cluster operators to advertise new node-level -resources that would be otherwise unknown to the system. - -Users can consume these resources in pod specs just like CPU and memory. -The scheduler takes care of the resource accounting so that no more than the -available amount is simultaneously allocated to pods. - -**Note:** Opaque integer resources are Alpha in Kubernetes version 1.5. -Only resource accounting is implemented; node-level isolation is still -under active development. - -Opaque integer resources are resources that begin with the prefix -`pod.alpha.kubernetes.io/opaque-int-resource-`. The API server -restricts quantities of these resources to whole numbers. Examples of -_valid_ quantities are `3`, `3000m` and `3Ki`. Examples of _invalid_ -quantities are `0.5` and `1500m`. - -There are two steps required to use opaque integer resources. First, the -cluster operator must advertise a per-node opaque resource on one or more -nodes. Second, users must request the opaque resource in pods. - -To advertise a new opaque integer resource, the cluster operator should -submit a `PATCH` HTTP request to the API server to specify the available -quantity in the `status.capacity` for a node in the cluster. After this -operation, the node's `status.capacity` will include a new resource. The -`status.allocatable` field is updated automatically with the new resource -asychronously by the Kubelet. Note that since the scheduler uses the -node `status.allocatable` value when evaluating pod fitness, there may -be a short delay between patching the node capacity with a new resource and the -first pod that requests the resource to be scheduled on that node. - -**Example:** - -The HTTP request below advertises 5 "foo" resources on node `k8s-node-1`. - -_NOTE: `~1` is the encoding for the character `/` in the patch path. -The operation path value in JSON-Patch is interpreted as a JSON-Pointer. -For more details, please refer to -[IETF RFC 6901, section 3](https://tools.ietf.org/html/rfc6901#section-3)._ - -```http -PATCH /api/v1/nodes/k8s-node-1/status HTTP/1.1 -Accept: application/json -Content-Type: application/json-patch+json -Host: k8s-master:8080 - -[ - { - "op": "add", - "path": "/status/capacity/pod.alpha.kubernetes.io~1opaque-int-resource-foo", - "value": "5" - } -] -``` - -To consume opaque resources in pods, include the name of the opaque -resource as a key in the `spec.containers[].resources.requests` map. - -The pod will be scheduled only if all of the resource requests are -satisfied (including cpu, memory and any opaque resources.) The pod will -remain in the `PENDING` state while the resource request cannot be met by any -node. - -**Example:** - -The pod below requests 2 cpus and 1 "foo" (an opaque resource.) - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: my-pod -spec: - containers: - - name: my-container - image: myimage - resources: - requests: - cpu: 2 - pod.alpha.kubernetes.io/opaque-int-resource-foo: 1 -``` - -## Planned Improvements - -The current system only allows resource quantities to be specified on a container. -It is planned to improve accounting for resources which are shared by all containers in a pod, -such as [EmptyDir volumes](/docs/user-guide/volumes/#emptydir). - -The current system only supports container requests and limits for CPU and Memory. -It is planned to add new resource types, including a node disk space -resource, and a framework for adding custom [resource types](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/resources.md). - -Kubernetes supports overcommitment of resources by supporting multiple levels of [Quality of Service](http://issue.k8s.io/168). - -Currently, one unit of CPU means different things on different cloud providers, and on different -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. +[Managing Compute Resources for Containers](/docs/concepts/configuration/manage-compute-resources-container/) diff --git a/docs/user-guide/config-best-practices.md b/docs/user-guide/config-best-practices.md index 2811d84ed0..85f65a9c5a 100644 --- a/docs/user-guide/config-best-practices.md +++ b/docs/user-guide/config-best-practices.md @@ -1,119 +1,7 @@ --- -assignees: -- mikedanese title: Best Practices for Configuration --- -This document is meant to highlight and consolidate in one place configuration best practices that are introduced throughout the user-guide and getting-started documentation and examples. This is a living document so if you think of something that is not on this list but might be useful to others, please don't hesitate to file an issue or submit a PR. - -## General Config Tips - -- When defining configurations, specify the latest stable API version (currently v1). - -- Configuration files should be stored in version control before being pushed to the cluster. This allows a configuration to be quickly rolled back if needed, and will aid with cluster re-creation and restoration if necessary. - -- Write your configuration files using YAML rather than JSON. They can be used interchangeably in almost all scenarios, but YAML tends to be more user-friendly for config. - -- Group related objects together in a single file where this makes sense. This format is often easier to manage than separate files. See the [guestbook-all-in-one.yaml](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/all-in-one/guestbook-all-in-one.yaml) file as an example of this syntax. -(Note also that many `kubectl` commands can be called on a directory, and so you can also call -`kubectl create` on a directory of config files— see below for more detail). - -- Don't specify default values unnecessarily, in order to simplify and minimize configs, and to - reduce error. For example, omit the selector and labels in a `ReplicationController` if you want - them to be the same as the labels in its `podTemplate`, since those fields are populated from the - `podTemplate` labels by default. See the [guestbook app's](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) .yaml files for some [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/frontend-deployment.yaml) of this. - -- Put an object description in an annotation to allow better introspection. - - -## "Naked" Pods vs Replication Controllers and Jobs - -- If there is a viable alternative to naked pods (i.e., pods not bound to a [replication controller - ](/docs/user-guide/replication-controller)), go with the alternative. Naked pods will not be rescheduled in the - event of node failure. - - Replication controllers are almost always preferable to creating pods, except for some explicit - [`restartPolicy: Never`](/docs/user-guide/pod-states/#restartpolicy) scenarios. A - [Job](/docs/user-guide/jobs/) object (currently in Beta), may also be appropriate. - - -## Services - -- It's typically best to create a [service](/docs/user-guide/services/) before corresponding [replication - controllers](/docs/user-guide/replication-controller/), so that the scheduler can spread the pods comprising the - service. You can also create a replication controller without specifying replicas (this will set - replicas=1), create a service, then scale up the replication controller. This can be useful in - ensuring that one replica works before creating lots of them. - -- Don't use `hostPort` (which specifies the port number to expose on the host) unless absolutely - necessary, e.g., for a node daemon. When you bind a Pod to a `hostPort`, there are a limited - number of places that pod can be scheduled, due to port conflicts— you can only schedule as many - such Pods as there are nodes in your Kubernetes cluster. - - If you only need access to the port for debugging purposes, you can use the [kubectl proxy and apiserver proxy](/docs/user-guide/connecting-to-applications-proxy/) or [kubectl port-forward](/docs/user-guide/connecting-to-applications-port-forward/). - You can use a [Service](/docs/user-guide/services/) object for external service access. - If you do need to expose a pod's port on the host machine, consider using a [NodePort](/docs/user-guide/services/#type-nodeport) service before resorting to `hostPort`. - -- Avoid using `hostNetwork`, for the same reasons as `hostPort`. - -- Use _headless services_ for easy service discovery when you don't need kube-proxy load balancing. - See [headless services](/docs/user-guide/services/#headless-services). - -## Using Labels - -- Define and use [labels](/docs/user-guide/labels/) that identify __semantic attributes__ of your application or - deployment. For example, instead of attaching a label to a set of pods to explicitly represent - some service (e.g., `service: myservice`), or explicitly representing the replication - controller managing the pods (e.g., `controller: mycontroller`), attach labels that identify - semantic attributes, such as `{ app: myapp, tier: frontend, phase: test, deployment: v3 }`. This - will let you select the object groups appropriate to the context— e.g., a service for all "tier: - frontend" pods, or all "test" phase components of app "myapp". See the - [guestbook](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) app for an example of this approach. - - A service can be made to span multiple deployments, such as is done across [rolling updates](/docs/user-guide/kubectl/kubectl_rolling-update/), by simply omitting release-specific labels from its selector, rather than updating a service's selector to match the replication controller's selector fully. - -- To facilitate rolling updates, include version info in replication controller names, e.g. as a - suffix to the name. It is useful to set a 'version' label as well. The rolling update creates a - new controller as opposed to modifying the existing controller. So, there will be issues with - version-agnostic controller names. See the [documentation](/docs/user-guide/kubectl/kubectl_rolling-update/) on - the rolling-update command for more detail. - - Note that the [Deployment](/docs/user-guide/deployments/) object obviates the need to manage replication - 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).) - -- 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 - controller, or served traffic by a service, by removing the relevant selector labels. If you - remove the labels of an existing pod, its controller will create a new pod to take its place. - This is a useful way to debug a previously "live" pod in a quarantine environment. See the - [`kubectl label`](/docs/user-guide/kubectl/kubectl_label/) command. - -## Container Images - -- The [default container image pull policy](/docs/user-guide/images/) is `IfNotPresent`, which causes the - [Kubelet](/docs/admin/kubelet/) to not pull an image if it already exists. If you would like to - always force a pull, you must specify a pull image policy of `Always` in your .yaml file - (`imagePullPolicy: Always`) or specify a `:latest` tag on your image. - - That is, if you're specifying an image with other than the `:latest` tag, e.g. `myimage:v1`, and - there is an image update to that same tag, the Kubelet won't pull the updated image. You can - 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 ` where possible. This looks for config objects in all `.yaml`, `.yml`, and `.json` files in `` and passes them to `create`. - -- Use `kubectl delete` rather than `stop`. `Delete` has a superset of the functionality of `stop`, and `stop` is deprecated. - -- 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 Deployments. See the [quick start guide](/docs/user-guide/quick-start/) for an example. - +{% include user-guide-content-moved.md %} +[Configuration Overview](/docs/concepts/configuration/overview/) diff --git a/docs/user-guide/configmap/index.md b/docs/user-guide/configmap/index.md index 3227e416c0..1355e599f2 100644 --- a/docs/user-guide/configmap/index.md +++ b/docs/user-guide/configmap/index.md @@ -291,34 +291,6 @@ SPECIAL_LEVEL_KEY=very SPECIAL_TYPE_KEY=charm ``` -#### Optional ConfigMap in environment variables - -There might be situations where environment variables are not -always required. These environment variables can be marked as optional in a -pod like so: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: dapi-test-pod -spec: - containers: - - name: test-container - image: gcr.io/google_containers/busybox - command: [ "/bin/sh", "-c", "env" ] - env: - - name: SPECIAL_LEVEL_KEY - valueFrom: - configMapKeyRef: - name: a-config - key: akey - optional: true - restartPolicy: Never -``` - -When this pod is run, the output will be empty. - ### Use-Case: Set command-line arguments with ConfigMap ConfigMaps can also be used to set the value of the command or arguments in a container. This is @@ -450,38 +422,6 @@ very You can project keys to specific paths and specific permissions on a per-file basis. The [Secrets](/docs/user-guide/secrets/) user guide explains the syntax. -#### Optional ConfigMap via volume plugin - -Volumes and files provided by a ConfigMap can be also be marked as optional. -The ConfigMap or the key specified does not have to exist. The mount path for -such items will always be created. - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: dapi-test-pod -spec: - containers: - - name: test-container - image: gcr.io/google_containers/busybox - command: [ "/bin/sh", "-c", "ls /etc/config" ] - volumeMounts: - - name: config-volume - mountPath: /etc/config - volumes: - - name: config-volume - configMap: - name: no-config - optional: true - restartPolicy: Never -``` - -When this pod is run, the output will be: - -```shell -``` - ## Real World Example: Configuring Redis Let's take a look at a real-world example: configuring redis using ConfigMap. Say we want to inject @@ -577,10 +517,9 @@ $ kubectl exec -it redis redis-cli ## Restrictions -ConfigMaps must be created before they are consumed in pods unless they are -marked as optional. Controllers may be written to tolerate missing -configuration data; consult individual components configured via ConfigMap on -a case-by-case basis. +ConfigMaps must be created before they are consumed in pods. Controllers may be written to tolerate +missing configuration data; consult individual components configured via ConfigMap on a case-by-case +basis. ConfigMaps reside in a namespace. They can only be referenced by pods in the same namespace. @@ -590,3 +529,4 @@ Kubelet only supports use of ConfigMap for pods it gets from the API server. Th created using kubectl, or indirectly via a replication controller. It does not include pods created via the Kubelet's `--manifest-url` flag, its `--config` flag, or its REST API (these are not common ways to create pods.) + diff --git a/docs/user-guide/configuring-containers.md b/docs/user-guide/configuring-containers.md deleted file mode 100644 index 8e09d7aaa4..0000000000 --- a/docs/user-guide/configuring-containers.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Configuring Containers ---- - -{% include user-guide-content-moved.md %} - -[Tasks](/docs/tasks/) diff --git a/docs/user-guide/connecting-to-applications-port-forward.md b/docs/user-guide/connecting-to-applications-port-forward.md index 4855994736..afa3559eba 100644 --- a/docs/user-guide/connecting-to-applications-port-forward.md +++ b/docs/user-guide/connecting-to-applications-port-forward.md @@ -5,46 +5,6 @@ assignees: title: Connect with Port Forwarding --- -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. +{% include user-guide-content-moved.md %} -## Creating a Redis master - -```shell -$ kubectl create -f examples/redis/redis-master.yaml -pods/redis-master -``` - -wait until the Redis master pod is Running and Ready, - -```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 6379, to verify this, - -```shell{% raw %} -$ kubectl get pods redis-master --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}' -6379{% endraw %} -``` - -then we forward the port 6379 on the local workstation to the port 6379 of pod redis-master, - -```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 -$ redis-cli -127.0.0.1:6379> ping -PONG -``` - -Now one can debug the database from the local workstation. +[Using Port Forwarding to Access Applications in a Cluster](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) diff --git a/docs/user-guide/connecting-to-applications-proxy.md b/docs/user-guide/connecting-to-applications-proxy.md index 559b06da9f..a95c2b06a2 100644 --- a/docs/user-guide/connecting-to-applications-proxy.md +++ b/docs/user-guide/connecting-to-applications-proxy.md @@ -5,28 +5,6 @@ assignees: title: Connect with Proxies --- -You have seen the [basics](/docs/user-guide/accessing-the-cluster) about `kubectl proxy` and `apiserver proxy`. This guide shows how to use them together to access a service([kube-ui](/docs/user-guide/ui)) running on the Kubernetes cluster from your workstation. +{% include user-guide-content-moved.md %} - -## Getting the apiserver proxy URL of kube-ui - -kube-ui is deployed as a cluster add-on. To find its apiserver proxy URL, - -```shell -$ kubectl cluster-info | grep "KubeUI" -KubeUI is running at https://173.255.119.104/api/v1/proxy/namespaces/kube-system/services/kube-ui -``` - -if this command does not find the URL, try the steps [here](/docs/user-guide/ui/#accessing-the-ui). - - -## Connecting to the kube-ui service from your local workstation - -The above proxy URL is an access to the kube-ui service provided by the apiserver. To access it, you still need to authenticate to the apiserver. `kubectl proxy` can handle the authentication. - -```shell -$ kubectl proxy --port=8001 -Starting to serve on localhost:8001 -``` - -Now you can access the kube-ui service on your local workstation at [http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/kube-ui](http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/kube-ui) \ No newline at end of file +[Using an HTTP Proxy to Access the Kubernetes API](/docs/tasks/access-kubernetes-api/http-proxy-access-api/) diff --git a/docs/user-guide/containers.md b/docs/user-guide/containers.md deleted file mode 100644 index dfe48ade49..0000000000 --- a/docs/user-guide/containers.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -assignees: -- mikedanese -title: Commands and Capabilities ---- - -{% include user-guide-content-moved.md %} - -* [Container Command and Arguments](/docs/concepts/configuration/container-command-args/) -* [Container Capabilities](/docs/concepts/policy/container-capabilities/) diff --git a/docs/user-guide/cron-jobs.md b/docs/user-guide/cron-jobs.md index 55b85adf46..db3153688a 100644 --- a/docs/user-guide/cron-jobs.md +++ b/docs/user-guide/cron-jobs.md @@ -19,10 +19,10 @@ A _Cron Job_ manages time based [Jobs](/docs/user-guide/jobs/), namely: One CronJob object is like one line of a _crontab_ (cron table) file. It runs a job periodically on a given schedule, written in [Cron](https://en.wikipedia.org/wiki/Cron) format. -**Note:**: The question mark (`?`) in the schedule has the same meaning as an asterisk `*`, +**Note:** The question mark (`?`) in the schedule has the same meaning as an asterisk `*`, that is, it stands for any of available value for a given field. -**Note:**: ScheduledJob resource was introduced in Kubernetes version 1.4, but starting +**Note:** ScheduledJob resource was introduced in Kubernetes version 1.4, but starting from version 1.5 its current name is CronJob. A typical use case is: @@ -32,7 +32,7 @@ A typical use case is: ### Prerequisites -You need a working Kubernetes cluster at version >= 1.4 (for ScheduledJob), >= 1.5 (for CronJobs), +You need a working Kubernetes cluster at version >= 1.4 (for ScheduledJob), >= 1.5 (for CronJob), with batch/v2alpha1 API turned on by passing `--runtime-config=batch/v2alpha1` while bringing up the API server (see [Turn on or off an API version for your cluster](/docs/admin/cluster-management/#turn-on-or-off-an-api-version-for-your-cluster) for more). You cannot use Cron Jobs on a hosted Kubernetes provider that has disabled alpha resources. diff --git a/docs/user-guide/debugging-services.md b/docs/user-guide/debugging-services.md index de9cec5c3f..6a1a692e8a 100644 --- a/docs/user-guide/debugging-services.md +++ b/docs/user-guide/debugging-services.md @@ -352,7 +352,7 @@ they are running fine and not crashing. The `-l app=hostnames` argument is a label selector - just like our `Service` has. Inside the Kubernetes system is a control loop which evaluates the -selector of every `Service` and save the results into an `Endpoints` object. +selector of every `Service` and saves the results into an `Endpoints` object. ```shell $ kubectl get endpoints hostnames diff --git a/docs/user-guide/deploying-applications.md b/docs/user-guide/deploying-applications.md deleted file mode 100644 index 9bbcd34282..0000000000 --- a/docs/user-guide/deploying-applications.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -assignees: -- bgrant0607 -- caesarxuchao -- thockin -title: Deploying Applications ---- - -* TOC -{:toc} - -## Launching a set of replicas using a configuration file - -Kubernetes creates and manages sets of replicated containers (actually, replicated [Pods](/docs/user-guide/pods)) using [*Deployments*](/docs/user-guide/deployments). - -A Deployment simply ensures that a specified number of pod "replicas" are running at any one time. If there are too many, it will kill some. If there are too few, it will start more. It's analogous to Google Compute Engine's [Instance Group Manager](https://cloud.google.com/compute/docs/instance-groups/manager/) or AWS's [Auto-scaling Group](http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AutoScalingGroup.html) (with no scaling policies). - -The Deployment created to run nginx by `kubectl run` in the [Quick start](/docs/user-guide/quick-start) could be specified using YAML as follows: - -{% include code.html language="yaml" file="run-my-nginx.yaml" ghlink="/docs/user-guide/run-my-nginx.yaml" %} - -Some differences compared to specifying just a pod are that the `kind` is `Deployment`, the number of `replicas` desired is specified, and the pod specification is under the `template` field. The names of the pods don't need to be specified explicitly because they are generated from the name of the Deployment. -View the [Deployment API -object](/docs/api-reference/extensions/v1beta1/definitions/#_v1beta1_deployment) -to view the list of supported fields. - -This Deployment can be created using `create`, just as with pods: - -```shell -$ kubectl create -f ./run-my-nginx.yaml -deployment "my-nginx" created -``` - -Unlike in the case where you directly create pods, a Deployment replaces pods that are deleted or terminated for any reason, such as in the case of node failure. For this reason, we recommend that you use a Deployment for a continuously running application even if your application requires only a single pod, in which case you can omit `replicas` and it will default to a single replica. - -## Viewing Deployment status - -You can view the Deployment you created using `get`: - -```shell -$ kubectl get deployment -NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE -my-nginx 2 2 2 2 6s -``` - -This tells you that your Deployment will ensure that you have two nginx replicas (desired replicas = 2). - -You can see those replicas using `get`, just as with pods you created directly: - -```shell -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -my-nginx-3800858182-9hk43 1/1 Running 0 8m -my-nginx-3800858182-e529s 1/1 Running 0 8m -``` - -## Deleting Deployments - -When you want to kill your application, delete your Deployment, as in the [Quick start](/docs/user-guide/quick-start): - -```shell -$ kubectl delete deployment/my-nginx -deployment "my-nginx" deleted -``` - -By default, this will also cause the pods managed by the Deployment to be deleted. If there were a large number of pods, this may take a while to complete. If you want to leave the pods running instead, specify `--cascade=false`. - -If you try to delete the pods before deleting the Deployments, it will just replace them, as it is supposed to do. - -## Labels - -Kubernetes uses user-defined key-value attributes called [*labels*](/docs/user-guide/labels) to categorize and identify sets of resources, such as pods and Deployments. The example above specified a single label in the pod template, with key `run` and value `my-nginx`. All pods created carry that label, which can be viewed using `-L`: - -```shell -$ kubectl get pods -L run -NAME READY STATUS RESTARTS AGE RUN -my-nginx-3800858182-1v53o 1/1 Running 0 46s my-nginx -my-nginx-3800858182-2ds1q 1/1 Running 0 46s my-nginx -``` - -The labels from the pod template are copied to the Deployment's labels by default, as well -- all resources in Kubernetes support labels: - -```shell -$ kubectl get deployment/my-nginx -L run -NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE RUN -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{% raw %} -$ kubectl get deployment/my-nginx -o template --template="{{.spec.selector}}" -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 -matchLabels. - -## What's next? - -[Learn about exposing applications to users and clients, and connecting tiers of your application together.](/docs/user-guide/connecting-applications) diff --git a/docs/user-guide/deployments.md b/docs/user-guide/deployments.md index 0b4ae0d85a..7610384eab 100644 --- a/docs/user-guide/deployments.md +++ b/docs/user-guide/deployments.md @@ -62,8 +62,8 @@ This indicates that the Deployment has created all three replicas, and all repli ```shell $ kubectl get rs -NAME DESIRED CURRENT AGE -nginx-deployment-2035384211 3 3 18s +NAME DESIRED CURRENT READY AGE +nginx-deployment-2035384211 3 3 0 18s ``` You may notice that the name of the Replica Set is always `-`. @@ -180,9 +180,9 @@ We can run `kubectl get rs` to see that the Deployment updated the Pods by creat ```shell $ kubectl get rs -NAME DESIRED CURRENT AGE -nginx-deployment-1564180365 3 3 6s -nginx-deployment-2035384211 0 0 36s +NAME DESIRED CURRENT READY AGE +nginx-deployment-1564180365 3 3 0 6s +nginx-deployment-2035384211 0 0 0 36s ``` Running `get pods` should now show only the new Pods: @@ -287,10 +287,10 @@ You will also see that both the number of old replicas (nginx-deployment-1564180 ```shell $ kubectl get rs -NAME DESIRED CURRENT AGE -nginx-deployment-1564180365 2 2 25s -nginx-deployment-2035384211 0 0 36s -nginx-deployment-3066724191 2 2 6s +NAME DESIRED CURRENT READY AGE +nginx-deployment-1564180365 2 2 0 25s +nginx-deployment-2035384211 0 0 0 36s +nginx-deployment-3066724191 2 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. @@ -514,10 +514,10 @@ The Deployment was still in progress when we paused it, so the actions of scalin ```shell $ kubectl get rs -NAME DESIRED CURRENT AGE -nginx-deployment-1564180365 2 2 1h -nginx-deployment-2035384211 2 2 1h -nginx-deployment-3066724191 0 0 1h +NAME DESIRED CURRENT READY AGE +nginx-deployment-1564180365 2 2 2 1h +nginx-deployment-2035384211 2 2 0 1h +nginx-deployment-3066724191 0 0 0 1h ``` In a separate terminal, watch for rollout status changes and you'll see the rollout won't continue: @@ -546,10 +546,10 @@ deployment nginx-deployment successfully rolled out ```shell $ kubectl get rs -NAME DESIRED CURRENT AGE -nginx-deployment-1564180365 3 3 1h -nginx-deployment-2035384211 0 0 1h -nginx-deployment-3066724191 0 0 1h +NAME DESIRED CURRENT READY AGE +nginx-deployment-1564180365 3 3 3 1h +nginx-deployment-2035384211 0 0 0 1h +nginx-deployment-3066724191 0 0 0 1h ``` Note: You cannot rollback a paused Deployment until you resume it. @@ -578,6 +578,7 @@ Kubernetes marks a Deployment as _complete_ when it has the following characteri equals or exceeds the number required by the Deployment strategy. * All of the replicas associated with the Deployment have been updated to the latest version you've specified, meaning any updates you've requested have been completed. +* No old pods for the Deployment are running. You can check if a Deployment has completed by using `kubectl rollout status`. If the rollout completed successfully, `kubectl rollout status` returns a zero exit code. @@ -615,12 +616,12 @@ the Deployment's `status.conditions`: * Status=False * Reason=ProgressDeadlineExceeded -See the [Kubernetes API conventions](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/devel/api-conventions.md#typical-status-properties) for more information on status conditions. +See the [Kubernetes API conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#typical-status-properties) for more information on status conditions. Note that in version 1.5, Kubernetes will take no action on a stalled Deployment other than to report a status condition with `Reason=ProgressDeadlineExceeded`. -**Note:** If you pause a Deployment, Kubernetes does not check progress against your specified deadline. You can safely pause a Deployment in the middle of a rollout and resume without triggering a the condition for exceeding the deadline. +**Note:** If you pause a Deployment, Kubernetes does not check progress against your specified deadline. You can safely pause a Deployment in the middle of a rollout and resume without triggering the condition for exceeding the deadline. You may experience transient errors with your Deployments, either due to a low timeout that you have set or due to any other kind of error that can be treated as transient. For example, let's suppose you have insufficient quota. If you describe the Deployment @@ -717,7 +718,7 @@ to a previous revision, or even pause it if you need to apply multiple tweaks in ### 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). +following the canary pattern described in [managing resources](/docs/concepts/cluster-administration/manage-deployment/#canary-deployments). ## Writing a Deployment Spec @@ -725,7 +726,7 @@ As with all other Kubernetes configs, a Deployment needs `apiVersion`, `kind`, a `metadata` fields. For general information about working with config files, see [deploying applications](/docs/user-guide/deploying-applications), [configuring containers](/docs/user-guide/configuring-containers), and [using kubectl to manage resources](/docs/user-guide/working-with-resources) documents. -A Deployment also needs a [`.spec` section](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status). +A Deployment also needs a [`.spec` section](https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status). ### Pod Template @@ -777,7 +778,7 @@ All existing Pods are killed before new ones are created when #### 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/tasks/run-application/rolling-update-replication-controller/) fashion when `.spec.strategy.type==RollingUpdate`. You can specify `maxUnavailable` and `maxSurge` to control the rolling update process. diff --git a/docs/user-guide/downward-api/index.md b/docs/user-guide/downward-api/index.md index 33b2b06c49..beb1cddd9b 100644 --- a/docs/user-guide/downward-api/index.md +++ b/docs/user-guide/downward-api/index.md @@ -5,137 +5,6 @@ assignees: title: Using the Downward API to Convey Pod Properties --- -It is sometimes useful for a container to have information about itself, but we -want to be careful not to over-couple containers to Kubernetes. The downward -API allows containers to consume information about themselves or the system and -expose that information how they want it, without necessarily coupling to the -Kubernetes client or REST API. +{% include user-guide-content-moved.md %} -An example of this is a "legacy" app that is already written assuming -that a particular environment variable will hold a unique identifier. While it -is often possible to "wrap" such applications, this is tedious and error prone, -and violates the goal of low coupling. Instead, the user should be able to use -the Pod's name, for example, and inject it into this well-known variable. - - -## Capabilities - -The following information is available to a `Pod` through the downward API: - -* The node's name -*   The pod's name -* The pod's namespace -* The pod's IP -* The pod's service account name -* A container's cpu limit -* A container's cpu request -* A container's memory limit -* A container's memory request - -More information will be exposed through this same API over time. - - -## Exposing pod information into a container - -Containers consume information from the downward API using environment -variables or using a volume plugin. - - -## Environment variables - -Most environment variables in the Kubernetes API use the `value` field to carry -simple values. However, the alternate `valueFrom` field allows you to specify -a `fieldRef` to select fields from the pod's definition, and a `resourceFieldRef` -to select fields from one of its container's definition. - -The `fieldRef` field is a structure that has an `apiVersion` field and a `fieldPath` -field. The `fieldPath` field is an expression designating a field of the pod. The -`apiVersion` field is the version of the API schema that the `fieldPath` is -written in terms of. If the `apiVersion` field is not specified it is -defaulted to the API version of the enclosing object. - -The `fieldRef` is evaluated and the resulting value is used as the value for -the environment variable. This allows users to publish their pod's name in any -environment variable they want. - -The `resourceFieldRef` is a structure that has a `containerName` field, a `resource` -field, and a `divisor` field. The `containerName` is the name of a container, -whose resource (cpu or memory) information is to be exposed. The `containerName` is -optional for environment variables and defaults to the current container. The -`resource` field is an expression designating a resource in a container, and the `divisor` -field specifies an output format of the resource being exposed. If the `divisor` -is not specified, it defaults to "1" for cpu and memory. The table shows possible -values for cpu and memory resources for `resource` and `divisor` settings: - - -| Setting | Cpu | Memory | -| ------------- |-------------| -----| -| resource | limits.cpu, requests.cpu| limits.memory, requests.memory| -| divisor | 1(cores), 1m(millicores) | 1(bytes), 1k(kilobytes), 1M(megabytes), 1G(gigabytes), 1T(terabytes), 1P(petabytes), 1E(exabytes), 1Ki(kibibyte), 1Mi(mebibyte), 1Gi(gibibyte), 1Ti(tebibyte), 1Pi(pebibyte), 1Ei(exbibyte)| - - -### Example - -This is an example of a pod that consumes its name and namespace via the -downward API: - -{% include code.html language="yaml" file="dapi-pod.yaml" ghlink="/docs/user-guide/downward-api/dapi-pod.yaml" %} - -This is an example of a pod that consumes its container's resources via the downward API: - -{% include code.html language="yaml" file="dapi-container-resources.yaml" ghlink="/docs/user-guide/downward-api/dapi-container-resources.yaml" %} - -## Downward API volume - -Using a similar syntax it's possible to expose pod information to containers using plain text files. -Downward API are dumped to a mounted volume. This is achieved using a `downwardAPI` -volume type and the different items represent the files to be created. `fieldPath` references the field to be exposed. -For exposing a container's resources limits and requests, `containerName` must be specified with `resourceFieldRef`. - -Downward API volume permits to store more complex data like [`metadata.labels`](/docs/user-guide/labels) and [`metadata.annotations`](/docs/user-guide/annotations). Currently key/value pair set fields are saved using `key="value"` format: - -```conf -key1="value1" -key2="value2" -``` - -In future, it will be possible to specify an output format option. - -Downward API volumes can expose: - -* The node's name -* The pod's name -* The pod's namespace -* The pod's labels -* The pod's annotations -* The pod's service account name -* A container's cpu limit -* A container's cpu request -* A container's memory limit -* A container's memory request - -The downward API volume refreshes its data in step with the kubelet refresh loop. When labels will be modifiable on the fly without respawning the pod containers will be able to detect changes through mechanisms such as [inotify](https://en.wikipedia.org/wiki/Inotify). - -In future, it will be possible to specify a specific annotation or label. - -#### Projecting keys to specific paths and file permissions - -You can project keys to specific paths and specific permissions on a per-file -basis. The [Secrets](/docs/user-guide/secrets/) user guide explains the syntax. - -### Example - -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="volume/dapi-volume.yaml" ghlink="/docs/user-guide/downward-api/volume/dapi-volume.yaml" %} - -This is an example of a pod that consumes its container's resources via the downward API volume. - -{% include code.html language="yaml" file="volume/dapi-volume-resources.yaml" ghlink="/docs/user-guide/downward-api/volume/dapi-volume-resources.yaml" %} - -For a more thorough example, see -[environment variables](/docs/user-guide/environment-guide/). - -## Default values for container resource limits - -If cpu and memory limits are not specified for a container, the downward API will default to the node allocatable value for cpu and memory. +[Exposing Pod Information to Containers Using a DownwardAPIVolumeFile](/docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information/) diff --git a/docs/user-guide/downward-api/volume/index.md b/docs/user-guide/downward-api/volume/index.md index 882b2da1e9..6f359cc797 100644 --- a/docs/user-guide/downward-api/volume/index.md +++ b/docs/user-guide/downward-api/volume/index.md @@ -2,118 +2,6 @@ title: Downward API Volumes --- -Following this example, you will create a pod with a downward API volume. -A downward API volume is a k8s volume plugin with the ability to save some pod information in a plain text file. The pod information can be for example some [metadata](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#metadata) or a container's [resources](/docs/user-guide/compute-resources). +{% include user-guide-content-moved.md %} -Supported metadata fields: - -1. `metadata.annotations` -2. `metadata.namespace` -3. `metadata.name` -4. `metadata.labels` - -Supported container's resources: - -1. `limits.cpu` -2. `limits.memory` -3. `requests.cpu` -4. `requests.memory` - -### Step Zero: Prerequisites - -This example assumes you have a Kubernetes cluster installed and running, and the `kubectl` command line tool somewhere in your path. Please see the [gettingstarted](/docs/getting-started-guides/) for installation instructions for your platform. - -### Step One: Create the pod - -Use the [dapi-volume.yaml](/docs/user-guide/downward-api/volume/dapi-volume.yaml) file to create a Pod with a downward API volume which stores pod labels and pod annotations to `/etc/labels` and `/etc/annotations` respectively. - -```shell -$ kubectl create -f docs/user-guide/downward-api/volume/dapi-volume.yaml -``` - -### Step Two: Examine pod/container output - -The pod displays (every 5 seconds) the content of the dump files which can be executed via the usual `kubectl log` command - -```shell -$ kubectl logs kubernetes-downwardapi-volume-example -cluster="test-cluster1" -rack="rack-22" -zone="us-est-coast" -build="two" -builder="john-doe" -kubernetes.io/config.seen="2015-08-24T13:47:23.432459138Z" -kubernetes.io/config.source="api" -``` - -### Internals - -In pod's `/etc` directory one may find the file created by the plugin (system files elided): - -```shell -$ kubectl exec kubernetes-downwardapi-volume-example -i -t -- sh -/ # ls -laR /etc -/etc: -total 4 -drwxrwxrwt 3 0 0 120 Jun 1 19:55 . -drwxr-xr-x 17 0 0 4096 Jun 1 19:55 .. -drwxr-xr-x 2 0 0 80 Jun 1 19:55 ..6986_01_06_15_55_10.473583074 -lrwxrwxrwx 1 0 0 31 Jun 1 19:55 ..data -> ..6986_01_06_15_55_10.473583074 -lrwxrwxrwx 1 0 0 18 Jun 1 19:55 annotations -> ..data/annotations -lrwxrwxrwx 1 0 0 13 Jun 1 19:55 labels -> ..data/labels - -/etc/..6986_01_06_15_55_10.473583074: -total 8 -drwxr-xr-x 2 0 0 80 Jun 1 19:55 . -drwxrwxrwt 3 0 0 120 Jun 1 19:55 .. --rw-r--r-- 1 0 0 129 Jun 1 19:55 annotations --rw-r--r-- 1 0 0 59 Jun 1 19:55 labels -/ # -``` - -The file `labels` is stored in a temporary directory (`..6986_01_06_15_55_10.473583074` in the example above) which is symlinked to by `..data`. Symlinks for annotations and labels in `/etc` point to files containing the actual metadata through the `..data` indirection.  This structure allows for dynamic atomic refresh of the metadata: updates are written to a new temporary directory, and the `..data` symlink is updated atomically using `rename(2)`. - -## Example of downward API volume with container resources - -Use the `docs/user-guide/downward-api/volume/dapi-volume-resources.yaml` file to create a Pod with a downward API volume which stores its container's limits and requests in /etc. - -```shell -$ kubectl create -f docs/user-guide/downward-api/volume/dapi-volume-resources.yaml -``` - -### Examine pod/container output - -In pod's `/etc` directory one may find the files created by the plugin: - -```shell -$ kubectl exec kubernetes-downwardapi-volume-example -i -t -- sh -/ # ls -alR /etc -/etc: -total 4 -drwxrwxrwt 3 0 0 160 Jun 1 19:47 . -drwxr-xr-x 17 0 0 4096 Jun 1 19:48 .. -drwxr-xr-x 2 0 0 120 Jun 1 19:47 ..6986_01_06_15_47_23.076909525 -lrwxrwxrwx 1 0 0 31 Jun 1 19:47 ..data -> ..6986_01_06_15_47_23.076909525 -lrwxrwxrwx 1 0 0 16 Jun 1 19:47 cpu_limit -> ..data/cpu_limit -lrwxrwxrwx 1 0 0 18 Jun 1 19:47 cpu_request -> ..data/cpu_request -lrwxrwxrwx 1 0 0 16 Jun 1 19:47 mem_limit -> ..data/mem_limit -lrwxrwxrwx 1 0 0 18 Jun 1 19:47 mem_request -> ..data/mem_request - -/etc/..6986_01_06_15_47_23.076909525: -total 16 -drwxr-xr-x 2 0 0 120 Jun 1 19:47 . -drwxrwxrwt 3 0 0 160 Jun 1 19:47 .. --rw-r--r-- 1 0 0 1 Jun 1 19:47 cpu_limit --rw-r--r-- 1 0 0 1 Jun 1 19:47 cpu_request --rw-r--r-- 1 0 0 8 Jun 1 19:47 mem_limit --rw-r--r-- 1 0 0 8 Jun 1 19:47 mem_request - -/ # cat /etc/cpu_limit -1 -/ # cat /etc/mem_limit -67108864 -/ # cat /etc/cpu_request -1 -/ # cat /etc/mem_request -33554432 -``` +[Exposing Pod Information to Containers Using a DownwardAPIVolumeFile](/docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information/) diff --git a/docs/user-guide/environment-guide/index.md b/docs/user-guide/environment-guide/index.md index cbdd806ecd..9db0f41f9b 100644 --- a/docs/user-guide/environment-guide/index.md +++ b/docs/user-guide/environment-guide/index.md @@ -4,97 +4,6 @@ assignees: title: Using Environment Variables --- -This example demonstrates running pods, replication controllers, and -services. It shows two types of pods: frontend and backend, with -services on top of both. Accessing the frontend pod will return -environment information about itself, and a backend pod that it has -accessed through the service. The goal is to illuminate the -environment metadata available to running containers inside the -Kubernetes cluster. The documentation for the Kubernetes environment -is [here](/docs/user-guide/container-environment). +{% include user-guide-content-moved.md %} -![Diagram](/images/docs/diagram.png) - -## Prerequisites - -This example assumes that you have a Kubernetes cluster installed and -running, and that you have installed the `kubectl` command line tool -somewhere in your path. Please see the [getting -started](/docs/getting-started-guides/) for installation instructions -for your platform. - -## Optional: Build your own containers - -These are the configuration files for the containers: - -* [backend-rc.yaml](https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/user-guide/environment-guide/backend-rc.yaml) -* [backend-srv.yaml](https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/user-guide/environment-guide/backend-srv.yaml) -* [show-rc.yaml](https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/user-guide/environment-guide/show-rc.yaml) -* [show-srv.yaml](https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/user-guide/environment-guide/show-srv.yaml) - -## 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 -``` - -## Query the service - -Use `kubectl describe service show-srv` to determine the public IP of -your service. - -> Note: If your platform does not support external load balancers, - you'll need to open the proper port and direct traffic to the - internal IP shown for the frontend service with the above command - -Run `curl :80` to query the service. You should get -something like this back: - -```shell -Pod Name: show-rc-xxu6i -Pod Namespace: default -USER_VAR: important information - -Kubernetes environment variables -BACKEND_SRV_SERVICE_HOST = 10.147.252.185 -BACKEND_SRV_SERVICE_PORT = 5000 -KUBERNETES_RO_SERVICE_HOST = 10.147.240.1 -KUBERNETES_RO_SERVICE_PORT = 80 -KUBERNETES_SERVICE_HOST = 10.147.240.2 -KUBERNETES_SERVICE_PORT = 443 -KUBE_DNS_SERVICE_HOST = 10.147.240.10 -KUBE_DNS_SERVICE_PORT = 53 - -Found backend ip: 10.147.252.185 port: 5000 -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 -an environment variable set in the [pod -definition](https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/user-guide/environment-guide/show-rc.yaml). Then, the dynamic Kubernetes environment -variables are scanned and printed. These are used to find the backend -service, named `backend-srv`. Finally, the frontend pod queries the -backend service and prints the information returned. Again the backend -pod returns its own pod name and namespace. - -Try running the `curl` command a few times, and notice what -changes. Ex: `watch -n 1 curl -s ` Firstly, the frontend service -is directing your request to different frontend pods each time. The -frontend pods are always contacting the backend through the backend -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 -``` +[Exposing Pod Information to Containers Through Environment Variables](/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/) diff --git a/docs/user-guide/federation/configmap.md b/docs/user-guide/federation/configmap.md index 9d8aa18cac..6929073cf8 100644 --- a/docs/user-guide/federation/configmap.md +++ b/docs/user-guide/federation/configmap.md @@ -2,86 +2,6 @@ title: Federated ConfigMap --- -This guide explains how to use ConfigMaps in a Federation control plane. +{% include user-guide-content-moved.md %} -* TOC -{:toc} - -## Prerequisites - -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/admin/federation/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). -Other tutorials, such as Kelsey Hightower's -[Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation), -might also help you create a Federated Kubernetes cluster. - -You should also have a basic -[working knowledge of Kubernetes](/docs/getting-started-guides/) in -general and [ConfigMaps](/docs/user-guide/ConfigMaps/) in particular. - -## Overview - -Federated ConfigMaps are very similar to the traditional [Kubernetes -ConfigMaps](/docs/user-guide/configmap/) and provide the same functionality. -Creating them in the federation control plane ensures that they are synchronized -across all the clusters in federation. - - -## Creating a Federated ConfigMap - -The API for Federated ConfigMap is 100% compatible with the -API for traditional Kubernetes ConfigMap. You can create a ConfigMap by sending -a request to the federation apiserver. - -You can do that using [kubectl](/docs/user-guide/kubectl/) by running: - -``` shell -kubectl --context=federation-cluster create -f myconfigmap.yaml -``` - -The `--context=federation-cluster` flag tells kubectl to submit the -request to the Federation apiserver instead of sending it to a Kubernetes -cluster. - -Once a Federated ConfigMap is created, the federation control plane will create -a matching ConfigMap in all underlying Kubernetes clusters. -You can verify this by checking each of the underlying clusters, for example: - -``` shell -kubectl --context=gce-asia-east1a get configmap myconfigmap -``` - -The above assumes that you have a context named 'gce-asia-east1a' -configured in your client for your cluster in that zone. - -These ConfigMaps in underlying clusters will match the Federated ConfigMap. - - -## Updating a Federated ConfigMap - -You can update a Federated ConfigMap as you would update a Kubernetes -ConfigMap; however, for a Federated ConfigMap, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. -The federation control plane ensures that whenever the Federated ConfigMap is -updated, it updates the corresponding ConfigMaps in all underlying clusters to -match it. - -## Deleting a Federated ConfigMap - -You can delete a Federated ConfigMap as you would delete a Kubernetes -ConfigMap; however, for a Federated ConfigMap, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. - -For example, you can do that using kubectl by running: - -```shell -kubectl --context=federation-cluster delete configmap -``` - -Note that at this point, deleting a Federated ConfigMap will not delete the -corresponding ConfigMaps from underlying clusters. -You must delete the underlying ConfigMaps manually. -We intend to fix this in the future. +[Federated ConfigMap](/docs/tasks/administer-federation/configmap/) diff --git a/docs/user-guide/federation/daemonsets.md b/docs/user-guide/federation/daemonsets.md index 7699ead4e3..ce1ae99b9e 100644 --- a/docs/user-guide/federation/daemonsets.md +++ b/docs/user-guide/federation/daemonsets.md @@ -2,82 +2,6 @@ title: Federated DaemonSet --- -This guide explains how to use DaemonSets in a federation control plane. +{% include user-guide-content-moved.md %} -* TOC -{:toc} - -## Prerequisites - -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/admin/federation/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). -Other tutorials, such as Kelsey Hightower's -[Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation), -might also help you create a Federated Kubernetes cluster. - -You should also have a basic -[working knowledge of Kubernetes](/docs/getting-started-guides/) in -general and DaemonSets in particular. - -## Overview - -DaemonSets in federation control plane ("Federated Daemonsets" in -this guide) are very similar to the traditional [Kubernetes -DaemonSets](/docs/user-guide/DaemonSets/) and provide the same functionality. -Creating them in the federation control plane ensures that they are synchronized -across all the clusters in federation. - - -## Creating a Federated Daemonset - -The API for Federated Daemonset is 100% compatible with the -API for traditional Kubernetes DaemonSet. You can create a DaemonSet by sending -a request to the federation apiserver. - -You can do that using [kubectl](/docs/user-guide/kubectl/) by running: - -``` shell -kubectl --context=federation-cluster create -f mydaemonset.yaml -``` - -The `--context=federation-cluster` flag tells kubectl to submit the -request to the Federation apiserver instead of sending it to a Kubernetes -cluster. - -Once a Federated Daemonset is created, the federation control plane will create -a matching DaemonSet in all underlying Kubernetes clusters. -You can verify this by checking each of the underlying clusters, for example: - -``` shell -kubectl --context=gce-asia-east1a get daemonset mydaemonset -``` - -The above assumes that you have a context named 'gce-asia-east1a' -configured in your client for your cluster in that zone. - -These DaemonSets in underlying clusters will match the Federated Daemonset. - - -## Updating a Federated Daemonset - -You can update a Federated Daemonset as you would update a Kubernetes -DaemonSet; however, for a Federated Daemonset, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. -The federation control plane ensures that whenever the Federated Daemonset is -updated, it updates the corresponding DaemonSets in all underlying clusters to -match it. - -## Deleting a Federated Daemonset - -You can delete a Federated Daemonset as you would delete a Kubernetes -DaemonSet; however, for a Federated Daemonset, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. - -For example, you can do that using kubectl by running: - -```shell -kubectl --context=federation-cluster delete daemonset mydaemonset -``` \ No newline at end of file +[Federated DaemonSet](/docs/tasks/administer-federation/daemonset/) diff --git a/docs/user-guide/federation/deployment.md b/docs/user-guide/federation/deployment.md index 51b092971d..df8456d709 100644 --- a/docs/user-guide/federation/deployment.md +++ b/docs/user-guide/federation/deployment.md @@ -2,107 +2,6 @@ title: Federated Deployment --- -This guide explains how to use Deployments in the Federation control plane. +{% include user-guide-content-moved.md %} -* TOC -{:toc} - -## Prerequisites - -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/admin/federation/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). -Other tutorials, such as Kelsey Hightower's -[Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation), -might also help you create a Federated Kubernetes cluster. - -You should also have a basic -[working knowledge of Kubernetes](/docs/getting-started-guides/) in -general and [Deployment](/docs/user-guide/deployments) in particular. - -## Overview - -Deployments in federation control plane (referred to as "Federated Deployments" in -this guide) are very similar to the traditional [Kubernetes -Deployment](/docs/user-guide/deployments/), and provide the same functionality. -Creating them in the federation control plane ensures that the desired number of -replicas exist across the registered clusters. - -**As of Kubernetes version 1.5, Federated Deployment is an Alpha feature. The core -functionality of Deployment is present, but some features -(such as full rollout compatibility) are still in development.** - -## Creating a Federated Deployment - -The API for Federated Deployment is compatible with the -API for traditional Kubernetes Deployment. You can create a Deployment by sending -a request to the federation apiserver. - -You can do that using [kubectl](/docs/user-guide/kubectl/) by running: - -``` shell -kubectl --context=federation-cluster create -f mydeployment.yaml -``` - -The '--context=federation-cluster' flag tells kubectl to submit the -request to the Federation apiserver instead of sending it to a Kubernetes -cluster. - -Once a Federated Deployment is created, the federation control plane will create -a Deployment in all underlying Kubernetes clusters. -You can verify this by checking each of the underlying clusters, for example: - -``` shell -kubectl --context=gce-asia-east1a get deployment mydep -``` - -The above assumes that you have a context named 'gce-asia-east1a' -configured in your client for your cluster in that zone. - -These Deployments in underlying clusters will match the federation Deployment -_except_ in the number of replicas and revision-related annotations. -Federation control plane ensures that the -sum of replicas in each cluster combined matches the desired number of replicas in the -Federated Deployment. - -### Spreading Replicas in Underlying Clusters - -By default, replicas are spread equally in all the underlying clusters. For ex: -if you have 3 registered clusters and you create a Federated Deployment with -`spec.replicas = 9`, then each Deployment in the 3 clusters will have -`spec.replicas=3`. -To modify the number of replicas in each cluster, you can specify -[FederatedReplicaSetPreference](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/federation/apis/federation/types.go) -as an annotation with key `federation.kubernetes.io/deployment-preferences` -on Federated Deployment. - - -## Updating a Federated Deployment - -You can update a Federated Deployment as you would update a Kubernetes -Deployment; however, for a Federated Deployment, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. -The federation control plane ensures that whenever the Federated Deployment is -updated, it updates the corresponding Deployments in all underlying clusters to -match it. So if the rolling update strategy was chosen then the underlying -cluster will do the rolling update independently and `maxSurge` and `maxUnavailable` -will apply only to individual clusters. This behavior may change in the future. - -If your update includes a change in number of replicas, the federation -control plane will change the number of replicas in underlying clusters to -ensure that their sum remains equal to the number of desired replicas in -Federated Deployment. - -## Deleting a Federated Deployment - -You can delete a Federated Deployment as you would delete a Kubernetes -Deployment; however, for a Federated Deployment, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. - -For example, you can do that using kubectl by running: - -```shell -kubectl --context=federation-cluster delete deployment mydep -``` +[Federated Deployment](/docs/tasks/administer-federation/deployment/) diff --git a/docs/user-guide/federation/events.md b/docs/user-guide/federation/events.md index 1d9f72ea0e..f148806bca 100644 --- a/docs/user-guide/federation/events.md +++ b/docs/user-guide/federation/events.md @@ -2,39 +2,6 @@ title: Federated Events --- -This guide explains how to use events in federation control plane to help in debugging. +{% include user-guide-content-moved.md %} - -* TOC -{:toc} - -## Prerequisites - -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/admin/federation/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). Other tutorials, for example -[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) -by Kelsey Hightower, are also available to help you. - -You are also expected to have a basic -[working knowledge of Kubernetes](/docs/getting-started-guides/) in -general. - -## Overview - -Events in federation control plane (referred to as "federation events" in -this guide) are very similar to the traditional Kubernetes -Events providing the same functionality. -Federation Events are stored only in federation control plane and are not passed on to the underlying Kubernetes clusters. - -Federation controllers create events as they process API resources to surface to the -user, the state that they are in. -You can get all events from federation apiserver by running: - -```shell -kubectl --context=federation-cluster get events -``` - -The standard kubectl get, update, delete commands will all work. +[Federated Evemts](/docs/tasks/administer-federation/events/) diff --git a/docs/user-guide/federation/federated-ingress.md b/docs/user-guide/federation/federated-ingress.md index a137ace1f2..b9a3dc2f51 100644 --- a/docs/user-guide/federation/federated-ingress.md +++ b/docs/user-guide/federation/federated-ingress.md @@ -2,355 +2,6 @@ title: Federated Ingress --- -This guide explains how to use Kubernetes Federated Ingress to deploy -a common HTTP(S) virtual IP load balancer across a federated service running in -multiple Kubernetes clusters. As of v1.4, clusters hosted in Google -Cloud (both GKE and GCE, or both) are supported. This makes it -easy to deploy a service that reliably serves HTTP(S) traffic -originating from web clients around the globe on a single, static IP -address. Low -network latency, high fault tolerance and easy administration are -ensured through intelligent request routing and automatic replica -relocation (using [Federated ReplicaSets](docs/user-guide/federation/federated-replicaset.md)). -Clients are automatically routed, via the shortest network path, to -the cluster closest to them with available capacity (despite the fact -that all clients use exactly the same static IP address). The load balancer -automatically checks the health of the pods comprising the service, -and avoids sending requests to unresponsive or slow pods (or entire -unresponsive clusters). +{% include user-guide-content-moved.md %} -Federated Ingress is released as an alpha feature, and supports Google Cloud Platform (GKE, -GCE and hybrid scenarios involving both) in Kubernetes v1.4. Work is under way to support other cloud -providers such as AWS, and other hybrid cloud scenarios (e.g. services -spanning private on-premise as well as public cloud Kubernetes -clusters). We welcome your feedback. - -* TOC -{:toc} - -## Prerequisites - -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/admin/federation/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). Other tutorials, for example -[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) -by Kelsey Hightower, are also available to help you. - -You are also expected to have a basic -[working knowledge of Kubernetes](/docs/getting-started-guides/) in -general, and [Ingress](/docs/user-guide/ingress/) in particular. - -## Overview - -Federated Ingresses are created in much that same way as traditional -[Kubernetes Ingresses](/docs/user-guide/ingress/): by making an API -call which specifies the desired properties of your logical ingress point. In the -case of Federated Ingress, this API call is directed to the -Federation API endpoint, rather than a Kubernetes cluster API -endpoint. The API for Federated Ingress is 100% compatible with the -API for traditional Kubernetes Services. - -Once created, the Federated Ingress automatically: - -1. creates matching Kubernetes Ingress objects in every cluster -underlying your Cluster Federation, -2. ensures that all of these in-cluster ingress objects share the same - logical global L7 (i.e. HTTP(S)) load balancer and IP address. -3. monitors the health and capacity of the service "shards" (i.e. your - pods) behind this ingress in each cluster -4. ensures that all client connections are routed to an appropriate -healthy backend service endpoint at all times, even in the event of -pod, cluster, -availability zone or regional outages. - -Note that in the case of Google Cloud, the logical L7 load balancer is -not a single physical device (which would present both a single point -of failure, and a single global network routing choke point), but -rather a -[truly global, highly available load balancing managed service](https://cloud.google.com/load-balancing/), -globally reachable via a single, static IP address. - -Clients inside your federated Kubernetes clusters (i.e. Pods) will be -automatically routed to the cluster-local shard of the Federated Service -backing the Ingress in their -cluster if it exists and is healthy, or the closest healthy shard in a -different cluster if it does not. Note that this involves a network -trip to the HTTP(s) load balancer, which resides outside your local -Kubernetes cluster but inside the same GCP region. - -## Creating a federated ingress - -You can create a federated ingress in any of the usual ways, for example using kubectl: - -``` shell -kubectl --context=federation-cluster create -f myingress.yaml -``` -For example ingress YAML configurations, see the [Ingress User Guide](/docs/user-guide/ingress/) -The '--context=federation-cluster' flag tells kubectl to submit the -request to the Federation API endpoint, with the appropriate -credentials. If you have not yet configured such a context, visit the -[federation admin guide](/docs/admin/federation/) or one of the -[administration tutorials](https://github.com/kelseyhightower/kubernetes-cluster-federation) -to find out how to do so. - -As described above, the Federated Ingress will automatically create -and maintain matching Kubernetes ingresses in all of the clusters -underlying your federation. These cluster-specific ingresses (and -their associated ingress controllers) configure and manage the load -balancing and health checking infrastructure that ensures that traffic -is load balanced to each cluster appropriately. - -You can verify this by checking in each of the underlying clusters, for example: - -``` shell -kubectl --context=gce-asia-east1a get ingress myingress -NAME HOSTS ADDRESS PORTS AGE -myingress * 130.211.5.194 80, 443 1m -``` - -The above assumes that you have a context named 'gce-asia-east1a' -configured in your client for your cluster in that zone. The name and -namespace of the underlying ingress will automatically match those of -the Federated Ingress that you created above (and if you happen to -have had ingresses of the same name and namespace already existing in -any of those clusters, they will be automatically adopted by the -Federation and updated to conform with the specification of your -Federated Ingress - either way, the end result will be the same). - -The status of your Federated Ingress will automatically reflect the -real-time status of the underlying Kubernetes ingresses, for example: - -``` shell -$kubectl --context=federation-cluster describe ingress myingress - -Name: myingress -Namespace: default -Address: 130.211.5.194 -TLS: - tls-secret terminates -Rules: - Host Path Backends - ---- ---- -------- - * * echoheaders-https:80 (10.152.1.3:8080,10.152.2.4:8080) -Annotations: - https-target-proxy: k8s-tps-default-myingress--ff1107f83ed600c0 - target-proxy: k8s-tp-default-myingress--ff1107f83ed600c0 - url-map: k8s-um-default-myingress--ff1107f83ed600c0 - backends: {"k8s-be-30301--ff1107f83ed600c0":"Unknown"} - forwarding-rule: k8s-fw-default-myingress--ff1107f83ed600c0 - https-forwarding-rule: k8s-fws-default-myingress--ff1107f83ed600c0 -Events: - FirstSeen LastSeen Count From SubobjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 3m 3m 1 {loadbalancer-controller } Normal ADD default/myingress - 2m 2m 1 {loadbalancer-controller } Normal CREATE ip: 130.211.5.194 -``` - -Note that: - -1. the address of your Federated Ingress -corresponds with the address of all of the -underlying Kubernetes ingresses (once these have been allocated - this -may take up to a few minutes). -2. we have not yet provisioned any backend Pods to receive -the network traffic directed to this ingress (i.e. 'Service -Endpoints' behind the service backing the Ingress), so the Federated Ingress does not yet consider these to -be healthy shards and will not direct traffic to any of these clusters. -3. the federation control system will -automatically reconfigure the load balancer controllers in all of the -clusters in your federation to make them consistent, and allow -them to share global load balancers. But this reconfiguration can -only complete successfully if there are no pre-existing Ingresses in -those clusters (this is a safety feature to prevent accidental -breakage of existing ingresses). So to ensure that your federated -ingresses function correctly, either start with new, empty clusters, or make -sure that you delete (and recreate if necessary) all pre-existing -Ingresses in the clusters comprising your federation. - -#Adding backend services and pods - -To render the underlying ingress shards healthy, we need to add -backend Pods behind the service upon which the Ingress is based. There are several ways to achieve this, but -the easiest is to create a [Federated Service](federated-services.md) and -[Federated Replicaset](federated-replicasets.md). Details of how those -work are covered in the aforementioned user guides - here we'll simply use them, to -create appropriately labelled pods and services in the 13 underlying clusters of -our federation: - -``` shell -kubectl --context=federation-cluster create -f services/nginx.yaml -``` - -``` shell - kubectl --context=federation-cluster create -f myreplicaset.yaml -``` - -Note that in order for your federated ingress to work correctly on -Google Cloud, the node ports of all of the underlying cluster-local -services need to be identical. If you're using a federated service -this is easy to do. Simply pick a node port that is not already -being used in any of your clusters, and add that to the spec of your -federated service. If you do not specify a node port for your -federated service, each cluster will choose it's own node port for -its cluster-local shard of the service, and these will probably end -up being different, which is not what you want. - -You can verify this by checking in each of the underlying clusters, for example: - -``` shell -kubectl --context=gce-asia-east1a get services nginx -NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE -nginx 10.63.250.98 104.199.136.89 80/TCP 9m -``` - - -## Hybrid cloud capabilities - -Federations of Kubernetes Clusters can include clusters running in -different cloud providers (e.g. Google Cloud, AWS), and on-premises -(e.g. on OpenStack). However, in Kubernetes v1.4, Federated Ingress is only -supported across Google Cloud clusters. In future versions we intend -to support hybrid cloud Ingress-based deployments. - -## Discovering a federated ingress - -Ingress objects (in both plain Kubernets clusters, and in federations -of clusters) expose one or more IP addresses (via -the Status.Loadbalancer.Ingress field) that remains static for the lifetime -of the Ingress object (in future, automatically managed DNS names -might also be added). All clients (whether internal to your cluster, -or on the external network or internet) should connect to one of these IP -or DNS addresses. As mentioned above, all client requests are automatically -routed, via the shortest network path, to a healthy pod in the -closest cluster to the origin of the request. So for example, HTTP(S) -requests from internet -users in Europe will be routed directly to the closest cluster in -Europe that has available capacity. If there are no such clusters in -Europe, the request will be routed to the next closest cluster -(typically in the U.S.). - -## Handling failures of backend pods and whole clusters - -Ingresses are backed by Services, which are typically (but not always) -backed by one or more ReplicaSets. For Federated Ingresses, it is -common practise to use the federated variants of Services and -ReplicaSets (see [Federated Services](federated-services.md) and -[Federated ReplicaSets](federated-replicasets.md)) for this purpose, as -described above. - -In particular, Federated ReplicaSets ensure that the desired number of -pods are kept running in each cluster, even in the event of node -failures. In the event of entire cluster or availability zone -failures, Federated ReplicaSets automatically place additional -replacas in the other available clusters in the federation to accommodate the -traffic which was previously being served by the now unavailable -cluster. While the Federated ReplicaSet ensures that sufficient replicas are -kept running, the Federated Ingress ensures that user traffic is -automatically redirected away from the failed cluster to other -available clusters. - -## Known issue - -GCE L7 load balancer back-ends and health checks are known to "flap"; this is due -to conflicting firewall rules in the federation's underlying clusters, which might override one another. To work around this problem, you can -install the firewall rules manually to expose the targets of all the -underlying clusters in your federation for each Federated Ingress -object. This way, the health checks can consistently pass and the GCE L7 load balancer -can remain stable. You install the rules using the -[`gcloud`](https://cloud.google.com/sdk/gcloud/) command line tool, -[Google Cloud Console](https://console.cloud.google.com) or the -[Google Compute Engine APIs](https://cloud.google.com/compute/docs/reference/latest/). - -You can install these rules using -[`gcloud`](https://cloud.google.com/sdk/gcloud/) as follows: - -```shell -gcloud compute firewall-rules create \ - --source-ranges 130.211.0.0/22 --allow [] \ - --target-tags [] \ - --network -``` - -where: - -1. `firewall-rule-name` can be any name. -2. `[]` is the comma separated list of node ports corresponding to the services that back the Federated Ingress. -3. [] is the comma separated list of the target tags assigned to the nodes in a Kubernetes cluster. -4. is the name of the network where the firewall rule must be installed. - -Example: -```shell -gcloud compute firewall-rules create my-federated-ingress-firewall-rule \ - --source-ranges 130.211.0.0/22 --allow tcp:30301, tcp:30061, tcp:34564 \ - --target-tags my-cluster-1-minion, my-cluster-2-minion \ - --network default -``` - - -## Troubleshooting - -#### I cannot connect to my cluster federation API -Check that your - -1. Client (typically kubectl) is correctly configured (including API endpoints and login credentials), and -2. Cluster Federation API server is running and network-reachable. - -See the [federation admin guide](/docs/admin/federation/) to learn -how to bring up a cluster federation correctly (or have your cluster administrator do this for you), and how to correctly configure your client. - -#### I can create a federated ingress/service/replicaset successfully against the cluster federation API, but no matching ingresses/services/replicasets are created in my underlying clusters - -Check that: - -1. Your clusters are correctly registered in the Cluster Federation API (`kubectl describe clusters`) -2. Your clusters are all 'Active'. This means that the cluster - Federation system was able to connect and authenticate against the - clusters' endpoints. If not, consult the event logs of the federation-controller-manager pod to ascertain what the failure might be. (`kubectl --namespace=federation logs $(kubectl get pods --namespace=federation -l module=federation-controller-manager -oname`) -3. That the login credentials provided to the Cluster Federation API - for the clusters have the correct authorization and quota to create - ingresses/services/replicasets in the relevant namespace in the - clusters. Again you should see associated error messages providing - more detail in the above event log file if this is not the case. -4. Whether any other error is preventing the service creation - operation from succeeding (look for `ingress-controller`, - `service-controller` or `replicaset-controller`, - errors in the output of `kubectl logs federation-controller-manager --namespace federation`). - -#### I can create a federated ingress successfully, but request load is not correctly distributed across the underlying clusters - -Check that: - -1. the services underlying your federated ingress in each cluster have - identical node ports. See [above](#creating_a_federated_ingress) for further explanation. -2. the load balancer controllers in each of your clusters are of the - correct type ("GLBC") and have been correctly reconfigured by the - federation control plane to share a global GCE load balancer (this - should happen automatically). If they of the correct type, and - have been correctly reconfigured, the UID data item in the GLBC - configmap in each cluster will be identical across all clusters. - See - [the GLBC docs](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/BETA_LIMITATIONS.md#changing-the-cluster-uid) - for further details. - If this is not the case, check the logs of your federation - controller manager to determine why this automated reconfiguration - might be failing. -3. no ingresses have been manually created in any of your clusters before the above - reconfiguration of the load balancer controller completed - successfully. Ingresses created before the reconfiguration of - your GLBC will interfere with the behavior of your federated - ingresses created after the reconfiguration (see - [the GLBC docs](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/BETA_LIMITATIONS.md#changing-the-cluster-uid) - for further information. To remedy this, - delete any ingresses created before the cluster joined the - federation (and had it's GLBC reconfigured), and recreate them if - necessary. - -#### This troubleshooting guide did not help me solve my problem - -Please use one of our [support channels](http://kubernetes.io/docs/troubleshooting/) to seek assistance. - -## For more information - - * [Federation proposal](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/proposals/federation.md) details use cases that motivated this work. +[Federated Ingress](/docs/tasks/administer-federation/ingress/) diff --git a/docs/user-guide/federation/index.md b/docs/user-guide/federation/index.md index 7ba0ca9c60..6e97d9429b 100644 --- a/docs/user-guide/federation/index.md +++ b/docs/user-guide/federation/index.md @@ -2,136 +2,6 @@ title: Federation User Guide --- -This guide explains why and how to manage multiple Kubernetes clusters using -federation. +{% include user-guide-content-moved.md %} - -* TOC -{:toc} - - -## Why federation - -Federation makes it easy to manage multiple clusters. It does so by providing 2 -major building blocks: - - * Sync resources across clusters: Federation provides the ability to keep - resources in multiple clusters in sync. This can be used, for example, to - ensure that the same deployment exists in multiple clusters. - * Cross cluster discovery: It provides the ability to auto-configure DNS - servers and load balancers with backends from all clusters. This can be used, - for example, to ensure that a global VIP or DNS record can be used to access - backends from multiple clusters. - -Some other use cases that federation enables are: - -* High Availability: By spreading load across clusters and auto configuring DNS - servers and load balancers, federation minimises the impact of cluster - failure. -* Avoiding provider lock-in: By making it easier to migrate applications across - clusters, federation prevents cluster provider lock-in. - - -Federation is not helpful unless you have multiple clusters. Some of the reasons -why you might want multiple clusters are: - -* Low latency: Having clusters in multiple regions minimises latency by serving - users from the cluster that is closest to them. -* Fault isolation: It might be better to have multiple small clusters rather - than a single large cluster for fault isolation (for example: multiple - clusters in different availability zones of a cloud provider). - [Multi cluster guide](/docs/admin/multi-cluster) has more details on this. -* Scalability: There are scalability limits to a single kubernetes cluster (this - should not be the case for most users. For more details: - https://github.com/kubernetes/community/blob/master/sig-scalability/goals.md). -* Hybrid cloud: You can have multiple clusters on different cloud providers or - on-premises data centers. - - -### Caveats - -While there are a lot of attractive use cases for federation, there are also -some caveats. - -* Increased network bandwidth and cost: The dederation control plane watches all - clusters to ensure that the current state is as expected. This can lead to - significant network cost if the clusters are running in different regions on - a cloud provider or on different cloud providers. -* Reduced cross cluster isolation: A bug in the federation control plane can - impact all clusters. This is mitigated by keeping the logic in federation - control plane to a minimum. It mostly delegates to the control plane in - kubernetes clusters whenever it can. The design and implementation also errs - on the side of safety and avoiding multicluster outage. -* Maturity: The federation project is relatively new and is not very mature. - Not all resources are available and many are still alpha. [Issue - 38893](https://github.com/kubernetes/kubernetes/issues/38893) ennumerates - known issues with the system that the team is busy solving. - -## Setup - -To be able to federate multiple clusters, we first need to setup a federation -control plane. -Follow the [setup guide](/docs/admin/federation/) to setup the -federation control plane. - -## Hybrid cloud capabilities - -Federations of Kubernetes Clusters can include clusters running in -different cloud providers (e.g. Google Cloud, AWS), and on-premises -(e.g. on OpenStack). Simply create all of the clusters that you -require, in the appropriate cloud providers and/or locations, and -register each cluster's API endpoint and credentials with your -Federation API Server (See the -[federation admin guide](/docs/admin/federation/) for details). - -Thereafter, your API resources can span different clusters -and cloud providers. - -## API resources - -Once we have the control plane setup, we can start creating federation API -resources. -The following guides explain some of the resources in detail: - -* [ConfigMap](/docs/user-guide/federation/configmap/) -* [DaemonSets](/docs/user-guide/federation/daemonsets/) -* [Deployment](/docs/user-guide/federation/deployment/) -* [Events](/docs/user-guide/federation/events/) -* [Ingress](/docs/user-guide/federation/federated-ingress/) -* [Namespaces](/docs/user-guide/federation/namespaces/) -* [ReplicaSets](/docs/user-guide/federation/replicasets/) -* [Secrets](/docs/user-guide/federation/secrets/) -* [Services](/docs/user-guide/federation/federated-services/) - -[API reference docs](/docs/federation/api-reference/) lists all the -resources supported by federation apiserver. - -## Cascading deletion - -Kubernetes version 1.5 includes support for cascading deletion of federated -resources. With cascading deletion, when you delete a resource from the -federation control plane, the corresponding resources in all underlying clusters -are also deleted. - -To enable cascading deletion, set the option -`DeleteOptions.orphanDependents=false` when you delete a resource from the -federation control plane. - -The following Federated resources are affected by cascading deletion: - -* Ingress -* Namespace -* ReplicaSet -* Secret -* Deployment -* DaemonSet - -Note: By default, deleting a resource from federation control plane does not -delete the corresponding resources from underlying clusters. - - -## For more information - -* [Federation - proposal](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/proposals/federation.md) -* [Kubecon2016 talk on federation](https://www.youtube.com/watch?v=pq9lbkmxpS8) +[Federation](/docs/concepts/cluster-administration/federation.md) diff --git a/docs/user-guide/federation/namespaces.md b/docs/user-guide/federation/namespaces.md index 5ed3ffafec..76b722c2b8 100644 --- a/docs/user-guide/federation/namespaces.md +++ b/docs/user-guide/federation/namespaces.md @@ -2,89 +2,6 @@ title: Federated Namespaces --- -This guide explains how to use namespaces in Federation control plane. +{% include user-guide-content-moved.md %} -* TOC -{:toc} - -## Prerequisites - -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/admin/federation/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). Other tutorials, for example -[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) -by Kelsey Hightower, are also available to help you. - -You are also expected to have a basic -[working knowledge of Kubernetes](/docs/getting-started-guides/) in -general and [Namespaces](/docs/user-guide/namespaces/) in particular. - -## Overview - -Namespaces in federation control plane (referred to as "federated namespaces" in -this guide) are very similar to the traditional [Kubernetes -Namespaces](/docs/user-guide/namespaces/) providing the same functionality. -Creating them in the federation control plane ensures that they are synchronized -across all the clusters in federation. - - -## Creating a Federated Namespace - -The API for Federated Namespaces is 100% compatible with the -API for traditional Kubernetes Namespaces. You can create a namespace by sending -a request to the federation apiserver. - -You can do that using kubectl by running: - -``` shell -kubectl --context=federation-cluster create -f myns.yaml -``` - -The '--context=federation-cluster' flag tells kubectl to submit the -request to the Federation apiserver instead of sending it to a Kubernetes -cluster. - -Once a federated namespace is created, the federation control plane will create -a matching namespace in all underlying Kubernetes clusters. -You can verify this by checking each of the underlying clusters, for example: - -``` shell -kubectl --context=gce-asia-east1a get namespaces myns -``` - -The above assumes that you have a context named 'gce-asia-east1a' -configured in your client for your cluster in that zone. The name and -spec of the underlying namespace will match those of -the Federated Namespace that you created above. - - -## Updating a Federated Namespace - -You can update a federated namespace as you would update a Kubernetes -namespace, just send the request to federation apiserver instead of sending it -to a specific Kubernetes cluster. -Federation control plan will ensure that whenever the federated namespace is -updated, it updates the corresponding namespaces in all underlying clusters to -match it. - -## Deleting a Federated Namespace - -You can delete a federated namespace as you would delete a Kubernetes -namespace, just send the request to federation apiserver instead of sending it -to a specific Kubernetes cluster. - -For example, you can do that using kubectl by running: - -```shell -kubectl --context=federation-cluster delete ns myns -``` - -As in Kubernetes, deleting a federated namespace will delete all resources in that -namespace from the federation control plane. - -Note that at this point, deleting a federated namespace will not delete the -corresponding namespaces and resources in those namespaces from underlying clusters. -Users are expected to delete them manually. -We intend to fix this in the future. +[Federated Namespaces](/docs/tasks/administer-federation/namespaces/) diff --git a/docs/user-guide/federation/replicasets.md b/docs/user-guide/federation/replicasets.md index c173a38996..5c597d74ec 100644 --- a/docs/user-guide/federation/replicasets.md +++ b/docs/user-guide/federation/replicasets.md @@ -2,104 +2,6 @@ title: Federated ReplicaSets --- -This guide explains how to use replica sets in the Federation control plane. +{% include user-guide-content-moved.md %} -* TOC -{:toc} - -## Prerequisites - -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/admin/federation/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). Other tutorials, for example -[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) -by Kelsey Hightower, are also available to help you. - -You are also expected to have a basic -[working knowledge of Kubernetes](/docs/getting-started-guides/) in -general and [ReplicaSets](/docs/user-guide/replicasets/) in particular. - -## Overview - -Replica Sets in federation control plane (referred to as "federated replica sets" in -this guide) are very similar to the traditional [Kubernetes -ReplicaSets](/docs/user-guide/replicasets/), and provide the same functionality. -Creating them in the federation control plane ensures that the desired number of -replicas exist across the registered clusters. - - -## Creating a Federated Replica Set - -The API for Federated Replica Set is 100% compatible with the -API for traditional Kubernetes Replica Set. You can create a replica set by sending -a request to the federation apiserver. - -You can do that using [kubectl](/docs/user-guide/kubectl/) by running: - -``` shell -kubectl --context=federation-cluster create -f myrs.yaml -``` - -The '--context=federation-cluster' flag tells kubectl to submit the -request to the Federation apiserver instead of sending it to a Kubernetes -cluster. - -Once a federated replica set is created, the federation control plane will create -a replica set in all underlying Kubernetes clusters. -You can verify this by checking each of the underlying clusters, for example: - -``` shell -kubectl --context=gce-asia-east1a get rs myrs -``` - -The above assumes that you have a context named 'gce-asia-east1a' -configured in your client for your cluster in that zone. - -These replica sets in underlying clusters will match the federation replica set -except in the number of replicas. Federation control plane will ensure that the -sum of replicas in each cluster match the desired number of replicas in the -federation replica set. - -### Spreading Replicas in Underlying Clusters - -By default, replicas are spread equally in all the underlying clusters. For ex: -if you have 3 registered clusters and you create a federated replica set with -`spec.replicas = 9`, then each replica set in the 3 clusters will have -`spec.replicas=3`. -To modify the number of replicas in each cluster, you can specify -[FederatedReplicaSetPreference](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/federation/apis/federation/types.go) -as an annotation with key `federation.kubernetes.io/replica-set-preferences` -on federated replica set. - - -## Updating a Federated Replica Set - -You can update a federated replica set as you would update a Kubernetes -replica set; however, for a federated replica set, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. -The Federation control plan ensures that whenever the federated replica set is -updated, it updates the corresponding replica sets in all underlying clusters to -match it. -If your update includes a change in number of replicas, the federation -control plane will change the number of replicas in underlying clusters to -ensure that their sum remains equal to the number of desired replicas in -federated replica set. - -## Deleting a Federated Replica Set - -You can delete a federated replica set as you would delete a Kubernetes -replica set; however, for a federated replica set, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. - -For example, you can do that using kubectl by running: - -```shell -kubectl --context=federation-cluster delete rs myrs -``` - -Note that at this point, deleting a federated replica set will not delete the -corresponding replica sets from underlying clusters. -You must delete the underlying Replica Sets manually. -We intend to fix this in the future. +[Federated ReplicaSets](/docs/tasks/administer-federation/replicaset/) diff --git a/docs/user-guide/federation/secrets.md b/docs/user-guide/federation/secrets.md index 2c5eac6dba..bbd503e506 100644 --- a/docs/user-guide/federation/secrets.md +++ b/docs/user-guide/federation/secrets.md @@ -2,86 +2,6 @@ title: Federated Secrets --- -This guide explains how to use secrets in Federation control plane. +{% include user-guide-content-moved.md %} -* TOC -{:toc} - -## Prerequisites - -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/admin/federation/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). Other tutorials, for example -[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation) -by Kelsey Hightower, are also available to help you. - -You are also expected to have a basic -[working knowledge of Kubernetes](/docs/getting-started-guides/) in -general and [Secrets](/docs/user-guide/secrets/) in particular. - -## Overview - -Secrets in federation control plane (referred to as "federated secrets" in -this guide) are very similar to the traditional [Kubernetes -Secrets](/docs/user-guide/secrets/) providing the same functionality. -Creating them in the federation control plane ensures that they are synchronized -across all the clusters in federation. - - -## Creating a Federated Secret - -The API for Federated Secret is 100% compatible with the -API for traditional Kubernetes Secret. You can create a secret by sending -a request to the federation apiserver. - -You can do that using [kubectl](/docs/user-guide/kubectl/) by running: - -``` shell -kubectl --context=federation-cluster create -f mysecret.yaml -``` - -The '--context=federation-cluster' flag tells kubectl to submit the -request to the Federation apiserver instead of sending it to a Kubernetes -cluster. - -Once a federated secret is created, the federation control plane will create -a matching secret in all underlying Kubernetes clusters. -You can verify this by checking each of the underlying clusters, for example: - -``` shell -kubectl --context=gce-asia-east1a get secret mysecret -``` - -The above assumes that you have a context named 'gce-asia-east1a' -configured in your client for your cluster in that zone. - -These secrets in underlying clusters will match the federated secret. - - -## Updating a Federated Secret - -You can update a federated secret as you would update a Kubernetes -secret; however, for a federated secret, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. -The Federation control plan ensures that whenever the federated secret is -updated, it updates the corresponding secrets in all underlying clusters to -match it. - -## Deleting a Federated Secret - -You can delete a federated secret as you would delete a Kubernetes -secret; however, for a federated secret, you must send the request to -the federation apiserver instead of sending it to a specific Kubernetes cluster. - -For example, you can do that using kubectl by running: - -```shell -kubectl --context=federation-cluster delete secret mysecret -``` - -Note that at this point, deleting a federated secret will not delete the -corresponding secrets from underlying clusters. -You must delete the underlying secrets manually. -We intend to fix this in the future. +[Federated Secrets](/docs/tasks/administer-federation/secret/) diff --git a/docs/user-guide/garbage-collection.md b/docs/user-guide/garbage-collection.md index af90b4dd1a..16f9380866 100644 --- a/docs/user-guide/garbage-collection.md +++ b/docs/user-guide/garbage-collection.md @@ -4,35 +4,6 @@ assignees: title: Garbage Collection (Beta) --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -## Garbage Collection - -Note: the Garbage Collection is a beta feature and is enabled by default in Kubernetes version 1.4. - -### What does Garbage Collector do - -When you delete, for example, a ReplicaSet, it is often desirable for the server to automatically garbage collect all the Pods that the ReplicaSet creates. The Garbage Collector (GC) implements this. In general, when you delete an owner object, GC deletes that owner's dependent objects. - -### How to establish an owner-dependent relationship between objects - -Kubernetes 1.3 added a metadata.ownerReferences field to every Kubernetes API object. If an API object is a dependent of another object, ownerReference should point to the owning API object. - -When you create a ReplicationController or a ReplicaSet in Kubernetes 1.4, the Kubernetes control plane automatically sets the ownerReference field in each created pod to point to the owning ReplicationController or ReplicaSet. - -You can set up owner-dependent relationships among other objects by manually setting the ownerReference field on dependent objects. - -### Controlling whether Garbage Collector deletes dependents - -When deleting an object, you can request the GC to ***asynchronously*** delete its dependents by ***explicitly*** specifying `deleteOptions.orphanDependents=false` in the deletion request that you send to the API server. A 200 OK response from the API server indicates the owner is deleted. - -In Kubernetes version 1.5, synchronous garbage collection is under active development. See the tracking [issue](https://github.com/kubernetes/kubernetes/issues/29891) for more details. - -If you specify `deleteOptions.orphanDependents=true`, or leave it blank, then the GC will first reset the `ownerReferences` in the dependents, then delete the owner. Note that the deletion of the owner object is asynchronous, that is, a 200 OK response will be sent by the API server before the owner object gets deleted. - -### Other references - -[Design Doc](https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/garbage-collection.md) - -[Known issues](https://github.com/kubernetes/kubernetes/issues/26120) +[Garbage Collection](/docs/concepts/abstractions/controllers/garbage-collection/) diff --git a/docs/user-guide/getting-into-containers.md b/docs/user-guide/getting-into-containers.md index bf6a5a8a2f..ff89f111f6 100644 --- a/docs/user-guide/getting-into-containers.md +++ b/docs/user-guide/getting-into-containers.md @@ -5,70 +5,6 @@ assignees: title: Running Commands in a Container with kubectl exec --- -Developers can use `kubectl exec` to run commands in a container. This guide demonstrates two use cases. +{% include user-guide-content-moved.md %} -## Using kubectl exec to check the environment variables of a container - -Kubernetes exposes [services](/docs/user-guide/services/#environment-variables) through environment variables. It is convenient to check these environment variables using `kubectl exec`. - -We first create a pod and a service, - -```shell -$ kubectl create -f examples/guestbook/redis-master-controller.yaml -$ kubectl create -f examples/guestbook/redis-master-service.yaml -``` -wait until the pod is Running and Ready, - -```shell -$ kubectl get pod -NAME READY REASON RESTARTS AGE -redis-master-ft9ex 1/1 Running 0 12s -``` - -then we can check the environment variables of the pod, - -```shell -$ kubectl exec redis-master-ft9ex env -... -REDIS_MASTER_SERVICE_PORT=6379 -REDIS_MASTER_SERVICE_HOST=10.0.0.219 -... -``` - -We can use these environment variables in applications to find the service. - - -## Using kubectl exec to check the mounted volumes - -It is convenient to use `kubectl exec` to check if the volumes are mounted as expected. -We first create a Pod with a volume mounted at /data/redis, - -```shell -kubectl create -f docs/user-guide/walkthrough/pod-redis.yaml -``` - -wait until the pod is Running and Ready, - -```shell -$ kubectl get pods -NAME READY REASON RESTARTS AGE -storage 1/1 Running 0 1m -``` - -we then use `kubectl exec` to verify that the volume is mounted at /data/redis, - -```shell -$ kubectl exec storage ls /data -redis -``` - -## Using kubectl exec to open a bash terminal in a pod - -After all, open a terminal in a pod is the most direct way to introspect the pod. Assuming the pod/storage is still running, run - -```shell -$ kubectl exec -ti storage -- bash -root@storage:/data# -``` - -This gets you a terminal. \ No newline at end of file +[Getting a Shell to a Running Container](/docs/tasks/kubectl/get-shell-running-container/) diff --git a/docs/user-guide/horizontal-pod-autoscaling/index.md b/docs/user-guide/horizontal-pod-autoscaling/index.md index 44ad3440e2..b88e5f520a 100644 --- a/docs/user-guide/horizontal-pod-autoscaling/index.md +++ b/docs/user-guide/horizontal-pod-autoscaling/index.md @@ -69,7 +69,7 @@ The detailed documentation of `kubectl autoscale` can be found [here](/docs/user ## Autoscaling during rolling update -Currently in Kubernetes, it is possible to perform a [rolling update](/docs/user-guide/rolling-updates/) by managing replication controllers directly, +Currently in Kubernetes, it is possible to perform a [rolling update](/docs/tasks/run-application/rolling-update-replication-controller/) 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. diff --git a/docs/user-guide/horizontal-pod-autoscaling/walkthrough.md b/docs/user-guide/horizontal-pod-autoscaling/walkthrough.md index f0a5cbc64a..616061e930 100644 --- a/docs/user-guide/horizontal-pod-autoscaling/walkthrough.md +++ b/docs/user-guide/horizontal-pod-autoscaling/walkthrough.md @@ -23,7 +23,7 @@ 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 the php-apache image. -The image can be found [here](/docs/user-guide/horizontal-pod-autoscaling/image). +The Dockerfile can be found [here](/docs/user-guide/horizontal-pod-autoscaling/image/Dockerfile). It defines an [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: diff --git a/docs/user-guide/images.md b/docs/user-guide/images.md index 5b523e5615..0d12db8904 100644 --- a/docs/user-guide/images.md +++ b/docs/user-guide/images.md @@ -25,7 +25,7 @@ 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. +Note that you should avoid using `:latest` tag, see [Best Practices for Configuration](/docs/concepts/configuration/overview/#container-images) for more information. ## Using a Private Registry diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index 9c69683525..94eaacf3d7 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -4,11 +4,13 @@ assignees: title: User Guide --- +{% include user-guide-migration-notice.md %} + The Kubernetes **Guides** can help you work with various aspects of the Kubernetes system. * The Kubernetes [User Guide](#user-guide-internal) can help you run programs and services on an existing Kubernetes cluster. * The [Cluster Admin Guide](/docs/admin/) can help you set up and administrate your own Kubernetes cluster. -* The [Developer Guide](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel) can help you either write code to directly access the Kubernetes API, or to contribute directly to the Kubernetes project. +* The [Developer Guide] can help you either write code to directly access the Kubernetes API, or to contribute directly to the Kubernetes project. ## Kubernetes User Guide @@ -19,7 +21,7 @@ The following topics in the Kubernetes User Guide can help you run applications 1. [Deploying continuously running applications](/docs/user-guide/deploying-applications/) 1. [Connecting applications: exposing applications to clients and users](/docs/user-guide/connecting-applications/) 1. [Working with containers in production](/docs/user-guide/production-pods/) -1. [Managing deployments](/docs/user-guide/managing-deployments/) +1. [Managing deployments](/docs/concepts/cluster-administration/manage-deployment/) 1. [Application introspection and debugging](/docs/user-guide/introspection-and-debugging/) 1. [Using the Kubernetes web user interface](/docs/user-guide/ui/) 1. [Logging](/docs/user-guide/logging/overview/) @@ -54,7 +56,7 @@ Before running examples in the user guides, please ensure you have completed the : A service defines a set of pods and a means by which to access them, such as single stable IP address and corresponding DNS name. [**Volume**](/docs/user-guide/volumes/) -: A volume is a directory, possibly with some data in it, which is accessible to a Container as part of its filesystem. Kubernetes volumes build upon [Docker Volumes](https://docs.docker.com/userguide/dockervolumes/), adding provisioning of the volume directory and/or device. +: A volume is a directory, possibly with some data in it, which is accessible to a Container as part of its filesystem. Kubernetes volumes build upon [Docker Volumes](https://docs.docker.com/engine/tutorials/dockervolumes/), adding provisioning of the volume directory and/or device. [**Secret**](/docs/user-guide/secrets/) : A secret stores sensitive data, such as authentication tokens, which can be made available to containers upon request. @@ -83,6 +85,8 @@ Pods and containers * [Downward API: accessing system configuration from a pod](/docs/user-guide/downward-api/) * [Images and registries](/docs/user-guide/images/) * [Migrating from docker-cli to kubectl](/docs/user-guide/docker-cli-to-kubectl/) - * [Configuration Best Practices and Tips](/docs/user-guide/config-best-practices/) + * [Configuration Best Practices and Tips](/docs/concepts/configuration/overview/) * [Assign pods to selected nodes](/docs/user-guide/node-selection/) - * [Perform a rolling update on a running group of pods](/docs/user-guide/update-demo/) + * [Perform a rolling update on a running group of pods](/docs/tasks/run-application/rolling-update-replication-controller/) + +[Developer Guide]: https://github.com/kubernetes/community/blob/master/contributors/devel/README.md diff --git a/docs/user-guide/ingress.md b/docs/user-guide/ingress.md index 809a025c57..0a4f13da2f 100644 --- a/docs/user-guide/ingress.md +++ b/docs/user-guide/ingress.md @@ -44,9 +44,9 @@ It can be configured to give services externally-reachable urls, load balance tr 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. -GCE/GKE deploys an ingress controller on the master. You can deploy any number of custom ingress controllers in a pod. You must annotate each ingress with the appropriate class, as indicated [here](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx#running-multiple-ingress-controllers) and [here](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/BETA_LIMITATIONS.md#disabling-glbc). +GCE/GKE deploys an ingress controller on the master. You can deploy any number of custom ingress controllers in a pod. You must annotate each ingress with the appropriate class, as indicated [here](https://github.com/kubernetes/ingress/tree/master/controllers/nginx#running-multiple-ingress-controllers) and [here](https://github.com/kubernetes/ingress/blob/master/controllers/gce/BETA_LIMITATIONS.md#disabling-glbc). -Make sure you review the [beta limitations](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/gce/BETA_LIMITATIONS.md) of this controller. In environments other than GCE/GKE, you need to [deploy a controller](https://github.com/kubernetes/contrib/tree/master/ingress/controllers) as a pod. +Make sure you review the [beta limitations](https://github.com/kubernetes/ingress/blob/master/controllers/gce/BETA_LIMITATIONS.md) of this controller. In environments other than GCE/GKE, you need to [deploy a controller](https://github.com/kubernetes/ingress/tree/master/controllers) as a pod. ## The Ingress Resource @@ -71,7 +71,7 @@ spec: __Lines 1-4__: As with all other Kubernetes config, an Ingress needs `apiVersion`, `kind`, and `metadata` fields. For general information about working with config files, see [here](/docs/user-guide/deploying-applications), [here](/docs/user-guide/configuring-containers), and [here](/docs/user-guide/working-with-resources). -__Lines 5-7__: Ingress [spec](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status) has all the information needed to configure a loadbalancer or proxy server. Most importantly, it contains a list of rules matched against all incoming requests. Currently the Ingress resource only supports http rules. +__Lines 5-7__: Ingress [spec](https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status) has all the information needed to configure a loadbalancer or proxy server. Most importantly, it contains a list of rules matched against all incoming requests. Currently the Ingress resource only supports http rules. __Lines 8-9__: Each http rule contains the following information: A host (e.g.: foo.bar.com, defaults to * in this example), a list of paths (e.g.: /testpath) each of which has an associated backend (test:80). Both the host and path must match the content of an incoming request before the loadbalancer directs traffic to the backend. @@ -81,11 +81,11 @@ __Global Parameters__: For the sake of simplicity the example Ingress has no glo ## Ingress controllers -In order for the Ingress resource to work, the cluster must have an Ingress controller running. This is unlike other types of controllers, which typically run as part of the `kube-controller-manager` binary, and which are typically started automatically as part of cluster creation. You need to choose the ingress controller implementation that is the best fit for your cluster, or implement one. Examples and instructions can be found [here](https://github.com/kubernetes/contrib/tree/master/ingress/controllers). +In order for the Ingress resource to work, the cluster must have an Ingress controller running. This is unlike other types of controllers, which typically run as part of the `kube-controller-manager` binary, and which are typically started automatically as part of cluster creation. You need to choose the ingress controller implementation that is the best fit for your cluster, or implement one. Examples and instructions can be found [here](https://github.com/kubernetes/ingress/tree/master/controllers). ## Before you begin -The following document describes a set of cross platform features exposed through the Ingress resource. Ideally, all Ingress controllers should fulfill this specification, but we're not there yet. The docs for the GCE and nginx controllers are [here](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/README.md) and [here](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/nginx/README.md) respectively. **Make sure you review controller specific docs so you understand the caveats of each one**. +The following document describes a set of cross platform features exposed through the Ingress resource. Ideally, all Ingress controllers should fulfill this specification, but we're not there yet. The docs for the GCE and nginx controllers are [here](https://github.com/kubernetes/ingress/blob/master/controllers/gce/README.md) and [here](https://github.com/kubernetes/ingress/blob/master/controllers/nginx/README.md) respectively. **Make sure you review controller specific docs so you understand the caveats of each one**. ## Types of Ingress @@ -214,13 +214,13 @@ spec: servicePort: 80 ``` -Note that there is a gap between TLS features supported by various Ingress controllers. Please refer to documentation on [nginx](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx#https), [GCE](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/gce#tls), or any other platform specific Ingress controller to understand how TLS works in your environment. +Note that there is a gap between TLS features supported by various Ingress controllers. Please refer to documentation on [nginx](https://github.com/kubernetes/ingress/blob/master/controllers/nginx/README.md#https), [GCE](https://github.com/kubernetes/ingress/blob/master/controllers/gce/README.md#tls), or any other platform specific Ingress controller to understand how TLS works in your environment. ### Loadbalancing An Ingress controller is bootstrapped with some loadbalancing policy settings that it applies to all Ingress, such as the loadbalancing algorithm, backend weight scheme etc. More advanced loadbalancing concepts (e.g.: persistent sessions, dynamic weights) are not yet exposed through the Ingress. You can still get these features through the [service loadbalancer](https://github.com/kubernetes/contrib/tree/master/service-loadbalancer). With time, we plan to distill loadbalancing patterns that are applicable cross platform into the Ingress resource. -It's also worth noting that even though health checks are not exposed directly through the Ingress, there exist parallel concepts in Kubernetes such as [readiness probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) which allow you to achieve the same end result. Please review the controller specific docs to see how they handle health checks ([nginx](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/nginx/README.md), [GCE](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/README.md#health-checks)). +It's also worth noting that even though health checks are not exposed directly through the Ingress, there exist parallel concepts in Kubernetes such as [readiness probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) which allow you to achieve the same end result. Please review the controller specific docs to see how they handle health checks ([nginx](https://github.com/kubernetes/ingress/blob/master/controllers/nginx/README.md), [GCE](https://github.com/kubernetes/ingress/blob/master/controllers/gce/README.md#health-checks)). ## Updating an Ingress @@ -282,7 +282,7 @@ Techniques for spreading traffic across failure domains differs between cloud pr * Combining L4 and L7 Ingress * More Ingress controllers -Please track the [L7 and Ingress proposal](https://github.com/kubernetes/kubernetes/pull/12827) for more details on the evolution of the resource, and the [Ingress sub-repository](https://github.com/kubernetes/contrib/tree/master/ingress) for more details on the evolution of various Ingress controllers. +Please track the [L7 and Ingress proposal](https://github.com/kubernetes/kubernetes/pull/12827) for more details on the evolution of the resource, and the [Ingress repository](https://github.com/kubernetes/ingress/tree/master) for more details on the evolution of various Ingress controllers. ## Alternatives diff --git a/docs/user-guide/jobs.md b/docs/user-guide/jobs.md index cc2f9d38c3..502de5a513 100644 --- a/docs/user-guide/jobs.md +++ b/docs/user-guide/jobs.md @@ -1,385 +1,7 @@ --- -assignees: -- erictune -- soltysh title: Jobs --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -## What is a Job? - -A _job_ creates one or more pods and ensures that a specified number of them successfully terminate. -As pods successfully complete, the _job_ tracks the successful completions. When a specified number -of successful completions is reached, the job itself is complete. Deleting a Job will cleanup the -pods it created. - -A simple case is to create one Job object in order to reliably run one Pod to completion. -The Job object will start a new Pod if the first pod fails or is deleted (for example -due to a node hardware failure or a node reboot). - -A Job can also be used to run multiple pods in parallel. - -### extensions/v1beta1.Job is deprecated - -Starting from version 1.5 `extensions/v1beta1.Job` is being deprecated, with a plan to be removed in -version 1.6 of Kubernetes (see this [issue](https://github.com/kubernetes/kubernetes/issues/32763)). -Please use `batch/v1.Job` instead. - -## Running an example Job - -Here is an example Job config. It computes π to 2000 places and prints it out. -It takes around 10s to complete. - -{% include code.html language="yaml" file="job.yaml" ghlink="/docs/user-guide/job.yaml" %} - -Run the example job by downloading the example file and then running this command: - -```shell -$ kubectl create -f ./job.yaml -job "pi" created -``` - -Check on the status of the job using this command: - -```shell -$ kubectl describe jobs/pi -Name: pi -Namespace: default -Image(s): perl -Selector: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495 -Parallelism: 1 -Completions: 1 -Start Time: Tue, 07 Jun 2016 10:56:16 +0200 -Labels: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495,job-name=pi -Pods Statuses: 0 Running / 1 Succeeded / 0 Failed -No volumes. -Events: - FirstSeen LastSeen Count From SubobjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: pi-dtn4q -``` - -To view completed pods of a job, use `kubectl get pods --show-all`. The `--show-all` will show completed pods too. - -To list all the pods that belong to job in a machine readable form, you can use a command like this: - -```shell -$ pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath={.items..metadata.name}) -echo $pods -pi-aiw0a -``` - -Here, the selector is the same as the selector for the job. The `--output=jsonpath` option specifies an expression -that just gets the name from each pod in the returned list. - -View the standard output of one of the pods: - -```shell -$ kubectl logs $pods -3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901 -``` - -## Writing a Job Spec - -As with all other Kubernetes config, a Job needs `apiVersion`, `kind`, and `metadata` fields. For -general information about working with config files, see [here](/docs/user-guide/simple-yaml), -[here](/docs/user-guide/configuring-containers), and [here](/docs/user-guide/working-with-resources). - -A Job also needs a [`.spec` section](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status). - -### Pod Template - -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 `apiVersion` or -`kind`. - -In addition to required fields for a Pod, a pod template in a job must specify appropriate -labels (see [pod selector](#pod-selector)) and an appropriate restart policy. - -Only a [`RestartPolicy`](/docs/user-guide/pod-states/#restartpolicy) equal to `Never` or `OnFailure` are allowed. - -### Pod Selector - -The `.spec.selector` field is optional. In almost all cases you should not specify it. -See section [specifying your own pod selector](#specifying-your-own-pod-selector). - - -### Parallel Jobs - -There are three main types of jobs: - -1. Non-parallel Jobs - - normally only one pod is started, unless the pod fails. - - job is complete as soon as Pod terminates successfully. -1. Parallel Jobs with a *fixed completion count*: - - specify a non-zero positive value for `.spec.completions` - - the job is complete when there is one successful pod for each value in the range 1 to `.spec.completions`. - - **not implemented yet:** each pod passed a different index in the range 1 to `.spec.completions`. -1. Parallel Jobs with a *work queue*: - - do not specify `.spec.completions` - - the pods must coordinate with themselves or an external service to determine what each should work on - - each pod is independently capable of determining whether or not all its peers are done, thus the entire Job is done. - - when _any_ pod terminates with success, no new pods are created. - - once at least one pod has terminated with success and all pods are terminated, then the job is completed with success. - - once any pod has exited with success, no other pod should still be doing any work or writing any output. They should all be - in the process of exiting. - -For a Non-parallel job, you can leave both `.spec.completions` and `.spec.parallelism` unset. When both are -unset, both are defaulted to 1. - -For a Fixed Completion Count job, you should set `.spec.completions` to the number of completions needed. -You can set `.spec.parallelism`, or leave it unset and it will default to 1. - -For a Work Queue Job, you must leave `.spec.completions` unset, and set `.spec.parallelism` to -a non-negative integer. - -For more information about how to make use of the different types of job, see the [job patterns](#job-patterns) section. - - -#### Controlling Parallelism - -The requested parallelism (`.spec.parallelism`) can be set to any non-negative value. -If it is unspecified, it defaults to 1. -If it is specified as 0, then the Job is effectively paused until it is increased. - -A job can be scaled up using the `kubectl scale` command. For example, the following -command sets `.spec.parallelism` of a job called `myjob` to 10: - -```shell -$ kubectl scale --replicas=$N jobs/myjob -job "myjob" scaled -``` - -You can also use the `scale` subresource of the Job resource. - -Actual parallelism (number of pods running at any instant) may be more or less than requested -parallelism, for a variety or reasons: - -- For Fixed Completion Count jobs, the actual number of pods running in parallel will not exceed the number of - remaining completions. Higher values of `.spec.parallelism` are effectively ignored. -- For work queue jobs, no new pods are started after any pod has succeeded -- remaining pods are allowed to complete, however. -- If the controller has not had time to react. -- If the controller failed to create pods for any reason (lack of ResourceQuota, lack of permission, etc.), - then there may be fewer pods than requested. -- The controller may throttle new pod creation due to excessive previous pod failures in the same Job. -- When a pod is gracefully shutdown, it takes time to stop. - -## Handling Pod and Container Failures - -A Container in a Pod may fail for a number of reasons, such as because the process in it exited with -a non-zero exit code, or the Container was killed for exceeding a memory limit, etc. If this -happens, and the `.spec.template.spec.restartPolicy = "OnFailure"`, then the Pod stays -on the node, but the Container is re-run. Therefore, your program needs to handle the case when it is -restarted locally, or else specify `.spec.template.spec.restartPolicy = "Never"`. -See [pods-states](/docs/user-guide/pod-states) for more information on `restartPolicy`. - -An entire Pod can also fail, for a number of reasons, such as when the pod is kicked off the node -(node is upgraded, rebooted, deleted, etc.), or if a container of the Pod fails and the -`.spec.template.spec.restartPolicy = "Never"`. When a Pod fails, then the Job controller -starts a new Pod. Therefore, your program needs to handle the case when it is restarted in a new -pod. In particular, it needs to handle temporary files, locks, incomplete output and the like -caused by previous runs. - -Note that even if you specify `.spec.parallelism = 1` and `.spec.completions = 1` and -`.spec.template.spec.restartPolicy = "Never"`, the same program may -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 -designed to support closely-communicating parallel processes, as commonly found in scientific -computing. It does support parallel processing of a set of independent but related *work items*. -These might be emails to be sent, frames to be rendered, files to be transcoded, ranges of keys in a -NoSQL database to scan, and so on. - -In a complex system, there may be multiple different sets of work items. Here we are just -considering one set of work items that the user wants to manage together — a *batch job*. - -There are several different patterns for parallel computation, each with strengths and weaknesses. -The tradeoffs are: - -- One Job object for each work item, vs. a single Job object for all work items. The latter is - better for large numbers of work items. The former creates some overhead for the user and for the - system to manage large numbers of Job objects. Also, with the latter, the resource usage of the job - (number of concurrently running pods) can be easily adjusted using the `kubectl scale` command. -- Number of pods created equals number of work items, vs. each pod can process multiple work items. - The former typically requires less modification to existing code and containers. The latter - is better for large numbers of work items, for similar reasons to the previous bullet. -- Several approaches use a work queue. This requires running a queue service, - and modifications to the existing program or container to make it use the work queue. - Other approaches are easier to adapt to an existing containerised application. - - -The tradeoffs are summarized here, with columns 2 to 4 corresponding to the above tradeoffs. -The pattern names are also links to examples and more detailed description. - -| Pattern | Single Job object | Fewer pods than work items? | Use app unmodified? | Works in Kube 1.1? | -| -------------------------------------------------------------------- |:-----------------:|:---------------------------:|:-------------------:|:-------------------:| -| [Job Template Expansion](/docs/user-guide/jobs/expansions) | | | ✓ | ✓ | -| [Queue with Pod Per Work Item](/docs/user-guide/jobs/work-queue-1/) | ✓ | | sometimes | ✓ | -| [Queue with Variable Pod Count](/docs/user-guide/jobs/work-queue-2/) | ✓ | ✓ | | ✓ | -| Single Job with Static Work Assignment | ✓ | | ✓ | | - -When you specify completions with `.spec.completions`, each Pod created by the Job controller -has an identical [`spec`](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status). This means that -all pods will have the same command line and the same -image, the same volumes, and (almost) the same environment variables. These patterns -are different ways to arrange for pods to work on different things. - -This table shows the required settings for `.spec.parallelism` and `.spec.completions` for each of the patterns. -Here, `W` is the number of work items. - -| Pattern | `.spec.completions` | `.spec.parallelism` | -| -------------------------------------------------------------------- |:-------------------:|:--------------------:| -| [Job Template Expansion](/docs/user-guide/jobs/expansions/) | 1 | should be 1 | -| [Queue with Pod Per Work Item](/docs/user-guide/jobs/work-queue-1/) | W | any | -| [Queue with Variable Pod Count](/docs/user-guide/jobs/work-queue-2/) | 1 | any | -| Single Job with Static Work Assignment | W | any | - - -## Advanced Usage - -### Specifying your own pod selector - -Normally, when you create a job object, you do not specify `spec.selector`. -The system defaulting logic adds this field when the job is created. -It picks a selector value that will not overlap with any other jobs. - -However, in some cases, you might need to override this automatically set selector. -To do this, you can specify the `spec.selector` of the job. - -Be very careful when doing this. If you specify a label selector which is not -unique to the pods of that job, and which matches unrelated pods, then pods of the unrelated -job may be deleted, or this job may count other pods as completing it, or one or both -of the jobs may refuse to create pods or run to completion. If a non-unique selector is -chosen, then other controllers (e.g. ReplicationController) and their pods may behave -in unpredicatable ways too. Kubernetes will not stop you from making a mistake when -specifying `spec.selector`. - -Here is an example of a case when you might want to use this feature. - -Say job `old` is already running. You want existing pods -to keep running, but you want the rest of the pods it creates -to use a different pod template and for the job to have a new name. -You cannot update the job because these fields are not updatable. -Therefore, you delete job `old` but leave its pods -running, using `kubectl delete jobs/old-one --cascade=false`. -Before deleting it, you make a note of what selector it uses: - -``` -kind: Job -metadata: - name: old - ... -spec: - selector: - matchLabels: - job-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002 - ... -``` - -Then you create a new job with name `new` and you explicitly specify the same selector. -Since the existing pods have label `job-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`, -they are controlled by job `new` as well. - -You need to specify `manualSelector: true` in the new job since you are not using -the selector that the system normally generates for you automatically. - -``` -kind: Job -metadata: - name: new - ... -spec: - manualSelector: true - selector: - matchLabels: - job-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002 - ... -``` - -The new Job itself will have a different uid from `a8f3d00d-c6d2-11e5-9f87-42010af00002`. Setting -`manualSelector: true` tells the system to that you know what you are doing and to allow this -mismatch. - -## Alternatives - -### Bare Pods - -When the node that a pod is running on reboots or fails, the pod is terminated -and will not be restarted. However, a Job will create new pods to replace terminated ones. -For this reason, we recommend that you use a job rather than a bare pod, even if your application -requires only a single pod. - -### Replication Controller - -Jobs are complementary to [Replication Controllers](/docs/user-guide/replication-controller). -A Replication Controller manages pods which are not expected to terminate (e.g. web servers), and a Job -manages pods that are expected to terminate (e.g. batch jobs). - -As discussed in [life of a pod](/docs/user-guide/pod-states), `Job` is *only* appropriate for pods with -`RestartPolicy` equal to `OnFailure` or `Never`. (Note: If `RestartPolicy` is not set, the default -value is `Always`.) - -### Single Job starts Controller Pod - -Another pattern is for a single Job to create a pod which then creates other pods, acting as a sort -of custom controller for those pods. This allows the most flexibility, but may be somewhat -complicated to get started with and offers less integration with Kubernetes. - -One example of this pattern would be a Job which starts a Pod which runs a script that in turn -starts a Spark master controller (see [spark example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/spark/README.md)), runs a spark -driver, and then cleans up. - -An advantage of this approach is that the overall process gets the completion guarantee of a Job -object, but complete control over what pods are created and how work is assigned to them. - -## Cron Jobs - -Support for creating Jobs at specified times/dates (i.e. cron) is available in Kubernetes [1.4](https://github.com/kubernetes/kubernetes/pull/11980). More information is available in the [cron job documents](http://kubernetes.io/docs/user-guide/cron-jobs/) +[Run to Completion Finite Workloads](/docs/concepts/jobs/run-to-completion-finite-workloads/) diff --git a/docs/user-guide/jobs/expansions/index.md b/docs/user-guide/jobs/expansions/index.md index 767ac65215..8d5cb87bd4 100644 --- a/docs/user-guide/jobs/expansions/index.md +++ b/docs/user-guide/jobs/expansions/index.md @@ -71,7 +71,7 @@ job "process-item-cherry" created Now, check on the jobs: ```shell -$ kubectl get jobs -l app=jobexample +$ kubectl get jobs -l jobgroup=jobexample JOB CONTAINER(S) IMAGE(S) SELECTOR SUCCESSFUL process-item-apple c busybox app in (jobexample),item in (apple) 1 process-item-banana c busybox app in (jobexample),item in (banana) 1 @@ -85,7 +85,7 @@ do not care to see.) We can check on the pods as well using the same label selector: ```shell -$ kubectl get pods -l app=jobexample +$ kubectl get pods -l jobgroup=jobexample --show-all NAME READY STATUS RESTARTS AGE process-item-apple-kixwv 0/1 Completed 0 4m process-item-banana-wrsf7 0/1 Completed 0 4m @@ -96,7 +96,7 @@ There is not a single command to check on the output of all jobs at once, but looping over all the pods is pretty easy: ```shell -$ for p in $(kubectl get pods -l app=jobexample -o name) +$ for p in $(kubectl get pods -l jobgroup=jobexample -o name) do kubectl logs $p done @@ -111,7 +111,7 @@ In the first example, each instance of the template had one parameter, and that used as a label. However label keys are limited in [what characters they can contain](/docs/user-guide/labels/#syntax-and-character-set). -This slightly more complex example uses a the jinja2 template language to generate our objects. +This slightly more complex example uses the jinja2 template language to generate our objects. We will use a one-line python script to convert the template to a file. First, copy and paste the following template of a Job object, into a file called `job.yaml.jinja2`: @@ -179,6 +179,7 @@ cat job.yaml.jinja2 | render_template | kubectl create -f - ## Alternatives If you have a large number of job objects, you may find that: + - even using labels, managing so many Job objects is cumbersome. - You exceed resource quota when creating all the Jobs at once, and do not want to wait to create them incrementally. diff --git a/docs/user-guide/jobs/work-queue-1/index.md b/docs/user-guide/jobs/work-queue-1/index.md index b2b68cff23..f926f4211f 100644 --- a/docs/user-guide/jobs/work-queue-1/index.md +++ b/docs/user-guide/jobs/work-queue-1/index.md @@ -101,7 +101,7 @@ Next we will verify we can create a queue, and publish and consume messages. # In the next line, rabbitmq-service is the hostname where the rabbitmq-service # can be reached. 5672 is the standard port for rabbitmq. -root@temp-loe07:/# BROKER_URL=amqp://guest:guest@rabbitmq-service:5672 +root@temp-loe07:/# export BROKER_URL=amqp://guest:guest@rabbitmq-service:5672 # If you could not resolve "rabbitmq-service" in the previous step, # then use this command instead: # root@temp-loe07:/# BROKER_URL=amqp://guest:guest@$RABBITMQ_SERVICE_SERVICE_HOST:5672 @@ -227,7 +227,7 @@ Name: job-wq-1 Namespace: default Image(s): gcr.io/causal-jigsaw-637/job-wq-1 Selector: app in (job-wq-1) -Parallelism: 4 +Parallelism: 2 Completions: 8 Labels: app=job-wq-1 Pods Statuses: 0 Running / 8 Succeeded / 0 Failed diff --git a/docs/user-guide/jobs/work-queue-2/index.md b/docs/user-guide/jobs/work-queue-2/index.md index 5e2e8a03ec..4fd806d392 100644 --- a/docs/user-guide/jobs/work-queue-2/index.md +++ b/docs/user-guide/jobs/work-queue-2/index.md @@ -47,7 +47,7 @@ If you're not working from the source tree, you could also download [`redis-pod. ## Filling the Queue with tasks -Now lets fill the queue with some "tasks". In our example, our tasks are just strings to be +Now let's fill the queue with some "tasks". In our example, our tasks are just strings to be printed. Start a temporary interactive pod for running the Redis CLI diff --git a/docs/user-guide/jsonpath.md b/docs/user-guide/jsonpath.md index 74ce7bbc77..54c2780da8 100644 --- a/docs/user-guide/jsonpath.md +++ b/docs/user-guide/jsonpath.md @@ -6,8 +6,8 @@ JSONPath template is composed of JSONPath expressions enclosed by {}. And we add three functions in addition to the original JSONPath syntax: 1. The `$` operator is optional since the expression always start from the root object by default. -2. We can use `""` to quote text inside JSONPath expression. -3. We can use `range` operator to iterate list. +2. We can use `""` to quote text inside JSONPath expressions. +3. We can use `range` operator to iterate lists. The result object is printed as its String() function. diff --git a/docs/user-guide/kubeconfig-file.md b/docs/user-guide/kubeconfig-file.md index b4d7425127..93877f8a84 100644 --- a/docs/user-guide/kubeconfig-file.md +++ b/docs/user-guide/kubeconfig-file.md @@ -305,7 +305,7 @@ $ kubectl config use-context federal-context ### Final notes for tying it all together -So, tying this all together, a quick start to creating your own kubeconfig file: +So, tying this all together, a quick start to create your own kubeconfig file: - Take a good look and understand how your api-server is being launched: You need to know YOUR security requirements and policies before you can design a kubeconfig file for convenient authentication. diff --git a/docs/user-guide/kubectl-cheatsheet.md b/docs/user-guide/kubectl-cheatsheet.md index c147304a7d..56f6d71de4 100644 --- a/docs/user-guide/kubectl-cheatsheet.md +++ b/docs/user-guide/kubectl-cheatsheet.md @@ -197,11 +197,12 @@ $ kubectl -n my-ns delete po,svc --all # Delete all pods and servic ```console $ kubectl logs my-pod # dump pod logs (stdout) +$ kubectl logs my-pod -c my-container # dump pod container logs (stdout, multi-container case) $ kubectl logs -f my-pod # stream pod logs (stdout) +$ kubectl logs -f my-pod -c my-container # stream pod container logs (stdout, multi-container case) $ kubectl run -i --tty busybox --image=busybox -- sh # Run pod as interactive shell $ kubectl attach my-pod -i # Attach to Running Container $ kubectl port-forward my-pod 5000:6000 # Forward port 6000 of Pod to your to 5000 on your local machine -$ kubectl port-forward my-svc 6000 # Forward port to service $ kubectl exec my-pod -- ls / # Run command in existing pod (1 container case) $ kubectl exec my-pod -c my-container -- ls / # Run command in existing pod (multi-container case) $ kubectl top pod POD_NAME --containers # Show metrics for a given pod and its containers @@ -242,7 +243,7 @@ Resource type | Abbreviated alias `namespaces` |`ns` `networkpolicies` | `nodes` |`no` -`petset` | +`statefulsets` | `persistentvolumeclaims` |`pvc` `persistentvolumes` |`pv` `pods` |`po` diff --git a/docs/user-guide/kubectl-conventions.md b/docs/user-guide/kubectl-conventions.md index fb0c467321..d3b3673dbf 100644 --- a/docs/user-guide/kubectl-conventions.md +++ b/docs/user-guide/kubectl-conventions.md @@ -23,7 +23,7 @@ If you need stable output in a script, you should: 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.) +* 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/concepts/configuration/overview/#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. @@ -71,4 +71,4 @@ flag, which will provide the object to be submitted to the cluster. ### `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. +* 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/concepts/cluster-administration/manage-deployment/#kubectl-apply) for the reason behind it. diff --git a/docs/user-guide/kubectl-overview.md b/docs/user-guide/kubectl-overview.md index 987e154703..8b16e6731e 100644 --- a/docs/user-guide/kubectl-overview.md +++ b/docs/user-guide/kubectl-overview.md @@ -7,8 +7,6 @@ title: kubectl Overview `kubectl` is a command line interface for running commands against Kubernetes clusters. This overview covers `kubectl` syntax, describes the command operations, and provides common examples. For details about each command, including all the supported flags and subcommands, see the [kubectl](/docs/user-guide/kubectl) reference documentation. For installation instructions see [prerequisites](/docs/user-guide/prereqs). -TODO: Auto-generate this file to ensure it's always in sync with any `kubectl` changes, see [#14177](http://pr.k8s.io/14177). - ## Syntax Use the following syntax to run `kubectl` commands from your terminal window: @@ -35,7 +33,7 @@ where `command`, `TYPE`, `NAME`, and `flags` are: * To specify multiple resource types individually: `TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>`
      Example: `$ kubectl get pod/example-pod1 replicationcontroller/example-rc1` * To specify resources with one or more files: `-f file1 -f file2 -f file<#>` - [Use YAML rather than JSON](/docs/user-guide/config-best-practices/#general-config-tips) since YAML tends to be more user-friendly, especially for configuration files.
      + [Use YAML rather than JSON](/docs/concepts/configuration/overview/#general-config-tips) since YAML tends to be more user-friendly, especially for configuration files.
      Example: `$ kubectl get pod -f ./pod.yaml` * `flags`: Specifies optional flags. For example, you can use the `-s` or `--server` flags to specify the address and port of the Kubernetes API server.
      **Important**: Flags that you specify from the command line override default values and any corresponding environment variables. diff --git a/docs/user-guide/kubectl/kubectl_apply.md b/docs/user-guide/kubectl/kubectl_apply.md index c729263d6c..81c1a12137 100644 --- a/docs/user-guide/kubectl/kubectl_apply.md +++ b/docs/user-guide/kubectl/kubectl_apply.md @@ -32,7 +32,7 @@ kubectl apply -f FILENAME # Apply the configuration in manifest.yaml that matches label app=nginx and delete all the other resources that are not in the file and match label app=nginx. kubectl apply --prune -f manifest.yaml -l app=nginx - # Apply the configuration in manifest.yaml and delete all the other configmaps that are not in the file. + # Apply the configuration in manifest.yaml and delete all the other configmaps with the same label key that are not in the file. kubectl apply --prune -f manifest.yaml --all --prune-whitelist=core/v1/ConfigMap ``` diff --git a/docs/user-guide/kubectl/kubectl_completion.md b/docs/user-guide/kubectl/kubectl_completion.md index 125b7791cd..f870bbd482 100644 --- a/docs/user-guide/kubectl/kubectl_completion.md +++ b/docs/user-guide/kubectl/kubectl_completion.md @@ -11,17 +11,19 @@ Output shell completion code for the given shell (bash or zsh). This command prints shell code which must be evaluation to provide interactive completion of kubectl commands. - $ source <(kubectl completion bash) + `$ source <(kubectl completion bash)` will load the kubectl completion code for bash. Note that this depends on the bash-completion framework. It must be sourced before sourcing the kubectl completion, e.g. on the Mac: +``` $ brew install bash-completion $ source $(brew --prefix)/etc/bash_completion $ source <(kubectl completion bash) +``` If you use zsh [1], the following will load kubectl zsh completion: - $ source <(kubectl completion zsh) + `$ source <(kubectl completion zsh)` [1] zsh completions are only supported in versions of zsh >= 5.2 diff --git a/docs/user-guide/kubectl/kubectl_describe.md b/docs/user-guide/kubectl/kubectl_describe.md index a5fd703d73..6db3c2d9b7 100644 --- a/docs/user-guide/kubectl/kubectl_describe.md +++ b/docs/user-guide/kubectl/kubectl_describe.md @@ -10,9 +10,9 @@ Show details of a specific resource or group of resources Show details of a specific resource or group of resources. This command joins many API calls together to form a detailed description of a given resource or group of resources. - +``` $ kubectl describe TYPE NAME_PREFIX - +``` will first check for an exact match on TYPE and NAME PREFIX. If no such resource exists, it will output details for every resource that has a name prefixed with NAME PREFIX. Valid resource types include: diff --git a/docs/user-guide/kubectl/kubectl_proxy.md b/docs/user-guide/kubectl/kubectl_proxy.md index 9616d6add6..f2e4b9f58a 100644 --- a/docs/user-guide/kubectl/kubectl_proxy.md +++ b/docs/user-guide/kubectl/kubectl_proxy.md @@ -11,19 +11,26 @@ Run a proxy to the Kubernetes API server To proxy all of the Kubernetes api and nothing else, use: +``` $ kubectl proxy --api-prefix=/ +``` To proxy only part of the Kubernetes api and also some static files: +``` $ kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/ +``` The above lets you 'curl localhost:8001/api/v1/pods'. To proxy the entire Kubernetes api at a different root, use: +``` $ kubectl proxy --api-prefix=/custom/ +``` + +The above lets you `curl localhost:8001/custom/api/v1/pods` -The above lets you 'curl localhost:8001/custom/api/v1/pods' ``` kubectl proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix] diff --git a/docs/user-guide/kubectl/kubectl_rolling-update.md b/docs/user-guide/kubectl/kubectl_rolling-update.md index 382e630c78..f20483e125 100644 --- a/docs/user-guide/kubectl/kubectl_rolling-update.md +++ b/docs/user-guide/kubectl/kubectl_rolling-update.md @@ -13,7 +13,7 @@ Perform a rolling update of the given ReplicationController. Replaces the specified replication controller with a new replication controller by updating one pod at a time to use the new PodTemplate. The new-controller.json must specify the same namespace as the existing replication controller and overwrite at least one (common) label in its replicaSelector. -! http://kubernetes.io/images/docs/kubectl_rollingupdate.svg +![kubectl_rollingupdate](http://kubernetes.io/images/docs/kubectl_rollingupdate.svg) ``` kubectl rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --image=NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC) diff --git a/docs/user-guide/logging/elasticsearch.md b/docs/user-guide/logging/elasticsearch.md index c61cfd7cd1..e55de7f30f 100644 --- a/docs/user-guide/logging/elasticsearch.md +++ b/docs/user-guide/logging/elasticsearch.md @@ -5,99 +5,6 @@ assignees: title: Logging with Elasticsearch and Kibana --- -On the Google Compute Engine (GCE) platform, the default logging support targets -[Stackdriver Logging](https://cloud.google.com/logging/), which is described in detail -in the [Logging With Stackdriver Logging](/docs/user-guide/logging/stackdriver). +{% include user-guide-content-moved.md %} -This article describes how to set up a cluster to ingest logs into -[Elasticsearch](https://www.elastic.co/products/elasticsearch), and view -them using [Kibana](https://www.elastic.co/products/kibana), as an alternative to -Stackdriver Logging when running on GCE. Note that Elasticsearch and Kibana do not work with Kubernetes clusters hosted on Google Container Engine. - -To use Elasticsearch and Kibana for cluster logging, you should set the -following environment variable as shown below when creating your cluster with -kube-up.sh: - -```shell -KUBE_LOGGING_DESTINATION=elasticsearch -``` - -You should also ensure that `KUBE_ENABLE_NODE_LOGGING=true` (which is the default for the GCE platform). - -Now, when you create a cluster, a message will indicate that the Fluentd log -collection daemons that run on each node will target Elasticsearch: - -```shell -$ cluster/kube-up.sh -... -Project: kubernetes-satnam -Zone: us-central1-b -... calling kube-up -Project: kubernetes-satnam -Zone: us-central1-b -+++ Staging server tars to Google Storage: gs://kubernetes-staging-e6d0e81793/devel -+++ kubernetes-server-linux-amd64.tar.gz uploaded (sha1 = 6987c098277871b6d69623141276924ab687f89d) -+++ kubernetes-salt.tar.gz uploaded (sha1 = bdfc83ed6b60fa9e3bff9004b542cfc643464cd0) -Looking for already existing resources -Starting master and configuring firewalls -Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/zones/us-central1-b/disks/kubernetes-master-pd]. -NAME ZONE SIZE_GB TYPE STATUS -kubernetes-master-pd us-central1-b 20 pd-ssd READY -Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/regions/us-central1/addresses/kubernetes-master-ip]. -+++ Logging using Fluentd to elasticsearch -``` - -The per-node Fluentd pods, the Elasticsearch pods, and the Kibana pods should -all be running in the kube-system namespace soon after the cluster comes to -life. - -```shell -$ kubectl get pods --namespace=kube-system -NAME READY REASON RESTARTS AGE -elasticsearch-logging-v1-78nog 1/1 Running 0 2h -elasticsearch-logging-v1-nj2nb 1/1 Running 0 2h -fluentd-elasticsearch-kubernetes-node-5oq0 1/1 Running 0 2h -fluentd-elasticsearch-kubernetes-node-6896 1/1 Running 0 2h -fluentd-elasticsearch-kubernetes-node-l1ds 1/1 Running 0 2h -fluentd-elasticsearch-kubernetes-node-lz9j 1/1 Running 0 2h -kibana-logging-v1-bhpo8 1/1 Running 0 2h -kube-dns-v3-7r1l9 3/3 Running 0 2h -monitoring-heapster-v4-yl332 1/1 Running 1 2h -monitoring-influx-grafana-v1-o79xf 2/2 Running 0 2h -``` - -The `fluentd-elasticsearch` pods gather logs from each node and send them to -the `elasticsearch-logging` pods, which are part of a -[service](/docs/user-guide/services/) named `elasticsearch-logging`. These -Elasticsearch pods store the logs and expose them via a REST API. -The `kibana-logging` pod provides a web UI for reading the logs stored in -Elasticsearch, and is part of a service named `kibana-logging`. - -The Elasticsearch and Kibana services are both in the `kube-system` namespace -and are not directly exposed via a publicly reachable IP address. To reach them, -follow the instructions for [Accessing services running in a cluster](/docs/user-guide/accessing-the-cluster/#accessing-services-running-on-the-cluster). - -If you try accessing the `elasticsearch-logging` service in your browser, you'll -see a status page that looks something like this: - -![Elasticsearch Status](/images/docs/es-browser.png) - -You can now type Elasticsearch queries directly into the browser, if you'd -like. See [Elasticsearch's documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html) -for more details on how to do so. - -Alternatively, you can view your cluster's logs using Kibana (again using the -[instructions for accessing a service running in the cluster](/docs/user-guide/accessing-the-cluster/#accessing-services-running-on-the-cluster)). -The first time you visit the Kibana URL you will be presented with a page that -asks you to configure your view of the ingested logs. Select the option for -timeseries values and select `@timestamp`. On the following page select the -`Discover` tab and then you should be able to see the ingested logs. -You can set the refresh interval to 5 seconds to have the logs -regularly refreshed. - -Here is a typical view of ingested logs from the Kibana viewer: - -![Kibana logs](/images/docs/kibana-logs.png) - -Kibana opens up all sorts of powerful options for exploring your logs! For some -ideas on how to dig into it, check out [Kibana's documentation](https://www.elastic.co/guide/en/kibana/current/discover.html). +[Logging Using ElasticSearch and Kibana](/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana/) diff --git a/docs/user-guide/logging/overview.md b/docs/user-guide/logging/overview.md index a9f00471cc..e5d2e24ae4 100644 --- a/docs/user-guide/logging/overview.md +++ b/docs/user-guide/logging/overview.md @@ -5,219 +5,6 @@ assignees: title: Logging Overview --- -Application and systems logs can help you understand what is happening inside your cluster. The logs are particularly useful for debugging problems and monitoring cluster activity. Most modern applications have some kind of logging mechanism; as such, most container engines are likewise designed to support some kind of logging. The easiest and most embraced logging method for containerized applications is to write to the standard output and standard error streams. +{% include user-guide-content-moved.md %} -However, the native functionality provided by a container engine or runtime is usually not enough for a complete logging solution. For example, if a container crashes, a pod is evicted, or a node dies, you'll usually still want to access your application's logs. As such, logs should have a separate storage and lifecycle independent of nodes, pods, or containers. This concept is called _cluster-level-logging_. Cluster-level logging requires a separate backend to store, analyze, and query logs. Kubernetes provides no native storage solution for log data, but you can integrate many existing logging solutions into your Kubernetes cluster. - -This document includes: - -* A basic demonstration of logging in Kubernetes using the standard output stream -* A detailed description of the node logging architecture in Kubernetes -* Guidance for implementing cluster-level logging in Kubernetes - -The guidance for cluster-level logging assumes that a logging backend is present inside or outside of your cluster. If you're not interested in having cluster-level logging, you might still find the description of how logs are stored and handled on the node to be useful. - -## Basic logging in Kubernetes - -In this section, you can see an example of basic logging in Kubernetes that -outputs data to the standard output stream. This demonstration uses -a [pod specification](/docs/user-guide/logging/examples/counter-pod.yaml) with -a container that writes some text to standard output once per second. - -{% include code.html language="yaml" file="examples/counter-pod.yaml" ghlink="/docs/user-guide/logging/examples/counter-pod.yaml" %} - -To run this pod, use the following command: - -```shell -$ kubectl create -f http://k8s.io/docs/user-guide/logging/examples/counter-pod.yaml -pod "counter" created -``` - -To fetch the logs, use the `kubectl logs` command, as follows - -```shell -$ kubectl logs counter -0: Mon Jan 1 00:00:00 UTC 2001 -1: Mon Jan 1 00:00:01 UTC 2001 -2: Mon Jan 1 00:00:02 UTC 2001 -... -``` - -You can use `kubectl logs` to retrieve logs from a previous instantiation of a container with `--previous` flag, in case the container has crashed. If your pod has multiple containers, you should specify which container's logs you want to access by appending a container name to the command. See the [`kubectl logs` documentation](/docs/user-guide/kubectl/kubectl_logs/) for more details. - -## Logging at the node level - -![Node level logging](/images/docs/user-guide/logging/logging-node-level.png) - -Everything a containerized application writes to `stdout` and `stderr` is handled and redirected somewhere by a container engine. For example, the Docker container engine redirects those two streams to [a logging driver](https://docs.docker.com/engine/admin/logging/overview), which is configured in Kubernetes to write to a file in json format. - -**Note:** The Docker json logging driver treats each line as a separate message. When using the Docker logging driver, there is no direct support for multi-line messages. You need to handle multi-line messages at the logging agent level or higher. - -By default, if a container restarts, the kubelet keeps one terminated container with its logs. If a pod is evicted from the node, all corresponding containers are also evicted, along with their logs. - -An important consideration in node-level logging is implementing log rotation, so that logs don't consume all available storage on the node. Kubernetes uses the [`logrotate`](http://www.linuxcommand.org/man_pages/logrotate8.html) tool to implement log rotation. - -Kubernetes performs log rotation daily, or if the log file grows beyond 10MB in size. Each rotation belongs to a single container; if the container repeatedly fails or the pod is evicted, all previous rotations for the container are lost. By default, Kubernetes keeps up to five logging rotations per container. - -The Kubernetes logging configuration differs depending on the node type. For example, you can find detailed information for GCI in the corresponding [configure helper](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/cluster/gce/gci/configure-helper.sh#L96). - -When you run [`kubectl logs`](/docs/user-guide/kubectl/kubectl_logs), as in the basic logging example, the kubelet on the node handles the request and reads directly from the log file, returning the contents in the response. Note that `kubectl logs` **only returns the last rotation**; you must manually extract prior rotations, if desired and cluster-level logging is not enabled. - -### System component logs - -There are two types of system components: those that run in a container and those -that do not run in a container. For example: - -* The Kubernets scheduler and kube-proxy run in a container. -* The kubelet and container runtime, for example Docker, do not run in containers. - -On machines with systemd, the kubelet and container runtime write to journald. If -systemd is not present, they write to `.log` files in the `/var/log` directory. -System components inside containers always write to the `/var/log` directory, -bypassing the default logging mechanism. They use the [glog](https://godoc.org/github.com/golang/glog) -logging library. You can find the conventions for logging severity for those -components in the [development docs on logging](https://github.com/kubernetes/community/blob/master/contributors/devel/logging.md). - -Similarly to the container logs, system component logs in the `/var/log` -directory are rotated daily and based on the log size. However, -system component logs have a higher size retention: by default, -they can store up to 100MB. - -## Cluster-level logging architectures - -While Kubernetes does not provide a native solution for cluster-level logging, there are several common approaches you can consider. Here are some options: - -* Use a node-level logging agent that runs on every node. -* Include a dedicated sidecar container for logging in an application pod. -* Push logs directly to a backend from within an application. - -### Using a node logging agent - -![Using a node level logging agent](/images/docs/user-guide/logging/logging-with-node-agent.png) - -You can implement cluster-level logging by including a _node-level logging agent_ on each node. The logging agent is a dedicated tool that exposes logs or pushes logs to a backend. Commonly, the logging agent is a container that has access to a directory with log files from all of the application containers on that node. - -Because the logging agent must run on every node, it's common to implement it as either a DaemonSet replica, a manifest pod, or a dedicated native process on the node. However the latter two approaches are deprecated and highly discouraged. - -Using a node-level logging agent is the most common and encouraged approach for a Kubernetes cluster, because it creates only one agent per node, and it doesn't require any changes to the applications running on the node. However, node-level logging _only works for applications' standard output and standard error_. - -Kubernetes doesn't specify a logging agent, but two optional logging agents are packaged with the Kubernetes release: [Stackdriver Logging](/docs/user-guide/logging/stackdriver) for use with Google Cloud Platform, and [Elasticsearch](/docs/user-guide/logging/elasticsearch). You can find more information and instructions in the dedicated documents. Both use [fluentd](http://www.fluentd.org/) with custom configuration as an agent on the node. - -### Using a sidecar container with the logging agent - -You can use a sidecar container in one of the following ways: - -* The sidecar container streams application logs to its own `stdout`. -* The sidecar container runs a logging agent, which is configured to pick up logs from an application container. - -#### Streaming sidecar container - -![Sidecar container with a streaming container](/images/docs/user-guide/logging/logging-with-streaming-sidecar.png) - -By having your sidecar containers stream to their own `stdout` and `stderr` -streams, you can take advantage of the kubelet and the logging agent that -already run on each node. The sidecar containers read logs from a file, a socket, -or the journald. Each individual sidecar container prints log to its own `stdout` -or `stderr` stream. - -This approach allows you to separate several log streams from different -parts of your application, some of which can lack support -for writing to `stdout` or `stderr`. The logic behind redirecting logs -is minimal, so it's hardly a significant overhead. Additionally, because -`stdout` and `stderr` are handled by the kubelet, you can use built-in tools -like `kubectl logs`. - -Consider the following example. A pod runs a single container, and the container -writes to two different log files, using two different formats. Here's a -configuration file for the Pod: - -{% include code.html language="yaml" file="examples/two-files-counter-pod.yaml" ghlink="/docs/user-guide/logging/examples/two-files-counter-pod.yaml" %} - -It would be a mess to have log entries of different formats in the same log -stream, even if you managed to redirect both components to the `stdout` stream of -the container. Instead, you could introduce two sidecar containers. Each sidecar -container could tail a particular log file from a shared volume and then redirect -the logs to its own `stdout` stream. - -Here's a configuration file for a pod that has two sidecar containers: - -{% include code.html language="yaml" file="examples/two-files-counter-pod-streaming-sidecar.yaml" ghlink="/docs/user-guide/logging/examples/two-files-counter-pod-streaming-sidecar.yaml" %} - -Now when you run this pod, you can access each log stream separately by -running the following commands: - -```shell -$ kubectl logs counter count-log-1 -0: Mon Jan 1 00:00:00 UTC 2001 -1: Mon Jan 1 00:00:01 UTC 2001 -2: Mon Jan 1 00:00:02 UTC 2001 -... -``` - -```shell -$ kubectl logs counter count-log-2 -Mon Jan 1 00:00:00 UTC 2001 INFO 0 -Mon Jan 1 00:00:01 UTC 2001 INFO 1 -Mon Jan 1 00:00:02 UTC 2001 INFO 2 -... -``` - -The node-level agent installed in your cluster picks up those log streams -automatically without any further configuration. If you like, you can configure -the agent to parse log lines depending on the source container. - -Note, that despite low CPU and memory usage (order of couple of millicores -for cpu and order of several megabytes for memory), writing logs to a file and -then streaming them to `stdout` can double disk usage. If you have -an application that writes to a single file, it's generally better to set -`/dev/stdout` as destination rather than implementing the streaming sidecar -container approach. - -Sidecar containers can also be used to rotate log files that cannot be -rotated by the application itself. [An example](https://github.com/samsung-cnct/logrotate) -of this approach is a small container running logrotate periodically. -However, it's recommended to use `stdout` and `stderr` directly and leave rotation -and retention policies to the kubelet. - -#### Sidecar container with a logging agent - -![Sidecar container with a logging agent](/images/docs/user-guide/logging/logging-with-sidecar-agent.png) - -If the node-level logging agent is not flexible enough for your situation, you -can create a sidecar container with a separate logging agent that you have -configured specifically to run with your application. - -**Note**: Using a logging agent in a sidecar container can lead -to significant resource consumption. Moreover, you won't be able to access -those logs using `kubectl logs` command, because they are not controlled -by the kubelet. - -As an example, you could use [Stackdriver](/docs/user-guide/logging/stackdriver/), -which uses fluentd as a logging agent. Here are two configuration files that -you can use to implement this approach. The first file contains -a [ConfigMap](/docs/user-guide/configmap/) to configure fluentd. - -{% include code.html language="yaml" file="examples/fluentd-sidecar-config.yaml" ghlink="/docs/user-guide/logging/examples/fluentd-sidecar-config.yaml" %} - -**Note**: The configuration of fluentd is beyond the scope of this article. For -information about configuring fluentd, see the -[official fluentd documentation](http://docs.fluentd.org/). - -The second file describes a pod that has a sidecar container running fluentd. -The pod mounts a volume where fluentd can pick up its configuration data. - -{% include code.html language="yaml" file="examples/two-files-counter-pod-agent-sidecar.yaml" ghlink="/docs/user-guide/logging/examples/two-files-counter-pod-agent-sidecar.yaml" %} - -After some time you can find log messages in the Stackdriver interface. - -Remember, that this is just an example and you can actually replace fluentd -with any logging agent, reading from any source inside an application -container. - -### Exposing logs directly from the application - -![Exposing logs directly from the application](/images/docs/user-guide/logging/logging-from-application.png) - -You can implement cluster-level logging by exposing or pushing logs directly from -every application; however, the implementation for such a logging mechanism -is outside the scope of Kubernetes. +[Logging and Monitoring Cluster Activity](/docs/concepts/clusters/logging/) diff --git a/docs/user-guide/logging/stackdriver.md b/docs/user-guide/logging/stackdriver.md index b71947ee1f..5664357ee5 100644 --- a/docs/user-guide/logging/stackdriver.md +++ b/docs/user-guide/logging/stackdriver.md @@ -5,144 +5,6 @@ assignees: title: Logging with Stackdriver Logging --- -Before reading this page, it's highly recommended to familiarize yourself with the [overview of logging in Kubernetes](/docs/user-guide/logging/overview). +{% include user-guide-content-moved.md %} -This article assumes that you have created a Kubernetes cluster with cluster-level logging support for sending logs to Stackdriver Logging. You can do this either by selecting the **Enable Stackdriver Logging** checkbox in the create cluster dialogue in [GKE](https://cloud.google.com/container-engine/), or by setting the `KUBE_LOGGING_DESTINATION` flag to `gcp` when manually starting a cluster using `kube-up.sh`. - -The following guide describes gathering a container's standard output and standard error. To gather logs written by an application to a file, you can use [a sidecar approach](https://github.com/kubernetes/contrib/blob/master/logging/fluentd-sidecar-gcp/README.md). - -## Overview - -After creation, you can discover logging agent pods in the `kube-system` namespace, -one per node, by running the following command: - -```shell -$ kubectl get pods --namespace=kube-system -NAME READY STATUS RESTARTS AGE -... -fluentd-gcp-v1.30-50gnc 1/1 Running 0 5d -fluentd-gcp-v1.30-v255c 1/1 Running 0 5d -fluentd-gcp-v1.30-f02l5 1/1 Running 0 5d -... -``` - -To understand how logging with Stackdriver works, consider the following -synthetic log generator pod specification [counter-pod.yaml](/docs/user-guide/logging/examples/counter-pod.yaml): - -{% include code.html language="yaml" file="examples/counter-pod.yaml" ghlink="/docs/user-guide/logging/examples/counter-pod.yaml" %} - -This pod specification has one container that runs a bash script -that writes out the value of a counter and the date once per -second, and runs indefinitely. Let's create this pod in the default namespace. - -```shell -$ kubectl create -f http://k8s.io/docs/user-guide/logging/examples/counter-pod.yaml -pod "counter" created -``` - -You can observe the running pod: - -```shell -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -counter 1/1 Running 0 5m -``` - -For a short period of time you can observe the 'Pending' pod status, because the kubelet -has to download the container image first. When the pod status changes to `Running` -you can use the `kubectl logs` command to view the output of this counter pod. - -```shell -$ kubectl logs counter -0: Mon Jan 1 00:00:00 UTC 2001 -1: Mon Jan 1 00:00:01 UTC 2001 -2: Mon Jan 1 00:00:02 UTC 2001 -... -``` - -As described in the logging overview, this command fetches log entries -from the container log file. If the container is killed and then restarted by -Kubernetes, you can still access logs from the previous container. However, -if the pod is evicted from the node, log files are lost. Let's demonstrate this -by deleting the currently running counter container: - -```shell -$ kubectl delete pod counter -pod "counter" deleted -``` - -and then recreating it: - -```shell -$ kubectl create -f http://k8s.io/docs/user-guide/logging/examples/counter-pod.yaml -pod "counter" created -``` - -After some time, you can access logs from the counter pod again: - -```shell -$ kubectl logs counter -0: Mon Jan 1 00:01:00 UTC 2001 -1: Mon Jan 1 00:01:01 UTC 2001 -2: Mon Jan 1 00:01:02 UTC 2001 -... -``` - -As expected, only recent log lines are present. However, for a real-world -application you will likely want to be able to access logs from all containers, -especially for the debug purposes. This is exactly when the previously enabled -Stackdriver Logging can help. - -## Viewing logs - -Stackdriver Logging agent attaches metadata to each log entry, for you to use later -in queries to select only the messages you're interested in: for example, -the messages from a particular pod. - -The most important pieces of metadata are the resource type and log name. -The resource type of a container log is `container`, which is named -`GKE Containers` in the UI (even if the Kubernetes cluster is not on GKE). -The log name is the name of the container, so that if you have a pod with -two containers, named `container_1` and `container_2` in the spec, their logs -will have log names `container_1` and `container_2` respectively. - -System components have resource type `compute`, which is named -`GCE VM Instance` in the interface. Log names for system components are fixed. -For a GKE node, every log entry from a system component has one the following -log names: - -* docker -* kubelet -* kube-proxy - -You can learn more about viewing logs on [the dedicated Stackdriver page](https://cloud.google.com/logging/docs/view/logs_viewer). - -One of the possible ways to view logs is using the -[`gcloud logging`](https://cloud.google.com/logging/docs/api/gcloud-logging) -command line interface from the [Google Cloud SDK](https://cloud.google.com/sdk/). -It uses Stackdriver Logging [filtering syntax](https://cloud.google.com/logging/docs/view/advanced_filters) -to query specific logs. For example, you can run the following command: - -```shell -$ gcloud beta logging read 'logName="projects/$YOUR_PROJECT_ID/logs/count"' --format json | jq '.[].textPayload' -... -"2: Mon Jan 1 00:01:02 UTC 2001\n" -"1: Mon Jan 1 00:01:01 UTC 2001\n" -"0: Mon Jan 1 00:01:00 UTC 2001\n" -... -"2: Mon Jan 1 00:00:02 UTC 2001\n" -"1: Mon Jan 1 00:00:01 UTC 2001\n" -"0: Mon Jan 1 00:00:00 UTC 2001\n" -``` - -As you can see, it outputs messages for the count container from both -the first and second runs, despite the fact that the kubelet already deleted -the logs for the first container. - -### Exporting logs - -You can export logs to [Google Cloud Storage](https://cloud.google.com/storage/) -or to [BigQuery](https://cloud.google.com/bigquery/) to run further -analysis. Stackdriver Logging offers the concept of sinks, where you can -specify the destination of log entries. More information is available on -the Stackdriver [Exporting Logs page](https://cloud.google.com/logging/docs/export/configure_export_v2). +[Logging Using Stackdriver](/docs/tasks/debug-application-cluster/logging-stackdriver/) diff --git a/docs/user-guide/managing-deployments.md b/docs/user-guide/managing-deployments.md index fc32a5bb46..84215a44bf 100644 --- a/docs/user-guide/managing-deployments.md +++ b/docs/user-guide/managing-deployments.md @@ -1,438 +1,7 @@ --- -assignees: -- bgrant0607 -- janetkuo -- mikedanese title: Managing Resources --- -You've deployed your application and exposed it via a service. Now what? Kubernetes provides a number of tools to help you manage your application deployment, including scaling and updating. Among the features we'll discuss in more depth are [configuration files](/docs/user-guide/configuring-containers/#configuration-in-kubernetes) and [labels](/docs/user-guide/deploying-applications/#labels). +{% include user-guide-content-moved.md %} +[Managing Resources](/docs/concepts/cluster-administration/manage-deployment/) -You can find all the files for this example [in our docs -repo here](https://github.com/kubernetes/kubernetes.github.io/tree/{{page.docsbranch}}/docs/user-guide/). - -* TOC -{:toc} - -## Organizing resource configurations - -Many applications require multiple resources to be created, such as a Deployment and a Service. Management of multiple resources can be simplified by grouping them together in the same file (separated by `---` in YAML). For example: - -{% include code.html language="yaml" file="nginx-app.yaml" ghlink="/docs/user-guide/nginx-app.yaml" %} - -Multiple resources can be created the same way as a single resource: - -```shell -$ kubectl create -f docs/user-guide/nginx-app.yaml -service "my-nginx-svc" created -deployment "my-nginx" created -``` - -The resources will be created in the order they appear in the file. Therefore, it's best to specify the service first, since that will ensure the scheduler can spread the pods associated with the service as they are created by the controller(s), such as Deployment. - -`kubectl create` also accepts multiple `-f` arguments: - -```shell -$ kubectl create -f docs/user-guide/nginx/nginx-svc.yaml -f docs/user-guide/nginx/nginx-deployment.yaml -``` - -And a directory can be specified rather than or in addition to individual files: - -```shell -$ kubectl create -f docs/user-guide/nginx/ -``` - -`kubectl` will read any files with suffixes `.yaml`, `.yml`, or `.json`. - -It is a recommended practice to put resources related to the same microservice or application tier into the same file, and to group all of the files associated with your application in the same directory. If the tiers of your application bind to each other using DNS, then you can then simply deploy all of the components of your stack en masse. - -A URL can also be specified as a configuration source, which is handy for deploying directly from configuration files checked into github: - -```shell -$ kubectl create -f https://raw.githubusercontent.com/kubernetes/kubernetes/master/docs/user-guide/nginx-deployment.yaml -deployment "nginx-deployment" created -``` - -## Bulk operations in kubectl - -Resource creation isn't the only operation that `kubectl` can perform in bulk. It can also extract resource names from configuration files in order to perform other operations, in particular to delete the same resources you created: - -```shell -$ kubectl delete -f docs/user-guide/nginx/ -deployment "my-nginx" deleted -service "my-nginx-svc" deleted -``` - -In the case of just two resources, it's also easy to specify both on the command line using the resource/name syntax: - -```shell -$ kubectl delete deployments/my-nginx services/my-nginx-svc -``` - -For larger numbers of resources, you'll find it easier to specify the selector (label query) specified using `-l` or `--selector`, to filter resources by their labels: - -```shell -$ kubectl delete deployment,services -l app=nginx -deployment "my-nginx" deleted -service "my-nginx-svc" deleted -``` - -Because `kubectl` outputs resource names in the same syntax it accepts, it's easy to chain operations using `$()` or `xargs`: - -```shell -$ kubectl get $(kubectl create -f docs/user-guide/nginx/ -o name | grep service) -NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE -my-nginx-svc 10.0.0.208 80/TCP 0s -``` - -With the above commands, we first create resources under docs/user-guide/nginx/ and print the resources created with `-o name` output format -(print each resource as resource/name). Then we `grep` only the "service", and then print it with `kubectl get`. - -If you happen to organize your resources across several subdirectories within a particular directory, you can recursively perform the operations on the subdirectories also, by specifying `--recursive` or `-R` alongside the `--filename,-f` flag. - -For instance, assume there is a directory `project/k8s/development` that holds all of the manifests needed for the development environment, organized by resource type: - -``` -project/k8s/development -├── configmap -│   └── my-configmap.yaml -├── deployment -│   └── my-deployment.yaml -└── pvc - └── my-pvc.yaml -``` - -By default, performing a bulk operation on `project/k8s/development` will stop at the first level of the directory, not processing any subdirectories. If we tried to create the resources in this directory using the following command, we'd encounter an error: - -```shell -$ kubectl create -f project/k8s/development -error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin) -``` - -Instead, specify the `--recursive` or `-R` flag with the `--filename,-f` flag as such: - -```shell -$ kubectl create -f project/k8s/development --recursive -configmap "my-config" created -deployment "my-deployment" created -persistentvolumeclaim "my-pvc" created -``` - -The `--recursive` flag works with any operation that accepts the `--filename,-f` flag such as: `kubectl {create,get,delete,describe,rollout} etc.` - -The `--recursive` flag also works when multiple `-f` arguments are provided: - -```shell -$ kubectl create -f project/k8s/namespaces -f project/k8s/development --recursive -namespace "development" created -namespace "staging" created -configmap "my-config" created -deployment "my-deployment" created -persistentvolumeclaim "my-pvc" created -``` - -If you're interested in learning more about `kubectl`, go ahead and read [kubectl Overview](/docs/user-guide/kubectl-overview). - -## Using labels effectively - -The examples we've used so far apply at most a single label to any resource. There are many scenarios where multiple labels should be used to distinguish sets from one another. - -For instance, different applications would use different values for the `app` label, but a multi-tier application, such as the [guestbook example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/), would additionally need to distinguish each tier. The frontend could carry the following labels: - -```yaml - labels: - app: guestbook - tier: frontend -``` - -while the Redis master and slave would have different `tier` labels, and perhaps even an additional `role` label: - -```yaml - labels: - app: guestbook - tier: backend - role: master -``` - -and - -```yaml - labels: - app: guestbook - tier: backend - role: slave -``` - -The labels allow us to slice and dice our resources along any dimension specified by a label: - -```shell -$ kubectl create -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml -$ kubectl get pods -Lapp -Ltier -Lrole -NAME READY STATUS RESTARTS AGE APP TIER ROLE -guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend -guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend -guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend -guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master -guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave -guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave -my-nginx-divi2 1/1 Running 0 29m nginx -my-nginx-o0ef1 1/1 Running 0 29m nginx -$ kubectl get pods -lapp=guestbook,role=slave -NAME READY STATUS RESTARTS AGE -guestbook-redis-slave-2q2yf 1/1 Running 0 3m -guestbook-redis-slave-qgazl 1/1 Running 0 3m -``` - -## Canary deployments - -Another scenario where multiple labels are needed is to distinguish deployments of different releases or configurations of the same component. It is common practice to deploy a *canary* of a new application release (specified via image tag in the pod template) side by side with the previous release so that the new release can receive live production traffic before fully rolling it out. - -For instance, you can use a `track` label to differentiate different releases. - -The primary, stable release would have a `track` label with value as `stable`: - -```yaml - name: frontend - replicas: 3 - ... - labels: - app: guestbook - tier: frontend - track: stable - ... - image: gb-frontend:v3 -``` - -and then you can create a new release of the guestbook frontend that carries the `track` label with different value (i.e. `canary`), so that two sets of pods would not overlap: - -```yaml - name: frontend-canary - replicas: 1 - ... - labels: - app: guestbook - tier: frontend - track: canary - ... - image: gb-frontend:v4 -``` - - -The frontend service would span both sets of replicas by selecting the common subset of their labels (i.e. omitting the `track` label), so that the traffic will be redirected to both applications: - -```yaml - selector: - app: guestbook - tier: frontend -``` - -You can tweak the number of replicas of the stable and canary releases to determine the ratio of each release that will receive live production traffic (in this case, 3:1). -Once you're confident, you can update the stable track to the new application release and remove the canary one. - -For a more concrete example, check the [tutorial of deploying Ghost](https://github.com/kelseyhightower/talks/tree/master/kubecon-eu-2016/demo#deploy-a-canary). - -## Updating labels - -Sometimes existing pods and other resources need to be relabeled before creating new resources. This can be done with `kubectl label`. -For example, if you want to label all your nginx pods as frontend tier, simply run: - -```shell -$ kubectl label pods -l app=nginx tier=fe -pod "my-nginx-2035384211-j5fhi" labeled -pod "my-nginx-2035384211-u2c7e" labeled -pod "my-nginx-2035384211-u3t6x" labeled -``` - -This first filters all pods with the label "app=nginx", and then labels them with the "tier=fe". -To see the pods you just labeled, run: - -```shell -$ kubectl get pods -l app=nginx -L tier -NAME READY STATUS RESTARTS AGE TIER -my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe -my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe -my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe -``` - -This outputs all "app=nginx" pods, with an additional label column of pods' tier (specified with `-L` or `--label-columns`). - -For more information, please see [labels](/docs/user-guide/labels/) and [kubectl label](/docs/user-guide/kubectl/kubectl_label/) document. - -## Updating annotations - -Sometimes you would want to attach annotations to resources. Annotations are arbitrary non-identifying metadata for retrieval by API clients such as tools, libraries, etc. This can be done with `kubectl annotate`. For example: - -```shell -$ kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx' -$ kubectl get pods my-nginx-v4-9gw19 -o yaml -apiversion: v1 -kind: pod -metadata: - annotations: - description: my frontend running nginx -... -``` - -For more information, please see [annotations](/docs/user-guide/annotations/) and [kubectl annotate](/docs/user-guide/kubectl/kubectl_annotate/) document. - -## Scaling your application - -When load on your application grows or shrinks, it's easy to scale with `kubectl`. For instance, to decrease the number of nginx replicas from 3 to 1, do: - -```shell -$ kubectl scale deployment/my-nginx --replicas=1 -deployment "my-nginx" scaled -``` - -Now you only have one pod managed by the deployment. - -```shell -$ kubectl get pods -l app=nginx -NAME READY STATUS RESTARTS AGE -my-nginx-2035384211-j5fhi 1/1 Running 0 30m -``` - -To have the system automatically choose the number of nginx replicas as needed, ranging from 1 to 3, do: - -```shell -$ kubectl autoscale deployment/my-nginx --min=1 --max=3 -deployment "my-nginx" autoscaled -``` - -Now your nginx replicas will be scaled up and down as needed, automatically. - -For more information, please see [kubectl scale](/docs/user-guide/kubectl/kubectl_scale/), [kubectl autoscale](/docs/user-guide/kubectl/kubectl_autoscale/) and [horizontal pod autoscaler](/docs/user-guide/horizontal-pod-autoscaler/) document. - - -## In-place updates of resources - -Sometimes it's necessary to make narrow, non-disruptive updates to resources you've created. - -### kubectl apply - -It is suggested to maintain a set of configuration files in source control (see [configuration as code](http://martinfowler.com/bliki/InfrastructureAsCode.html)), -so that they can be maintained and versioned along with the code for the resources they configure. -Then, you can use [`kubectl apply`](/docs/user-guide/kubectl/kubectl_apply/) to push your configuration changes to the cluster. - -This command will compare the version of the configuration that you're pushing with the previous version and apply the changes you've made, without overwriting any automated changes to properties you haven't specified. - -```shell -$ kubectl apply -f docs/user-guide/nginx/nginx-deployment.yaml -deployment "my-nginx" configured -``` - -Note that `kubectl apply` attaches an annotation to the resource in order to determine the changes to the configuration since the previous invocation. When it's invoked, `kubectl apply` does a three-way diff between the previous configuration, the provided input and the current configuration of the resource, in order to determine how to modify the resource. - -Currently, resources are created without this annotation, so the first invocation of `kubectl apply` will fall back to a two-way diff between the provided input and the current configuration of the resource. During this first invocation, it cannot detect the deletion of properties set when the resource was created. For this reason, it will not remove them. - -All subsequent calls to `kubectl apply`, and other commands that modify the configuration, such as `kubectl replace` and `kubectl edit`, will update the annotation, allowing subsequent calls to `kubectl apply` to detect and perform deletions using a three-way diff. - -**Note:** To use apply, always create resource initially with either `kubectl apply` or `kubectl create --save-config`. - -### kubectl edit - -Alternatively, you may also update resources with `kubectl edit`: - -```shell -$ kubectl edit deployment/my-nginx -``` - -This is equivalent to first `get` the resource, edit it in text editor, and then `apply` the resource with the updated version: - -```shell -$ kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml -$ vi /tmp/nginx.yaml -# do some edit, and then save the file -$ kubectl apply -f /tmp/nginx.yaml -deployment "my-nginx" configured -$ rm /tmp/nginx.yaml -``` - -This allows you to do more significant changes more easily. Note that you can specify the editor with your `EDITOR` or `KUBE_EDITOR` environment variables. - -For more information, please see [kubectl edit](/docs/user-guide/kubectl/kubectl_edit/) document. - -### kubectl patch - -Suppose you want to fix a typo of the container's image of a Deployment. One way to do that is with `kubectl patch`: - -```shell -# Suppose you have a Deployment with a container named "nginx" and its image "nignx" (typo), -# use container name "nginx" as a key to update the image from "nignx" (typo) to "nginx" -$ kubectl get deployment my-nginx -o yaml -``` - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -... -spec: - template: - spec: - containers: - - image: nignx - name: nginx -... -``` - -```shell -$ kubectl patch deployment my-nginx -p'{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx"}]}}}}' -"my-nginx" patched -$ kubectl get pod my-nginx-1jgkf -o yaml -``` - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -... -spec: - template: - spec: - containers: - - image: nginx - name: nginx -... -``` - -The patch is specified using json. - -The system ensures that you don't clobber changes made by other users or components by confirming that the `resourceVersion` doesn't differ from the version you edited. If you want to update regardless of other changes, remove the `resourceVersion` field when you edit the resource. However, if you do this, don't use your original configuration file as the source since additional fields most likely were set in the live state. - -For more information, please see [kubectl patch](/docs/user-guide/kubectl/kubectl_patch/) document. - -## Disruptive updates - -In some cases, you may need to update resource fields that cannot be updated once initialized, or you may just want to make a recursive change immediately, such as to fix broken pods created by a Deployment. To change such fields, use `replace --force`, which deletes and re-creates the resource. In this case, you can simply modify your original configuration file: - -```shell -$ kubectl replace -f docs/user-guide/nginx/nginx-deployment.yaml --force -deployment "my-nginx" deleted -deployment "my-nginx" replaced -``` - -## Updating your application without a service outage - -At some point, you'll eventually need to update your deployed application, typically by specifying a new image or image tag, as in the canary deployment scenario above. `kubectl` supports several update operations, each of which is applicable to different scenarios. - -We'll guide you through how to create and update applications with Deployments. If your deployed application is managed by Replication Controllers, -you should read [how to use `kubectl rolling-update`](/docs/user-guide/rolling-updates/) instead. - -Let's say you were running version 1.7.9 of nginx: - -```shell -$ kubectl run my-nginx --image=nginx:1.7.9 --replicas=3 -deployment "my-nginx" created -``` - -To update to version 1.9.1, simply change `.spec.template.spec.containers[0].image` from `nginx:1.7.9` to `nginx:1.9.1`, with the kubectl commands we learned above. - -```shell -$ kubectl edit deployment/my-nginx -``` - -That's it! The Deployment will declaratively update the deployed nginx application progressively behind the scene. It ensures that only a certain number of old replicas may be down while they are being updated, and only a certain number of new replicas may be created above the desired number of pods. To learn more details about it, visit [Deployment page](/docs/user-guide/deployments/). - -## What's next? - -- [Learn about how to use `kubectl` for application introspection and debugging.](/docs/user-guide/introspection-and-debugging/) -- [Configuration Best Practices and Tips](/docs/user-guide/config-best-practices/) diff --git a/docs/user-guide/persistent-volumes/index.md b/docs/user-guide/persistent-volumes/index.md index d6245e8198..e2d2661d13 100644 --- a/docs/user-guide/persistent-volumes/index.md +++ b/docs/user-guide/persistent-volumes/index.md @@ -172,23 +172,23 @@ In the CLI, the access modes are abbreviated to: | Volume Plugin | ReadWriteOnce| ReadOnlyMany| ReadWriteMany| | :--- | :---: | :---: | :---: | -| AWSElasticBlockStore | x | - | - | -| AzureFile | x | x | x | -| AzureDisk | x | - | - | -| CephFS | x | x | x | -| Cinder | x | - | - | -| FC | x | x | - | -| FlexVolume | x | x | - | -| Flocker | x | - | - | -| GCEPersistentDisk | x | x | - | -| Glusterfs | x | x | x | -| HostPath | x | - | - | -| iSCSI | x | x | - | -| PhotonPersistentDisk | x | - | - | -| Quobyte | x | x | x | -| NFS | x | x | x | -| RBD | x | x | - | -| VsphereVolume | x | - | - | +| AWSElasticBlockStore | ✓ | - | - | +| AzureFile | ✓ | ✓ | ✓ | +| AzureDisk | ✓ | - | - | +| CephFS | ✓ | ✓ | ✓ | +| Cinder | ✓ | - | - | +| FC | ✓ | ✓ | - | +| FlexVolume | ✓ | ✓ | - | +| Flocker | ✓ | - | - | +| GCEPersistentDisk | ✓ | ✓ | - | +| Glusterfs | ✓ | ✓ | ✓ | +| HostPath | ✓ | - | - | +| iSCSI | ✓ | ✓ | - | +| PhotonPersistentDisk | ✓ | - | - | +| Quobyte | ✓ | ✓ | ✓ | +| NFS | ✓ | ✓ | ✓ | +| RBD | ✓ | ✓ | - | +| VsphereVolume | ✓ | - | - | ### Class @@ -396,7 +396,7 @@ parameters: zone: us-central1-a ``` -* `type`: `pd-standard` or `pd-ssd`. Default: `pd-ssd` +* `type`: `pd-standard` or `pd-ssd`. Default: `pd-standard` * `zone`: GCE zone. If not specified, a random zone in the same region as controller-manager will be chosen. #### Glusterfs @@ -421,9 +421,9 @@ parameters: * `restauthenabled` : Gluster REST service authentication boolean that enables authentication to the REST server. If this value is 'true', `restuser` and `restuserkey` or `secretNamespace` + `secretName` have to be filled. This option is deprecated, authentication is enabled when any of `restuser`, `restuserkey`, `secretName` or `secretNamespace` is specified. * `restuser` : Gluster REST service/Heketi user who has access to create volumes in the Gluster Trusted Pool. * `restuserkey` : Gluster REST service/Heketi user's password which will be used for authentication to the REST server. This parameter is deprecated in favor of `secretNamespace` + `secretName`. -* `secretNamespace` + `secretName` : Identification of Secret instance that containes user password to use when talking to Gluster REST service. These parameters are optional, empty password will be used when both `secretNamespace` and `secretName` are omitted. The provided secret must have type "kubernetes.io/glusterfs", e.g. created in this way: +* `secretNamespace` + `secretName` : Identification of Secret instance that contains user password to use when talking to Gluster REST service. These parameters are optional, empty password will be used when both `secretNamespace` and `secretName` are omitted. The provided secret must have type "kubernetes.io/glusterfs", e.g. created in this way: ``` - $ kubectl create secret heketi-secret --type="kubernetes.io/glusterfs" --from-literal=key='opensesame' --namespace=default + $ kubectl create secret generic heketi-secret --type="kubernetes.io/glusterfs" --from-literal=key='opensesame' --namespace=default ``` #### OpenStack Cinder @@ -482,7 +482,7 @@ parameters: * `userId`: Ceph client ID that is used to map the RBD image. Default is the same as `adminId`. * `userSecretName`: The name of Ceph Secret for `userId` to map RBD image. It must exist in the same namespace as PVCs. This parameter is required. The provided secret must have type "kubernetes.io/rbd", e.g. created in this way: ``` - $ kubectl create secret ceph-secret --type="kubernetes.io/rbd" --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' --namespace=kube-system + $ kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' --namespace=kube-system ``` #### Quobyte @@ -507,9 +507,9 @@ parameters: * `quobyteAPIServer`: API Server of Quobyte in the format `http(s)://api-server:7860` * `registry`: Quobyte registry to use to mount the volume. You can specify the registry as ``:`` pair or if you want to specify multiple registries you just have to put a comma between them e.q. ``:,:,:``. The host can be an IP address or if you have a working DNS you can also provide the DNS names. * `adminSecretNamespace`: The namespace for `adminSecretName`. Default is "default". -* `adminSecretName`: secret that holds information about the Quobyte user and the password to authenticate agains the API server. The provided secret must have type "kubernetes.io/quobyte", e.g. created in this way: +* `adminSecretName`: secret that holds information about the Quobyte user and the password to authenticate against the API server. The provided secret must have type "kubernetes.io/quobyte", e.g. created in this way: ``` - $ kubectl create secret quobyte-admin-secret --type="kubernetes.io/quobyte" --from-literal=key='opensesame' --namespace=kube-system + $ kubectl create secret generic quobyte-admin-secret --type="kubernetes.io/quobyte" --from-literal=key='opensesame' --namespace=kube-system ``` * `user`: maps all access to this user. Default is "root". * `group`: maps all access to this group. Default is "nfsnobody". @@ -532,7 +532,7 @@ parameters: * `skuName`: Azure storage account Sku tier. Default is empty. * `location`: Azure storage account location. Default is empty. -* `storageAccount`: Azure storage account name. If storage account is not provided, all storage accounts associated with the resource group are searched to find one that matches `skuName` and `location`. If storage account is provided, `skuName` and `location` are ignored. +* `storageAccount`: Azure storage account name. If storage account is not provided, all storage accounts associated with the resource group are searched to find one that matches `skuName` and `location`. If storage account is provided, it must reside in the same resource group as the cluster, and `skuName` and `location` are ignored. ## Writing Portable Configuration diff --git a/docs/user-guide/persistent-volumes/walkthrough.md b/docs/user-guide/persistent-volumes/walkthrough.md deleted file mode 100644 index 2feee3f7d9..0000000000 --- a/docs/user-guide/persistent-volumes/walkthrough.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -assignees: -- jsafrane -- saad-ali -title: Persistent Volumes Walkthrough ---- - -{% include user-guide-content-moved.md %} - -[Configuring a Pod to Use a Persistent Volume for Storage](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/) diff --git a/docs/user-guide/petset/bootstrapping/index.md b/docs/user-guide/petset/bootstrapping/index.md index de3ccb4bd8..1988cba12a 100644 --- a/docs/user-guide/petset/bootstrapping/index.md +++ b/docs/user-guide/petset/bootstrapping/index.md @@ -10,7 +10,9 @@ assignees: title: Bootstrapping Pet Sets --- -__Warning:__ Starting in Kubernetes version 1.5, PetSet has been renamed to [StatefulSet](/docs/concepts/abstractions/controllers/statefulsets). To use (or continue to use) PetSet in Kubernetes 1.5, you _must_ [migrate](/docs/tasks/manage-stateful-set/upgrade-pet-set-to-stateful-set/) your existing PetSets to StatefulSets. For information on working with StatefulSet, see the tutorial on [how to run replicated stateful applications](/docs/tutorials/stateful-application/run-replicated-stateful-application). +{% include user-guide-content-moved.md %} + +[PetSets](/docs/concepts/abstractions/controllers/petsets/) + -__This document has been deprecated__. diff --git a/docs/user-guide/pod-security-policy/index.md b/docs/user-guide/pod-security-policy/index.md index da1c6514d6..d3b40902ea 100644 --- a/docs/user-guide/pod-security-policy/index.md +++ b/docs/user-guide/pod-security-policy/index.md @@ -163,5 +163,5 @@ following ## Working With RBAC -Use PodSecurityPolicy to control access to privileged containers based on role and groups. +In Kubernetes 1.5 and newer, you can use PodSecurityPolicy to control access to privileged containers based on user role and groups. (see [more details](https://github.com/kubernetes/kubernetes/blob/master/examples/podsecuritypolicy/rbac/README.md)). diff --git a/docs/user-guide/pod-states.md b/docs/user-guide/pod-states.md index 462f8b65bd..a3cea728cc 100644 --- a/docs/user-guide/pod-states.md +++ b/docs/user-guide/pod-states.md @@ -4,168 +4,6 @@ assignees: title: The Lifecycle of a Pod --- -Updated: 4/14/2015 - -This document covers the lifecycle of a pod. It is not an exhaustive document, but an introduction to the topic. - -## Pod Phase - -As consistent with the overall [API convention](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#typical-status-properties), phase is a simple, high-level summary of the phase of the lifecycle of a pod. It is not intended to be a comprehensive rollup of observations of container-level or even pod-level conditions or other state, nor is it intended to be a comprehensive state machine. - -The number and meanings of `PodPhase` values are tightly guarded. Other than what is documented here, nothing should be assumed about pods with a given `PodPhase`. - -* Pending: The pod has been accepted by the system, but one or more of the container images has not been created. This includes time before being scheduled as well as time spent downloading images over the network, which could take a while. -* Running: The pod has been bound to a node, and all of the containers have been created. At least one container is still running, or is in the process of starting or restarting. -* Succeeded: All containers in the pod have terminated in success, and will not be restarted. -* Failed: All containers in the pod have terminated, at least one container has terminated in failure (exited with non-zero exit status or was terminated by the system). -* Unknown: For some reason the state of the pod could not be obtained, typically due to an error in communicating with the host of the pod. - -## Pod Conditions - -A pod containing containers that specify readiness probes will also report the Ready condition. Condition status values may be `True`, `False`, or `Unknown`. - -## Container Probes - -A [Probe](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#Probe) is a diagnostic performed periodically by the kubelet on a container. Specifically the diagnostic is one of three [Handlers](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#Handler): - -* `ExecAction`: executes a specified command inside the container expecting on success that the command exits with status code 0. -* `TCPSocketAction`: performs a tcp check against the container's IP address on a specified port expecting on success that the port is open. -* `HTTPGetAction`: performs an HTTP Get against the container's IP address on a specified port and path expecting on success that the response has a status code greater than or equal to 200 and less than 400. - -Each probe will have one of three results: - -* `Success`: indicates that the container passed the diagnostic. -* `Failure`: indicates that the container failed the diagnostic. -* `Unknown`: indicates that the diagnostic failed so no action should be taken. - -The kubelet can optionally perform and react to two kinds of probes on running containers: - -* `LivenessProbe`: indicates whether the container is *live*, i.e. running. If the LivenessProbe fails, the kubelet will kill the container and the container will be subjected to its [RestartPolicy](#restartpolicy). The default state of Liveness before the initial delay is `Success`. The state of Liveness for a container when no probe is provided is assumed to be `Success`. -* `ReadinessProbe`: indicates whether the container is *ready* to service requests. If the ReadinessProbe fails, the endpoints controller will remove the pod's IP address from the endpoints of all services that match the pod. The default state of Readiness before the initial delay is `Failure`. The state of Readiness for a container when no probe is provided is assumed to be `Success`. - -### When should I use liveness or readiness probes? - -If the process in your container is able to crash on its own whenever it encounters an issue or becomes unhealthy, you do not necessarily need a liveness probe - the kubelet will automatically perform the correct action in accordance with the RestartPolicy when the process crashes. - -If you'd like your container to be killed and restarted if a probe fails, then specify a LivenessProbe and a RestartPolicy of `Always` or `OnFailure`. - -If you'd like to start sending traffic to a pod only when a probe succeeds, specify a ReadinessProbe. In this case, the ReadinessProbe may be the same as the LivenessProbe, but the existence of the ReadinessProbe in the spec means that the pod will start without receiving any traffic and only start receiving traffic once the probe starts succeeding. - -If a container wants the ability to take itself down for maintenance, you can specify a ReadinessProbe that checks an endpoint specific to readiness which is different than the LivenessProbe. - -Note that if you just want to be able to drain requests when the pod is deleted, you do not necessarily need a ReadinessProbe - on deletion, the pod automatically puts itself into an unready state regardless of whether the ReadinessProbe exists or not while it waits for the containers in the pod to stop. - -## Container Statuses - -More detailed information about the current (and previous) container statuses can be found in [ContainerStatuses](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#PodStatus). The information reported depends on the current [ContainerState](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#ContainerState), which may be Waiting, Running, or Terminated. - -## RestartPolicy - -The possible values for RestartPolicy are `Always`, `OnFailure`, or `Never`. If RestartPolicy is not set, the default value is `Always`. RestartPolicy applies to all containers in the pod. RestartPolicy only refers to restarts of the containers by the Kubelet on the same node. Failed containers that are restarted by Kubelet, are restarted with an exponential back-off delay, the delay is in multiples of sync-frequency 0, 1x, 2x, 4x, 8x ... capped at 5 minutes and is reset after 10 minutes of successful execution. As discussed in the [pods document](/docs/user-guide/pods/#durability-of-pods-or-lack-thereof), once bound to a node, a pod will never be rebound to another node. This means that some kind of controller is necessary in order for a pod to survive node failure, even if just a single pod at a time is desired. - -Three types of controllers are currently available: - -- Use a [`Job`](/docs/user-guide/jobs/) for pods which are expected to terminate (e.g. batch computations). -- Use a [`ReplicationController`](/docs/user-guide/replication-controller/) or [`Deployment`](/docs/user-guide/deployments/) - for pods which are not expected to terminate (e.g. web servers). -- Use a [`DaemonSet`](/docs/admin/daemons/): Use for pods which need to run 1 per machine because they provide a - machine-specific system service. -If you are unsure whether to use ReplicationController or Daemon, then see [Daemon Set versus -Replication Controller](/docs/admin/daemons/#daemon-set-versus-replication-controller). - -`ReplicationController` is *only* appropriate for pods with `RestartPolicy = Always`. -`Job` is *only* appropriate for pods with `RestartPolicy` equal to `OnFailure` or `Never`. - -All 3 types of controllers contain a PodTemplate, which has all the same fields as a Pod. -It is recommended to create the appropriate controller and let it create pods, rather than to -directly create pods yourself. That is because pods alone are not resilient to machine failures, -but Controllers are. - -## Pod lifetime - -In general, pods which are created do not disappear until someone destroys them. This might be a human or a `ReplicationController`, or another controller. The only exception to this rule is that pods with a `PodPhase` of `Succeeded` or `Failed` for more than some duration (determined by the master) will expire and be automatically reaped. - -If a node dies or is disconnected from the rest of the cluster, some entity within the system (call it the NodeController for now) is responsible for applying policy (e.g. a timeout) and marking any pods on the lost node as `Failed`. - -## Examples - -### Advanced livenessProbe example - -Liveness probes are executed by `kubelet`, so all requests will be made within kubelet network namespace. - -```yaml -apiVersion: v1 -kind: Pod -metadata: - labels: - test: liveness - name: liveness-http -spec: - containers: - - args: - - /server - image: gcr.io/google_containers/liveness - livenessProbe: - httpGet: - # when "host" is not defined, "PodIP" will be used - # host: my-host - # when "scheme" is not defined, "HTTP" scheme will be used. Only "HTTP" and "HTTPS" are allowed - # scheme: HTTPS - path: /healthz - port: 8080 - httpHeaders: - - name: X-Custom-Header - value: Awesome - initialDelaySeconds: 15 - timeoutSeconds: 1 - name: liveness -``` - -### Example states - - * Pod is `Running`, 1 container, container exits success - * Log completion event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: pod becomes `Succeeded` - * Never: pod becomes `Succeeded` - - * Pod is `Running`, 1 container, container exits failure - * Log failure event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: restart container, pod stays `Running` - * Never: pod becomes `Failed` - - * Pod is `Running`, 2 containers, container 1 exits failure - * Log failure event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: restart container, pod stays `Running` - * Never: pod stays `Running` - * When container 2 exits... - * Log failure event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: restart container, pod stays `Running` - * Never: pod becomes `Failed` - - * Pod is `Running`, container becomes OOM - * Container terminates in failure - * Log OOM event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: restart container, pod stays `Running` - * Never: log failure event, pod becomes `Failed` - - * Pod is `Running`, a disk dies - * All containers are killed - * Log appropriate event - * Pod becomes `Failed` - * If running under a controller, pod will be recreated elsewhere - - * Pod is `Running`, its node is segmented out - * NodeController waits for timeout - * NodeController marks pod `Failed` - * If running under a controller, pod will be recreated elsewhere +{% include user-guide-content-moved.md %} +[Pod Lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/) diff --git a/docs/user-guide/pods/index.md b/docs/user-guide/pods/index.md index 321900c948..47e2dcaf3b 100644 --- a/docs/user-guide/pods/index.md +++ b/docs/user-guide/pods/index.md @@ -1,5 +1,5 @@ --- -assignees: +assignees: title: Pods --- @@ -60,7 +60,7 @@ related thing (e.g. volume) is also destroyed and created anew. ![pod diagram](/images/docs/pod.svg){: style="max-width: 50%" } -*A multi-container pod that contains a file puller and a +*A multi-container pod that contains a file puller and a web server that uses a persistent volume for shared storage between the containers.* ## Motivation for pods @@ -150,7 +150,7 @@ Pod is exposed as a primitive in order to facilitate: * clean composition of Kubelet-level functionality with cluster-level functionality — Kubelet is effectively the "pod controller" * high-availability applications, which will expect pods to be replaced in advance of their termination and certainly in advance of deletion, such as in the case of planned evictions, image prefetching, or live pod migration [#3949](http://issue.k8s.io/3949) -There is new first-class support for stateful pods with the [StatefulSet](/docs/concepts/controllers/statefulsets/) controller (currently in beta). The feature was alpha in 1.4 and was called [PetSet](/docs/user-guide/petset/). For prior versions of Kubernetes, best practice for having stateful pods is to create a replication controller with `replicas` equal to `1` and a corresponding service, see [this MySQL deployment example](/docs/tutorials/stateful-application/run-stateful-application/). +There is new first-class support for stateful pods with the [StatefulSet](/docs/concepts/abstractions/controllers/statefulsets/) controller (currently in beta). The feature was alpha in 1.4 and was called [PetSet](/docs/user-guide/petset/). For prior versions of Kubernetes, best practice for having stateful pods is to create a replication controller with `replicas` equal to `1` and a corresponding service, see [this MySQL deployment example](/docs/tutorials/stateful-application/run-stateful-application/). ## Termination of Pods @@ -168,7 +168,7 @@ An example flow: 6. When the grace period expires, any processes still running in the Pod are killed with SIGKILL. 7. The Kubelet will finish deleting the Pod on the API server by setting grace period 0 (immediate deletion). The Pod disappears from the API and is no longer visible from the client. -By default, all deletes are graceful within 30 seconds. The `kubectl delete` command supports the `--grace-period=` option which allows a user to override the default and specify their own value. The value `0` [force deletes](/docs/user-guide/pods/#force-termination-of-pods) the pod. In kubectl version >= 1.5, you must specify an additional flag `--force` along with `--grace-period=0` in order to perform force deletions. +By default, all deletes are graceful within 30 seconds. The `kubectl delete` command supports the `--grace-period=` option which allows a user to override the default and specify their own value. The value `0` [force deletes](/docs/user-guide/pods/#force-termination-of-pods) the pod. In kubectl version >= 1.5, you must specify an additional flag `--force` along with `--grace-period=0` in order to perform force deletions. ### Force deletion of pods diff --git a/docs/user-guide/pods/init-container.md b/docs/user-guide/pods/init-container.md index ce7679d40e..90a862ea02 100644 --- a/docs/user-guide/pods/init-container.md +++ b/docs/user-guide/pods/init-container.md @@ -1,168 +1,7 @@ --- -assignees: -- erictune title: Init Containers --- -* TOC -{:toc} - -In addition to having one or more main containers (or **app containers**), a -pod can also have one or more **init containers** which run before the app -containers. Init containers allow you to reduce and reorganize setup scripts -and "glue code". - -## Overview - -An init container is exactly like a regular container, except that it always -runs to completion and each init container must complete successfully before -the next one is started. If the init container fails, Kubernetes will restart -the pod until the init container succeeds. If a pod is marked as `RestartNever`, -the pod will fail if the init container fails. - -You specify a container as an init container by adding an annotation. -The annotation key is `pod.beta.kubernetes.io/init-containers`. The annotation -value is a JSON array of [objects of type `v1.Container` -](http://kubernetes.io/docs/api-reference/v1/definitions/#_v1_container) - -Once the feature exits beta, the init containers will be specified on the Pod -Spec alongside the app `containers` array. -The status of the init containers is returned as another annotation - -`pod.beta.kubernetes.io/init-container-statuses` -- as an array of the -container statuses (similar to the `status.containerStatuses` field). - -Init containers support all of the same features as normal containers, -including resource limits, volumes, and security settings. The resource -requests and limits for an init container are [handled slightly differently]( -#resources). Init containers do not support readiness probes since they will -run to completion before the pod can be ready. -An init container has all of the fields of an app container. - -If you specify multiple init containers for a pod, those containers run one at -a time in sequential order. Each must succeed before the next can run. Once all -init containers have run to completion, Kubernetes initializes the pod and runs -the application containers as usual. - -## What are Init Containers Good For? - -Because init containers have separate images from application containers, they -have some advantages for start-up related code. These include: - -* they can contain utilities that are not desirable to include in the app container - image for security reasons, -* they can contain utilities or custom code for setup that is not present in an app - image. (No need to make an image `FROM` another image just to use a tool like - `sed`, `awk`, `python`, `dig`, etc during setup). -* the application image builder and the deployer roles can work independently without - the need to jointly build a single app image. - -Because init containers have different filesystem view (Linux namespaces) from -app containers, they can be given access to Secrets that the app containers are -not able to access. - -Since init containers run to completion before any app containers start, and -since app containers run in parallel, they provide an easier way to block or -delay the startup of application containers until some precondition is met. - -Because init containers run in sequence and there can be multiple init containers, -they can be composed easily. - -Here are some ideas for how to use init containers: -- Wait for a service to be created with a shell command like: - `for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1` -- Register this pod with a remote server with a command like: - `curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(POD_NAME)&ip=$(POD_IP)'` - using `POD_NAME` and `POD_IP` from the downward API. -- Wait for some time before starting the app container with a command like `sleep 60`. -- Clone a git repository into a volume -- Place values like a POD_IP into a configuration file, and run a template tool (e.g. jinja) - to generate a configuration file to be consumed by the main app contianer. - -Complete usage examples can be found in the [StatefulSets -documentation](/docs/concepts/abstractions/controllers/statefulsets/) and the [Production Pods -guide](/docs/user-guide/production-pods.md#handling-initialization). - - -## Detailed Behavior - -Each pod may have 0..N init containers defined along with the existing -1..M app containers. - -On startup of the pod, after the network and volumes are initialized, the init -containers are started in order. Each container must exit successfully before -the next is invoked. If a container fails to start (due to the runtime) or -exits with failure, it is retried according to the pod RestartPolicy, except -when the pod restart policy is RestartPolicyAlways, in which case just the init -containers use RestartPolicyOnFailure. - -A pod cannot be ready until all init containers have succeeded. The ports on an -init container are not aggregated under a service. A pod that is being -initialized is in the `Pending` phase but should has a condition `Initializing` -set to `true`. - -If the pod is [restarted](#pod-restart-reasons) all init containers must -execute again. - -Changes to the init container spec are limited to the container image field. -Altering an init container image field is equivalent to restarting the pod. - -Because init containers can be restarted, retried, or reexecuted, init container -code should be idempotent. In particular, code that writes to files on EmptyDirs -should be prepared for the possibility that an output file already exists. - -An init container has all of the fields of an app container. The following -fields are prohibited from being used on init containers by validation: - -* `readinessProbe` - init containers must exit for pod startup to continue, - are not included in rotation, and so cannot define readiness distinct from - completion. - -Init container authors may use `activeDeadlineSeconds` on the pod and -`livenessProbe` on the container to prevent init containers from failing -forever. The active deadline includes init containers. - -The name of each app and init container in a pod must be unique - it is a -validation error for any container to share a name. - -### Resources - -Given the ordering and execution for init containers, the following rules -for resource usage apply: - -* The highest of any particular resource request or limit defined on all init - containers is the **effective init request/limit** -* The pod's **effective request/limit** for a resource is the higher of: - * sum of all app containers request/limit for a resource - * effective init request/limit for a resource -* Scheduling is done based on effective requests/limits, which means - init containers can reserve resources for initialization that are not used - during the life of the pod. -* QoS tier of the pod's **effective QoS tier** is the QoS tier for init containers - and app containers alike. - -Quota and limits are applied based on the effective pod request and -limit. - -Pod level cGroups are based on the effective pod request and limit, the -same as the scheduler. - - -## Pod Restart Reasons - -A Pod may "restart", causing reexecution of init containers, for the following -reasons: - -* An init container image is changed by a user updating the Pod Spec. - * App container image changes only restart the app container. -* The pod infrastructure container is restarted. - * This is uncommon and would have to be done by someone with root access to nodes. -* All containers in a pod are terminated, requiring a restart (RestartPolicyAlways) AND the record of init container completion has been lost due to garbage collection. - -## Support and compatibility - -A cluster with Kubelet and Apiserver version 1.4.0 or greater supports init -containers with the beta annotations. Support varies for other combinations of -Kubelet and Apiserver version; see the [release notes -](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md) for details. - +{% include user-guide-content-moved.md %} +* [Init Containers](/docs/concepts/abstractions/init-containers/) \ No newline at end of file diff --git a/docs/user-guide/pods/multi-container.md b/docs/user-guide/pods/multi-container.md index 55e0e56f84..465379e51c 100644 --- a/docs/user-guide/pods/multi-container.md +++ b/docs/user-guide/pods/multi-container.md @@ -4,172 +4,6 @@ assignees: title: Creating Multi-Container Pods --- -* TOC -{:toc} +{% include user-guide-content-moved.md %} -A pod is a group of containers that are scheduled -onto the same host. Pods serve as units of scheduling, deployment, and -horizontal scaling/replication. Pods share fate, and share some resources, such -as storage volumes and IP addresses. - -## Creating a pod - -Multi-container pods must be created with the `create` command. Properties -are passed to the command as a YAML- or JSON-formatted configuration file. - -The `create` command can be used to create a pod directly, or it can create -a pod or pods through a `Deployment`. It is highly recommended that -you use a -[Deployment](/docs/user-guide/deployments/) -to create your pods. It watches for failed pods and will start up -new pods as required to maintain the specified number. - -If you don't want a Deployment to monitor your pod (e.g. your pod -is writing non-persistent data which won't survive a restart, or your pod is -intended to be very short-lived), you can create a pod directly with the -`create` command. - -### Using `create` - -Note: We recommend using a -[Deployment](/docs/user-guide/deployments/) -to create pods. You should use the instructions below only if you don't want -to create a Deployment. - -If your pod will contain more than one container, or if you don't want to -create a Deployment to manage your pod, use the -`kubectl create` command and pass a pod specification as a JSON- or -YAML-formatted configuration file. - -```shell -$ kubectl create -f FILE -``` - -Where: - -* `-f FILE` or `--filename FILE` is the name of a - [pod configuration file](#pod-configuration-file) in either JSON or YAML - format. - -A successful create request returns the pod name. Use the -[`kubectl get`](#viewing_a_pod) command to view status after creation. - -### Pod configuration file - -A pod configuration file specifies required information about the pod. -It can be formatted as YAML or as JSON, and supports the following fields: - -{% capture tabspec %}configfiles -JSON,json,pod-config.json,/docs/user-guide/pods/pod-config.json -YAML,yaml,pod-config.yaml,/docs/user-guide/pods/pod-config.yaml{% endcapture %} -{% include tabs.html %} - -Required fields are: - -* `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. - * `labels`: Optional. Labels are arbitrary key:value pairs that can be used - by - [Deployment](/docs/user-guide/deployments/) - and [services](/docs/user-guide/services/) for grouping and targeting - pods. - * `generateName`: Required if `name` is not set. A prefix to use to generate - a unique name. Has the same validation rules as `name`. - * `namespace`: Required. The namespace of the pod. - * `annotations`: Optional. A map of string keys and values that can be used - by external tooling to store and retrieve arbitrary metadata about - objects. -* `spec`: The pod specification. See [The `spec` schema](#the_spec_schema) for - details. - - -### The `spec` schema - -A full description of the `spec` schema is contained in the -[Kubernetes API reference](/docs/api-reference/v1/definitions/#_v1_podspec). - -The following fields are required or commonly used in the `spec` schema: - -{% capture tabspec %}specfiles -JSON,json,pod-spec-common.json,/docs/user-guide/pods/pod-spec-common.json -YAML,yaml,pod-spec-common.yaml,/docs/user-guide/pods/pod-spec-common.yaml{% endcapture %} -{% include tabs.html %} - -#### `containers[]` - -A list of containers belonging to the pod. Containers cannot be added or removed once the pod is created, and there must be at least one container in a pod. - -The `containers` object **must contain**: - -* `name`: Name of the container. It must be a DNS_LABEL and be unique within the pod. Cannot be updated. -* `image`: Docker image name. - -The `containers` object **commonly contains** the following optional properties: - -* `command[]`: The entrypoint array. Commands are not executed within a shell. The docker image's entrypoint is used if this is not provided. Cannot be updated. -* `args[]`: A command array containing arguments to the entrypoint. The docker image's `cmd` is used if this is not provided. Cannot be updated. -* `env[]`: A list of environment variables in key:value format to set in the container. Cannot be updated. - * `name`: The name of the environment variable; must be a `C_IDENTIFIER`. - * `value`: The value of the environment variable. Defaults to empty string. -* `imagePullPolicy`: The image pull policy. Accepted values are: - * `Always` - * `Never` - * `IfNotPresent`Defaults to `Always` if `:latest` tag is specified, or `IfNotPresent` otherwise. Cannot be updated. -* `ports[]`: A list of ports to expose from the container. Cannot be updated. - * `containerPort`: The port number to expose on the pod's IP address. - * `name`: The name for the port that can be referred to by services. Must be a `DNS_LABEL` and be unique without the pod. - * `protocol`: Protocol for the port. Must be UDP or TCP. Default is TCP. -* `resources`: The Compute resources required by this container. Contains: - * `cpu`: CPUs to reserve for each container. Default is whole CPUs; scale suffixes (e.g. `100m` for one hundred milli-CPUs) are supported. If the host does not have enough available resources, your pod will not be scheduled. - * `memory`: Memory to reserve for each container. Default is bytes; [binary scale suffixes](http://en.wikipedia.org/wiki/Binary_prefix) (e.g. `100Mi` for one hundred mebibytes) are supported. If the host does not have enough available resources, your pod will not be scheduled.Cannot be updated. - -#### `restartPolicy` - -Restart policy for all containers within the pod. Options are: - -* `Always` -* `OnFailure` -* `Never` - -#### `volumes[]` - -A list of volumes that can be mounted by containers belonging to the pod. You must specify a `name` and a source for each volume. The container must also include a `volumeMount` with matching `name`. Source is one of: - -* `emptyDir`: A temporary directory that shares a pod's lifetime. Contains: - * `medium`: The type of storage used to back the volume. Must be an empty string (default) or `Memory`. -* `hostPath`: A pre-existing host file or directory. This is generally used for privileged system daemons or other agents tied to the host. Contains: - * `path`: The path of the directory on the host. -* `secret`: Secret to populate volume. Secrets are used to hold sensitive information, such as passwords, OAuth tokens, and SSH keys. Learn more from [the docs on secrets](/docs/user-guide/secrets/). Contains: - * `secretName`: The name of a secret in the pod's namespace. - -The `name` must be a DNS_LABEL and unique within the pod. - - -### Sample file - -For example, the following configuration file creates two containers: a -`redis` key-value store image, and a `django` frontend image. - -{% capture tabspec %}samplefiles -JSON,json,pod-sample.json,/docs/user-guide/pods/pod-sample.json -YAML,yaml,pod-sample.yaml,/docs/user-guide/pods/pod-sample.yaml{% endcapture %} -{% include tabs.html %} - -## Viewing a pod - -{% include_relative _viewing-a-pod.md %} - -## Deleting a pod - -If you created your pod directly with `kubectl create`, use `kubectl delete`: - -```shell -$ kubectl delete pod NAME -``` - -A successful delete request returns the name of the deleted pod. +[Communicating Between Containers Running in the Same Pod](/docs/tasks/configure-pod-container/communicate-containers-same-pod/) diff --git a/docs/user-guide/pods/single-container.md b/docs/user-guide/pods/single-container.md deleted file mode 100644 index fd7a44ba66..0000000000 --- a/docs/user-guide/pods/single-container.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Creating Single-Container Pods ---- - -{% include user-guide-content-moved.md %} - -[Running a Stateless Application Using a Deployment](/docs/tutorials/stateless-application/run-stateless-application-deployment/) diff --git a/docs/user-guide/production-pods.md b/docs/user-guide/production-pods.md deleted file mode 100644 index 5ea3a0edd5..0000000000 --- a/docs/user-guide/production-pods.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Working with Containers in Production ---- - -{% include user-guide-content-moved.md %} - -* [Configuring a Pod to Use a Volume for Storage](/docs/tasks/configure-pod-container/configure-volume-storage/) - -* [Distributing Credentials Securely](/docs/tasks/configure-pod-container/distribute-credentials-secure/) - -* [Pulling an Image from a Private Registry](/docs/tasks/configure-pod-container/pull-image-private-registry/) - -* [Communicating Between Containers Running in the Same Pod](/docs/tasks/configure-pod-container/communicate-containers-same-pod/) - -* [Assigning CPU and RAM Resources to a Container](/docs/tasks/configure-pod-container/assign-cpu-ram-container/) - -* [Configuring Liveness and Readiness Probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) - -* [Configuring Pod Initialization](/docs/tasks/configure-pod-container/configure-pod-initialization/) - -* [Attaching Handlers to Container Lifecycle Events](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/) - -* [Determining the Reason for Pod Failure](/docs/tasks/debug-application-cluster/determine-reason-pod-failure/) diff --git a/docs/user-guide/quick-start.md b/docs/user-guide/quick-start.md deleted file mode 100644 index 6cef04810d..0000000000 --- a/docs/user-guide/quick-start.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -assignees: -- bgrant0607 -- janetkuo -title: Launching, Exposing, and Killing Applications ---- - -This guide will help you get oriented to Kubernetes and running your first containers on the cluster. If you are already familiar with the docker-cli, you can also checkout the docker-cli to kubectl migration guide [here](/docs/user-guide/docker-cli-to-kubectl). - -* TOC -{:toc} - -## Launching a simple application, and exposing it to the Internet - -Once your application is packaged into a container and pushed to an image registry, you're ready to deploy it to Kubernetes. -Through integration with some cloud providers (for example Google Compute Engine, AWS EC2, and Azure ACS), Kubernetes also enables you to request it to provision a public IP address for your application. - -For example, [nginx](http://wiki.nginx.org/Main) is a popular HTTP server, with a [pre-built container on Docker hub](https://registry.hub.docker.com/_/nginx/). The [`kubectl run`](/docs/user-guide/kubectl/kubectl_run) commands below will create two nginx replicas, listening on port 80, and a public IP address for your application. - -```shell -$ kubectl run my-nginx --image=nginx --replicas=2 --port=80 -deployment "my-nginx" created -``` - -To expose your service to the public Internet, run: - -```shell -$ kubectl expose deployment my-nginx --target-port=80 --type=LoadBalancer -service "my-nginx" exposed -``` -Note: The type, LoadBalancer, is highly dependent upon the underlying platform that Kubernetes is running on. If your cloud provider doesn't have a load balancer implementation (e.g. OpenStack) for Kubernetes, you can simply use the allocated [NodePort](http://kubernetes.io/docs/user-guide/services/#type-nodeport) as a rudimentary form of load balancing across your endpoints. - -You can see that they are running by: - -```shell -$ kubectl get po -NAME READY STATUS RESTARTS AGE -my-nginx-3800858182-h9v8d 1/1 Running 0 1m -my-nginx-3800858182-wqafx 1/1 Running 0 1m -``` - -Kubernetes will ensure that your application keeps running, by automatically restarting containers that fail, spreading containers across nodes, and recreating containers on new nodes when nodes fail. - -To find the public IP address assigned to your application, execute: - -```shell -$ kubectl get service my-nginx -NAME CLUSTER_IP EXTERNAL_IP PORT(S) AGE -my-nginx 10.179.240.1 25.1.2.3 80/TCP 8s -``` - -You may need to wait for a minute or two for the external IP address to be provisioned. - -In order to access your nginx landing page, you also have to make sure that traffic from external IPs is allowed. Do this by opening a [firewall to allow traffic on port 80](/docs/user-guide/services-firewalls). - -If you're running on AWS, Kubernetes creates an ELB for you. ELBs use host -names, not IPs, so you will have to do `kubectl describe service/my-nginx` and look -for the `LoadBalancer Ingress` host name. Traffic from external IPs is allowed -automatically. - -## Killing the application - -To kill the application and delete its containers and public IP address, do: - -```shell -$ kubectl delete deployment,service my-nginx -deployment "my-nginx" deleted -service "my-nginx" deleted -``` - -## What's next? - -* [Learn about how to configure common container parameters, such as commands and environment variables.](/docs/user-guide/configuring-containers) diff --git a/docs/user-guide/replicasets.md b/docs/user-guide/replicasets.md index ea3e7bde14..2b6a767be2 100644 --- a/docs/user-guide/replicasets.md +++ b/docs/user-guide/replicasets.md @@ -94,7 +94,7 @@ of the replicated pods. kubectl create -f hpa-rs.yaml ``` -Alternatively, you can just use the `kubectl autoscale` command to acomplish the same +Alternatively, you can just use the `kubectl autoscale` command to accomplish the same (and it's easier!) ```shell diff --git a/docs/user-guide/replication-controller/index.md b/docs/user-guide/replication-controller/index.md index 0fee281cdb..824ab21841 100644 --- a/docs/user-guide/replication-controller/index.md +++ b/docs/user-guide/replication-controller/index.md @@ -194,7 +194,7 @@ Ideally, the rolling update controller would take application readiness into acc The two ReplicationControllers would need to create pods with at least one differentiating label, such as the image tag of the primary container of the pod, since it is typically image updates that motivate rolling updates. Rolling update is implemented in the client tool -[`kubectl rolling-update`](/docs/user-guide/kubectl/kubectl_rolling-update). Visit [`kubectl rolling-update` tutorial](/docs/user-guide/rolling-updates/) for more concrete examples. +[`kubectl rolling-update`](/docs/user-guide/kubectl/kubectl_rolling-update). Visit [`kubectl rolling-update` task](/docs/tasks/run-application/rolling-update-replication-controller/) for more concrete examples. ### Multiple release tracks @@ -261,4 +261,4 @@ safe to terminate when the machine is otherwise ready to be rebooted/shutdown. ## For more information -Read [ReplicationController Operations](/docs/user-guide/replication-controller/operations/). +Read [Run Stateless AP Replication Controller](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/). diff --git a/docs/user-guide/replication-controller/operations.md b/docs/user-guide/replication-controller/operations.md index b3bd6115cc..d3d4697400 100644 --- a/docs/user-guide/replication-controller/operations.md +++ b/docs/user-guide/replication-controller/operations.md @@ -1,230 +1,6 @@ --- -assignees: -- bprashanth title: Replication Controller Operations --- -* TOC -{:toc} - -A replication controller ensures that a specified number of pod "replicas" are -running at any one time. If there are too many, it will kill some. If there are -too few, it will start more. - -## Creating a replication controller - -Replication controllers are created with `kubectl create`: - -```shell -$ kubectl create -f FILE -``` - -Where: - -* `-f FILE` or `--filename FILE` is a relative path to a - [configuration file](#replication_controller_configuration_file) in - either JSON or YAML format. - -You can use the [sample file](#sample_file) below to try a create request. - -A successful create request returns the name of the replication controller. To -view more details about the controller, see -[Viewing replication controllers](#viewing_replication_controllers) below. - -### Replication controller configuration file - -When creating a replication controller, you must point to a configuration file -as the value of the `-f` flag. The configuration -file can be formatted as YAML or as JSON, and supports the following fields: - -```json -{ - "apiVersion": "v1", - "kind": "ReplicationController", - "metadata": { - "name": "", - "labels": "", - "namespace": "" - }, - "spec": { - "replicas": int, - "selector": { - "":"" - }, - "template": { - "metadata": { - "labels": { - "":"" - } - }, - "spec": { - // See 'The spec schema' below - } - } - } -} -``` - -Required fields are: - -* `kind`: Always `ReplicationController`. -* `apiVersion`: Currently `v1`. -* `metadata`: An object containing: - * `name`: Required if `generateName` is not specified. The name of this - replication controller. It must be an - [RFC1035](https://www.ietf.org/rfc/rfc1035.txt) compatible value and be - unique within the namespace. - * `labels`: Optional. Labels are arbitrary key:value pairs that can be used - for grouping and targeting by other resources and services. - * `generateName`: Required if `name` is not set. A prefix to use to generate - a unique name. Has the same validation rules as `name`. - * `namespace`: Optional. The namespace of the replication controller. - * `annotations`: Optional. A map of string keys and values that can be used - by external tooling to store and retrieve arbitrary metadata about - objects. -* `spec`: The configuration for this replication controller. It must - contain: - * `replicas`: The number of pods to create and maintain. - * `selector`: A map of key:value pairs assigned to the set of pods that - this replication controller is responsible for managing. **This must** - **match the key:value pairs in the `template`'s `labels` field**. - * `template` contains: - * A `metadata` object with `labels` for the pod. - * The [`spec` schema](#the_spec_schema) that defines the pod - configuration. - -### The `spec` schema - -The `spec` schema (that is a child of `template`) is described in the locations -below: - -* The [`spec` schema](/docs/user-guide/pods/multi-container/#the_spec_schema) - section of the Creating Multi-Container Pods page covers required and - frequently-used fields. -* The entire `spec` schema is documented in the - [Kubernetes API reference](/docs/api-reference/v1/definitions/#_v1_podspec). - -### Sample file - -The following sample file creates 2 pods, each containing a single container -using the `redis` image. Port 80 on each container is opened. The replication -controller is tagged with the `serving` label. The pods are given the label -`frontend` and the `selector` is set to `frontend`, to indicate that the -controller should manage pods with the `frontend` label. - -```json -{ - "kind": "ReplicationController", - "apiVersion": "v1", - "metadata": { - "name": "frontend-controller", - "labels": { - "state": "serving" - } - }, - "spec": { - "replicas": 2, - "selector": { - "app": "frontend" - }, - "template": { - "metadata": { - "labels": { - "app": "frontend" - } - }, - "spec": { - "volumes": null, - "containers": [ - { - "name": "php-redis", - "image": "redis", - "ports": [ - { - "containerPort": 80, - "protocol": "TCP" - } - ], - "imagePullPolicy": "IfNotPresent" - } - ], - "restartPolicy": "Always", - "dnsPolicy": "ClusterFirst" - } - } - } -} -``` - -## Updating replication controller pods - -See [Rolling Updates](/docs/user-guide/rolling-updates/). - -## Resizing a replication controller - -See -[Resizing a replication controller](/docs/user-guide/resizing-a-replication-controller/). - -## Viewing replication controllers - -To list replication controllers on a cluster, use the `kubectl get` command: - -```shell -$ kubectl get rc -``` - -A successful get command returns all replication controllers on the cluster in -the specified or default namespace. For example: - -```shell -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -frontend php-redis redis name=frontend 2 -``` - -You can also use `get rc NAME` to return information about a specific -replication controller. - -To view detailed information about a specific replication controller, use the -`kubectl describe` command: - -```shell -$ kubectl describe rc NAME -``` - -A successful describe request returns details about the replication controller -including number and status of pods managed, and recent events: - -```conf -Name: frontend -Namespace: default -Image(s): gcr.io/google_samples/gb-frontend:v3 -Selector: name=frontend -Labels: name=frontend -Replicas: 2 current / 2 desired -Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Fri, 06 Nov 2015 16:52:50 -0800 Fri, 06 Nov 2015 16:52:50 -0800 1 {replication-controller } SuccessfulCreate Created pod: frontend-gyx2h - Fri, 06 Nov 2015 16:52:50 -0800 Fri, 06 Nov 2015 16:52:50 -0800 1 {replication-controller } SuccessfulCreate Created pod: frontend-vc9w4 -``` - -## Deleting replication controllers - -To delete a replication controller as well as the pods that it controls, use -`kubectl delete`: - -```shell -$ kubectl delete rc NAME -``` - -By default, `kubectl delete rc` will resize the controller to zero (effectively -deleting all pods) before deleting it. - -To delete a replication controller without deleting its pods, use -`kubectl delete` and specify `--cascade=false`: - -```shell -$ kubectl delete rc NAME --cascade=false -``` - -A successful delete request returns the name of the deleted resource. +{% include user-guide-content-moved.md %} +[Run Stateless AP Replication Controller](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/) diff --git a/docs/user-guide/resizing-a-replication-controller.md b/docs/user-guide/resizing-a-replication-controller.md index c60ce8e60b..156841d586 100644 --- a/docs/user-guide/resizing-a-replication-controller.md +++ b/docs/user-guide/resizing-a-replication-controller.md @@ -4,33 +4,5 @@ assignees: title: Resizing a Replication Controller --- -To increase or decrease the number of pods under a replication controller's -control, use the `kubectl scale` command: - - $ kubectl scale rc NAME --replicas=COUNT \ - [--current-replicas=COUNT] \ - [--resource-version=VERSION] - -Tip: You can use the `rc` alias in your commands in place of -`replicationcontroller`. - -Required fields are: - -* `NAME`: The name of the replication controller to update. -* `--replicas=COUNT`: The desired number of replicas. - -Optional fields are: - -* `--current-replicas=COUNT`: A precondition for current size. If specified, - the resize will only take place if the current number of replicas matches - this value. -* `--resource-version=VERSION`: A precondition for resource version. If - specified, the resize will only take place if the current replication - controller version matches this value. Versions are specified in the - `labels` field of the replication controller's configuration file, as a - key:value pair with a key of `version`. For example, - `--resource-version test` matches: - - "labels": { - "version": "test" - } +{% include user-guide-content-moved.md %} +[Run Stateless AP Replication Controller](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/#resizing-a-replication-controller) diff --git a/docs/user-guide/rolling-updates.md b/docs/user-guide/rolling-updates.md index 6bd3c469c8..996f613c9f 100644 --- a/docs/user-guide/rolling-updates.md +++ b/docs/user-guide/rolling-updates.md @@ -1,256 +1,6 @@ --- -assignees: -- janetkuo title: Rolling Updates --- -* TOC -{:toc} - -## Overview - -To update a service without an outage, `kubectl` supports what is called ['rolling update'](/docs/user-guide/kubectl/kubectl_rolling-update), which updates one pod at a time, rather than taking down the entire service at the same time. See the [rolling update design document](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/simple-rolling-update.md) and the [example of rolling update](/docs/user-guide/update-demo/) for more information. - -Note that `kubectl rolling-update` only supports Replication Controllers. However, if you deploy applications with Replication Controllers, -consider switching them to [Deployments](/docs/user-guide/deployments/). A Deployment is a higher-level controller that automates rolling updates -of applications declaratively, and therefore is recommended. If you still want to keep your Replication Controllers and use `kubectl rolling-update`, keep reading: - -A rolling update applies changes to the configuration of pods being managed by -a replication controller. The changes can be passed as a new replication -controller configuration file; or, if only updating the image, a new container -image can be specified directly. - -A rolling update works by: - -1. Creating a new replication controller with the updated configuration. -2. Increasing/decreasing the replica count on the new and old controllers until - the correct number of replicas is reached. -3. Deleting the original replication controller. - -Rolling updates are initiated with the `kubectl rolling-update` command: - - $ kubectl rolling-update NAME \ - ([NEW_NAME] --image=IMAGE | -f FILE) - -## Passing a configuration file - -To initiate a rolling update using a configuration file, pass the new file to -`kubectl rolling-update`: - - $ kubectl rolling-update NAME -f FILE - -The configuration file must: - -* Specify a different `metadata.name` value. - -* Overwrite at least one common label in its `spec.selector` field. - -* Use the same `metadata.namespace`. - -Replication controller configuration files are described in -[Creating Replication Controllers](/docs/user-guide/replication-controller/operations/). - -### Examples - - // Update pods of frontend-v1 using new replication controller data in frontend-v2.json. - $ kubectl rolling-update frontend-v1 -f frontend-v2.json - - // Update pods of frontend-v1 using JSON data passed into stdin. - $ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f - - -## Updating the container image - -To update only the container image, pass a new image name and tag with the -`--image` flag and (optionally) a new controller name: - - $ kubectl rolling-update NAME [NEW_NAME] --image=IMAGE:TAG - -The `--image` flag is only supported for single-container pods. Specifying -`--image` with multi-container pods returns an error. - -If no `NEW_NAME` is specified, a new replication controller is created with -a temporary name. Once the rollout is complete, the old controller is deleted, -and the new controller is updated to use the original name. - -The update will fail if `IMAGE:TAG` is identical to the -current value. For this reason, we recommend the use of versioned tags as -opposed to values such as `:latest`. Doing a rolling update from `image:latest` -to a new `image:latest` will fail, even if the image at that tag has changed. -Moreover, the use of `:latest` is not recommended, see -[Best Practices for Configuration](/docs/user-guide/config-best-practices/#container-images) for more information. - -### Examples - - // Update the pods of frontend-v1 to frontend-v2 - $ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 - - // Update the pods of frontend, keeping the replication controller name - $ kubectl rolling-update frontend --image=image:v2 - -## Required and optional fields - -Required fields are: - -* `NAME`: The name of the replication controller to update. - -as well as either: - -* `-f FILE`: A replication controller configuration file, in either JSON or - YAML format. The configuration file must specify a new top-level `id` value - and include at least one of the existing `spec.selector` key:value pairs. - See the - [Replication Controller Operations](/docs/user-guide/replication-controller/operations#replication-controller-configuration-file) - page for details. -
      -
      - or: -
      -
      -* `--image IMAGE:TAG`: The name and tag of the image to update to. Must be - different than the current image:tag currently specified. - -Optional fields are: - -* `NEW_NAME`: Only used in conjunction with `--image` (not with `-f FILE`). The - name to assign to the new replication controller. -* `--poll-interval DURATION`: The time between polling the controller status - after update. Valid units are `ns` (nanoseconds), `us` or `µs` (microseconds), - `ms` (milliseconds), `s` (seconds), `m` (minutes), or `h` (hours). Units can - be combined (e.g. `1m30s`). The default is `3s`. -* `--timeout DURATION`: The maximum time to wait for the controller to update a - pod before exiting. Default is `5m0s`. Valid units are as described for - `--poll-interval` above. -* `--update-period DURATION`: The time to wait between updating pods. Default - is `1m0s`. Valid units are as described for `--poll-interval` above. - -Additional information about the `kubectl rolling-update` command is available -from the [`kubectl` reference](/docs/user-guide/kubectl/kubectl_rolling-update/). - -## Walkthrough - -Let's say you were running version 1.7.9 of nginx: - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx -spec: - replicas: 5 - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.7.9 - ports: - - containerPort: 80 -``` - -To update to version 1.9.1, you can use [`kubectl rolling-update --image`](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/simple-rolling-update.md) to specify the new image: - -```shell -$ kubectl rolling-update my-nginx --image=nginx:1.9.1 -Created my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 -``` - -In another window, you can see that `kubectl` added a `deployment` label to the pods, whose value is a hash of the configuration, to distinguish the new pods from the old: - -```shell -$ kubectl get pods -l app=nginx -L deployment -NAME READY STATUS RESTARTS AGE DEPLOYMENT -my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-k156z 1/1 Running 0 1m ccba8fbd8cc8160970f63f9a2696fc46 -my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-v95yh 1/1 Running 0 35s ccba8fbd8cc8160970f63f9a2696fc46 -my-nginx-divi2 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e -my-nginx-o0ef1 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e -my-nginx-q6all 1/1 Running 0 8m 2d1d7a8f682934a254002b56404b813e -``` - -`kubectl rolling-update` reports progress as it progresses: - -``` -Scaling up my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 0 to 3, scaling down my-nginx from 3 to 0 (keep 3 pods available, don't exceed 4 pods) -Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 1 -Scaling my-nginx down to 2 -Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 2 -Scaling my-nginx down to 1 -Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 3 -Scaling my-nginx down to 0 -Update succeeded. Deleting old controller: my-nginx -Renaming my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 to my-nginx -replicationcontroller "my-nginx" rolling updated -``` - -If you encounter a problem, you can stop the rolling update midway and revert to the previous version using `--rollback`: - -```shell -$ kubectl rolling-update my-nginx --rollback -Setting "my-nginx" replicas to 1 -Continuing update with existing controller my-nginx. -Scaling up nginx from 1 to 1, scaling down my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 1 to 0 (keep 1 pods available, don't exceed 2 pods) -Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 down to 0 -Update succeeded. Deleting my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 -replicationcontroller "my-nginx" rolling updated -``` - -This is one example where the immutability of containers is a huge asset. - -If you need to update more than just the image (e.g., command arguments, environment variables), you can create a new replication controller, with a new name and distinguishing label value, such as: - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx-v4 -spec: - replicas: 5 - selector: - app: nginx - deployment: v4 - template: - metadata: - labels: - app: nginx - deployment: v4 - spec: - containers: - - name: nginx - image: nginx:1.9.2 - args: ["nginx", "-T"] - ports: - - containerPort: 80 -``` - -and roll it out: - -```shell -$ kubectl rolling-update my-nginx -f ./nginx-rc.yaml -Created my-nginx-v4 -Scaling up my-nginx-v4 from 0 to 5, scaling down my-nginx from 4 to 0 (keep 4 pods available, don't exceed 5 pods) -Scaling my-nginx-v4 up to 1 -Scaling my-nginx down to 3 -Scaling my-nginx-v4 up to 2 -Scaling my-nginx down to 2 -Scaling my-nginx-v4 up to 3 -Scaling my-nginx down to 1 -Scaling my-nginx-v4 up to 4 -Scaling my-nginx down to 0 -Scaling my-nginx-v4 up to 5 -Update succeeded. Deleting old controller: my-nginx -replicationcontroller "my-nginx-v4" rolling updated -``` - -You can also run the [update demo](/docs/user-guide/update-demo/) to see a visual representation of the rolling update process. - -## Troubleshooting - -If the `timeout` duration is reached during a rolling update, the operation will -fail with some pods belonging to the new replication controller, and some to the -original controller. - -To continue the update from where it failed, retry using the same command. - -To roll back to the original state before the attempted update, append the -`--rollback=true` flag to the original command. This will revert all changes. +{% include user-guide-content-moved.md %} +[Rolling Update Replication Controller](/docs/tasks/run-application/rolling-update-replication-controller/) diff --git a/docs/user-guide/secrets/index.md b/docs/user-guide/secrets/index.md index 9723e00aee..8b7c7ae2fb 100644 --- a/docs/user-guide/secrets/index.md +++ b/docs/user-guide/secrets/index.md @@ -375,41 +375,6 @@ However, it is using its local ttl-based cache for getting the current value of As a result, the total delay from the moment when the secret is updated to the moment when new keys are projected to the pod can be as long as kubelet sync period + ttl of secrets cache in kubelet. -#### Optional Secrets as Files from a Pod - -Volumes and files provided by a Secret can be also be marked as optional. -The Secret or the key within a Secret does not have to exist. The mount path for -such items will always be created. - -```json -{ - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "mypod", - "namespace": "myns" - }, - "spec": { - "containers": [{ - "name": "mypod", - "image": "redis", - "volumeMounts": [{ - "name": "foo", - "mountPath": "/etc/foo" - }] - }], - "volumes": [{ - "name": "foo", - "secret": { - "secretName": "mysecret", - "defaultMode": 256, - "optional": true - } - }] - } -} -``` - #### Using Secrets as Environment Variables To use a secret in an environment variable in a pod: @@ -456,30 +421,6 @@ $ echo $SECRET_PASSWORD 1f2d1e2e67df ``` -#### Optional Secrets from Environment Variables - -You may not want to require all your secrets to exist. They can be marked as -optional as shown in the pod: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: optional-secret-env-pod -spec: - containers: - - name: mycontainer - image: redis - env: - - name: OPTIONAL_SECRET - valueFrom: - secretKeyRef: - name: mysecret - key: username - optional: true - restartPolicy: Never -``` - #### Using imagePullSecrets An imagePullSecret is a way to pass a secret that contains a Docker (or other) image registry @@ -511,8 +452,7 @@ can be automatically attached to pods based on their service account. Secret volume sources are validated to ensure that the specified object reference actually points to an object of type `Secret`. Therefore, a secret -needs to be created before any pods that depend on it, unless it is marked as -optional. +needs to be created before any pods that depend on it. Secret API objects reside in a namespace. They can only be referenced by pods in that same namespace. @@ -532,12 +472,12 @@ not common ways to create pods.) When a pod is created via the API, there is no check whether a referenced secret exists. Once a pod is scheduled, the kubelet will try to fetch the -secret value. If a required secret cannot be fetched because it does not -exist or because of a temporary lack of connection to the API server, the -kubelet will periodically retry. It will report an event about the pod -explaining the reason it is not started yet. Once the secret is fetched, the -kubelet will create and mount a volume containing it. None of the pod's -containers will start until all the pod's volumes are mounted. +secret value. If the secret cannot be fetched because it does not exist or +because of a temporary lack of connection to the API server, kubelet will +periodically retry. It will report an event about the pod explaining the +reason it is not started yet. Once the secret is fetched, the kubelet will +create and mount a volume containing it. None of the pod's containers will +start until all the pod's volumes are mounted. ## Use cases @@ -594,8 +534,8 @@ consumes it in a volume: When the container's command runs, the pieces of the key will be available in: ```shell -/etc/secret-volume/id-rsa.pub -/etc/secret-volume/id-rsa +/etc/secret-volume/ssh-publickey +/etc/secret-volume/ssh-privatekey ``` The container is then free to use the secret data to establish an ssh connection. diff --git a/docs/user-guide/secrets/walkthrough.md b/docs/user-guide/secrets/walkthrough.md deleted file mode 100644 index 11ca7672df..0000000000 --- a/docs/user-guide/secrets/walkthrough.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -assignees: -title: Secrets Walkthrough ---- - -Following this example, you will create a secret and a [pod](/docs/user-guide/pods/) that consumes that secret in a [volume](/docs/user-guide/volumes/). See [Secrets design document](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/secrets.md) for more information. - -## Step Zero: Prerequisites - -This example assumes you have a Kubernetes cluster installed and running, and that you have -installed the `kubectl` command line tool somewhere in your path. Please see the [getting -started](/docs/getting-started-guides/) for installation instructions for your platform. - -## Step One: Create the secret - -A secret contains a set of named byte arrays. - -Use the [`secret.yaml`](/docs/user-guide/secrets/secret.yaml) file to create a secret: - -```shell -$ kubectl create -f docs/user-guide/secrets/secret.yaml -``` - -You can use `kubectl` to see information about the secret: - -```shell -$ kubectl get secrets -NAME TYPE DATA -test-secret Opaque 2 - -$ kubectl describe secret test-secret -Name: test-secret -Labels: -Annotations: - -Type: Opaque - -Data -==== -data-1: 9 bytes -data-2: 11 bytes -``` - -## Step Two: Create a pod that consumes a secret - -Pods consume secrets in volumes. Now that you have created a secret, you can create a pod that -consumes it. - -Use the [`secret-pod.yaml`](/docs/user-guide/secrets/secret-pod.yaml) file to create a Pod that consumes the secret. - -```shell -$ kubectl create -f docs/user-guide/secrets/secret-pod.yaml -``` - -This pod runs a binary that displays the content of one of the pieces of secret data in the secret -volume: - -```shell -$ kubectl logs secret-test-pod -2015-04-29T21:17:24.712206409Z content of file "/etc/secret-volume/data-1": value-1 -``` \ No newline at end of file diff --git a/docs/user-guide/service-accounts.md b/docs/user-guide/service-accounts.md index d1129a1983..ad1c0a68bf 100644 --- a/docs/user-guide/service-accounts.md +++ b/docs/user-guide/service-accounts.md @@ -147,8 +147,18 @@ NAME TYPE DATA myregistrykey kubernetes.io/.dockerconfigjson 1 ``` -Next, read/modify/write the service account for the namespace to use this secret as an imagePullSecret +Next, read/modify/write the service account for the namespace to use this secret as an imagePullSecret. +Automated version using json and the jq utility: +```shell +kubectl get serviceaccounts default -o json | + jq 'del(.metadata.resourceVersion)'| + jq 'setpath(["imagePullSecrets"];[{"name":"myregistrykey"}])' | + kubectl replace serviceaccount default -f - + +``` + +Interactive version requiring manual edit: ```shell $ kubectl get serviceaccounts default -o yaml > ./sa.yaml $ cat sa.yaml diff --git a/docs/user-guide/simple-nginx.md b/docs/user-guide/simple-nginx.md deleted file mode 100644 index 2a6b11133f..0000000000 --- a/docs/user-guide/simple-nginx.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Running Your First Containers ---- - -{% include user-guide-content-moved.md %} - -[Running a Stateless Application Using a Deployment](/docs/tutorials/stateless-application/run-stateless-application-deployment/) diff --git a/docs/user-guide/ui.md b/docs/user-guide/ui.md index da2b2e611c..cb330f1f9b 100644 --- a/docs/user-guide/ui.md +++ b/docs/user-guide/ui.md @@ -97,7 +97,8 @@ track=stable - **Namespace**: Kubernetes supports multiple virtual clusters backed by the same physical cluster. These virtual clusters are called [namespaces](/docs/admin/namespaces/). They let you partition resources into logically named groups. - Dashboard offers all available namespaces in a dropdown list, and allows you to create a new namespace. The namespace name may contain a maximum of 63 alphanumeric characters and dashes (-). + Dashboard offers all available namespaces in a dropdown list, and allows you to create a new namespace. The namespace name may contain a maximum of 63 alphanumeric characters and dashes (-) but can not contain capital letters. + Namespace names should not consist of only numbers. If the name is set as a number, such as 10, the pod will be put in the default namespace. In case the creation of the namespace is successful, it is selected by default. If the creation fails, the first namespace is selected. @@ -147,7 +148,7 @@ Detail views for workloads show status and specification information and surface ![Deployment detail view](/images/docs/ui-dashboard-deployment-detail.png) #### Services and discovery -Services and discovery view shows Kubernetes resources that allow for exposing services to external world and discovering them within a cluster. For that reason, Service and Ingress views show Pods targeted by them, internal endpoints for cluster connections and endpoints for external users. +Services and discovery view shows Kubernetes resources that allow for exposing services to external world and discovering them within a cluster. For that reason, Service and Ingress views show Pods targeted by them, internal endpoints for cluster connections and external endpoints for external users. ![Service list partial view](/images/docs/ui-dashboard-service-list.png) diff --git a/docs/user-guide/update-demo/index.md b/docs/user-guide/update-demo/index.md index f2e3f8a0f2..610c884f24 100644 --- a/docs/user-guide/update-demo/index.md +++ b/docs/user-guide/update-demo/index.md @@ -1,107 +1,6 @@ --- -assignees: -- mikedanese title: Rolling Update Demo --- -This example demonstrates the usage of Kubernetes to perform a [rolling update](/docs/user-guide/kubectl/kubectl_rolling-update/) on a running group of [pods](/docs/user-guide/pods/). See [here](/docs/user-guide/managing-deployments/#updating-your-application-without-a-service-outage) to understand why you need a rolling update. Also check [rolling update design document](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/simple-rolling-update.md) for more information. - -The files for this example are viewable in [our docs repo -here](https://github.com/kubernetes/kubernetes.github.io/tree/{{page.docsbranch}}/docs/user-guide/update-demo). - -### Step Zero: Prerequisites - -This example assumes that you have forked the docs repository and [turned up a Kubernetes cluster](/docs/getting-started-guides/): - -```shell -$ git clone -b {{page.docsbranch}} https://github.com/kubernetes/kubernetes.github.io -$ cd kubernetes.github.io -``` - -### Step One: Turn up the UX for the demo - -You can use bash job control to run this in the background (note that you must use the default port -- 8001 -- for the following demonstration to work properly). -This can sometimes spew to the output so you could also run it in a different terminal. You have to run `kubectl proxy` in the root of the -Kubernetes repository. Otherwise you will get "404 page not found" errors as the paths will not match. You can find more information about `kubectl proxy` -[here](/docs/user-guide/kubectl/kubectl_proxy). - -```shell -$ kubectl proxy --www=docs/user-guide/update-demo/local/ & -I0218 15:18:31.623279 67480 proxy.go:36] Starting to serve on localhost:8001 -``` - -Now visit the [demo website](http://localhost:8001/static). You won't see anything much quite yet. - -### Step Two: Run the replication controller - -Now we will turn up two replicas of an [image](/docs/user-guide/images/). They all serve on internal port 80. - -```shell -$ kubectl create -f docs/user-guide/update-demo/nautilus-rc.yaml -``` - -After pulling the image from the Docker Hub to your worker nodes (which may take a minute or so) you'll see a couple of squares in the UI detailing the pods that are running along with the image that they are serving up. A cute little nautilus. - -### Step Three: Try scaling the replication controller - -Now we will increase the number of replicas from two to four: - -```shell -$ kubectl scale rc update-demo-nautilus --replicas=4 -``` - -If you go back to the [demo website](http://localhost:8001/static/index.html) you should eventually see four boxes, one for each pod. - -### Step Four: Update the docker image - -We will now update the docker image to serve a different image by doing a rolling update to a new Docker image. - -```shell -$ kubectl rolling-update update-demo-nautilus --update-period=10s -f docs/user-guide/update-demo/kitten-rc.yaml -``` - -The rolling-update command in kubectl will do 2 things: - -1. Create a new [replication controller](/docs/user-guide/replication-controller/) with a pod template that uses the new image (`gcr.io/google_containers/update-demo:kitten`) -2. Scale the old and new replication controllers until the new controller replaces the old. This will kill the current pods one at a time, spinning up new ones to replace them. - -Watch the [demo website](http://localhost:8001/static/index.html), it will update one pod every 10 seconds until all of the pods have the new image. -Note that the new replication controller definition does not include the replica count, so the current replica count of the old replication controller is preserved. -But if the replica count had been specified, the final replica count of the new replication controller will be equal to this number. - -### Step Five: Bring down the pods - -```shell -$ kubectl delete rc update-demo-kitten -``` - -This first stops the replication controller by turning the target number of replicas to 0 and then deletes the controller. - -### Step Six: Cleanup - -After you are done running this demo make sure to kill the proxy running in the background: - -```shell -$ jobs -[1]+ Running ./kubectl proxy --www=local/ & -$ kill %1 -[1]+ Terminated: 15 ./kubectl proxy --www=local/ -``` - -### Updating the Docker images - -If you want to build your own docker images, you can set `$DOCKER_HUB_USER` to your Docker user id and run the included shell script. It can take a few minutes to download/upload stuff. - -```shell -$ export DOCKER_HUB_USER=my-docker-id -$ ./docs/user-guide/update-demo/build-images.sh -``` - -To use your custom docker image in the above examples, you will need to change the image name in `docs/user-guide/update-demo/nautilus-rc.yaml` and `docs/user-guide/update-demo/kitten-rc.yaml`. - -### Image Copyright - -Note that the images included here are public domain. - -* [kitten](http://commons.wikimedia.org/wiki/File:Kitten-stare.jpg) -* [nautilus](http://commons.wikimedia.org/wiki/File:Nautilus_pompilius.jpg) +{% include user-guide-content-moved.md %} +[Rolling Update Replication Controller](/docs/tasks/run-application/rolling-update-replication-controller/) diff --git a/docs/user-guide/update-demo/index.md.orig b/docs/user-guide/update-demo/index.md.orig new file mode 100644 index 0000000000..14bf74ee1f --- /dev/null +++ b/docs/user-guide/update-demo/index.md.orig @@ -0,0 +1,107 @@ +--- +assignees: +- mikedanese +title: Rolling Update Demo +--- + +This example demonstrates the usage of Kubernetes to perform a [rolling update](/docs/user-guide/kubectl/kubectl_rolling-update/) on a running group of [pods](/docs/user-guide/pods/). See [here](/docs/concepts/cluster-administration/manage-deployment/#updating-your-application-without-a-service-outage) to understand why you need a rolling update. Also check [rolling update design document](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/simple-rolling-update.md) for more information. + +The files for this example are viewable in [our docs repo +here](https://github.com/kubernetes/kubernetes.github.io/tree/{{page.docsbranch}}/docs/user-guide/update-demo). + +### Step Zero: Prerequisites + +This example assumes that you have forked the docs repository and [turned up a Kubernetes cluster](/docs/getting-started-guides/): + +```shell +$ git clone -b {{page.docsbranch}} https://github.com/kubernetes/kubernetes.github.io +$ cd kubernetes.github.io +``` + +### Step One: Turn up the UX for the demo + +You can use bash job control to run this in the background (note that you must use the default port -- 8001 -- for the following demonstration to work properly). +This can sometimes spew to the output so you could also run it in a different terminal. You have to run `kubectl proxy` in the root of the +Kubernetes repository. Otherwise you will get "404 page not found" errors as the paths will not match. You can find more information about `kubectl proxy` +[here](/docs/user-guide/kubectl/kubectl_proxy). + +```shell +$ kubectl proxy --www=docs/user-guide/update-demo/local/ & +I0218 15:18:31.623279 67480 proxy.go:36] Starting to serve on localhost:8001 +``` + +Now visit the [demo website](http://localhost:8001/static). You won't see anything much quite yet. + +### Step Two: Run the replication controller + +Now we will turn up two replicas of an [image](/docs/user-guide/images/). They all serve on internal port 80. + +```shell +$ kubectl create -f docs/user-guide/update-demo/nautilus-rc.yaml +``` + +After pulling the image from the Docker Hub to your worker nodes (which may take a minute or so) you'll see a couple of squares in the UI detailing the pods that are running along with the image that they are serving up. A cute little nautilus. + +### Step Three: Try scaling the replication controller + +Now we will increase the number of replicas from two to four: + +```shell +$ kubectl scale rc update-demo-nautilus --replicas=4 +``` + +If you go back to the [demo website](http://localhost:8001/static/index.html) you should eventually see four boxes, one for each pod. + +### Step Four: Update the docker image + +We will now update the docker image to serve a different image by doing a rolling update to a new Docker image. + +```shell +$ kubectl rolling-update update-demo-nautilus --update-period=10s -f docs/user-guide/update-demo/kitten-rc.yaml +``` + +The rolling-update command in kubectl will do 2 things: + +1. Create a new [replication controller](/docs/user-guide/replication-controller/) with a pod template that uses the new image (`gcr.io/google_containers/update-demo:kitten`) +2. Scale the old and new replication controllers until the new controller replaces the old. This will kill the current pods one at a time, spinning up new ones to replace them. + +Watch the [demo website](http://localhost:8001/static/index.html), it will update one pod every 10 seconds until all of the pods have the new image. +Note that the new replication controller definition does not include the replica count, so the current replica count of the old replication controller is preserved. +But if the replica count had been specified, the final replica count of the new replication controller will be equal to this number. + +### Step Five: Bring down the pods + +```shell +$ kubectl delete rc update-demo-kitten +``` + +This first stops the replication controller by turning the target number of replicas to 0 and then deletes the controller. + +### Step Six: Cleanup + +After you are done running this demo make sure to kill the proxy running in the background: + +```shell +$ jobs +[1]+ Running ./kubectl proxy --www=local/ & +$ kill %1 +[1]+ Terminated: 15 ./kubectl proxy --www=local/ +``` + +### Updating the Docker images + +If you want to build your own docker images, you can set `$DOCKER_HUB_USER` to your Docker user id and run the included shell script. It can take a few minutes to download/upload stuff. + +```shell +$ export DOCKER_HUB_USER=my-docker-id +$ ./docs/user-guide/update-demo/build-images.sh +``` + +To use your custom docker image in the above examples, you will need to change the image name in `docs/user-guide/update-demo/nautilus-rc.yaml` and `docs/user-guide/update-demo/kitten-rc.yaml`. + +### Image Copyright + +Note that the images included here are public domain. + +* [kitten](http://commons.wikimedia.org/wiki/File:Kitten-stare.jpg) +* [nautilus](http://commons.wikimedia.org/wiki/File:Nautilus_pompilius.jpg) diff --git a/docs/user-guide/walkthrough/index.md b/docs/user-guide/walkthrough/index.md index d7872b2260..e0400ec7ed 100644 --- a/docs/user-guide/walkthrough/index.md +++ b/docs/user-guide/walkthrough/index.md @@ -9,7 +9,7 @@ title: Kubernetes 101 For Kubernetes 101, we will cover kubectl, pods, volumes, and multiple containers -In order for the kubectl usage examples to work, make sure you have an examples directory locally, either from [a release](https://github.com/kubernetes/kubernetes/releases) or [the source](https://github.com/kubernetes/kubernetes). +In order for the kubectl usage examples to work, make sure you have an example directory locally, either from [a release](https://github.com/kubernetes/kubernetes/releases) or [the source](https://github.com/kubernetes/kubernetes). * TOC {:toc} diff --git a/docs/user-guide/working-with-resources.md b/docs/user-guide/working-with-resources.md index 07a9bd55b7..7b55db4e25 100644 --- a/docs/user-guide/working-with-resources.md +++ b/docs/user-guide/working-with-resources.md @@ -5,54 +5,6 @@ assignees: title: Using kubectl to Manage Resources --- -*This document is aimed at users who have worked through some of the examples, -and who want to learn more about using kubectl to manage resources such -as pods and services. Users who want to access the REST API directly, -and developers who want to extend the Kubernetes API should -refer to the [api conventions](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md) and -the [api document](/docs/api/).* +{% include user-guide-content-moved.md %} -## Resources are Automatically Modified - -When you create a resource such as pod, and then retrieve the created -resource, a number of the fields of the resource are added. -You can see this at work in the following example: - -```shell -$ cat > /tmp/original.yaml < /tmp/current.yaml -pods/original -$ wc -l /tmp/original.yaml /tmp/current.yaml - 51 /tmp/current.yaml - 9 /tmp/original.yaml - 60 total -``` - -The resource we posted had only 9 lines, but the one we got back had 51 lines. -If you `diff -u /tmp/original.yaml /tmp/current.yaml`, you can see the fields added to the pod. -The system adds fields in several ways: - - - Some fields are added synchronously with creation of the resource and some are set asynchronously. - - For example: `metadata.uid` is set synchronously. (Read more about [metadata](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#metadata)). - - For example, `status.hostIP` is set only after the pod has been scheduled. This often happens fast, but you may notice pods which do not have this set yet. This is called Late Initialization. (Read more about [status](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status) and [late initialization](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#late-initialization)). - - Some fields are set to default values. Some defaults vary by cluster and some are fixed for the API at a certain version. (Read more about [defaulting](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#defaulting)). - - For example, `spec.containers[0].imagePullPolicy` always defaults to `IfNotPresent` in api v1. - - For example, `spec.containers[0].resources.limits.cpu` may be defaulted to `100m` on some clusters, to some other value on others, and not defaulted at all on others. - -The API will generally not modify fields that you have set; it just sets ones which were unspecified. - -## Finding Documentation on Resource Fields - -You can browse auto-generated API documentation [here](/docs/api/). +[Kubernetes Object Management](/docs/concepts/tools/kubectl/object-management-overview/) diff --git a/docs/whatisk8s.md b/docs/whatisk8s.md index 8a9d5b04db..0b81cc80c5 100644 --- a/docs/whatisk8s.md +++ b/docs/whatisk8s.md @@ -5,113 +5,6 @@ assignees: title: What is Kubernetes? --- -Kubernetes is an [open-source platform for automating deployment, scaling, and operations of application containers](http://www.slideshare.net/BrianGrant11/wso2con-us-2015-kubernetes-a-platform-for-automating-deployment-scaling-and-operations) across clusters of hosts, providing container-centric infrastructure. +{% include user-guide-content-moved.md %} -With Kubernetes, you are able to quickly and efficiently respond to customer demand: - - - Deploy your applications quickly and predictably. - - Scale your applications on the fly. - - Seamlessly roll out new features. - - Optimize use of your hardware by using only the resources you need. - -Our goal is to foster an ecosystem of components and tools that relieve the burden of running applications in public and private clouds. - -#### Kubernetes is: - -* **portable**: public, private, hybrid, multi-cloud -* **extensible**: modular, pluggable, hookable, composable -* **self-healing**: auto-placement, auto-restart, auto-replication, auto-scaling - -The Kubernetes project was started by Google in 2014. Kubernetes builds upon a [decade and a half of experience that Google has with running production workloads at scale](https://research.google.com/pubs/pub43438.html), combined with best-of-breed ideas and practices from the community. - -##### Ready to [Get Started](/docs/getting-started-guides/)? - -## Why containers? - -Looking for reasons why you should be using [containers](http://aucouranton.com/2014/06/13/linux-containers-parallels-lxc-openvz-docker-and-more/)? - -![Why Containers?](/images/docs/why_containers.svg) - -The *Old Way* to deploy applications was to install the applications on a host using the operating system package manager. This had the disadvantage of entangling the applications' executables, configuration, libraries, and lifecycles with each other and with the host OS. One could build immutable virtual-machine images in order to achieve predictable rollouts and rollbacks, but VMs are heavyweight and non-portable. - -The *New Way* is to deploy containers based on operating-system-level virtualization rather than hardware virtualization. These containers are isolated from each other and from the host: they have their own filesystems, they can't see each others' processes, and their computational resource usage can be bounded. They are easier to build than VMs, and because they are decoupled from the underlying infrastructure and from the host filesystem, they are portable across clouds and OS distributions. - -Because containers are small and fast, one application can be packed in each container image. This one-to-one application-to-image relationship unlocks the full benefits of containers. With containers, immutable container images can be created at build/release time rather than deployment time, since each application doesn't need to be composed with the rest of the application stack, nor married to the production infrastructure environment. Generating container images at build/release time enables a consistent environment to be carried from development into production. -Similarly, containers are vastly more transparent than VMs, which facilitates monitoring and management. This is especially true when the containers' process lifecycles are managed by the infrastructure rather than hidden by a process supervisor inside the container. Finally, with a single application per container, managing the containers becomes tantamount to managing deployment of the application. - -Summary of container benefits: - -* **Agile application creation and deployment**: - Increased ease and efficiency of container image creation compared to VM image use. -* **Continuous development, integration, and deployment**: - Provides for reliable and frequent container image build and deployment with quick and easy rollbacks (due to image immutability). -* **Dev and Ops separation of concerns**: - Create application container images at build/release time rather than deployment time, thereby decoupling applications from infrastructure. -* **Environmental consistency across development, testing, and production**: - Runs the same on a laptop as it does in the cloud. -* **Cloud and OS distribution portability**: - Runs on Ubuntu, RHEL, CoreOS, on-prem, Google Container Engine, and anywhere else. -* **Application-centric management**: - Raises the level of abstraction from running an OS on virtual hardware to run an application on an OS using logical resources. -* **Loosely coupled, distributed, elastic, liberated [micro-services](http://martinfowler.com/articles/microservices.html)**: - Applications are broken into smaller, independent pieces and can be deployed and managed dynamically -- not a fat monolithic stack running on one big single-purpose machine. -* **Resource isolation**: - Predictable application performance. -* **Resource utilization**: - High efficiency and density. - -#### Why do I need Kubernetes and what can it do? - -At a minimum, Kubernetes can schedule and run application containers on clusters of physical or virtual machines. However, Kubernetes also allows developers to 'cut the cord' to physical and virtual machines, moving from a **host-centric** infrastructure to a **container-centric** infrastructure, which provides the full advantages and benefits inherent to containers. Kubernetes provides the infrastructure to build a truly **container-centric** development environment. - -Kubernetes satisfies a number of common needs of applications running in production, such as: - -* [co-locating helper processes](/docs/user-guide/pods/), facilitating composite applications and preserving the one-application-per-container model, -* [mounting storage systems](/docs/user-guide/volumes/), -* [distributing secrets](/docs/user-guide/secrets/), -* [application health checking](/docs/user-guide/production-pods/#liveness-and-readiness-probes-aka-health-checks), -* [replicating application instances](/docs/user-guide/replication-controller/), -* [horizontal auto-scaling](/docs/user-guide/horizontal-pod-autoscaling/), -* [naming and discovery](/docs/user-guide/connecting-applications/), -* [load balancing](/docs/user-guide/services/), -* [rolling updates](/docs/user-guide/update-demo/), -* [resource monitoring](/docs/user-guide/monitoring/), -* [log access and ingestion](/docs/user-guide/logging/overview/), -* [support for introspection and debugging](/docs/user-guide/introspection-and-debugging/), and -* [identity and authorization](/docs/admin/authorization/). - -This provides the simplicity of Platform as a Service (PaaS) with the flexibility of Infrastructure as a Service (IaaS), and facilitates portability across infrastructure providers. - -For more details, see the [user guide](/docs/user-guide/). - -#### Why and how is Kubernetes a platform? - -Even though Kubernetes provides a lot of functionality, there are always new scenarios that would benefit from new features. Application-specific workflows can be streamlined to accelerate developer velocity. Ad hoc orchestration that is acceptable initially often requires robust automation at scale. This is why Kubernetes was also designed to serve as a platform for building an ecosystem of components and tools to make it easier to deploy, scale, and manage applications. - -[Labels](/docs/user-guide/labels/) empower users to organize their resources however they please. [Annotations](/docs/user-guide/annotations/) enable users to decorate resources with custom information to facilitate their workflows and provide an easy way for management tools to checkpoint state. - -Additionally, the [Kubernetes control plane](/docs/admin/cluster-components) is built upon the same [APIs](/docs/api/) that are available to developers and users. Users can write their own controllers, [schedulers](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/scheduler.md), etc., if they choose, with [their own APIs](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/extending-api.md) that can be targeted by a general-purpose [command-line tool](/docs/user-guide/kubectl-overview/). - -This [design](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/principles.md) has enabled a number of other systems to build atop Kubernetes. - -#### Kubernetes is not: - -Kubernetes is not a traditional, all-inclusive PaaS (Platform as a Service) system. We preserve user choice where it is important. - -* Kubernetes does not limit the types of applications supported. It does not dictate application frameworks (e.g., [Wildfly](http://wildfly.org/)), restrict the set of supported language runtimes (e.g., Java, Python, Ruby), cater to only [12-factor applications](http://12factor.net/), nor distinguish "apps" from "services". Kubernetes aims to support an extremely diverse variety of workloads, including stateless, stateful, and data-processing workloads. If an application can run in a container, it should run great on Kubernetes. -* Kubernetes does not provide middleware (e.g., message buses), data-processing frameworks (e.g., Spark), databases (e.g., mysql), nor cluster storage systems (e.g., Ceph) as built-in services. Such applications run on Kubernetes. -* Kubernetes does not have a click-to-deploy service marketplace. -* Kubernetes is unopinionated in the source-to-image space. It does not deploy source code and does not build your application. Continuous Integration (CI) workflow is an area where different users and projects have their own requirements and preferences, so we support layering CI workflows on Kubernetes but don't dictate how it should work. -* Kubernetes allows users to choose the logging, monitoring, and alerting systems of their choice. (Though we do provide some integrations as proof of concept.) -* Kubernetes does not provide nor mandate a comprehensive application configuration language/system (e.g., [jsonnet](https://github.com/google/jsonnet)). -* Kubernetes does not provide nor adopt any comprehensive machine configuration, maintenance, management, or self-healing systems. - -On the other hand, a number of PaaS systems run *on* Kubernetes, such as [Openshift](https://github.com/openshift/origin), [Deis](http://deis.io/), and [Eldarion](http://eldarion.cloud/). You could also roll your own custom PaaS, integrate with a CI system of your choice, or get along just fine with just Kubernetes: bring your container images and deploy them on Kubernetes. - -Since Kubernetes operates at the application level rather than at just the hardware level, it provides some generally applicable features common to PaaS offerings, such as deployment, scaling, load balancing, logging, monitoring, etc. However, Kubernetes is not monolithic, and these default solutions are optional and pluggable. - -Additionally, Kubernetes is not a mere "orchestration system"; it eliminates the need for orchestration. The technical definition of "orchestration" is execution of a defined workflow: do A, then B, then C. In contrast, Kubernetes is comprised of a set of independent, composable control processes that continuously drive current state towards the provided desired state. It shouldn't matter how you get from A to C: make it so. Centralized control is also not required; the approach is more akin to "choreography". This results in a system that is easier to use and more powerful, robust, resilient, and extensible. - -#### What does *Kubernetes* mean? K8s? - -The name **Kubernetes** originates from Greek, meaning "helmsman" or "pilot", and is the root of "governor" and ["cybernetic"](http://www.etymonline.com/index.php?term=cybernetics). **K8s** is an abbreviation derived by replacing the 8 letters "ubernete" with 8. +[What is Kubernetes?](/docs/concepts/overview/what-is-kubernetes/) diff --git a/images/community_logos/mirantis_logo.png b/images/community_logos/mirantis_logo.png index d2c395e323..4f407a37bb 100644 Binary files a/images/community_logos/mirantis_logo.png and b/images/community_logos/mirantis_logo.png differ diff --git a/docs/admin/ha-master-gce.png b/images/docs/ha-master-gce.png similarity index 100% rename from docs/admin/ha-master-gce.png rename to images/docs/ha-master-gce.png diff --git a/images/square-logos/asm.png b/images/square-logos/asm.png new file mode 100644 index 0000000000..6e383ccb99 Binary files /dev/null and b/images/square-logos/asm.png differ diff --git a/images/square-logos/avinetworks.png b/images/square-logos/avinetworks.png new file mode 100644 index 0000000000..0910e54ab5 Binary files /dev/null and b/images/square-logos/avinetworks.png differ diff --git a/images/square-logos/ca.png b/images/square-logos/ca.png new file mode 100644 index 0000000000..96089e040b Binary files /dev/null and b/images/square-logos/ca.png differ diff --git a/images/square-logos/cloudplex.png b/images/square-logos/cloudplex.png new file mode 100644 index 0000000000..1943b433e8 Binary files /dev/null and b/images/square-logos/cloudplex.png differ diff --git a/images/square-logos/coscale.png b/images/square-logos/coscale.png new file mode 100644 index 0000000000..de68cb49f3 Binary files /dev/null and b/images/square-logos/coscale.png differ diff --git a/images/square-logos/eta.png b/images/square-logos/eta.png new file mode 100644 index 0000000000..ec9ab9d5cb Binary files /dev/null and b/images/square-logos/eta.png differ diff --git a/images/square-logos/infracloud.png b/images/square-logos/infracloud.png new file mode 100644 index 0000000000..849772332d Binary files /dev/null and b/images/square-logos/infracloud.png differ diff --git a/images/square-logos/inwinstack.png b/images/square-logos/inwinstack.png new file mode 100644 index 0000000000..5a849db4da Binary files /dev/null and b/images/square-logos/inwinstack.png differ diff --git a/images/square-logos/kumina.png b/images/square-logos/kumina.png new file mode 100644 index 0000000000..75f31ca8ef Binary files /dev/null and b/images/square-logos/kumina.png differ diff --git a/images/square-logos/nats.png b/images/square-logos/nats.png new file mode 100644 index 0000000000..4dcb111683 Binary files /dev/null and b/images/square-logos/nats.png differ diff --git a/images/square-logos/puppet.png b/images/square-logos/puppet.png index b07f038315..48f1870545 100644 Binary files a/images/square-logos/puppet.png and b/images/square-logos/puppet.png differ diff --git a/images/square-logos/rxm.png b/images/square-logos/rxm.png new file mode 100644 index 0000000000..3b48b41071 Binary files /dev/null and b/images/square-logos/rxm.png differ diff --git a/images/square-logos/semantix.png b/images/square-logos/semantix.png new file mode 100644 index 0000000000..0915a8040a Binary files /dev/null and b/images/square-logos/semantix.png differ diff --git a/images/square-logos/signalfx.png b/images/square-logos/signalfx.png new file mode 100644 index 0000000000..590a59904f Binary files /dev/null and b/images/square-logos/signalfx.png differ diff --git a/images/square-logos/spotinst.png b/images/square-logos/spotinst.png new file mode 100644 index 0000000000..645abbed45 Binary files /dev/null and b/images/square-logos/spotinst.png differ diff --git a/images/square-logos/supergiant.png b/images/square-logos/supergiant.png new file mode 100644 index 0000000000..0ead81d2c6 Binary files /dev/null and b/images/square-logos/supergiant.png differ diff --git a/index.html b/index.html index 5e860832d7..30cb9264b5 100644 --- a/index.html +++ b/index.html @@ -172,7 +172,6 @@ cid: home -{% include footer.html %}
      diff --git a/netlify.toml b/netlify.toml index bac7e0b5ab..37e285cb2d 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,6 +1,6 @@ [build] - command = "make build" + command = "make build generate-redirects" publish = "_site" [context.deploy-preview] - command = "make build-preview" + command = "make build-preview generate-redirects" diff --git a/redirects.rb b/redirects.rb new file mode 100644 index 0000000000..4cb238a811 --- /dev/null +++ b/redirects.rb @@ -0,0 +1,72 @@ +# This script generates a redirects file that Netlify's CDN +# can use to forward visitor to the right content. +# +# You can read more details about this file in Netlify documentation: +# +# https://www.netlify.com/docs/redirects/ +# +# USAGE: +# +# Run this script with Ruby to generate the _redirects file in this repository. +# It works with any Ruby version higher than 1.8. +# +# ruby redirects.rb +# +# If you want to test a change without modifying the content of the current file, +# you can print the output of the script setting the DEBUG environment variable +# when you run the script: +# +# DEBUG=1 ruby redirects.rb +# +# You can test if the content generated is correct in this playground: +# +# https://play.netlify.com/redirects +# +# HOW TO ADD NEW RULES: +# +# This script is divided in two sections. +# +# The first section handles static redirects, +# those that you know the old path and the new path and never change. +# +# If you want to add one of these redirects, add the rule to the `fixed_redirects` variable, +# in a new line before the closing """. The format for basic 301 redirects is the following one, +# check Netlify's documentation linked above for other rules: +# +# /OLD_PATH /NEW_PATH_OR_URL +# +# The second section handles redirects that change depending on the branch that's deployed +# in the site. For instance, when you want to redirect a path to content in +# the kubernetes main repository but the content is specific to a branch that +# matches the deployed branch. +# +# If you want to add one of there redirects, add the old path to the `branch_redirects` list. For instance, +# when you deploy the branch release-1.5 on Netlify, this script will generate the following redirects: +# +# /examples/* https://github.com/kubernetes/kubernetes/tree/release-1.5/examples/:splat +# /cluster/* https://github.com/kubernetes/kubernetes/tree/release-1.5/cluster/:splat +# /docs/devel/* https://github.com/kubernetes/kubernetes/tree/release-1.5/docs/devel/:splat +# /docs/design/* https://github.com/kubernetes/kubernetes/tree/release-1.5/docs/design/:splat +# +REPO_TMPL = "https://github.com/kubernetes/kubernetes/tree/%s/%s/:splat" + +fixed_redirects = """# 301 redirects (301 is the default status when no other one is provided for each line) +/third_party/swagger-ui /kubernetes/third_party/swagger-ui/ +/resource-quota /docs/admin/resourcequota/ +/horizontal-pod-autoscaler /docs/user-guide/horizontal-pod-autoscaling/ +/docs/user-guide/overview /docs/whatisk8s/ +/docs/roadmap https://github.com/kubernetes/kubernetes/milestones/ +/api-ref https://github.com/kubernetes/kubernetes/milestones/ +""" + +branch_redirects = ["examples" , "cluster", "docs/devel", "docs/design"] + +branch_redirects.each do |name| + dest = REPO_TMPL % [ENV.fetch("HEAD", "master"), name] + rule = "\n/#{name}/* #{dest}" + + fixed_redirects << rule +end + +output = ENV["DEBUG"] ? STDOUT : File.open(ENV.fetch("REDIRECTS_PATH", "_redirects"), "w+") +output.puts fixed_redirects diff --git a/robots.txt b/robots.txt index 9bb39d8dbd..3fbd70eb24 100644 --- a/robots.txt +++ b/robots.txt @@ -6,4 +6,24 @@ Disallow: /v1.1/ Disallow: /404/ Disallow: 404.html +Disallow: /docs/user-guide/configuring-containers +Disallow: /docs/user-guide/containers +Disallow: /docs/user-guide/deploying-applications +Disallow: /docs/user-guide/liveness/index +Disallow: /docs/user-guide/simple-nginx +Disallow: /docs/user-guide/production-pods +Disallow: /docs/user-guide/quick-start + +Disallow: /docs/user-guide/persistent-volumes/walkthrough +Disallow: /docs/user-guide/pods/single-container + +Disallow: /docs/user-guide/secrets/walkthrough + SITEMAP: http://kubernetes.io/sitemap.xml + + + + + + +

    nodeSelector

    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection/README

    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection

    false

    object

    nodeSelector
    object
    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection/READMENodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: http://kubernetes.io/docs/user-guide/node-selection
    restartPolicy
    string