Merge with upstream master
This commit is contained in:
+7
-7
@@ -7,16 +7,16 @@ install:
|
|||||||
- export PATH=$GOPATH/bin:$PATH
|
- export PATH=$GOPATH/bin:$PATH
|
||||||
- mkdir -p $HOME/gopath/src/k8s.io
|
- mkdir -p $HOME/gopath/src/k8s.io
|
||||||
- mv $TRAVIS_BUILD_DIR $HOME/gopath/src/k8s.io/website && cd $HOME/gopath/src/k8s.io/website
|
- mv $TRAVIS_BUILD_DIR $HOME/gopath/src/k8s.io/website && cd $HOME/gopath/src/k8s.io/website
|
||||||
# Fetch dependencies for us to run the tests in test/examples_test.go
|
|
||||||
- go get -t -v k8s.io/website/test
|
|
||||||
# Make sure we are testing against the correct branch
|
|
||||||
- pushd $GOPATH/src/k8s.io/kubernetes && git checkout release-1.11 && popd
|
|
||||||
|
|
||||||
# Simplified deduplication of dependencies.
|
# Make sure we are testing against the correct branch
|
||||||
|
- pushd $GOPATH/src/k8s.io && git clone https://github.com/kubernetes/kubernetes && popd
|
||||||
|
- pushd $GOPATH/src/k8s.io/kubernetes && git checkout release-1.11 && popd
|
||||||
- cp -L -R $GOPATH/src/k8s.io/kubernetes/vendor/ $GOPATH/src/
|
- cp -L -R $GOPATH/src/k8s.io/kubernetes/vendor/ $GOPATH/src/
|
||||||
- rm -r $GOPATH/src/k8s.io/kubernetes/vendor/
|
- rm -r $GOPATH/src/k8s.io/kubernetes/vendor/
|
||||||
|
|
||||||
|
# Fetch additional dependencies to run the tests in examples/examples_test.go
|
||||||
|
- go get -t -v k8s.io/website/content/en/examples
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# TODO(bep)
|
- go test -v k8s.io/website/content/en/examples
|
||||||
- go test -v k8s.io/website/test #fixed by https://github.com/kubernetes/website/pull/8388
|
|
||||||
#- ./verify-docs-format.sh
|
#- ./verify-docs-format.sh
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
# Reviewers can /lgtm /approve but not sufficient for auto-merge without an
|
# Reviewers can /lgtm /approve but not sufficient for auto-merge without an
|
||||||
# approver
|
# approver
|
||||||
reviewers:
|
reviewers:
|
||||||
- zhangxiaoyu-zidif
|
- Rajakavitha1
|
||||||
- xiangpengzhao
|
|
||||||
- stewart-yu
|
- stewart-yu
|
||||||
- Rajakavitha1
|
- xiangpengzhao
|
||||||
|
- zhangxiaoyu-zidif
|
||||||
|
|
||||||
# Approvers have all the ability of reviewers but their /approve makes
|
# Approvers have all the ability of reviewers but their /approve makes
|
||||||
# auto-merge happen if a /lgtm exists, or vice versa, or they can do both
|
# auto-merge happen if a /lgtm exists, or vice versa, or they can do both
|
||||||
# No need for approvers to also be listed as reviewers
|
# No need for approvers to also be listed as reviewers
|
||||||
approvers:
|
approvers:
|
||||||
- heckj
|
|
||||||
- bradamant3
|
- bradamant3
|
||||||
- bradtopol
|
- bradtopol
|
||||||
- steveperry-53
|
|
||||||
- zacharysarah
|
|
||||||
- chenopis
|
- chenopis
|
||||||
|
- kbarnard10
|
||||||
- mistyhacks
|
- mistyhacks
|
||||||
|
- steveperry-53
|
||||||
- tengqm
|
- tengqm
|
||||||
|
- zacharysarah
|
||||||
|
- zparnold
|
||||||
|
|||||||
@@ -120,14 +120,14 @@ cid: home
|
|||||||
<main>
|
<main>
|
||||||
<h3>Case Studies</h3>
|
<h3>Case Studies</h3>
|
||||||
<div id="caseStudiesWrapper">
|
<div id="caseStudiesWrapper">
|
||||||
<div>
|
|
||||||
<p>Driving Banking Innovation with Cloud Native</p>
|
|
||||||
<a href="/case-studies/ing">Read more</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<p>Supporting Fast Decisioning Applications with Kubernetes</p>
|
<p>Supporting Fast Decisioning Applications with Kubernetes</p>
|
||||||
<a href="/case-studies/capital-one">Read more</a>
|
<a href="/case-studies/capital-one">Read more</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>Driving Banking Innovation with Cloud Native</p>
|
||||||
|
<a href="/case-studies/ing">Read more</a>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>Cloud Native at Northwestern Mutual</p>
|
<p>Cloud Native at Northwestern Mutual</p>
|
||||||
<a href="/case-studies/northwestern-mutual/">Read more</a>
|
<a href="/case-studies/northwestern-mutual/">Read more</a>
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: Meet Our Contributors - Monthly Streaming YouTube Mentoring Series
|
||||||
|
date: 2018-07-10
|
||||||
|
---
|
||||||
|
|
||||||
|
**Author**: Paris Pittman (Google)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
July 11th at 2:30pm and 8pm UTC kicks off our next installment of Meet Our Contributors YouTube series. This month is special: members of the steering committee will be on to answer any and all questions from the community on the first 30 minutes of the 8pm UTC session. More on submitting questions below.
|
||||||
|
|
||||||
|
[Meet Our Contributors](https://github.com/kubernetes/community/blob/master/mentoring/meet-our-contributors.md) was created to give an opportunity to new and current contributors alike to get time in front of our upstream community to ask questions that you would typically ask a mentor. We have 3-6 contributors on each session (an AM and PM session depending on where you are in the world!) answer questions [live on a YouTube stream](https://www.youtube.com/c/KubernetesCommunity/live). If you miss it, don’t stress, the recording is up after it’s over. Check out a past episode [here](https://www.youtube.com/watch?v=EVsXi3Zhlo0&list=PL69nYSiGNLP3QpQrhZq_sLYo77BVKv09F).
|
||||||
|
|
||||||
|
As you can imagine, the questions span broadly from introductory - “what’s a SIG?” to more advanced - “why’s my test flaking?” You’ll also hear growth related advice questions such as “what’s my best path to becoming an approver?” We’re happy to do a live code/docs review or explain part of the codebase as long as we have a few days notice.
|
||||||
|
|
||||||
|
We answer at least 10 questions per session and have helped 500+ people to date. This is a scalable mentoring initiative that makes it easy for all parties to share information, get advice, and get going with what they are trying to accomplish. We encourage you to submit questions for our next session:
|
||||||
|
|
||||||
|
- Join the Kubernetes Slack channel - #meet-our-contributors - to ask your question or for more detailed information. DM paris@ if you would like to remain anonymous.
|
||||||
|
- Twitter works, too, with the hashtag #k8smoc
|
||||||
|
|
||||||
|
If you are contributor reading this that has wanted to mentor but just can’t find the time - this is for you! [Reach out to us](https://goo.gl/forms/ZcnFiqNR5EQH03zm2).
|
||||||
|
|
||||||
|
You can join us live on June 6th at 2:30pm and 8pm UTC, and every first Wednesday of the month, on the [Kubernetes Community live stream](https://www.youtube.com/c/KubernetesCommunity/live). We look forward to seeing you there!
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: "CoreDNS GA for Kubernetes Cluster DNS"
|
||||||
|
date: 2018-07-10
|
||||||
|
---
|
||||||
|
|
||||||
|
**Author**: John Belamaric (Infoblox)
|
||||||
|
|
||||||
|
**Editor’s note: this post is part of a [series of in-depth articles](https://kubernetes.io/blog/2018/06/27/kubernetes-1.11-release-announcement/) on what’s new in Kubernetes 1.11**
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
In Kubernetes 1.11, [CoreDNS](https://coredns.io) has reached General Availability (GA) for DNS-based service discovery, as an alternative to the kube-dns addon. This means that CoreDNS will be offered as an option in upcoming versions of the various installation tools. In fact, the kubeadm team chose to make it the default option starting with Kubernetes 1.11.
|
||||||
|
|
||||||
|
DNS-based service discovery has been part of Kubernetes for a long time with the kube-dns cluster addon. This has generally worked pretty well, but there have been some concerns around the reliability, flexibility and security of the implementation.
|
||||||
|
|
||||||
|
CoreDNS is a general-purpose, authoritative DNS server that provides a backwards-compatible, but extensible, integration with Kubernetes. It resolves the issues seen with kube-dns, and offers a number of unique features that solve a wider variety of use cases.
|
||||||
|
|
||||||
|
In this article, you will learn about the differences in the implementations of kube-dns and CoreDNS, and some of the helpful extensions offered by CoreDNS.
|
||||||
|
|
||||||
|
## Implemenation differences
|
||||||
|
|
||||||
|
In kube-dns, several containers are used within a single pod: `kubedns`, `dnsmasq`, and `sidecar`. The `kubedns`
|
||||||
|
container watches the Kubernetes API and serves DNS records based on the [Kubernetes DNS specification](https://github.com/kubernetes/dns/blob/master/docs/specification.md), `dnsmasq` provides caching and stub domain support, and `sidecar` provides metrics and health checks.
|
||||||
|
|
||||||
|
This setup leads to a few issues that have been seen over time. For one, security vulnerabilities in `dnsmasq` have led to the need
|
||||||
|
for a security-patch release of Kubernetes in the past. Additionally, because `dnsmasq` handles the stub domains,
|
||||||
|
but `kubedns` handles the External Services, you cannot use a stub domain in an external service, which is very
|
||||||
|
limiting to that functionality (see [dns#131](https://github.com/kubernetes/dns/issues/131)).
|
||||||
|
|
||||||
|
All of these functions are done in a single container in CoreDNS, which is running a process written in Go. The
|
||||||
|
different plugins that are enabled replicate (and enhance) the functionality found in kube-dns.
|
||||||
|
|
||||||
|
## Configuring CoreDNS
|
||||||
|
|
||||||
|
In kube-dns, you can [modify a ConfigMap](https://kubernetes.io/blog/2017/04/configuring-private-dns-zones-upstream-nameservers-kubernetes/) to change the behavior of your service discovery. This allows the addition of
|
||||||
|
features such as serving stub domains, modifying upstream nameservers, and enabling federation.
|
||||||
|
|
||||||
|
In CoreDNS, you similarly can modify the ConfigMap for the CoreDNS [Corefile](https://coredns.io/2017/07/23/corefile-explained/) to change how service discovery
|
||||||
|
works. This Corefile configuration offers many more options than you will find in kube-dns, since it is the
|
||||||
|
primary configuration file that CoreDNS uses for configuration of all of its features, even those that are not
|
||||||
|
Kubernetes related.
|
||||||
|
|
||||||
|
When upgrading from kube-dns to CoreDNS using `kubeadm`, your existing ConfigMap will be used to generate the
|
||||||
|
customized Corefile for you, including all of the configuration for stub domains, federation, and upstream nameservers. See [Using CoreDNS for Service Discovery](https://kubernetes.io/docs/tasks/administer-cluster/coredns/) for more details.
|
||||||
|
|
||||||
|
|
||||||
|
## Bug fixes and enhancements
|
||||||
|
|
||||||
|
There are several open issues with kube-dns that are resolved in CoreDNS, either in default configuration or with some customized configurations.
|
||||||
|
|
||||||
|
* [dns#55 - Custom DNS entries for kube-dns](https://github.com/kubernetes/dns/issues/55) may be handled using the "fallthrough" mechanism in the [kubernetes plugin](https://coredns.io/plugins/kubernetes), using the [rewrite plugin](https://coredns.io/plugins/rewrite), or simply serving a subzone with a different plugin such as the [file plugin](https://coredns.io/plugins/file).
|
||||||
|
|
||||||
|
* [dns#116 - Only one A record set for headless service with pods having single hostname](https://github.com/kubernetes/dns/issues/116). This issue is fixed without any additional configuration.
|
||||||
|
* [dns#131 - externalName not using stubDomains settings](https://github.com/kubernetes/dns/issues/131). This issue is fixed without any additional configuration.
|
||||||
|
* [dns#167 - enable skyDNS round robin A/AAAA records](https://github.com/kubernetes/dns/issues/167). The equivalent functionality can be configured using the [load balance plugin](https://coredns.io/plugins/loadbalance).
|
||||||
|
* [dns#190 - kube-dns cannot run as non-root user](https://github.com/kubernetes/dns/issues/190). This issue is solved today by using a non-default image, but it will be made the default CoreDNS behavior in a future release.
|
||||||
|
* [dns#232 - fix pod hostname to be podname for dns srv records](https://github.com/kubernetes/dns/issues/232) is an enhancement that is supported through the "endpoint_pod_names" feature described below.
|
||||||
|
|
||||||
|
|
||||||
|
## Metrics
|
||||||
|
|
||||||
|
The functional behavior of the default CoreDNS configuration is the same as kube-dns. However,
|
||||||
|
one difference you need to be aware of is that the published metrics are not the same. In kube-dns,
|
||||||
|
you get separate metrics for `dnsmasq` and `kubedns` (skydns). In CoreDNS there is a completely
|
||||||
|
different set of metrics, since it is all a single process. You can find more details on these
|
||||||
|
metrics on the CoreDNS [Prometheus plugin](https://coredns.io/plugins/metrics/) page.
|
||||||
|
|
||||||
|
## Some special features
|
||||||
|
|
||||||
|
The standard CoreDNS Kubernetes configuration is designed to be backwards compatible with the prior
|
||||||
|
kube-dns behavior. But with some configuration changes, CoreDNS can allow you to modify how the
|
||||||
|
DNS service discovery works in your cluster. A number of these features are intended to still be
|
||||||
|
compliant with the [Kubernetes DNS specification](https://github.com/kubernetes/dns/blob/master/docs/specification.md);
|
||||||
|
they enhance functionality but remain backward compatible. Since CoreDNS is not
|
||||||
|
*only* made for Kubernetes, but is instead a general-purpose DNS server, there are many things you
|
||||||
|
can do beyond that specification.
|
||||||
|
|
||||||
|
### Pods verified mode
|
||||||
|
|
||||||
|
In kube-dns, pod name records are "fake". That is, any "a-b-c-d.namespace.pod.cluster.local" query will
|
||||||
|
return the IP address "a.b.c.d". In some cases, this can weaken the identity guarantees offered by TLS. So,
|
||||||
|
CoreDNS offers a "pods verified" mode, which will only return the IP address if there is a pod in the
|
||||||
|
specified namespace with that IP address.
|
||||||
|
|
||||||
|
### Endpoint names based on pod names
|
||||||
|
|
||||||
|
In kube-dns, when using a headless service, you can use an SRV request to get a list of
|
||||||
|
all endpoints for the service:
|
||||||
|
|
||||||
|
```
|
||||||
|
dnstools# host -t srv headless
|
||||||
|
headless.default.svc.cluster.local has SRV record 10 33 0 6234396237313665.headless.default.svc.cluster.local.
|
||||||
|
headless.default.svc.cluster.local has SRV record 10 33 0 6662363165353239.headless.default.svc.cluster.local.
|
||||||
|
headless.default.svc.cluster.local has SRV record 10 33 0 6338633437303230.headless.default.svc.cluster.local.
|
||||||
|
dnstools#
|
||||||
|
```
|
||||||
|
|
||||||
|
However, the endpoint DNS names are (for practical purposes) random. In CoreDNS, by default, you get endpoint
|
||||||
|
DNS names based upon the endpoint IP address:
|
||||||
|
|
||||||
|
```
|
||||||
|
dnstools# host -t srv headless
|
||||||
|
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-14.headless.default.svc.cluster.local.
|
||||||
|
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-18.headless.default.svc.cluster.local.
|
||||||
|
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-4.headless.default.svc.cluster.local.
|
||||||
|
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-9.headless.default.svc.cluster.local.
|
||||||
|
```
|
||||||
|
|
||||||
|
For some applications, it is desirable to have the pod name for this, rather than the pod IP
|
||||||
|
address (see for example [kubernetes#47992](https://github.com/kubernetes/kubernetes/issues/47992) and [coredns#1190](https://github.com/coredns/coredns/pull/1190)). To enable this in CoreDNS, you specify the "endpoint_pod_names" option in your Corefile, which results in this:
|
||||||
|
|
||||||
|
```
|
||||||
|
dnstools# host -t srv headless
|
||||||
|
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-qv84p.headless.default.svc.cluster.local.
|
||||||
|
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-zc8lx.headless.default.svc.cluster.local.
|
||||||
|
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-q7lf2.headless.default.svc.cluster.local.
|
||||||
|
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-566rt.headless.default.svc.cluster.local.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Autopath
|
||||||
|
|
||||||
|
CoreDNS also has a special feature to improve latency in DNS requests for external names. In Kubernetes, the
|
||||||
|
DNS search path for pods specifies a long list of suffixes. This enables the use of short names when requesting
|
||||||
|
services in the cluster - for example, "headless" above, rather than "headless.default.svc.cluster.local". However,
|
||||||
|
when requesting an external name - "infoblox.com", for example - several invalid DNS queries are made by the client,
|
||||||
|
requiring a roundtrip from the client to kube-dns each time (actually to `dnsmasq` and then to `kubedns`, since [negative caching is disabled](https://github.com/kubernetes/dns/issues/121)):
|
||||||
|
|
||||||
|
* infoblox.com.default.svc.cluster.local -> NXDOMAIN
|
||||||
|
* infoblox.com.svc.cluster.local -> NXDOMAIN
|
||||||
|
* infoblox.com.cluster.local -> NXDOMAIN
|
||||||
|
* infoblox.com.your-internal-domain.com -> NXDOMAIN
|
||||||
|
* infoblox.com -> returns a valid record
|
||||||
|
|
||||||
|
In CoreDNS, an optional feature called [autopath](https://coredns.io/plugins/autopath) can be enabled that will cause this search path to be followed
|
||||||
|
*in the server*. That is, CoreDNS will figure out from the source IP address which namespace the client pod is in,
|
||||||
|
and it will walk this search list until it gets a valid answer. Since the first 3 of these are resolved internally
|
||||||
|
within CoreDNS itself, it cuts out all of the back and forth between the client and server, reducing latency.
|
||||||
|
|
||||||
|
### A few other Kubernetes specific features
|
||||||
|
|
||||||
|
In CoreDNS, you can use standard DNS zone transfer to export the entire DNS record set. This is useful for
|
||||||
|
debugging your services as well as importing the cluster zone into other DNS servers.
|
||||||
|
|
||||||
|
You can also filter by namespaces or a label selector. This can allow you to run specific CoreDNS instances that will only server records that match the filters, exposing only a limited set of your services via DNS.
|
||||||
|
|
||||||
|
## Extensibility
|
||||||
|
|
||||||
|
In addition to the features described above, CoreDNS is easily extended. It is possible to build custom versions
|
||||||
|
of CoreDNS that include your own features. For example, this ability has been used to extend CoreDNS to do recursive resolution
|
||||||
|
with the [unbound plugin](https://https://coredns.io/explugins/unbound), to server records directly from a database with the [pdsql plugin](https://coredns.io/explugins/pdsql), and to allow multiple CoreDNS instances to share a common level 2 cache with the [redisc plugin](https://coredns.io/explugins/redisc).
|
||||||
|
|
||||||
|
Many other interesting extensions have been added, which you will find on the [External Plugins](https://coredns.io/explugins/) page of the CoreDNS site. One that is really interesting for Kubernetes and Istio users is the [kubernetai plugin](https://coredns.io/explugins/kubernetai), which allows a single CoreDNS instance to connect to multiple Kubernetes clusters and provide service discovery across all of them.
|
||||||
|
|
||||||
|
## What's Next?
|
||||||
|
|
||||||
|
CoreDNS is an independent project, and as such is developing many features that are not directly
|
||||||
|
related to Kubernetes. However, a number of these will have applications within Kubernetes. For example,
|
||||||
|
the upcoming integration with policy engines will allow CoreDNS to make intelligent choices about which endpoint
|
||||||
|
to return when a headless service is requested. This could be used to route traffic to a local pod, or
|
||||||
|
to a more responsive pod. Many other features are in development, and of course as an open source project, we welcome you to suggest and contribute your own features!
|
||||||
|
|
||||||
|
The features and differences described above are a few examples. There is much more you can do with CoreDNS.
|
||||||
|
You can find out more on the [CoreDNS Blog](https://coredns.io/blog).
|
||||||
|
|
||||||
|
### Get involved with CoreDNS
|
||||||
|
|
||||||
|
CoreDNS is an incubated [CNCF](https:://cncf.io) project.
|
||||||
|
|
||||||
|
We're most active on Slack (and Github):
|
||||||
|
|
||||||
|
- Slack: #coredns on <https://slack.cncf.io>
|
||||||
|
- Github: <https://github.com/coredns/coredns>
|
||||||
|
|
||||||
|
More resources can be found:
|
||||||
|
|
||||||
|
- Website: <https://coredns.io>
|
||||||
|
- Blog: <https://blog.coredns.io>
|
||||||
|
- Twitter: [@corednsio](https://twitter.com/corednsio)
|
||||||
|
- Mailing list/group: <coredns-discuss@googlegroups.com>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: 'Dynamic Kubelet Configuration'
|
||||||
|
date: 2018-07-11
|
||||||
|
---
|
||||||
|
|
||||||
|
**Author**: Michael Taufen (Google)
|
||||||
|
|
||||||
|
**Editor’s note: this post is part of a [series of in-depth articles](https://kubernetes.io/blog/2018/06/27/kubernetes-1.11-release-announcement/) on what’s new in Kubernetes 1.11**
|
||||||
|
|
||||||
|
## Why Dynamic Kubelet Configuration?
|
||||||
|
|
||||||
|
Kubernetes provides API-centric tooling that significantly improves workflows for managing applications and infrastructure. Most Kubernetes installations, however, run the Kubelet as a native process on each host, outside the scope of standard Kubernetes APIs.
|
||||||
|
|
||||||
|
In the past, this meant that cluster administrators and service providers could not rely on Kubernetes APIs to reconfigure Kubelets in a live cluster. In practice, this required operators to either ssh into machines to perform manual reconfigurations, use third-party configuration management automation tools, or create new VMs with the desired configuration already installed, then migrate work to the new machines. These approaches are environment-specific and can be expensive.
|
||||||
|
|
||||||
|
Dynamic Kubelet configuration gives cluster administrators and service providers the ability to reconfigure Kubelets in a live cluster via Kubernetes APIs.
|
||||||
|
|
||||||
|
## What is Dynamic Kubelet Configuration?
|
||||||
|
|
||||||
|
Kubernetes v1.10 made it possible to configure the Kubelet via a beta [config file](https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/) API. Kubernetes already provides the ConfigMap abstraction for storing arbitrary file data in the API server.
|
||||||
|
|
||||||
|
Dynamic Kubelet configuration extends the Node object so that a Node can refer to a ConfigMap that contains the same type of config file. When a Node is updated to refer to a new ConfigMap, the associated Kubelet will attempt to use the new configuration.
|
||||||
|
|
||||||
|
## How does it work?
|
||||||
|
|
||||||
|
Dynamic Kubelet configuration provides the following core features:
|
||||||
|
|
||||||
|
* Kubelet attempts to use the dynamically assigned configuration.
|
||||||
|
* Kubelet "checkpoints" configuration to local disk, enabling restarts without API server access.
|
||||||
|
* Kubelet reports assigned, active, and last-known-good configuration sources in the Node status.
|
||||||
|
* When invalid configuration is dynamically assigned, Kubelet automatically falls back to a last-known-good configuration and reports errors in the Node status.
|
||||||
|
|
||||||
|
To use the dynamic Kubelet configuration feature, a cluster administrator or service provider will first post a ConfigMap containing the desired configuration, then set each Node.Spec.ConfigSource.ConfigMap reference to refer to the new ConfigMap. Operators can update these references at their preferred rate, giving them the ability to perform controlled rollouts of new configurations.
|
||||||
|
|
||||||
|
Each Kubelet watches its associated Node object for changes. When the Node.Spec.ConfigSource.ConfigMap reference is updated, the Kubelet will "checkpoint" the new ConfigMap by writing the files it contains to local disk. The Kubelet will then exit, and the OS-level process manager will restart it. Note that if the Node.Spec.ConfigSource.ConfigMap reference is not set, the Kubelet uses the set of flags and config files local to the machine it is running on.
|
||||||
|
|
||||||
|
Once restarted, the Kubelet will attempt to use the configuration from the new checkpoint. If the new configuration passes the Kubelet's internal validation, the Kubelet will update Node.Status.Config to reflect that it is using the new configuration. If the new configuration is invalid, the Kubelet will fall back to its last-known-good configuration and report an error in Node.Status.Config.
|
||||||
|
|
||||||
|
Note that the default last-known-good configuration is the combination of Kubelet command-line flags with the Kubelet's local configuration file. Command-line flags that overlap with the config file always take precedence over both the local configuration file and dynamic configurations, for backwards-compatibility.
|
||||||
|
|
||||||
|
See the following diagram for a high-level overview of a configuration update for a single Node:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## How can I learn more?
|
||||||
|
|
||||||
|
Please see the official tutorial at https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/, which contains more in-depth details on user workflow, how a configuration becomes "last-known-good," how the Kubelet "checkpoints" config, and possible failure modes.
|
||||||
@@ -1,11 +1,18 @@
|
|||||||
---
|
---
|
||||||
title: Concepts
|
title: Concepts
|
||||||
main_menu: true
|
main_menu: true
|
||||||
|
content_template: templates/concept
|
||||||
weight: 40
|
weight: 40
|
||||||
---
|
---
|
||||||
|
|
||||||
|
{{% capture overview %}}
|
||||||
|
|
||||||
The Concepts section helps you learn about the parts of the Kubernetes system and the abstractions Kubernetes uses to represent your cluster, and helps you obtain a deeper understanding of how Kubernetes works.
|
The Concepts section helps you learn about the parts of the Kubernetes system and the abstractions Kubernetes uses to represent your cluster, and helps you obtain a deeper understanding of how Kubernetes works.
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
|
||||||
|
{{% capture body %}}
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
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.
|
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.
|
||||||
@@ -57,9 +64,12 @@ The nodes in a cluster are the machines (VMs, physical servers, etc) that run yo
|
|||||||
|
|
||||||
* [Annotations](/docs/concepts/overview/working-with-objects/annotations/)
|
* [Annotations](/docs/concepts/overview/working-with-objects/annotations/)
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
|
||||||
### What's next
|
{{% capture whatsnext %}}
|
||||||
|
|
||||||
If you would like to write a concept page, see
|
If you would like to write a concept page, see
|
||||||
[Using Page Templates](/docs/home/contribute/page-templates/)
|
[Using Page Templates](/docs/home/contribute/page-templates/)
|
||||||
for information about the concept page type and the concept template.
|
for information about the concept page type and the concept template.
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ All communication paths from the cluster to the master terminate at the
|
|||||||
apiserver (none of the other master components are designed to expose remote
|
apiserver (none of the other master components are designed to expose remote
|
||||||
services). In a typical deployment, the apiserver is configured to listen for
|
services). In a typical deployment, the apiserver is configured to listen for
|
||||||
remote connections on a secure HTTPS port (443) with one or more forms of
|
remote connections on a secure HTTPS port (443) with one or more forms of
|
||||||
client [authentication](/docs/admin/authentication/) enabled. One or more forms
|
client [authentication](/docs/reference/access-authn-authz/authentication/) enabled. One or more forms
|
||||||
of [authorization](/docs/admin/authorization/) should be enabled, especially
|
of [authorization](/docs/admin/authorization/) should be enabled, especially
|
||||||
if [anonymous requests](/docs/admin/authentication/#anonymous-requests) or
|
if [anonymous requests](/docs/reference/access-authn-authz/authentication/#anonymous-requests) or
|
||||||
[service account tokens](/docs/admin/authentication/#service-account-tokens)
|
[service account tokens](/docs/reference/access-authn-authz/authentication/#service-account-tokens)
|
||||||
are allowed.
|
are allowed.
|
||||||
|
|
||||||
Nodes should be provisioned with the public root certificate for the cluster
|
Nodes should be provisioned with the public root certificate for the cluster
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Before choosing a guide, here are some considerations:
|
|||||||
|
|
||||||
Note: Not all distros are actively maintained. Choose distros which have been tested with a recent version of Kubernetes.
|
Note: Not all distros are actively maintained. Choose distros which have been tested with a recent version of Kubernetes.
|
||||||
|
|
||||||
If you are using a guide involving Salt, see [Configuring Kubernetes with Salt](/docs/admin/salt/).
|
-If you are using a guide involving Salt, see [Configuring Kubernetes with Salt](/docs/setup/salt/).
|
||||||
|
|
||||||
## Managing a cluster
|
## Managing a cluster
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@ If you are using a guide involving Salt, see [Configuring Kubernetes with Salt](
|
|||||||
|
|
||||||
* [Kubernetes Container Environment](/docs/concepts/containers/container-environment-variables/) describes the environment for Kubelet managed containers on a Kubernetes node.
|
* [Kubernetes Container Environment](/docs/concepts/containers/container-environment-variables/) describes the environment for Kubelet managed containers on a Kubernetes node.
|
||||||
|
|
||||||
* [Controlling Access to the Kubernetes API](/docs/admin/accessing-the-api/) describes how to set up permissions for users and service accounts.
|
* [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/) describes how to set up permissions for users and service accounts.
|
||||||
|
|
||||||
* [Authenticating](/docs/admin/authentication/) explains authentication in Kubernetes, including the various authentication options.
|
* [Authenticating](/docs/reference/access-authn-authz/authentication/) explains authentication in Kubernetes, including the various authentication options.
|
||||||
|
|
||||||
* [Authorization](/docs/admin/authorization/) is separate from authentication, and controls how HTTP calls are handled.
|
* [Authorization](/docs/admin/authorization/) is separate from authentication, and controls how HTTP calls are handled.
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ 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
|
writes to two different log files, using two different formats. Here's a
|
||||||
configuration file for the Pod:
|
configuration file for the Pod:
|
||||||
|
|
||||||
{{< code file="two-files-counter-pod.yaml" >}}
|
{{< codenew file="admin/logging/two-files-counter-pod.yaml" >}}
|
||||||
|
|
||||||
It would be a mess to have log entries of different formats in the same log
|
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
|
stream, even if you managed to redirect both components to the `stdout` stream of
|
||||||
@@ -170,7 +170,7 @@ the logs to its own `stdout` stream.
|
|||||||
|
|
||||||
Here's a configuration file for a pod that has two sidecar containers:
|
Here's a configuration file for a pod that has two sidecar containers:
|
||||||
|
|
||||||
{{< code file="two-files-counter-pod-streaming-sidecar.yaml" >}}
|
{{< codenew file="admin/logging/two-files-counter-pod-streaming-sidecar.yaml" >}}
|
||||||
|
|
||||||
Now when you run this pod, you can access each log stream separately by
|
Now when you run this pod, you can access each log stream separately by
|
||||||
running the following commands:
|
running the following commands:
|
||||||
@@ -226,7 +226,7 @@ which uses fluentd as a logging agent. Here are two configuration files that
|
|||||||
you can use to implement this approach. The first file contains
|
you can use to implement this approach. The first file contains
|
||||||
a [ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/) to configure fluentd.
|
a [ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/) to configure fluentd.
|
||||||
|
|
||||||
{{< code file="fluentd-sidecar-config.yaml" >}}
|
{{< codenew file="admin/logging/fluentd-sidecar-config.yaml" >}}
|
||||||
|
|
||||||
**Note**: The configuration of fluentd is beyond the scope of this article. For
|
**Note**: The configuration of fluentd is beyond the scope of this article. For
|
||||||
information about configuring fluentd, see the
|
information about configuring fluentd, see the
|
||||||
@@ -235,7 +235,7 @@ information about configuring fluentd, see the
|
|||||||
The second file describes a pod that has a sidecar container running fluentd.
|
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.
|
The pod mounts a volume where fluentd can pick up its configuration data.
|
||||||
|
|
||||||
{{< code file="two-files-counter-pod-agent-sidecar.yaml" >}}
|
{{< codenew file="admin/logging/two-files-counter-pod-agent-sidecar.yaml" >}}
|
||||||
|
|
||||||
After some time you can find log messages in the Stackdriver interface.
|
After some time you can find log messages in the Stackdriver interface.
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ You've deployed your application and exposed it via a service. Now what? Kuberne
|
|||||||
|
|
||||||
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:
|
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:
|
||||||
|
|
||||||
{{< code file="nginx-app.yaml" >}}
|
{{< codenew file="application/nginx-app.yaml" >}}
|
||||||
|
|
||||||
Multiple resources can be created the same way as a single resource:
|
Multiple resources can be created the same way as a single resource:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl create -f https://k8s.io/docs/concepts/cluster-administration/nginx-app.yaml
|
$ kubectl create -f https://k8s.io/examples/application/nginx-app.yaml
|
||||||
service "my-nginx-svc" created
|
service "my-nginx-svc" created
|
||||||
deployment "my-nginx" created
|
deployment "my-nginx" created
|
||||||
```
|
```
|
||||||
@@ -37,13 +37,13 @@ The resources will be created in the order they appear in the file. Therefore, i
|
|||||||
`kubectl create` also accepts multiple `-f` arguments:
|
`kubectl create` also accepts multiple `-f` arguments:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl create -f https://k8s.io/docs/concepts/cluster-administration/nginx/nginx-svc.yaml -f https://k8s.io/docs/concepts/cluster-administration/nginx/nginx-deployment.yaml
|
$ kubectl create -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
And a directory can be specified rather than or in addition to individual files:
|
And a directory can be specified rather than or in addition to individual files:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl create -f https://k8s.io/docs/concepts/cluster-administration/nginx/
|
$ kubectl create -f https://k8s.io/examples/application/nginx/
|
||||||
```
|
```
|
||||||
|
|
||||||
`kubectl` will read any files with suffixes `.yaml`, `.yml`, or `.json`.
|
`kubectl` will read any files with suffixes `.yaml`, `.yml`, or `.json`.
|
||||||
@@ -53,8 +53,8 @@ It is a recommended practice to put resources related to the same microservice o
|
|||||||
A URL can also be specified as a configuration source, which is handy for deploying directly from configuration files checked into github:
|
A URL can also be specified as a configuration source, which is handy for deploying directly from configuration files checked into github:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl create -f https://raw.githubusercontent.com/kubernetes/website/master/docs/concepts/cluster-administration/nginx-deployment.yaml
|
$ kubectl create -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml
|
||||||
deployment "nginx-deployment" created
|
deployment "my-nginx" created
|
||||||
```
|
```
|
||||||
|
|
||||||
## Bulk operations in kubectl
|
## Bulk operations in kubectl
|
||||||
@@ -62,7 +62,7 @@ deployment "nginx-deployment" created
|
|||||||
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:
|
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
|
```shell
|
||||||
$ kubectl delete -f https://k8s.io/docs/concepts/cluster-administration/nginx-app.yaml
|
$ kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
|
||||||
deployment "my-nginx" deleted
|
deployment "my-nginx" deleted
|
||||||
service "my-nginx-svc" deleted
|
service "my-nginx-svc" deleted
|
||||||
```
|
```
|
||||||
@@ -89,7 +89,7 @@ NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
|||||||
my-nginx-svc 10.0.0.208 <pending> 80/TCP 0s
|
my-nginx-svc 10.0.0.208 <pending> 80/TCP 0s
|
||||||
```
|
```
|
||||||
|
|
||||||
With the above commands, we first create resources under `docs/concepts/cluster-administration/nginx/` and print the resources created with `-o name` output format
|
With the above commands, we first create resources under `examples/application/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`.
|
(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.
|
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.
|
||||||
@@ -321,7 +321,7 @@ Then, you can use [`kubectl apply`](/docs/reference/generated/kubectl/kubectl-co
|
|||||||
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.
|
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
|
```shell
|
||||||
$ kubectl apply -f docs/concepts/cluster-administration/nginx/nginx-deployment.yaml
|
$ kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
|
||||||
deployment "my-nginx" configured
|
deployment "my-nginx" configured
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -371,7 +371,7 @@ and
|
|||||||
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:
|
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
|
```shell
|
||||||
$ kubectl replace -f docs/concepts/cluster-administration/nginx/nginx-deployment.yaml --force
|
$ kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
|
||||||
deployment "my-nginx" deleted
|
deployment "my-nginx" deleted
|
||||||
deployment "my-nginx" replaced
|
deployment "my-nginx" replaced
|
||||||
```
|
```
|
||||||
@@ -405,4 +405,4 @@ That's it! The Deployment will declaratively update the deployed nginx applicati
|
|||||||
- [Learn about how to use `kubectl` for application introspection and debugging.](/docs/tasks/debug-application-cluster/debug-application-introspection/)
|
- [Learn about how to use `kubectl` for application introspection and debugging.](/docs/tasks/debug-application-cluster/debug-application-introspection/)
|
||||||
- [Configuration Best Practices and Tips](/docs/concepts/configuration/overview/)
|
- [Configuration Best Practices and Tips](/docs/concepts/configuration/overview/)
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: nginx-deployment
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: nginx
|
|
||||||
replicas: 3
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: nginx
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: nginx
|
|
||||||
image: nginx:1.7.9
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
@@ -54,6 +54,7 @@ One cpu, in Kubernetes, is equivalent to:
|
|||||||
- 1 AWS vCPU
|
- 1 AWS vCPU
|
||||||
- 1 GCP Core
|
- 1 GCP Core
|
||||||
- 1 Azure vCore
|
- 1 Azure vCore
|
||||||
|
- 1 IBM vCPU
|
||||||
- 1 *Hyperthread* on a bare-metal Intel processor with Hyperthreading
|
- 1 *Hyperthread* on a bare-metal Intel processor with Hyperthreading
|
||||||
|
|
||||||
Fractional requests are allowed. A Container with
|
Fractional requests are allowed. A Container with
|
||||||
|
|||||||
@@ -132,22 +132,22 @@ Adding an API does not directly let you affect the behavior of existing APIs (e.
|
|||||||
|
|
||||||
### API Access Extensions
|
### API Access Extensions
|
||||||
|
|
||||||
When a request reaches the Kubernetes API Server, it is first Authenticated, then Authorized, then subject to various types of Admission Control. See [[Accessing the API](/docs/admin/accessing-the-api/)] for more on this flow.
|
When a request reaches the Kubernetes API Server, it is first Authenticated, then Authorized, then subject to various types of Admission Control. See [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/)] for more on this flow.
|
||||||
|
|
||||||
Each of these steps offers extension points.
|
Each of these steps offers extension points.
|
||||||
|
|
||||||
Kubernetes has several built-in authentication methods that it supports. It can also sit behind an authenticating proxy, and it can send a token from an Authorization header to a remote service for verification (a webhook). All of these methods are covered in the [Authentication documentation](/docs/admin/authentication/).
|
Kubernetes has several built-in authentication methods that it supports. It can also sit behind an authenticating proxy, and it can send a token from an Authorization header to a remote service for verification (a webhook). All of these methods are covered in the [Authentication documentation](/docs/reference/access-authn-authz/authentication/).
|
||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
|
|
||||||
[Authentication](/docs/admin/authentication) maps headers or certificates in all requests to a username for the client making the request.
|
[Authentication](/docs/reference/access-authn-authz/authentication/) maps headers or certificates in all requests to a username for the client making the request.
|
||||||
|
|
||||||
Kubernetes provides several built-in authentication methods, and an [Authentication webhook](/docs/admin/authentication/#webhook-token-authentication) method if those don't meet your needs.
|
Kubernetes provides several built-in authentication methods, and an [Authentication webhook](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication) method if those don't meet your needs.
|
||||||
|
|
||||||
|
|
||||||
### Authorization
|
### Authorization
|
||||||
|
|
||||||
[Authorization](/docs/admin/authorization/webhook/) determines whether specific users can read, write, and do other operations on API resources. It just works at the level of whole resources -- it doesn't discriminate based on arbitrary object fields. If the built-in authorization options don't meet your needs, and [Authorization webhook](/docs/admin/authorization/webhook/) allows calling out to user-provided code to make an authorization decision.
|
[Authorization](/docs/reference/access-authn-authz/webhook/) determines whether specific users can read, write, and do other operations on API resources. It just works at the level of whole resources -- it doesn't discriminate based on arbitrary object fields. If the built-in authorization options don't meet your needs, and [Authorization webhook](/docs/reference/access-authn-authz/webhook/) allows calling out to user-provided code to make an authorization decision.
|
||||||
|
|
||||||
|
|
||||||
### Dynamic Admission Control
|
### Dynamic Admission Control
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Overall API conventions are described in the [API conventions doc](https://git.k
|
|||||||
|
|
||||||
API endpoints, resource types and samples are described in [API Reference](/docs/reference).
|
API endpoints, resource types and samples are described in [API Reference](/docs/reference).
|
||||||
|
|
||||||
Remote access to the API is discussed in the [access doc](/docs/admin/accessing-the-api).
|
Remote access to the API is discussed in the [Controlling API Access doc](/docs/reference/access-authn-authz/controlling-access/).
|
||||||
|
|
||||||
The Kubernetes API also serves as the foundation for the declarative configuration schema for the system. The [kubectl](/docs/reference/kubectl/overview/) command-line tool can be used to create, update, delete, and get API objects.
|
The Kubernetes API also serves as the foundation for the declarative configuration schema for the system. The [kubectl](/docs/reference/kubectl/overview/) command-line tool can be used to create, update, delete, and get API objects.
|
||||||
|
|
||||||
|
|||||||
@@ -65,18 +65,18 @@ configuration file that was used to create the object.
|
|||||||
|
|
||||||
Here's an example of an object configuration file:
|
Here's an example of an object configuration file:
|
||||||
|
|
||||||
{{< code file="simple_deployment.yaml" >}}
|
{{< codenew file="application/simple_deployment.yaml" >}}
|
||||||
|
|
||||||
Create the object using `kubectl apply`:
|
Create the object using `kubectl apply`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml
|
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Print the live configuration using `kubectl get`:
|
Print the live configuration using `kubectl get`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml -o yaml
|
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The output shows that the `kubectl.kubernetes.io/last-applied-configuration` annotation
|
The output shows that the `kubectl.kubernetes.io/last-applied-configuration` annotation
|
||||||
@@ -139,12 +139,12 @@ kubectl apply -f <directory>/
|
|||||||
|
|
||||||
Here's an example configuration file:
|
Here's an example configuration file:
|
||||||
|
|
||||||
{{< code file="simple_deployment.yaml" >}}
|
{{< codenew file="application/simple_deployment.yaml" >}}
|
||||||
|
|
||||||
Create the object using `kubectl apply`:
|
Create the object using `kubectl apply`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml
|
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
@@ -155,7 +155,7 @@ configuration file instead of a directory.
|
|||||||
Print the live configuration using `kubectl get`:
|
Print the live configuration using `kubectl get`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml -o yaml
|
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The output shows that the `kubectl.kubernetes.io/last-applied-configuration` annotation
|
The output shows that the `kubectl.kubernetes.io/last-applied-configuration` annotation
|
||||||
@@ -210,7 +210,7 @@ kubectl scale deployment/nginx-deployment --replicas=2
|
|||||||
Print the live configuration using `kubectl get`:
|
Print the live configuration using `kubectl get`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml -o yaml
|
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The output shows that the `replicas` field has been set to 2, and the `last-applied-configuration`
|
The output shows that the `replicas` field has been set to 2, and the `last-applied-configuration`
|
||||||
@@ -257,18 +257,18 @@ spec:
|
|||||||
Update the `simple_deployment.yaml` configuration file to change the image from
|
Update the `simple_deployment.yaml` configuration file to change the image from
|
||||||
`nginx:1.7.9` to `nginx:1.11.9`, and delete the `minReadySeconds` field:
|
`nginx:1.7.9` to `nginx:1.11.9`, and delete the `minReadySeconds` field:
|
||||||
|
|
||||||
{{< code file="update_deployment.yaml" >}}
|
{{< codenew file="application/update_deployment.yaml" >}}
|
||||||
|
|
||||||
Apply the changes made to the configuration file:
|
Apply the changes made to the configuration file:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://k8s.io/docs/concepts/overview/object-management-kubectl/update_deployment.yaml
|
kubectl apply -f https://k8s.io/examples/application/update_deployment.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Print the live configuration using `kubectl get`:
|
Print the live configuration using `kubectl get`:
|
||||||
|
|
||||||
```
|
```
|
||||||
kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml -o yaml
|
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The output shows the following changes to the live configuration:
|
The output shows the following changes to the live configuration:
|
||||||
@@ -417,7 +417,7 @@ to calculate which fields should be deleted or set:
|
|||||||
|
|
||||||
Here's an example. Suppose this is the configuration file for a Deployment object:
|
Here's an example. Suppose this is the configuration file for a Deployment object:
|
||||||
|
|
||||||
{{< code file="update_deployment.yaml" >}}
|
{{< codenew file="application/update_deployment.yaml" >}}
|
||||||
|
|
||||||
Also, suppose this is the live configuration for the same Deployment object:
|
Also, suppose this is the live configuration for the same Deployment object:
|
||||||
|
|
||||||
@@ -463,7 +463,10 @@ Here are the merge calculations that would be performed by `kubectl apply`:
|
|||||||
|
|
||||||
1. Calculate the fields to delete by reading values from
|
1. Calculate the fields to delete by reading values from
|
||||||
`last-applied-configuration` and comparing them to values in the
|
`last-applied-configuration` and comparing them to values in the
|
||||||
configuration file. In this example, `minReadySeconds` appears in the
|
configuration file.
|
||||||
|
Clear fields explicitly set to null in the local object configuration file
|
||||||
|
regardless of whether they appear in the `last-applied-configuration`.
|
||||||
|
In this example, `minReadySeconds` appears in the
|
||||||
`last-applied-configuration` annotation, but does not appear in the configuration file.
|
`last-applied-configuration` annotation, but does not appear in the configuration file.
|
||||||
**Action:** Clear `minReadySeconds` from the live configuration.
|
**Action:** Clear `minReadySeconds` from the live configuration.
|
||||||
2. Calculate the fields to set by reading values from the configuration
|
2. Calculate the fields to set by reading values from the configuration
|
||||||
@@ -517,12 +520,6 @@ spec:
|
|||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< comment >}}
|
|
||||||
TODO(1.6): For 1.6, add the following bullet point to 1.
|
|
||||||
|
|
||||||
- clear fields explicitly set to null in the local object configuration file regardless of whether they appear in the last-applied-configuration
|
|
||||||
{{< /comment >}}
|
|
||||||
|
|
||||||
### How different types of fields are merged
|
### How different types of fields are merged
|
||||||
|
|
||||||
How a particular field in a configuration file is merged with
|
How a particular field in a configuration file is merged with
|
||||||
@@ -716,18 +713,18 @@ not specified when the object is created.
|
|||||||
|
|
||||||
Here's a configuration file for a Deployment. The file does not specify `strategy`:
|
Here's a configuration file for a Deployment. The file does not specify `strategy`:
|
||||||
|
|
||||||
{{< code file="simple_deployment.yaml" >}}
|
{{< codenew file="application/simple_deployment.yaml" >}}
|
||||||
|
|
||||||
Create the object using `kubectl apply`:
|
Create the object using `kubectl apply`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml
|
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Print the live configuration using `kubectl get`:
|
Print the live configuration using `kubectl get`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml -o yaml
|
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The output shows that the API server set several fields to default values in the live
|
The output shows that the API server set several fields to default values in the live
|
||||||
@@ -871,31 +868,10 @@ Recommendation: These fields should be explicitly defined in the object configur
|
|||||||
|
|
||||||
### How to clear server-defaulted fields or fields set by other writers
|
### How to clear server-defaulted fields or fields set by other writers
|
||||||
|
|
||||||
As of Kubernetes 1.5, fields that do not appear in the configuration file cannot be
|
|
||||||
cleared by a merge operation. Here are some workarounds:
|
|
||||||
|
|
||||||
Option 1: Remove the field by directly modifying the live object.
|
|
||||||
|
|
||||||
{{< note >}}
|
|
||||||
**Note:** As of Kubernetes 1.5, `kubectl edit` does not work with `kubectl apply`.
|
|
||||||
Using these together will cause unexpected behavior.
|
|
||||||
{{< /note >}}
|
|
||||||
|
|
||||||
Option 2: Remove the field through the configuration file.
|
|
||||||
|
|
||||||
1. Add the field to the configuration file to match the live object.
|
|
||||||
1. Apply the configuration file; this updates the annotation to include the field.
|
|
||||||
1. Delete the field from the configuration file.
|
|
||||||
1. Apply the configuration file; this deletes the field from the live object and annotation.
|
|
||||||
|
|
||||||
{{< comment >}}
|
|
||||||
TODO(1.6): Update this with the following for 1.6
|
|
||||||
|
|
||||||
Fields that do not appear in the configuration file can be cleared by
|
Fields that do not appear in the configuration file can be cleared by
|
||||||
setting their values to `null` and then applying the configuration file.
|
setting their values to `null` and then applying the configuration file.
|
||||||
For fields defaulted by the server, this triggers re-defaulting
|
For fields defaulted by the server, this triggers re-defaulting
|
||||||
the values.
|
the values.
|
||||||
{{< /comment >}}
|
|
||||||
|
|
||||||
## How to change ownership of a field between the configuration file and direct imperative writers
|
## How to change ownership of a field between the configuration file and direct imperative writers
|
||||||
|
|
||||||
@@ -994,13 +970,6 @@ template:
|
|||||||
controller-selector: "extensions/v1beta1/deployment/nginx"
|
controller-selector: "extensions/v1beta1/deployment/nginx"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Known Issues
|
|
||||||
|
|
||||||
* Prior to Kubernetes 1.6, `kubectl apply` did not support operating on objects stored in a
|
|
||||||
[custom resource](/docs/concepts/api-extension/custom-resources/).
|
|
||||||
For these cluster versions, you should instead use [imperative object configuration](/docs/concepts/overview/object-management-kubectl/imperative-config/).
|
|
||||||
{{% /capture %}}
|
|
||||||
|
|
||||||
{{% capture whatsnext %}}
|
{{% capture whatsnext %}}
|
||||||
- [Managing Kubernetes Objects Using Imperative Commands](/docs/concepts/overview/object-management-kubectl/imperative-command/)
|
- [Managing Kubernetes Objects Using Imperative Commands](/docs/concepts/overview/object-management-kubectl/imperative-command/)
|
||||||
- [Imperative Management of Kubernetes Objects Using Configuration Files](/docs/concepts/overview/object-management-kubectl/imperative-config/)
|
- [Imperative Management of Kubernetes Objects Using Configuration Files](/docs/concepts/overview/object-management-kubectl/imperative-config/)
|
||||||
|
|||||||
@@ -36,12 +36,14 @@ 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:
|
Here's an example `.yaml` file that shows the required fields and object spec for a Kubernetes Deployment:
|
||||||
|
|
||||||
{{< code file="nginx-deployment.yaml" >}}
|
{{< codenew file="application/deployment.yaml" >}}
|
||||||
|
|
||||||
One way to create a Deployment using a `.yaml` file like the one above is to use the [`kubectl create`](/docs/reference/generated/kubectl/kubectl-commands#create) command in the `kubectl` command-line interface, passing the `.yaml` file as an argument. Here's an example:
|
One way to create a Deployment using a `.yaml` file like the one above is to use the
|
||||||
|
[`kubectl create`](/docs/reference/generated/kubectl/kubectl-commands#create) command
|
||||||
|
in the `kubectl` command-line interface, passing the `.yaml` file as an argument. Here's an example:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl create -f https://k8s.io/docs/concepts/overview/working-with-objects/nginx-deployment.yaml --record
|
$ kubectl create -f https://k8s.io/examples/application/deployment.yaml --record
|
||||||
```
|
```
|
||||||
|
|
||||||
The output is similar to this:
|
The output is similar to this:
|
||||||
|
|||||||
@@ -98,4 +98,14 @@ in some namespaces. However namespace resources are not themselves in a namespa
|
|||||||
And low-level resources, such as [nodes](/docs/admin/node) and
|
And low-level resources, such as [nodes](/docs/admin/node) and
|
||||||
persistentVolumes, are not in any namespace.
|
persistentVolumes, are not in any namespace.
|
||||||
|
|
||||||
|
To see which Kubernetes resources are and aren't in a namespace:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# In a namespace
|
||||||
|
$ kubectl api-resources --namespaced=true
|
||||||
|
|
||||||
|
# Not in a namespace
|
||||||
|
$ kubectl api-resources --namespaced=false
|
||||||
|
```
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: nginx-deployment
|
|
||||||
spec:
|
|
||||||
replicas: 3
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: nginx
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: nginx
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: nginx
|
|
||||||
image: nginx:1.7.9
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
@@ -144,11 +144,11 @@ example of authorizing a PodSecurityPolicy, see
|
|||||||
### Troubleshooting
|
### Troubleshooting
|
||||||
|
|
||||||
- The [Controller Manager](/docs/admin/kube-controller-manager/) must be run
|
- The [Controller Manager](/docs/admin/kube-controller-manager/) must be run
|
||||||
against [the secured API port](/docs/admin/accessing-the-api/), and must not
|
against [the secured API port](/docs/reference/access-authn-authz/controlling-access/),
|
||||||
have superuser permissions. Otherwise requests would bypass authentication and
|
and must not have superuser permissions. Otherwise requests would bypass
|
||||||
authorization modules, all PodSecurityPolicy objects would be allowed, and users
|
authentication and authorization modules, all PodSecurityPolicy objects would be
|
||||||
would be able to create privileged containers. For more details on configuring
|
allowed, and users would be able to create privileged containers. For more details
|
||||||
Controller Manager authorization, see [Controller
|
on configuring Controller Manager authorization, see [Controller
|
||||||
Roles](/docs/admin/authorization/rbac/#controller-roles).
|
Roles](/docs/admin/authorization/rbac/#controller-roles).
|
||||||
|
|
||||||
## Policy Order
|
## Policy Order
|
||||||
|
|||||||
+16
-17
@@ -44,13 +44,17 @@ fe00::2 ip6-allrouters
|
|||||||
10.200.0.4 nginx
|
10.200.0.4 nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
by default, the hosts file only includes ipv4 and ipv6 boilerplates like `localhost` and its own hostname.
|
By default, the `hosts` file only includes IPv4 and IPv6 boilerplates like
|
||||||
|
`localhost` and its own hostname.
|
||||||
|
|
||||||
## Adding Additional Entries with HostAliases
|
## Adding Additional Entries with HostAliases
|
||||||
|
|
||||||
In addition to the default boilerplate, we can add additional entries to the hosts file to resolve `foo.local`, `bar.local` to `127.0.0.1` and `foo.remote`, `bar.remote` to `10.1.2.3`, we can by adding HostAliases to the Pod under `.spec.hostAliases`:
|
In addition to the default boilerplate, we can add additional entries to the
|
||||||
|
`hosts` file to resolve `foo.local`, `bar.local` to `127.0.0.1` and `foo.remote`,
|
||||||
|
`bar.remote` to `10.1.2.3`, we can by adding HostAliases to the Pod under
|
||||||
|
`.spec.hostAliases`:
|
||||||
|
|
||||||
{{< code file="hostaliases-pod.yaml" >}}
|
{{< codenew file="service/networking/hostaliases-pod.yaml" >}}
|
||||||
|
|
||||||
This Pod can be started with the following commands:
|
This Pod can be started with the following commands:
|
||||||
|
|
||||||
@@ -63,7 +67,7 @@ NAME READY STATUS RESTARTS AGE IP
|
|||||||
hostaliases-pod 0/1 Completed 0 6s 10.244.135.10 node3
|
hostaliases-pod 0/1 Completed 0 6s 10.244.135.10 node3
|
||||||
```
|
```
|
||||||
|
|
||||||
The hosts file content would look like this:
|
The `hosts` file content would look like this:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl logs hostaliases-pod
|
$ kubectl logs hostaliases-pod
|
||||||
@@ -83,22 +87,17 @@ fe00::2 ip6-allrouters
|
|||||||
|
|
||||||
With the additional entries specified at the bottom.
|
With the additional entries specified at the bottom.
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
HostAlias is only supported in 1.7+.
|
|
||||||
|
|
||||||
HostAlias support in 1.7 is limited to non-hostNetwork Pods because kubelet only manages the hosts file for non-hostNetwork Pods.
|
|
||||||
|
|
||||||
In 1.8, HostAlias is supported for all Pods regardless of network configuration.
|
|
||||||
|
|
||||||
## Why Does Kubelet Manage the Hosts File?
|
## Why Does Kubelet Manage the Hosts File?
|
||||||
|
|
||||||
Kubelet [manages](https://github.com/kubernetes/kubernetes/issues/14633) the hosts file for each container of the Pod to prevent Docker from [modifying](https://github.com/moby/moby/issues/17190) the file after the containers have already been started.
|
Kubelet [manages](https://github.com/kubernetes/kubernetes/issues/14633) the
|
||||||
|
`hosts` file for each container of the Pod to prevent Docker from
|
||||||
|
[modifying](https://github.com/moby/moby/issues/17190) the file after the
|
||||||
|
containers have already been started.
|
||||||
|
|
||||||
Because of the managed-nature of the file, any user-written content will be overwritten whenever the hosts file is remounted by Kubelet in the event of a container restart or a Pod reschedule. Thus, it is not suggested to modify the contents of the file.
|
Because of the managed-nature of the file, any user-written content will be
|
||||||
|
overwritten whenever the `hosts` file is remounted by Kubelet in the event of
|
||||||
|
a container restart or a Pod reschedule. Thus, it is not suggested to modify
|
||||||
|
the contents of the file.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
{{% capture whatsnext %}}
|
|
||||||
|
|
||||||
{{% /capture %}}
|
|
||||||
|
|||||||
@@ -28,11 +28,12 @@ This guide uses a simple nginx server to demonstrate proof of concept. The same
|
|||||||
|
|
||||||
## Exposing pods to the cluster
|
## Exposing pods to the cluster
|
||||||
|
|
||||||
We did this in a previous example, but let's do it once again and focus on the networking perspective. Create an nginx pod, and note that it has a container port specification:
|
We did this in a previous example, but let's do it once again and focus on the networking perspective.
|
||||||
|
Create an nginx Pod, and note that it has a container port specification:
|
||||||
|
|
||||||
{{< code file="run-my-nginx.yaml" >}}
|
{{< codenew file="service/networking/run-my-nginx.yaml" >}}
|
||||||
|
|
||||||
This makes it accessible from any node in your cluster. Check the nodes the pod is running on:
|
This makes it accessible from any node in your cluster. Check the nodes the Pod is running on:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl create -f ./run-my-nginx.yaml
|
$ kubectl create -f ./run-my-nginx.yaml
|
||||||
@@ -69,9 +70,15 @@ service "my-nginx" exposed
|
|||||||
|
|
||||||
This is equivalent to `kubectl create -f` the following yaml:
|
This is equivalent to `kubectl create -f` the following yaml:
|
||||||
|
|
||||||
{{< code file="nginx-svc.yaml" >}}
|
{{< codenew file="service/networking/nginx-svc.yaml" >}}
|
||||||
|
|
||||||
This specification will create a Service which targets TCP port 80 on any Pod with the `run: my-nginx` label, and expose it on an abstracted Service port (`targetPort`: is the port the container accepts traffic on, `port`: is the abstracted Service port, which can be any port other pods use to access the Service). View [service API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core) to see the list of supported fields in service definition.
|
This specification will create a Service which targets TCP port 80 on any Pod
|
||||||
|
with the `run: my-nginx` label, and expose it on an abstracted Service port
|
||||||
|
(`targetPort`: is the port the container accepts traffic on, `port`: is the
|
||||||
|
abstracted Service port, which can be any port other pods use to access the
|
||||||
|
Service).
|
||||||
|
View [Service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core)
|
||||||
|
API object to see the list of supported fields in service definition.
|
||||||
Check your Service:
|
Check your Service:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -80,7 +87,13 @@ NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
|||||||
my-nginx 10.0.162.149 <none> 80/TCP 21s
|
my-nginx 10.0.162.149 <none> 80/TCP 21s
|
||||||
```
|
```
|
||||||
|
|
||||||
As mentioned previously, a Service is backed by a group of pods. These pods are exposed through `endpoints`. The Service's selector will be evaluated continuously and the results will be POSTed to an Endpoints object also named `my-nginx`. When a pod dies, it is automatically removed from the endpoints, and new pods matching the Service's selector will automatically get added to the endpoints. Check the endpoints, and note that the IPs are the same as the pods created in the first step:
|
As mentioned previously, a Service is backed by a group of Pods. These Pods are
|
||||||
|
exposed through `endpoints`. The Service's selector will be evaluated continuously
|
||||||
|
and the results will be POSTed to an Endpoints object also named `my-nginx`.
|
||||||
|
When a Pod dies, it is automatically removed from the endpoints, and new Pods
|
||||||
|
matching the Service's selector will automatically get added to the endpoints.
|
||||||
|
Check the endpoints, and note that the IPs are the same as the Pods created in
|
||||||
|
the first step:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl describe svc my-nginx
|
$ kubectl describe svc my-nginx
|
||||||
@@ -101,15 +114,22 @@ NAME ENDPOINTS AGE
|
|||||||
my-nginx 10.244.2.5:80,10.244.3.4:80 1m
|
my-nginx 10.244.2.5:80,10.244.3.4:80 1m
|
||||||
```
|
```
|
||||||
|
|
||||||
You should now be able to curl the nginx Service on `<CLUSTER-IP>:<PORT>` from any node in your cluster. Note that the Service IP is completely virtual, it never hits the wire, if you're curious about how this works you can read more about the [service proxy](/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies).
|
You should now be able to curl the nginx Service on `<CLUSTER-IP>:<PORT>` from
|
||||||
|
any node in your cluster. Note that the Service IP is completely virtual, it
|
||||||
|
never hits the wire. If you're curious about how this works you can read more
|
||||||
|
about the [service proxy](/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies).
|
||||||
|
|
||||||
## Accessing the Service
|
## Accessing the Service
|
||||||
|
|
||||||
Kubernetes supports 2 primary modes of finding a Service - environment variables and DNS. The former works out of the box while the latter requires the [kube-dns cluster addon](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kube-dns/README.md).
|
Kubernetes supports 2 primary modes of finding a Service - environment variables
|
||||||
|
and DNS. The former works out of the box while the latter requires the
|
||||||
|
[kube-dns cluster addon](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kube-dns/README.md).
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
When a Pod runs on a Node, the kubelet adds a set of environment variables for each active Service. This introduces an ordering problem. To see why, inspect the environment of your running nginx pods (your pod name will be different):
|
When a Pod runs on a Node, the kubelet adds a set of environment variables for
|
||||||
|
each active Service. This introduces an ordering problem. To see why, inspect
|
||||||
|
the environment of your running nginx Pods (your Pod name will be different):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
|
$ kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
|
||||||
@@ -118,7 +138,14 @@ KUBERNETES_SERVICE_PORT=443
|
|||||||
KUBERNETES_SERVICE_PORT_HTTPS=443
|
KUBERNETES_SERVICE_PORT_HTTPS=443
|
||||||
```
|
```
|
||||||
|
|
||||||
Note there's no mention of your Service. This is because you created the replicas before the Service. Another disadvantage of doing this is that the scheduler might put both pods on the same machine, which will take your entire Service down if it dies. We can do this the right way by killing the 2 pods and waiting for the Deployment to recreate them. This time around the Service exists *before* the replicas. This will give you scheduler-level Service spreading of your pods (provided all your nodes have equal capacity), as well as the right environment variables:
|
Note there's no mention of your Service. This is because you created the replicas
|
||||||
|
before the Service. Another disadvantage of doing this is that the scheduler might
|
||||||
|
put both Pods on the same machine, which will take your entire Service down if
|
||||||
|
it dies. We can do this the right way by killing the 2 Pods and waiting for the
|
||||||
|
Deployment to recreate them. This time around the Service exists *before* the
|
||||||
|
replicas. This will give you scheduler-level Service spreading of your Pods
|
||||||
|
(provided all your nodes have equal capacity), as well as the right environment
|
||||||
|
variables:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2;
|
$ kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2;
|
||||||
@@ -150,7 +177,11 @@ NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
|||||||
kube-dns 10.0.0.10 <none> 53/UDP,53/TCP 8m
|
kube-dns 10.0.0.10 <none> 53/UDP,53/TCP 8m
|
||||||
```
|
```
|
||||||
|
|
||||||
If it isn't running, you can [enable it](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md#how-do-i-configure-it). The rest of this section will assume you have a Service with a long lived IP (my-nginx), and a dns server that has assigned a name to that IP (the kube-dns cluster addon), so you can talk to the Service from any pod in your cluster using standard methods (e.g. gethostbyname). Let's run another curl application to test this:
|
If it isn't running, you can [enable it](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md#how-do-i-configure-it).
|
||||||
|
The rest of this section will assume you have a Service with a long lived IP
|
||||||
|
(my-nginx), and a DNS server that has assigned a name to that IP (the kube-dns
|
||||||
|
cluster addon), so you can talk to the Service from any pod in your cluster using
|
||||||
|
standard methods (e.g. gethostbyname). Let's run another curl application to test this:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl run curl --image=radial/busyboxplus:curl -i --tty
|
$ kubectl run curl --image=radial/busyboxplus:curl -i --tty
|
||||||
@@ -221,13 +252,16 @@ nginxsecret Opaque 2 1m
|
|||||||
|
|
||||||
Now modify your nginx replicas to start an https server using the certificate in the secret, and the Service, to expose both ports (80 and 443):
|
Now modify your nginx replicas to start an https server using the certificate in the secret, and the Service, to expose both ports (80 and 443):
|
||||||
|
|
||||||
{{< code file="nginx-secure-app.yaml" >}}
|
{{< codenew file="service/networking/nginx-secure-app.yaml" >}}
|
||||||
|
|
||||||
Noteworthy points about the nginx-secure-app manifest:
|
Noteworthy points about the nginx-secure-app manifest:
|
||||||
|
|
||||||
- It contains both Deployment and Service specification in the same file.
|
- It contains both Deployment and Service specification in the same file.
|
||||||
- The [nginx server](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/https-nginx/default.conf) serves http traffic on port 80 and https traffic on 443, and nginx Service exposes both ports.
|
- The [nginx server](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/https-nginx/default.conf)
|
||||||
- Each container has access to the keys through a volume mounted at /etc/nginx/ssl. This is setup *before* the nginx server is started.
|
serves HTTP traffic on port 80 and HTTPS traffic on 443, and nginx Service
|
||||||
|
exposes both ports.
|
||||||
|
- Each container has access to the keys through a volume mounted at `/etc/nginx/ssl`.
|
||||||
|
This is setup *before* the nginx server is started.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml
|
$ kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml
|
||||||
@@ -247,7 +281,7 @@ Note how we supplied the `-k` parameter to curl in the last step, this is becaus
|
|||||||
so we have to tell curl to ignore the CName mismatch. By creating a Service we linked the CName used in the certificate with the actual DNS name used by pods during Service lookup.
|
so we have to tell curl to ignore the CName mismatch. By creating a Service we linked the CName used in the certificate with the actual DNS name used by pods during Service lookup.
|
||||||
Let's test this from a pod (the same secret is being reused for simplicity, the pod only needs nginx.crt to access the Service):
|
Let's test this from a pod (the same secret is being reused for simplicity, the pod only needs nginx.crt to access the Service):
|
||||||
|
|
||||||
{{< code file="curlpod.yaml" >}}
|
{{< codenew file="service/networking/curlpod.yaml" >}}
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl create -f ./curlpod.yaml
|
$ kubectl create -f ./curlpod.yaml
|
||||||
@@ -262,7 +296,11 @@ $ kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacer
|
|||||||
|
|
||||||
## Exposing the Service
|
## Exposing the Service
|
||||||
|
|
||||||
For some parts of your applications you may want to expose a Service onto an external IP address. Kubernetes supports two ways of doing this: NodePorts and LoadBalancers. The Service created in the last section already used `NodePort`, so your nginx https replica is ready to serve traffic on the internet if your node has a public IP.
|
For some parts of your applications you may want to expose a Service onto an
|
||||||
|
external IP address. Kubernetes supports two ways of doing this: NodePorts and
|
||||||
|
LoadBalancers. The Service created in the last section already used `NodePort`,
|
||||||
|
so your nginx HTTPS replica is ready to serve traffic on the internet if your
|
||||||
|
node has a public IP.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl get svc my-nginx -o yaml | grep nodePort -C 5
|
$ kubectl get svc my-nginx -o yaml | grep nodePort -C 5
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ Below are the properties a user can specify in the `dnsConfig` field:
|
|||||||
|
|
||||||
The following is an example Pod with custom DNS settings:
|
The following is an example Pod with custom DNS settings:
|
||||||
|
|
||||||
{{< code file="custom-dns.yaml" >}}
|
{{< codenew file="service/networking/custom-dns.yaml" >}}
|
||||||
|
|
||||||
When the Pod above is created, the container `test` gets the following contents
|
When the Pod above is created, the container `test` gets the following contents
|
||||||
in its `/etc/resolv.conf` file:
|
in its `/etc/resolv.conf` file:
|
||||||
|
|||||||
@@ -111,9 +111,11 @@ Make sure you review your controller's specific docs so you understand the cavea
|
|||||||
|
|
||||||
### Single Service Ingress
|
### Single Service Ingress
|
||||||
|
|
||||||
There are existing Kubernetes concepts that allow you to expose a single service (see [alternatives](#alternatives)), however you can do so through an Ingress as well, by specifying a *default backend* with no rules.
|
There are existing Kubernetes concepts that allow you to expose a single Service
|
||||||
|
(see [alternatives](#alternatives)), however you can do so through an Ingress
|
||||||
|
as well, by specifying a *default backend* with no rules.
|
||||||
|
|
||||||
{{< code file="ingress.yaml" >}}
|
{{< codenew file="service/networking/ingress.yaml" >}}
|
||||||
|
|
||||||
If you create it using `kubectl create -f` you should see:
|
If you create it using `kubectl create -f` you should see:
|
||||||
|
|
||||||
@@ -123,11 +125,17 @@ NAME RULE BACKEND ADDRESS
|
|||||||
test-ingress - testsvc:80 107.178.254.228
|
test-ingress - testsvc:80 107.178.254.228
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `107.178.254.228` is the IP allocated by the Ingress controller to satisfy this Ingress. The `RULE` column shows that all traffic sent to the IP is directed to the Kubernetes Service listed under `BACKEND`.
|
Where `107.178.254.228` is the IP allocated by the Ingress controller to satisfy
|
||||||
|
this Ingress. The `RULE` column shows that all traffic sent to the IP are
|
||||||
|
directed to the Kubernetes Service listed under `BACKEND`.
|
||||||
|
|
||||||
### Simple fanout
|
### Simple fanout
|
||||||
|
|
||||||
As described previously, pods within kubernetes have IPs only visible on the cluster network, so we need something at the edge accepting ingress traffic and proxying it to the right endpoints. This component is usually a highly available loadbalancer. An Ingress allows you to keep the number of loadbalancers down to a minimum, for example, a setup like:
|
As described previously, Pods within kubernetes have IPs only visible on the
|
||||||
|
cluster network, so we need something at the edge accepting ingress traffic and
|
||||||
|
proxying it to the right endpoints. This component is usually a highly available
|
||||||
|
loadbalancer. An Ingress allows you to keep the number of loadbalancers down
|
||||||
|
to a minimum. For example, a setup like:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
foo.bar.com -> 178.91.123.132 -> / foo s1:80
|
foo.bar.com -> 178.91.123.132 -> / foo s1:80
|
||||||
@@ -168,7 +176,10 @@ test -
|
|||||||
/foo s1:80
|
/foo s1:80
|
||||||
/bar s2:80
|
/bar s2:80
|
||||||
```
|
```
|
||||||
The Ingress controller will provision an implementation specific loadbalancer that satisfies the Ingress, as long as the services (s1, s2) exist. When it has done so, you will see the address of the loadbalancer under the last column of the Ingress.
|
The Ingress controller will provision an implementation specific loadbalancer
|
||||||
|
that satisfies the Ingress, as long as the services (`s1`, `s2`) exist.
|
||||||
|
When it has done so, you will see the address of the loadbalancer under the
|
||||||
|
last column of the Ingress.
|
||||||
|
|
||||||
### Name based virtual hosting
|
### Name based virtual hosting
|
||||||
|
|
||||||
@@ -180,7 +191,8 @@ foo.bar.com --| |-> foo.bar.com s1:80
|
|||||||
bar.foo.com --| |-> bar.foo.com s2:80
|
bar.foo.com --| |-> bar.foo.com s2:80
|
||||||
```
|
```
|
||||||
|
|
||||||
The following Ingress tells the backing loadbalancer to route requests based on the [Host header](https://tools.ietf.org/html/rfc7230#section-5.4).
|
The following Ingress tells the backing loadbalancer to route requests based on
|
||||||
|
the [Host header](https://tools.ietf.org/html/rfc7230#section-5.4).
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
@@ -203,11 +215,23 @@ spec:
|
|||||||
servicePort: 80
|
servicePort: 80
|
||||||
```
|
```
|
||||||
|
|
||||||
__Default Backends__: An Ingress with no rules, like the one shown in the previous section, sends all traffic to a single default backend. You can use the same technique to tell a loadbalancer where to find your website's 404 page, by specifying a set of rules *and* a default backend. Traffic is routed to your default backend if none of the Hosts in your Ingress match the Host in the request header, and/or none of the paths match the URL of the request.
|
__Default Backends__: An Ingress with no rules, like the one shown in the previous
|
||||||
|
section, sends all traffic to a single default backend. You can use the same
|
||||||
|
technique to tell a loadbalancer where to find your website's 404 page, by
|
||||||
|
specifying a set of rules *and* a default backend. Traffic is routed to your
|
||||||
|
default backend if none of the Hosts in your Ingress match the Host in the
|
||||||
|
request header, and/or none of the paths match the URL of the request.
|
||||||
|
|
||||||
### TLS
|
### TLS
|
||||||
|
|
||||||
You can secure an Ingress by specifying a [secret](/docs/user-guide/secrets) that contains a TLS private key and certificate. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. If the TLS configuration section in an Ingress specifies different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS, e.g.:
|
You can secure an Ingress by specifying a [secret](/docs/concepts/configuration/secret)
|
||||||
|
that contains a TLS private key and certificate. Currently the Ingress only
|
||||||
|
supports a single TLS port, 443, and assumes TLS termination. If the TLS
|
||||||
|
configuration section in an Ingress specifies different hosts, they will be
|
||||||
|
multiplexed on the same port according to the hostname specified through the
|
||||||
|
SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret
|
||||||
|
must contain keys named `tls.crt` and `tls.key` that contain the certificate
|
||||||
|
and private key to use for TLS, e.g.:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
@@ -221,7 +245,8 @@ metadata:
|
|||||||
type: Opaque
|
type: Opaque
|
||||||
```
|
```
|
||||||
|
|
||||||
Referencing this secret in an Ingress will tell the Ingress controller to secure the channel from the client to the loadbalancer using TLS:
|
Referencing this secret in an Ingress will tell the Ingress controller to
|
||||||
|
secure the channel from the client to the loadbalancer using TLS:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
@@ -236,13 +261,30 @@ spec:
|
|||||||
servicePort: 80
|
servicePort: 80
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that there is a gap between TLS features supported by various Ingress controllers. Please refer to documentation on [nginx](https://git.k8s.io/ingress-nginx/README.md#https), [GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https), 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://git.k8s.io/ingress-nginx/README.md#https),
|
||||||
|
[GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https), or any other
|
||||||
|
platform specific Ingress controller to understand how TLS works in your environment.
|
||||||
|
|
||||||
### Loadbalancing
|
### Loadbalancing
|
||||||
|
|
||||||
An Ingress controller is bootstrapped with some load balancing policy settings that it applies to all Ingress, such as the load balancing algorithm, backend weight scheme, and others. More advanced load balancing 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/ingress-nginx/blob/master/docs/ingress-controller-catalog.md). With time, we plan to distill load balancing patterns that are applicable cross platform into the Ingress resource.
|
An Ingress controller is bootstrapped with some load balancing policy settings
|
||||||
|
that it applies to all Ingress, such as the load balancing algorithm, backend
|
||||||
|
weight scheme, and others. More advanced load balancing 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/ingress-nginx/blob/master/docs/ingress-controller-catalog.md).
|
||||||
|
With time, we plan to distill load balancing 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://git.k8s.io/ingress-nginx/README.md), [GCE](https://git.k8s.io/ingress-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://git.k8s.io/ingress-nginx/README.md),
|
||||||
|
[GCE](https://git.k8s.io/ingress-gce/README.md#health-checks)).
|
||||||
|
|
||||||
## Updating an Ingress
|
## Updating an Ingress
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ nodeAffinity:
|
|||||||
In addition, `node.kubernetes.io/unschedulable:NoSchedule` toleration is added
|
In addition, `node.kubernetes.io/unschedulable:NoSchedule` toleration is added
|
||||||
automatically to DaemonSet Pods. The DaemonSet controller ignores
|
automatically to DaemonSet Pods. The DaemonSet controller ignores
|
||||||
`unschedulable` Nodes when scheduling DaemonSet Pods. You must enable
|
`unschedulable` Nodes when scheduling DaemonSet Pods. You must enable
|
||||||
`TaintModesByCondition` to ensure that the default scheduler behaves the same
|
`TaintNodesByCondition` to ensure that the default scheduler behaves the same
|
||||||
way and schedules DaemonSet pods on `unschedulable` nodes.
|
way and schedules DaemonSet pods on `unschedulable` nodes.
|
||||||
|
|
||||||
When this feature and `TaintNodesByCondition` are enabled together, if DaemonSet
|
When this feature and `TaintNodesByCondition` are enabled together, if DaemonSet
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ weight: 60
|
|||||||
The role of the Kubernetes garbage collector is to delete certain objects
|
The role of the Kubernetes garbage collector is to delete certain objects
|
||||||
that once had an owner, but no longer have an owner.
|
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.
|
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ Given a deployment where the workers are named kubernetes-alpha.
|
|||||||
|
|
||||||
Deploy new workers:
|
Deploy new workers:
|
||||||
|
|
||||||
juju deploy kubernetes-beta
|
juju deploy kubernetes-alpha
|
||||||
|
|
||||||
Pause the old workers so your workload migrates:
|
Pause the old workers so your workload migrates:
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ Guide](http://kubernetes.io/docs/admin/).
|
|||||||
|
|
||||||
## Writing plugins
|
## Writing plugins
|
||||||
|
|
||||||
* **Authentication** ([Authentication](http://kubernetes.io/docs/admin/authentication/)):
|
* **Authentication** ([Authentication](http://kubernetes.io/docs/reference/access-authn-authz/authentication/)):
|
||||||
The current and planned states of authentication tokens.
|
The current and planned states of authentication tokens.
|
||||||
|
|
||||||
* **Authorization Plugins** ([Authorization](http://kubernetes.io/docs/admin/authorization/)):
|
* **Authorization Plugins** ([Authorization](http://kubernetes.io/docs/admin/authorization/)):
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ Once TLS is established, the HTTP request moves to the Authentication step.
|
|||||||
This is shown as step **1** in the diagram.
|
This is shown as step **1** in the diagram.
|
||||||
The cluster creation script or cluster admin configures the API server to run
|
The cluster creation script or cluster admin configures the API server to run
|
||||||
one or more Authenticator Modules.
|
one or more Authenticator Modules.
|
||||||
Authenticators are described in more detail [here](/docs/admin/authentication/).
|
Authenticators are described in more detail [here](/docs/reference/access-authn-authz/authentication/).
|
||||||
|
|
||||||
The input to the authentication step is the entire HTTP request, however, it typically
|
The input to the authentication step is the entire HTTP request, however, it typically
|
||||||
just examines the headers and/or client certificate.
|
just examines the headers and/or client certificate.
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ To enable X509 client certificate authentication to the kubelet's HTTPS endpoint
|
|||||||
|
|
||||||
* start the kubelet with the `--client-ca-file` flag, providing a CA bundle to verify client certificates with
|
* start the kubelet with the `--client-ca-file` flag, providing a CA bundle to verify client certificates with
|
||||||
* start the apiserver with `--kubelet-client-certificate` and `--kubelet-client-key` flags
|
* start the apiserver with `--kubelet-client-certificate` and `--kubelet-client-key` flags
|
||||||
* see the [apiserver authentication documentation](/docs/admin/authentication/#x509-client-certs) for more details
|
* see the [apiserver authentication documentation](/docs/reference/access-authn-authz/authentication/#x509-client-certs) for more details
|
||||||
|
|
||||||
To enable API bearer tokens (including service account tokens) to be used to authenticate to the kubelet's HTTPS endpoint:
|
To enable API bearer tokens (including service account tokens) to be used to authenticate to the kubelet's HTTPS endpoint:
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ and progress on the feature is being tracked as [feature #43](https://github.com
|
|||||||
|
|
||||||
## kube-apiserver configuration
|
## kube-apiserver configuration
|
||||||
|
|
||||||
The API server should be configured with an [authenticator](/docs/admin/authentication/) that can authenticate tokens as a user in the `system:bootstrappers` group.
|
The API server should be configured with an [authenticator](/docs/reference/access-authn-authz/authentication/) that can authenticate tokens as a user in the `system:bootstrappers` group.
|
||||||
|
|
||||||
This group will later be used in the controller-manager configuration to scope approvals in the default approval
|
This group will later be used in the controller-manager configuration to scope approvals in the default approval
|
||||||
controller. As this feature matures, you should ensure tokens are bound to a Role-Based Access Control (RBAC) policy which limits requests
|
controller. As this feature matures, you should ensure tokens are bound to a Role-Based Access Control (RBAC) policy which limits requests
|
||||||
@@ -45,7 +45,7 @@ name should be as depicted:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Add the `--token-auth-file=FILENAME` flag to the kube-apiserver command (in your systemd unit file perhaps) to enable the token file.
|
Add the `--token-auth-file=FILENAME` flag to the kube-apiserver command (in your systemd unit file perhaps) to enable the token file.
|
||||||
See docs [here](/docs/admin/authentication/#static-token-file) for further details.
|
See docs [here](/docs/reference/access-authn-authz/authentication/#static-token-file) for further details.
|
||||||
|
|
||||||
### Client certificate CA bundle
|
### Client certificate CA bundle
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,15 +5,35 @@ reviewers:
|
|||||||
- erictune
|
- erictune
|
||||||
- krousey
|
- krousey
|
||||||
- clove
|
- clove
|
||||||
|
content_template: templates/concept
|
||||||
---
|
---
|
||||||
|
|
||||||
|
{{% capture overview %}}
|
||||||
|
|
||||||
See also: [Kubectl Overview](/docs/reference/kubectl/overview/) and [JsonPath Guide](/docs/reference/kubectl/jsonpath).
|
See also: [Kubectl Overview](/docs/reference/kubectl/overview/) and [JsonPath Guide](/docs/reference/kubectl/jsonpath).
|
||||||
|
|
||||||
|
This page is an overview of the `kubectl` command.
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
|
||||||
|
{{% capture body %}}
|
||||||
|
|
||||||
|
# kubectl - Cheat Sheet
|
||||||
|
|
||||||
## Kubectl Autocomplete
|
## Kubectl Autocomplete
|
||||||
|
|
||||||
```console
|
### BASH
|
||||||
$ source <(kubectl completion bash) # setup autocomplete in bash, bash-completion package should be installed first.
|
|
||||||
$ source <(kubectl completion zsh) # setup autocomplete in zsh
|
```bash
|
||||||
|
source <(kubectl completion bash) # setup autocomplete in bash into the current shell, bash-completion package should be installed first.
|
||||||
|
echo "source <(kubectl completion bash)" >> ~/.bashrc # add autocomplete permanently to your bash shell.
|
||||||
|
```
|
||||||
|
|
||||||
|
### ZSH
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source <(kubectl completion zsh) # setup autocomplete in zsh into the current shell
|
||||||
|
echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc # add autocomplete permanently to your zsh shell
|
||||||
```
|
```
|
||||||
|
|
||||||
## Kubectl Context and Configuration
|
## Kubectl Context and Configuration
|
||||||
@@ -22,23 +42,23 @@ Set which Kubernetes cluster `kubectl` communicates with and modifies configurat
|
|||||||
information. See [Authenticating Across Clusters with kubeconfig](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) documentation for
|
information. See [Authenticating Across Clusters with kubeconfig](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) documentation for
|
||||||
detailed config file information.
|
detailed config file information.
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl config view # Show Merged kubeconfig settings.
|
kubectl config view # Show Merged kubeconfig settings.
|
||||||
|
|
||||||
# use multiple kubeconfig files at the same time and view merged config
|
# use multiple kubeconfig files at the same time and view merged config
|
||||||
$ KUBECONFIG=~/.kube/config:~/.kube/kubconfig2 kubectl config view
|
KUBECONFIG=~/.kube/config:~/.kube/kubconfig2 kubectl config view
|
||||||
|
|
||||||
# Get the password for the e2e user
|
# Get the password for the e2e user
|
||||||
$ kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'
|
kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'
|
||||||
|
|
||||||
$ kubectl config current-context # Display the current-context
|
kubectl config current-context # Display the current-context
|
||||||
$ kubectl config use-context my-cluster-name # set the default context to my-cluster-name
|
kubectl config use-context my-cluster-name # set the default context to my-cluster-name
|
||||||
|
|
||||||
# add a new cluster to your kubeconf that supports basic auth
|
# add a new cluster to your kubeconf that supports basic auth
|
||||||
$ kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword
|
kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword
|
||||||
|
|
||||||
# set a context utilizing a specific username and namespace.
|
# set a context utilizing a specific username and namespace.
|
||||||
$ kubectl config set-context gce --user=cluster-admin --namespace=foo \
|
kubectl config set-context gce --user=cluster-admin --namespace=foo \
|
||||||
&& kubectl config use-context gce
|
&& kubectl config use-context gce
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -47,16 +67,16 @@ $ kubectl config set-context gce --user=cluster-admin --namespace=foo \
|
|||||||
Kubernetes manifests can be defined in json or yaml. The file extension `.yaml`,
|
Kubernetes manifests can be defined in json or yaml. The file extension `.yaml`,
|
||||||
`.yml`, and `.json` can be used.
|
`.yml`, and `.json` can be used.
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl create -f ./my-manifest.yaml # create resource(s)
|
kubectl create -f ./my-manifest.yaml # create resource(s)
|
||||||
$ kubectl create -f ./my1.yaml -f ./my2.yaml # create from multiple files
|
kubectl create -f ./my1.yaml -f ./my2.yaml # create from multiple files
|
||||||
$ kubectl create -f ./dir # create resource(s) in all manifest files in dir
|
kubectl create -f ./dir # create resource(s) in all manifest files in dir
|
||||||
$ kubectl create -f https://git.io/vPieo # create resource(s) from url
|
kubectl create -f https://git.io/vPieo # create resource(s) from url
|
||||||
$ kubectl run nginx --image=nginx # start a single instance of nginx
|
kubectl run nginx --image=nginx # start a single instance of nginx
|
||||||
$ kubectl explain pods,svc # get the documentation for pod and svc manifests
|
kubectl explain pods,svc # get the documentation for pod and svc manifests
|
||||||
|
|
||||||
# Create multiple YAML objects from stdin
|
# Create multiple YAML objects from stdin
|
||||||
$ cat <<EOF | kubectl create -f -
|
cat <<EOF | kubectl create -f -
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
@@ -83,7 +103,7 @@ spec:
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create a secret with several keys
|
# Create a secret with several keys
|
||||||
$ cat <<EOF | kubectl create -f -
|
cat <<EOF | kubectl create -f -
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
@@ -98,145 +118,145 @@ EOF
|
|||||||
|
|
||||||
## Viewing, Finding Resources
|
## Viewing, Finding Resources
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
# Get commands with basic output
|
# Get commands with basic output
|
||||||
$ kubectl get services # List all services in the namespace
|
kubectl get services # List all services in the namespace
|
||||||
$ kubectl get pods --all-namespaces # List all pods in all namespaces
|
kubectl get pods --all-namespaces # List all pods in all namespaces
|
||||||
$ kubectl get pods -o wide # List all pods in the namespace, with more details
|
kubectl get pods -o wide # List all pods in the namespace, with more details
|
||||||
$ kubectl get deployment my-dep # List a particular deployment
|
kubectl get deployment my-dep # List a particular deployment
|
||||||
$ kubectl get pods --include-uninitialized # List all pods in the namespace, including uninitialized ones
|
kubectl get pods --include-uninitialized # List all pods in the namespace, including uninitialized ones
|
||||||
|
|
||||||
# Describe commands with verbose output
|
# Describe commands with verbose output
|
||||||
$ kubectl describe nodes my-node
|
kubectl describe nodes my-node
|
||||||
$ kubectl describe pods my-pod
|
kubectl describe pods my-pod
|
||||||
|
|
||||||
$ kubectl get services --sort-by=.metadata.name # List Services Sorted by Name
|
kubectl get services --sort-by=.metadata.name # List Services Sorted by Name
|
||||||
|
|
||||||
# List pods Sorted by Restart Count
|
# List pods Sorted by Restart Count
|
||||||
$ kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
|
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
|
||||||
|
|
||||||
# Get the version label of all pods with label app=cassandra
|
# Get the version label of all pods with label app=cassandra
|
||||||
$ kubectl get pods --selector=app=cassandra rc -o \
|
kubectl get pods --selector=app=cassandra rc -o \
|
||||||
jsonpath='{.items[*].metadata.labels.version}'
|
jsonpath='{.items[*].metadata.labels.version}'
|
||||||
|
|
||||||
# Get all running pods in the namespace
|
# Get all running pods in the namespace
|
||||||
$ kubectl get pods --field-selector=status.phase=Running
|
kubectl get pods --field-selector=status.phase=Running
|
||||||
|
|
||||||
# Get ExternalIPs of all nodes
|
# Get ExternalIPs of all nodes
|
||||||
$ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'
|
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'
|
||||||
|
|
||||||
# List Names of Pods that belong to Particular RC
|
# List Names of Pods that belong to Particular RC
|
||||||
# "jq" command useful for transformations that are too complex for jsonpath, it can be found at https://stedolan.github.io/jq/
|
# "jq" command useful for transformations that are too complex for jsonpath, it can be found at https://stedolan.github.io/jq/
|
||||||
$ sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
|
sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
|
||||||
$ echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})
|
echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})
|
||||||
|
|
||||||
# Check which nodes are ready
|
# Check which nodes are ready
|
||||||
$ JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
|
JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
|
||||||
&& kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"
|
&& kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"
|
||||||
|
|
||||||
# List all Secrets currently in use by a pod
|
# List all Secrets currently in use by a pod
|
||||||
$ kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
|
kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
|
||||||
|
|
||||||
# List Events sorted by timestamp
|
# List Events sorted by timestamp
|
||||||
$ kubectl get events --sort-by=.metadata.creationTimestamp
|
kubectl get events --sort-by=.metadata.creationTimestamp
|
||||||
```
|
```
|
||||||
|
|
||||||
## Updating Resources
|
## Updating Resources
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl rolling-update frontend-v1 -f frontend-v2.json # Rolling update pods of frontend-v1
|
kubectl rolling-update frontend-v1 -f frontend-v2.json # Rolling update pods of frontend-v1
|
||||||
$ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 # Change the name of the resource and update the image
|
kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 # Change the name of the resource and update the image
|
||||||
$ kubectl rolling-update frontend --image=image:v2 # Update the pods image of frontend
|
kubectl rolling-update frontend --image=image:v2 # Update the pods image of frontend
|
||||||
$ kubectl rolling-update frontend-v1 frontend-v2 --rollback # Abort existing rollout in progress
|
kubectl rolling-update frontend-v1 frontend-v2 --rollback # Abort existing rollout in progress
|
||||||
$ cat pod.json | kubectl replace -f - # Replace a pod based on the JSON passed into stdin
|
cat pod.json | kubectl replace -f - # Replace a pod based on the JSON passed into stdin
|
||||||
|
|
||||||
# Force replace, delete and then re-create the resource. Will cause a service outage.
|
# Force replace, delete and then re-create the resource. Will cause a service outage.
|
||||||
$ kubectl replace --force -f ./pod.json
|
kubectl replace --force -f ./pod.json
|
||||||
|
|
||||||
# Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000
|
# Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000
|
||||||
$ kubectl expose rc nginx --port=80 --target-port=8000
|
kubectl expose rc nginx --port=80 --target-port=8000
|
||||||
|
|
||||||
# Update a single-container pod's image version (tag) to v4
|
# Update a single-container pod's image version (tag) to v4
|
||||||
$ kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
|
kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
|
||||||
|
|
||||||
$ kubectl label pods my-pod new-label=awesome # Add a Label
|
kubectl label pods my-pod new-label=awesome # Add a Label
|
||||||
$ kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # Add an annotation
|
kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # Add an annotation
|
||||||
$ kubectl autoscale deployment foo --min=2 --max=10 # Auto scale a deployment "foo"
|
kubectl autoscale deployment foo --min=2 --max=10 # Auto scale a deployment "foo"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Patching Resources
|
## Patching Resources
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # Partially update a node
|
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # Partially update a node
|
||||||
|
|
||||||
# Update a container's image; spec.containers[*].name is required because it's a merge key
|
# Update a container's image; spec.containers[*].name is required because it's a merge key
|
||||||
$ kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
|
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
|
||||||
|
|
||||||
# Update a container's image using a json patch with positional arrays
|
# Update a container's image using a json patch with positional arrays
|
||||||
$ kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'
|
kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'
|
||||||
|
|
||||||
# Disable a deployment livenessProbe using a json patch with positional arrays
|
# Disable a deployment livenessProbe using a json patch with positional arrays
|
||||||
$ kubectl patch deployment valid-deployment --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'
|
kubectl patch deployment valid-deployment --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'
|
||||||
|
|
||||||
# Add a new element to a positional array
|
# Add a new element to a positional array
|
||||||
$ kubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]'
|
kubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Editing Resources
|
## Editing Resources
|
||||||
The edit any API resource in an editor.
|
The edit any API resource in an editor.
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl edit svc/docker-registry # Edit the service named docker-registry
|
kubectl edit svc/docker-registry # Edit the service named docker-registry
|
||||||
$ KUBE_EDITOR="nano" kubectl edit svc/docker-registry # Use an alternative editor
|
KUBE_EDITOR="nano" kubectl edit svc/docker-registry # Use an alternative editor
|
||||||
```
|
```
|
||||||
|
|
||||||
## Scaling Resources
|
## Scaling Resources
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl scale --replicas=3 rs/foo # Scale a replicaset named 'foo' to 3
|
kubectl scale --replicas=3 rs/foo # Scale a replicaset named 'foo' to 3
|
||||||
$ kubectl scale --replicas=3 -f foo.yaml # Scale a resource specified in "foo.yaml" to 3
|
kubectl scale --replicas=3 -f foo.yaml # Scale a resource specified in "foo.yaml" to 3
|
||||||
$ kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # If the deployment named mysql's current size is 2, scale mysql to 3
|
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # If the deployment named mysql's current size is 2, scale mysql to 3
|
||||||
$ kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Scale multiple replication controllers
|
kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Scale multiple replication controllers
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deleting Resources
|
## Deleting Resources
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl delete -f ./pod.json # Delete a pod using the type and name specified in pod.json
|
kubectl delete -f ./pod.json # Delete a pod using the type and name specified in pod.json
|
||||||
$ kubectl delete pod,service baz foo # Delete pods and services with same names "baz" and "foo"
|
kubectl delete pod,service baz foo # Delete pods and services with same names "baz" and "foo"
|
||||||
$ kubectl delete pods,services -l name=myLabel # Delete pods and services with label name=myLabel
|
kubectl delete pods,services -l name=myLabel # Delete pods and services with label name=myLabel
|
||||||
$ kubectl delete pods,services -l name=myLabel --include-uninitialized # Delete pods and services, including uninitialized ones, with label name=myLabel
|
kubectl delete pods,services -l name=myLabel --include-uninitialized # Delete pods and services, including uninitialized ones, with label name=myLabel
|
||||||
$ kubectl -n my-ns delete po,svc --all # Delete all pods and services, including uninitialized ones, in namespace my-ns,
|
kubectl -n my-ns delete po,svc --all # Delete all pods and services, including uninitialized ones, in namespace my-ns,
|
||||||
```
|
```
|
||||||
|
|
||||||
## Interacting with running Pods
|
## Interacting with running Pods
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl logs my-pod # dump pod logs (stdout)
|
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 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 # stream pod logs (stdout)
|
||||||
$ kubectl logs -f my-pod -c my-container # stream pod container logs (stdout, multi-container case)
|
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 run -i --tty busybox --image=busybox -- sh # Run pod as interactive shell
|
||||||
$ kubectl attach my-pod -i # Attach to Running Container
|
kubectl attach my-pod -i # Attach to Running Container
|
||||||
$ kubectl port-forward my-pod 5000:6000 # Listen on port 5000 on the local machine and forward to port 6000 on my-pod
|
kubectl port-forward my-pod 5000:6000 # Listen on port 5000 on the local machine and forward to port 6000 on my-pod
|
||||||
$ kubectl exec my-pod -- ls / # Run command in existing pod (1 container case)
|
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 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
|
kubectl top pod POD_NAME --containers # Show metrics for a given pod and its containers
|
||||||
```
|
```
|
||||||
|
|
||||||
## Interacting with Nodes and Cluster
|
## Interacting with Nodes and Cluster
|
||||||
|
|
||||||
```console
|
```bash
|
||||||
$ kubectl cordon my-node # Mark my-node as unschedulable
|
kubectl cordon my-node # Mark my-node as unschedulable
|
||||||
$ kubectl drain my-node # Drain my-node in preparation for maintenance
|
kubectl drain my-node # Drain my-node in preparation for maintenance
|
||||||
$ kubectl uncordon my-node # Mark my-node as schedulable
|
kubectl uncordon my-node # Mark my-node as schedulable
|
||||||
$ kubectl top node my-node # Show metrics for a given node
|
kubectl top node my-node # Show metrics for a given node
|
||||||
$ kubectl cluster-info # Display addresses of the master and services
|
kubectl cluster-info # Display addresses of the master and services
|
||||||
$ kubectl cluster-info dump # Dump current cluster state to stdout
|
kubectl cluster-info dump # Dump current cluster state to stdout
|
||||||
$ kubectl cluster-info dump --output-directory=/path/to/cluster-state # Dump current cluster state to /path/to/cluster-state
|
kubectl cluster-info dump --output-directory=/path/to/cluster-state # Dump current cluster state to /path/to/cluster-state
|
||||||
|
|
||||||
# If a taint with that key and effect already exists, its value is replaced as specified.
|
# If a taint with that key and effect already exists, its value is replaced as specified.
|
||||||
$ kubectl taint nodes foo dedicated=special-user:NoSchedule
|
kubectl taint nodes foo dedicated=special-user:NoSchedule
|
||||||
```
|
```
|
||||||
|
|
||||||
### Resource types
|
### Resource types
|
||||||
@@ -247,15 +267,23 @@ List all supported resource types along with their shortnames, [API group](/docs
|
|||||||
$ kubectl api-resources
|
$ kubectl api-resources
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Resource types
|
||||||
|
|
||||||
|
List all supported resource types along with their shortnames, [API group](/docs/concepts/overview/kubernetes-api/#api-groups), whether they are [namespaced](/docs/concepts/overview/working-with-objects/namespaces), and [Kind](/docs/concepts/overview/working-with-objects/kubernetes-objects):
|
||||||
|
|
||||||
|
```console
|
||||||
|
kubectl api-resources
|
||||||
|
```
|
||||||
|
|
||||||
Other operations for exploring API resources:
|
Other operations for exploring API resources:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ kubectl api-resources --namespaced=true # All namespaced resources
|
kubectl api-resources --namespaced=true # All namespaced resources
|
||||||
$ kubectl api-resources --namespaced=false # All non-namespaced resources
|
kubectl api-resources --namespaced=false # All non-namespaced resources
|
||||||
$ kubectl api-resources -o name # All resources with simple output (just the resource name)
|
kubectl api-resources -o name # All resources with simple output (just the resource name)
|
||||||
$ kubectl api-resources -o wide # All resources with expanded (aka "wide") output
|
kubectl api-resources -o wide # All resources with expanded (aka "wide") output
|
||||||
$ kubectl api-resources --verbs=list,get # All resources that support the "list" and "get" request verbs
|
kubectl api-resources --verbs=list,get # All resources that support the "list" and "get" request verbs
|
||||||
$ kubectl api-resources --api-group=extensions # All resources in the "extensions" API group
|
kubectl api-resources --api-group=extensions # All resources in the "extensions" API group
|
||||||
```
|
```
|
||||||
|
|
||||||
### Formatting output
|
### Formatting output
|
||||||
@@ -289,3 +317,14 @@ Verbosity | Description
|
|||||||
`--v=8` | Display HTTP request contents.
|
`--v=8` | Display HTTP request contents.
|
||||||
`--v=9` | Display HTTP request contents without truncation of contents.
|
`--v=9` | Display HTTP request contents without truncation of contents.
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
|
||||||
|
{{% capture whatsnext %}}
|
||||||
|
|
||||||
|
* Learn more about [Overview of kubectl](/docs/reference/kubectl/overview/).
|
||||||
|
|
||||||
|
* See [kubectl](/docs/reference/kubectl/kubectl/) options.
|
||||||
|
|
||||||
|
* Also [kubectl Usage Conventions](/docs/reference/kubectl/conventions/) to understand how to use it in reusable scripts.
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -336,6 +336,16 @@ if they don't know their PodIP.
|
|||||||
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
|
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
|
||||||
```
|
```
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
|
|
||||||
|
{{% tab name="JuniperContrail/TungstenFabric" %}}
|
||||||
|
Provides overlay SDN solution, delivering multicloud networking, hybrid cloud networking,
|
||||||
|
simultaneous overlay-underlay support, network policy enforcement, network isolation,
|
||||||
|
service chaining and flexible load balancing.
|
||||||
|
|
||||||
|
There are multiple, flexible ways to install JuniperContrail/TungstenFabric CNI.
|
||||||
|
|
||||||
|
Kindly refer to this quickstart: [TungstenFabric](https://tungstenfabric.github.io/website/)
|
||||||
|
{{% /tab %}}
|
||||||
{{< /tabs >}}
|
{{< /tabs >}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -72,13 +72,13 @@ These solutions allow you to create Kubernetes clusters on a range of Cloud IaaS
|
|||||||
few commands. These solutions are actively developed and have active community support.
|
few commands. These solutions are actively developed and have active community support.
|
||||||
|
|
||||||
* [Conjure-up Kubernetes with Ubuntu on AWS, Azure, Google Cloud, Oracle Cloud](/docs/getting-started-guides/ubuntu/)
|
* [Conjure-up Kubernetes with Ubuntu on AWS, Azure, Google Cloud, Oracle Cloud](/docs/getting-started-guides/ubuntu/)
|
||||||
* [Google Compute Engine (GCE)](/docs/getting-started-guides/gce/)
|
* [Google Compute Engine (GCE)](/docs/setup/turnkey/gce/)
|
||||||
* [AWS](/docs/getting-started-guides/aws/)
|
* [AWS](/docs/setup/turnkey/aws/)
|
||||||
* [Azure](/docs/getting-started-guides/azure/)
|
* [Azure](/docs/setup/turnkey/azure/)
|
||||||
* [Tectonic by CoreOS](https://coreos.com/tectonic)
|
* [Tectonic by CoreOS](https://coreos.com/tectonic)
|
||||||
* [CenturyLink Cloud](/docs/getting-started-guides/clc/)
|
* [CenturyLink Cloud](/docs/setup/turnkey/clc/)
|
||||||
* [IBM Cloud](https://github.com/patrocinio/kubernetes-softlayer)
|
* [IBM Cloud](https://github.com/patrocinio/kubernetes-softlayer)
|
||||||
* [Stackpoint.io](/docs/getting-started-guides/stackpoint/)
|
* [Stackpoint.io](/docs/setup/turnkey/stackpoint/)
|
||||||
* [Madcore.Ai](https://madcore.ai/)
|
* [Madcore.Ai](https://madcore.ai/)
|
||||||
* [Kubermatic](https://cloud.kubermatic.io)
|
* [Kubermatic](https://cloud.kubermatic.io)
|
||||||
* [Rancher 2.0](https://rancher.com/docs/rancher/v2.x/en/)
|
* [Rancher 2.0](https://rancher.com/docs/rancher/v2.x/en/)
|
||||||
@@ -163,15 +163,15 @@ Madcore.Ai | Jenkins DSL | Ubuntu | flannel | [docs](https://madc
|
|||||||
Platform9 | | multi-support | multi-support | [docs](https://platform9.com/managed-kubernetes/) | Commercial
|
Platform9 | | multi-support | multi-support | [docs](https://platform9.com/managed-kubernetes/) | Commercial
|
||||||
Kubermatic | | multi-support | multi-support | [docs](http://docs.kubermatic.io/) | Commercial
|
Kubermatic | | multi-support | multi-support | [docs](http://docs.kubermatic.io/) | Commercial
|
||||||
Giant Swarm | | CoreOS | flannel and/or Calico | [docs](https://docs.giantswarm.io/) | Commercial
|
Giant Swarm | | CoreOS | flannel and/or Calico | [docs](https://docs.giantswarm.io/) | Commercial
|
||||||
GCE | Saltstack | Debian | GCE | [docs](/docs/getting-started-guides/gce/) | Project
|
GCE | Saltstack | Debian | GCE | [docs](/docs/setup/turnkey/gce/) | Project
|
||||||
Azure Container Service | | Ubuntu | Azure | [docs](https://azure.microsoft.com/en-us/services/container-service/) | Commercial
|
Azure Container Service | | Ubuntu | Azure | [docs](https://azure.microsoft.com/en-us/services/container-service/) | Commercial
|
||||||
Azure (IaaS) | | Ubuntu | Azure | [docs](/docs/getting-started-guides/azure/) | [Community (Microsoft)](https://github.com/Azure/acs-engine)
|
Azure (IaaS) | | Ubuntu | Azure | [docs](/docs/setup/turnkey/azure/) | [Community (Microsoft)](https://github.com/Azure/acs-engine)
|
||||||
Bare-metal | custom | Fedora | _none_ | [docs](/docs/getting-started-guides/fedora/fedora_manual_config/) | Project
|
Bare-metal | custom | Fedora | _none_ | [docs](/docs/getting-started-guides/fedora/fedora_manual_config/) | Project
|
||||||
Bare-metal | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | Community ([@aveshagarwal](https://github.com/aveshagarwal))
|
Bare-metal | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | Community ([@aveshagarwal](https://github.com/aveshagarwal))
|
||||||
libvirt | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | Community ([@aveshagarwal](https://github.com/aveshagarwal))
|
libvirt | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | Community ([@aveshagarwal](https://github.com/aveshagarwal))
|
||||||
KVM | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | Community ([@aveshagarwal](https://github.com/aveshagarwal))
|
KVM | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | Community ([@aveshagarwal](https://github.com/aveshagarwal))
|
||||||
DCOS | Marathon | CoreOS/Alpine | custom | [docs](/docs/getting-started-guides/dcos/) | Community ([Kubernetes-Mesos Authors](https://github.com/mesosphere/kubernetes-mesos/blob/master/AUTHORS.md))
|
DCOS | Marathon | CoreOS/Alpine | custom | [docs](/docs/getting-started-guides/dcos/) | Community ([Kubernetes-Mesos Authors](https://github.com/mesosphere/kubernetes-mesos/blob/master/AUTHORS.md))
|
||||||
AWS | CoreOS | CoreOS | flannel | [docs](/docs/getting-started-guides/aws/) | Community
|
AWS | CoreOS | CoreOS | flannel | [docs](/docs/setup/turnkey/aws/) | Community
|
||||||
GCE | CoreOS | CoreOS | flannel | [docs](/docs/getting-started-guides/coreos/) | Community ([@pires](https://github.com/pires))
|
GCE | CoreOS | CoreOS | flannel | [docs](/docs/getting-started-guides/coreos/) | Community ([@pires](https://github.com/pires))
|
||||||
Vagrant | CoreOS | CoreOS | flannel | [docs](/docs/getting-started-guides/coreos/) | Community ([@pires](https://github.com/pires), [@AntonioMeireles](https://github.com/AntonioMeireles))
|
Vagrant | CoreOS | CoreOS | flannel | [docs](/docs/getting-started-guides/coreos/) | Community ([@pires](https://github.com/pires), [@AntonioMeireles](https://github.com/AntonioMeireles))
|
||||||
CloudStack | Ansible | CoreOS | flannel | [docs](/docs/getting-started-guides/cloudstack/) | Community ([@sebgoa](https://github.com/sebgoa))
|
CloudStack | Ansible | CoreOS | flannel | [docs](/docs/getting-started-guides/cloudstack/) | Community ([@sebgoa](https://github.com/sebgoa))
|
||||||
@@ -185,7 +185,7 @@ Oracle Cloud | Juju | Ubuntu | flannel/calico/canal | [docs]
|
|||||||
Rackspace | Juju | Ubuntu | flannel/calico/canal | [docs](/docs/getting-started-guides/ubuntu/) | [Commercial](https://www.ubuntu.com/kubernetes) and [Community](https://jujucharms.com/kubernetes)
|
Rackspace | Juju | Ubuntu | flannel/calico/canal | [docs](/docs/getting-started-guides/ubuntu/) | [Commercial](https://www.ubuntu.com/kubernetes) and [Community](https://jujucharms.com/kubernetes)
|
||||||
VMware vSphere | Juju | Ubuntu | flannel/calico/canal | [docs](/docs/getting-started-guides/ubuntu/) | [Commercial](https://www.ubuntu.com/kubernetes) and [Community](https://jujucharms.com/kubernetes)
|
VMware vSphere | Juju | Ubuntu | flannel/calico/canal | [docs](/docs/getting-started-guides/ubuntu/) | [Commercial](https://www.ubuntu.com/kubernetes) and [Community](https://jujucharms.com/kubernetes)
|
||||||
Bare Metal | Juju | Ubuntu | flannel/calico/canal | [docs](/docs/getting-started-guides/ubuntu/) | [Commercial](https://www.ubuntu.com/kubernetes) and [Community](https://jujucharms.com/kubernetes)
|
Bare Metal | Juju | Ubuntu | flannel/calico/canal | [docs](/docs/getting-started-guides/ubuntu/) | [Commercial](https://www.ubuntu.com/kubernetes) and [Community](https://jujucharms.com/kubernetes)
|
||||||
AWS | Saltstack | Debian | AWS | [docs](/docs/getting-started-guides/aws/) | Community ([@justinsb](https://github.com/justinsb))
|
AWS | Saltstack | Debian | AWS | [docs](/docs/setup/turnkey/aws/) | Community ([@justinsb](https://github.com/justinsb))
|
||||||
AWS | kops | Debian | AWS | [docs](https://github.com/kubernetes/kops/) | Community ([@justinsb](https://github.com/justinsb))
|
AWS | kops | Debian | AWS | [docs](https://github.com/kubernetes/kops/) | Community ([@justinsb](https://github.com/justinsb))
|
||||||
Bare-metal | custom | Ubuntu | flannel | [docs](/docs/getting-started-guides/ubuntu/) | Community ([@resouer](https://github.com/resouer), [@WIZARD-CXY](https://github.com/WIZARD-CXY))
|
Bare-metal | custom | Ubuntu | flannel | [docs](/docs/getting-started-guides/ubuntu/) | Community ([@resouer](https://github.com/resouer), [@WIZARD-CXY](https://github.com/WIZARD-CXY))
|
||||||
oVirt | | | | [docs](/docs/getting-started-guides/ovirt/) | Community ([@simon3z](https://github.com/simon3z))
|
oVirt | | | | [docs](/docs/getting-started-guides/ovirt/) | Community ([@simon3z](https://github.com/simon3z))
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ You need to prepare several certs:
|
|||||||
Unless you plan to have a real CA generate your certs, you will need
|
Unless you plan to have a real CA generate your certs, you will need
|
||||||
to generate a root cert and use that to sign the master, kubelet, and
|
to generate a root cert and use that to sign the master, kubelet, and
|
||||||
kubectl certs. How to do this is described in the [authentication
|
kubectl certs. How to do this is described in the [authentication
|
||||||
documentation](/docs/admin/authentication/#creating-certificates/).
|
documentation](/docs/concepts/cluster-administration/certificates/).
|
||||||
|
|
||||||
You will end up with the following files (we will use these variables later on)
|
You will end up with the following files (we will use these variables later on)
|
||||||
|
|
||||||
@@ -262,7 +262,7 @@ The admin user (and any users) need:
|
|||||||
|
|
||||||
Your tokens and passwords need to be stored in a file for the apiserver
|
Your tokens and passwords need to be stored in a file for the apiserver
|
||||||
to read. This guide uses `/var/lib/kube-apiserver/known_tokens.csv`.
|
to read. This guide uses `/var/lib/kube-apiserver/known_tokens.csv`.
|
||||||
The format for this file is described in the [authentication documentation](/docs/admin/authentication/).
|
The format for this file is described in the [authentication documentation](/docs/reference/access-authn-authz/authentication/#static-token-file).
|
||||||
|
|
||||||
For distributing credentials to clients, the convention in Kubernetes is to put the credentials
|
For distributing credentials to clients, the convention in Kubernetes is to put the credentials
|
||||||
into a [kubeconfig file](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/).
|
into a [kubeconfig file](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/).
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ certificate.
|
|||||||
|
|
||||||
On some clusters, the apiserver does not require authentication; it may serve
|
On some clusters, the apiserver does not require authentication; it may serve
|
||||||
on localhost, or be protected by a firewall. There is not a standard
|
on localhost, or be protected by a firewall. There is not a standard
|
||||||
for this. [Configuring Access to the API](/docs/admin/accessing-the-api)
|
for this. [Configuring Access to the API](/docs/reference/access-authn-authz/controlling-access/)
|
||||||
describes how a cluster admin can configure this. Such approaches may conflict
|
describes how a cluster admin can configure this. Such approaches may conflict
|
||||||
with future high-availability support.
|
with future high-availability support.
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ The UI can _only_ be accessed from the machine where the command is executed. Se
|
|||||||
You may access the UI directly via the Kubernetes master apiserver. Open a browser and navigate to ``https://<master-ip>:<apiserver-port>/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/``, where `<master-ip>` is IP address or domain name of the Kubernetes
|
You may access the UI directly via the Kubernetes master apiserver. Open a browser and navigate to ``https://<master-ip>:<apiserver-port>/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/``, where `<master-ip>` is IP address or domain name of the Kubernetes
|
||||||
master.
|
master.
|
||||||
|
|
||||||
Please note, this works only if the apiserver is set up to allow authentication with username and password. This is not currently the case with some setup tools (e.g., `kubeadm`). Refer to the [authentication admin documentation](/docs/admin/authentication/) for information on how to configure authentication manually.
|
Please note, this works only if the apiserver is set up to allow authentication with username and password. This is not currently the case with some setup tools (e.g., `kubeadm`). Refer to the [authentication admin documentation](/docs/reference/access-authn-authz/authentication/) for information on how to configure authentication manually.
|
||||||
|
|
||||||
If the username and password are configured but unknown to you, then use `kubectl config view` to find it.
|
If the username and password are configured but unknown to you, then use `kubectl config view` to find it.
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ certificate.
|
|||||||
|
|
||||||
On some clusters, the API server does not require authentication; it may serve
|
On some clusters, the API server does not require authentication; it may serve
|
||||||
on localhost, or be protected by a firewall. There is not a standard
|
on localhost, or be protected by a firewall. There is not a standard
|
||||||
for this. [Configuring Access to the API](/docs/admin/accessing-the-api)
|
for this. [Configuring Access to the API](/docs/reference/access-authn-authz/controlling-access/)
|
||||||
describes how a cluster admin can configure this. Such approaches may conflict
|
describes how a cluster admin can configure this. Such approaches may conflict
|
||||||
with future high-availability support.
|
with future high-availability support.
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ allow users to be subdivided into groups.
|
|||||||
All API clients must be authenticated, even those that are part of the infrastructure like nodes,
|
All API clients must be authenticated, even those that are part of the infrastructure like nodes,
|
||||||
proxies, the scheduler, and volume plugins. These clients are typically [service accounts](/docs/admin/service-accounts-admin/) or use x509 client certificates, and they are created automatically at cluster startup or are setup as part of the cluster installation.
|
proxies, the scheduler, and volume plugins. These clients are typically [service accounts](/docs/admin/service-accounts-admin/) or use x509 client certificates, and they are created automatically at cluster startup or are setup as part of the cluster installation.
|
||||||
|
|
||||||
Consult the [authentication reference document](/docs/admin/authentication/) for more information.
|
Consult the [authentication reference document](/docs/reference/access-authn-authz/authentication/) for more information.
|
||||||
|
|
||||||
### API Authorization
|
### API Authorization
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
isClusterService: false
|
|
||||||
serviceType: "LoadBalancer"
|
|
||||||
plugins:
|
|
||||||
kubernetes:
|
|
||||||
enabled: false
|
|
||||||
etcd:
|
|
||||||
enabled: true
|
|
||||||
zones:
|
|
||||||
- "example.com."
|
|
||||||
endpoint: "http://etcd-cluster.my-namespace:2379"
|
|
||||||
@@ -60,7 +60,18 @@ The CoreDNS default configuration should be customized to suit the federation.
|
|||||||
Shown below is the Values.yaml, which overrides the default
|
Shown below is the Values.yaml, which overrides the default
|
||||||
configuration parameters on the CoreDNS chart.
|
configuration parameters on the CoreDNS chart.
|
||||||
|
|
||||||
{{< code file="Values.yaml" >}}
|
```yaml
|
||||||
|
isClusterService: false
|
||||||
|
serviceType: "LoadBalancer"
|
||||||
|
plugins:
|
||||||
|
kubernetes:
|
||||||
|
enabled: false
|
||||||
|
etcd:
|
||||||
|
enabled: true
|
||||||
|
zones:
|
||||||
|
- "example.com."
|
||||||
|
endpoint: "http://etcd-cluster.my-namespace:2379"
|
||||||
|
```
|
||||||
|
|
||||||
The above configuration file needs some explanation:
|
The above configuration file needs some explanation:
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ received from the external policy engine.
|
|||||||
|
|
||||||
Shown below is an example ConfigMap for the Admission Controller:
|
Shown below is an example ConfigMap for the Admission Controller:
|
||||||
|
|
||||||
{{< code file="scheduling-policy-admission.yaml" >}}
|
{{< codenew file="federation/scheduling-policy-admission.yaml" >}}
|
||||||
|
|
||||||
The ConfigMap contains three files:
|
The ConfigMap contains three files:
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ Create a Service in the host cluster to contact the external policy engine:
|
|||||||
|
|
||||||
Shown below is an example Service for OPA.
|
Shown below is an example Service for OPA.
|
||||||
|
|
||||||
{{< code file="policy-engine-service.yaml" >}}
|
{{< codenew file="federation/policy-engine-service.yaml" >}}
|
||||||
|
|
||||||
Create a Deployment in the host cluster with the Federation control plane:
|
Create a Deployment in the host cluster with the Federation control plane:
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ Create a Deployment in the host cluster with the Federation control plane:
|
|||||||
|
|
||||||
Shown below is an example Deployment for OPA.
|
Shown below is an example Deployment for OPA.
|
||||||
|
|
||||||
{{< code file="policy-engine-deployment.yaml" >}}
|
{{< codenew file="federation/policy-engine-deployment.yaml" >}}
|
||||||
|
|
||||||
## Configuring placement policies via ConfigMaps
|
## Configuring placement policies via ConfigMaps
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ Annotate one of the clusters to indicate that it is PCI certified.
|
|||||||
|
|
||||||
Deploy a Federated ReplicaSet to test the placement policy.
|
Deploy a Federated ReplicaSet to test the placement policy.
|
||||||
|
|
||||||
{{< code file="replicaset-example-policy.yaml" >}}
|
{{< codenew file="federation/replicaset-example-policy.yaml" >}}
|
||||||
|
|
||||||
Shown below is the command to deploy a ReplicaSet that *does* match the policy.
|
Shown below is the command to deploy a ReplicaSet that *does* match the policy.
|
||||||
|
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ includes who the Kubernetes API trusts. The ability to approve CSRs should
|
|||||||
not be granted broadly or lightly. The requirements of the challenge
|
not be granted broadly or lightly. The requirements of the challenge
|
||||||
noted in the previous section and the repercussions of issuing a specific
|
noted in the previous section and the repercussions of issuing a specific
|
||||||
certificate should be fully understood before granting this permission. See
|
certificate should be fully understood before granting this permission. See
|
||||||
[here](/docs/admin/authentication#x509-client-certs) for information on how
|
[here](/docs/reference/access-authn-authz/authentication/#x509-client-certs) for information on how
|
||||||
certificates interact with authentication.
|
certificates interact with authentication.
|
||||||
|
|
||||||
## A Note to Cluster Administrators
|
## A Note to Cluster Administrators
|
||||||
|
|||||||
@@ -191,10 +191,10 @@ done
|
|||||||
|
|
||||||
Next, we'll run a simple "Hello AppArmor" pod with the deny-write profile:
|
Next, we'll run a simple "Hello AppArmor" pod with the deny-write profile:
|
||||||
|
|
||||||
{{< code file="hello-apparmor-pod.yaml" >}}
|
{{< codenew file="pods/security/hello-apparmor.yaml" >}}
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ kubectl create -f ./hello-apparmor-pod.yaml
|
$ kubectl create -f ./hello-apparmor.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
If we look at the pod events, we can see that the Pod container was created with the AppArmor
|
If we look at the pod events, we can see that the Pod container was created with the AppArmor
|
||||||
|
|||||||
@@ -35,85 +35,56 @@ This page provides a real world example of how to configure Redis using a Config
|
|||||||
|
|
||||||
You can follow the steps below to configure a Redis cache using data stored in a ConfigMap.
|
You can follow the steps below to configure a Redis cache using data stored in a ConfigMap.
|
||||||
|
|
||||||
1. Create a ConfigMap from the `docs/tutorials/configuration/configmap/redis/redis-config` file:
|
First create a ConfigMap from the `examples/pods/config/redis-config` file:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl create configmap example-redis-config --from-file=https://k8s.io/docs/tutorials/configuration/configmap/redis/redis-config
|
kubectl create configmap example-redis-config --from-file=https://k8s.io/examples/pods/config/redis-config
|
||||||
kubectl get configmap example-redis-config -o yaml
|
kubectl get configmap example-redis-config -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
data:
|
data:
|
||||||
redis-config: |
|
redis-config: |
|
||||||
maxmemory 2mb
|
maxmemory 2mb
|
||||||
maxmemory-policy allkeys-lru
|
maxmemory-policy allkeys-lru
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
creationTimestamp: 2016-03-30T18:14:41Z
|
creationTimestamp: 2016-03-30T18:14:41Z
|
||||||
name: example-redis-config
|
name: example-redis-config
|
||||||
namespace: default
|
namespace: default
|
||||||
resourceVersion: "24686"
|
resourceVersion: "24686"
|
||||||
selfLink: /api/v1/namespaces/default/configmaps/example-redis-config
|
selfLink: /api/v1/namespaces/default/configmaps/example-redis-config
|
||||||
uid: 460a2b6e-f6a3-11e5-8ae5-42010af00002
|
uid: 460a2b6e-f6a3-11e5-8ae5-42010af00002
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Create a pod specification that uses the config data stored in the ConfigMap:
|
Now create a pod specification that uses the config data stored in the ConfigMap:
|
||||||
|
|
||||||
```yaml
|
{{< codenew file="pods/config/redis-pod.yaml" >}}
|
||||||
apiVersion: v1
|
|
||||||
kind: Pod
|
|
||||||
metadata:
|
|
||||||
name: redis
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: redis
|
|
||||||
image: kubernetes/redis:v1
|
|
||||||
env:
|
|
||||||
- name: MASTER
|
|
||||||
value: "true"
|
|
||||||
ports:
|
|
||||||
- containerPort: 6379
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: "0.1"
|
|
||||||
volumeMounts:
|
|
||||||
- mountPath: /redis-master-data
|
|
||||||
name: data
|
|
||||||
- mountPath: /redis-master
|
|
||||||
name: config
|
|
||||||
volumes:
|
|
||||||
- name: data
|
|
||||||
emptyDir: {}
|
|
||||||
- name: config
|
|
||||||
configMap:
|
|
||||||
name: example-redis-config
|
|
||||||
items:
|
|
||||||
- key: redis-config
|
|
||||||
path: redis.conf
|
|
||||||
```
|
|
||||||
1. Create the pod:
|
|
||||||
|
|
||||||
```shell
|
Create the pod:
|
||||||
kubectl create -f https://k8s.io/docs/tutorials/configuration/configmap/redis/redis-pod.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
In the example, the config volume is mounted at `/redis-master`.
|
```shell
|
||||||
It uses `path` to add the `redis-config` key to a file named `redis.conf`.
|
kubectl create -f https://k8s.io/examples/pods/config/redis-pod.yaml
|
||||||
The file path for the redis config, therefore, is `/redis-master/redis.conf`.
|
```
|
||||||
This is where the image will look for the config file for the redis master.
|
|
||||||
|
|
||||||
1. Use `kubectl exec` to enter the pod and run the `redis-cli` tool to verify that the configuration was correctly applied:
|
In the example, the config volume is mounted at `/redis-master`.
|
||||||
|
It uses `path` to add the `redis-config` key to a file named `redis.conf`.
|
||||||
|
The file path for the redis config, therefore, is `/redis-master/redis.conf`.
|
||||||
|
This is where the image will look for the config file for the redis master.
|
||||||
|
|
||||||
```shell
|
Use `kubectl exec` to enter the pod and run the `redis-cli` tool to verify that
|
||||||
kubectl exec -it redis redis-cli
|
the configuration was correctly applied:
|
||||||
127.0.0.1:6379> CONFIG GET maxmemory
|
|
||||||
1) "maxmemory"
|
```shell
|
||||||
2) "2097152"
|
kubectl exec -it redis redis-cli
|
||||||
127.0.0.1:6379> CONFIG GET maxmemory-policy
|
127.0.0.1:6379> CONFIG GET maxmemory
|
||||||
1) "maxmemory-policy"
|
1) "maxmemory"
|
||||||
2) "allkeys-lru"
|
2) "2097152"
|
||||||
```
|
127.0.0.1:6379> CONFIG GET maxmemory-policy
|
||||||
|
1) "maxmemory-policy"
|
||||||
|
2) "allkeys-lru"
|
||||||
|
```
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Minikube provides a simple way of running Kubernetes on your local machine for f
|
|||||||
|
|
||||||
{{% capture prerequisites %}}
|
{{% capture prerequisites %}}
|
||||||
|
|
||||||
* For OS X, you need [Homebrew](https://brew.sh) to install the `xhyve` driver.
|
* For OS X, you can use [Homebrew](https://brew.sh) to install Minikube.
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
**Note:** If you see the following Homebrew error when you run `brew update` after you update your computer to MacOS 10.13:
|
**Note:** If you see the following Homebrew error when you run `brew update` after you update your computer to MacOS 10.13:
|
||||||
@@ -62,21 +62,13 @@ instead of Docker for Mac, the instructions to install Minikube may be
|
|||||||
slightly different. For general Minikube installation instructions, see
|
slightly different. For general Minikube installation instructions, see
|
||||||
the [Minikube installation guide](/docs/getting-started-guides/minikube/).
|
the [Minikube installation guide](/docs/getting-started-guides/minikube/).
|
||||||
|
|
||||||
Use `curl` to download and install the latest Minikube release:
|
Use Homebrew to install the latest Minikube release:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 && \
|
brew cask install minikube
|
||||||
chmod +x minikube && \
|
|
||||||
sudo mv minikube /usr/local/bin/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Use Homebrew to install the xhyve driver and set its permissions:
|
Install the HyperKit driver, as described by the
|
||||||
|
[Minikube driver installation guide](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperkit-driver).
|
||||||
```shell
|
|
||||||
brew install docker-machine-driver-xhyve
|
|
||||||
sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
|
|
||||||
sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
|
|
||||||
```
|
|
||||||
|
|
||||||
Use Homebrew to download the `kubectl` command-line tool, which you can
|
Use Homebrew to download the `kubectl` command-line tool, which you can
|
||||||
use to interact with Kubernetes clusters:
|
use to interact with Kubernetes clusters:
|
||||||
@@ -100,29 +92,17 @@ docker images
|
|||||||
If NO proxy is required, start the Minikube cluster:
|
If NO proxy is required, start the Minikube cluster:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
minikube start --vm-driver=xhyve
|
minikube start --vm-driver=hyperkit
|
||||||
```
|
```
|
||||||
If a proxy server is required, use the following method to start Minikube cluster with proxy setting:
|
If a proxy server is required, use the following method to start Minikube cluster with proxy setting:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
minikube start --vm-driver=xhyve --docker-env HTTP_PROXY=http://your-http-proxy-host:your-http-proxy-port --docker-env HTTPS_PROXY=http(s)://your-https-proxy-host:your-https-proxy-port
|
minikube start --vm-driver=hyperkit --docker-env HTTP_PROXY=http://your-http-proxy-host:your-http-proxy-port --docker-env HTTPS_PROXY=http(s)://your-https-proxy-host:your-https-proxy-port
|
||||||
```
|
```
|
||||||
|
|
||||||
The `--vm-driver=xhyve` flag specifies that you are using Docker for Mac. The
|
The `--vm-driver=hyperkit` flag specifies that you are using Docker for Mac. The
|
||||||
default VM driver is VirtualBox.
|
default VM driver is VirtualBox.
|
||||||
|
|
||||||
Note if `minikube start --vm-driver=xhyve` is unsuccessful due to the error:
|
|
||||||
```
|
|
||||||
Error creating machine: Error in driver during machine creation: Could not convert the UUID to MAC address: exit status 1
|
|
||||||
```
|
|
||||||
|
|
||||||
Then the following may resolve the `minikube start --vm-driver=xhyve` issue:
|
|
||||||
```
|
|
||||||
rm -rf ~/.minikube
|
|
||||||
sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
|
|
||||||
sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
|
|
||||||
```
|
|
||||||
|
|
||||||
Now set the Minikube context. The context is what determines which cluster
|
Now set the Minikube context. The context is what determines which cluster
|
||||||
`kubectl` is interacting with. You can see all your available contexts in the
|
`kubectl` is interacting with. You can see all your available contexts in the
|
||||||
`~/.kube/config` file.
|
`~/.kube/config` file.
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ The following manifest describes a single-instance WordPress Deployment and Serv
|
|||||||
1. Create a WordPress Service and Deployment from the `wordpress-deployment.yaml` file:
|
1. Create a WordPress Service and Deployment from the `wordpress-deployment.yaml` file:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl create -f https://k8s.io/examples/wordpress/wordpress-deployment.yaml
|
kubectl create -f https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Verify that a PersistentVolume got dynamically provisioned:
|
2. Verify that a PersistentVolume got dynamically provisioned:
|
||||||
|
|||||||
@@ -848,13 +848,13 @@ This is because the Pods in the `zk` `StatefulSet` have a `PodAntiAffinity` spec
|
|||||||
- key: "app"
|
- key: "app"
|
||||||
operator: In
|
operator: In
|
||||||
values:
|
values:
|
||||||
- zk-hs
|
- zk
|
||||||
topologyKey: "kubernetes.io/hostname"
|
topologyKey: "kubernetes.io/hostname"
|
||||||
```
|
```
|
||||||
|
|
||||||
The `requiredDuringSchedulingIgnoredDuringExecution` field tells the
|
The `requiredDuringSchedulingIgnoredDuringExecution` field tells the
|
||||||
Kubernetes Scheduler that it should never co-locate two Pods from the `zk-hs`
|
Kubernetes Scheduler that it should never co-locate two Pods which have `app` label
|
||||||
Service in the domain defined by the `topologyKey`. The `topologyKey`
|
as `zk` in the domain defined by the `topologyKey`. The `topologyKey`
|
||||||
`kubernetes.io/hostname` indicates that the domain is an individual node. Using
|
`kubernetes.io/hostname` indicates that the domain is an individual node. Using
|
||||||
different rules, labels, and selectors, you can extend this technique to spread
|
different rules, labels, and selectors, you can extend this technique to spread
|
||||||
your ensemble across physical, network, and power failure domains.
|
your ensemble across physical, network, and power failure domains.
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ You (or your {{< glossary_tooltip text="cluster operator" term_id="cluster-opera
|
|||||||
|
|
||||||
For even more comprehensive reading about security best practices, consider checking out the following topics:
|
For even more comprehensive reading about security best practices, consider checking out the following topics:
|
||||||
|
|
||||||
* {{< link text="Authentication" url="/docs/admin/authentication/" >}} (Is the user who they say they are?)
|
* {{< link text="Authentication" url="/docs/reference/access-authn-authz/authentication/" >}} (Is the user who they say they are?)
|
||||||
* {{< link text="Authorization" url="/docs/admin/authorization/" >}} (Does the user actually have permissions to do what they're asking?)
|
* {{< link text="Authorization" url="/docs/admin/authorization/" >}} (Does the user actually have permissions to do what they're asking?)
|
||||||
|
|
||||||
#### Resource isolation and management
|
#### Resource isolation and management
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ Securing your cluster includes work beyond the scope of Kubernetes itself.
|
|||||||
|
|
||||||
In Kubernetes, you configure access control:
|
In Kubernetes, you configure access control:
|
||||||
|
|
||||||
* [Controlling Access to the Kubernetes API](/docs/admin/accessing-the-api/)
|
* [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/)
|
||||||
* [Authenticating](/docs/admin/authentication/)
|
* [Authenticating](/docs/reference/access-authn-authz/authentication/)
|
||||||
* [Using Admission Controllers](/docs/admin/admission-controllers/)
|
* [Using Admission Controllers](/docs/admin/admission-controllers/)
|
||||||
|
|
||||||
You also configure authorization. That is, you determine not just how users and services authenticate to the API server, or whether they have access, but also what resources they have access to. Role-based access control (RBAC) is the recommended mechanism for controlling authorization to Kubernetes resources. Other authorization modes are available for more specific use cases.
|
You also configure authorization. That is, you determine not just how users and services authenticate to the API server, or whether they have access, but also what resources they have access to. Role-based access control (RBAC) is the recommended mechanism for controlling authorization to Kubernetes resources. Other authorization modes are available for more specific use cases.
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: fluentd-config
|
||||||
data:
|
data:
|
||||||
fluentd.conf: |
|
fluentd.conf: |
|
||||||
<source>
|
<source>
|
||||||
@@ -20,6 +23,3 @@ data:
|
|||||||
<match **>
|
<match **>
|
||||||
type google_cloud
|
type google_cloud
|
||||||
</match>
|
</match>
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: fluentd-config
|
|
||||||
@@ -56,7 +56,6 @@ import (
|
|||||||
storage_validation "k8s.io/kubernetes/pkg/apis/storage/validation"
|
storage_validation "k8s.io/kubernetes/pkg/apis/storage/validation"
|
||||||
"k8s.io/kubernetes/pkg/capabilities"
|
"k8s.io/kubernetes/pkg/capabilities"
|
||||||
"k8s.io/kubernetes/pkg/registry/batch/job"
|
"k8s.io/kubernetes/pkg/registry/batch/job"
|
||||||
schedulerapilatest "k8s.io/kubernetes/pkg/scheduler/api/latest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getCodecForObject(obj runtime.Object) (runtime.Codec, error) {
|
func getCodecForObject(obj runtime.Object) (runtime.Codec, error) {
|
||||||
@@ -237,7 +236,7 @@ func validateObject(obj runtime.Object) (errors field.ErrorList) {
|
|||||||
|
|
||||||
// Walks inDir for any json/yaml files. Converts yaml to json, and calls fn for
|
// Walks inDir for any json/yaml files. Converts yaml to json, and calls fn for
|
||||||
// each file found with the contents in data.
|
// each file found with the contents in data.
|
||||||
func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) error {
|
func walkConfigFiles(inDir string, t *testing.T, fn func(name, path string, data [][]byte)) error {
|
||||||
return filepath.Walk(inDir, func(path string, info os.FileInfo, err error) error {
|
return filepath.Walk(inDir, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -249,7 +248,6 @@ func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) er
|
|||||||
|
|
||||||
file := filepath.Base(path)
|
file := filepath.Base(path)
|
||||||
if ext := filepath.Ext(file); ext == ".json" || ext == ".yaml" {
|
if ext := filepath.Ext(file); ext == ".json" || ext == ".yaml" {
|
||||||
//glog.Infof("Testing %s", path)
|
|
||||||
data, err := ioutil.ReadFile(path)
|
data, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -285,6 +283,7 @@ func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) er
|
|||||||
docs = append(docs, data)
|
docs = append(docs, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Logf("Checking file %s\n", name)
|
||||||
fn(name, path, docs)
|
fn(name, path, docs)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -294,99 +293,74 @@ func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) er
|
|||||||
func TestExampleObjectSchemas(t *testing.T) {
|
func TestExampleObjectSchemas(t *testing.T) {
|
||||||
// Please help maintain the alphabeta order in the map
|
// Please help maintain the alphabeta order in the map
|
||||||
cases := map[string]map[string][]runtime.Object{
|
cases := map[string]map[string][]runtime.Object{
|
||||||
"docs/concepts/cluster-administration": {
|
"admin": {
|
||||||
|
"namespace-dev": {&api.Namespace{}},
|
||||||
|
"namespace-prod": {&api.Namespace{}},
|
||||||
|
},
|
||||||
|
"admin/cloud": {
|
||||||
|
"ccm-example": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.DaemonSet{}},
|
||||||
|
"pvl-initializer-config": {&admissionregistration.InitializerConfiguration{}},
|
||||||
|
},
|
||||||
|
"admin/dns": {
|
||||||
|
"busybox": {&api.Pod{}},
|
||||||
|
"dns-horizontal-autoscaler": {&extensions.Deployment{}},
|
||||||
|
},
|
||||||
|
"admin/logging": {
|
||||||
"fluentd-sidecar-config": {&api.ConfigMap{}},
|
"fluentd-sidecar-config": {&api.ConfigMap{}},
|
||||||
"nginx-app": {&api.Service{}, &extensions.Deployment{}},
|
|
||||||
"nginx-deployment": {&extensions.Deployment{}},
|
|
||||||
"two-files-counter-pod": {&api.Pod{}},
|
"two-files-counter-pod": {&api.Pod{}},
|
||||||
"two-files-counter-pod-agent-sidecar": {&api.Pod{}},
|
"two-files-counter-pod-agent-sidecar": {&api.Pod{}},
|
||||||
"two-files-counter-pod-streaming-sidecar": {&api.Pod{}},
|
"two-files-counter-pod-streaming-sidecar": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"docs/concepts/cluster-administration/nginx": {
|
"admin/resource": {
|
||||||
"nginx-deployment": {&extensions.Deployment{}},
|
"cpu-constraints": {&api.LimitRange{}},
|
||||||
"nginx-svc": {&api.Service{}},
|
"cpu-constraints-pod": {&api.Pod{}},
|
||||||
|
"cpu-constraints-pod-2": {&api.Pod{}},
|
||||||
|
"cpu-constraints-pod-3": {&api.Pod{}},
|
||||||
|
"cpu-constraints-pod-4": {&api.Pod{}},
|
||||||
|
"cpu-defaults": {&api.LimitRange{}},
|
||||||
|
"cpu-defaults-pod": {&api.Pod{}},
|
||||||
|
"cpu-defaults-pod-2": {&api.Pod{}},
|
||||||
|
"cpu-defaults-pod-3": {&api.Pod{}},
|
||||||
|
"memory-constraints": {&api.LimitRange{}},
|
||||||
|
"memory-constraints-pod": {&api.Pod{}},
|
||||||
|
"memory-constraints-pod-2": {&api.Pod{}},
|
||||||
|
"memory-constraints-pod-3": {&api.Pod{}},
|
||||||
|
"memory-constraints-pod-4": {&api.Pod{}},
|
||||||
|
"memory-defaults": {&api.LimitRange{}},
|
||||||
|
"memory-defaults-pod": {&api.Pod{}},
|
||||||
|
"memory-defaults-pod-2": {&api.Pod{}},
|
||||||
|
"memory-defaults-pod-3": {&api.Pod{}},
|
||||||
|
"quota-mem-cpu": {&api.ResourceQuota{}},
|
||||||
|
"quota-mem-cpu-pod": {&api.Pod{}},
|
||||||
|
"quota-mem-cpu-pod-2": {&api.Pod{}},
|
||||||
|
"quota-objects": {&api.ResourceQuota{}},
|
||||||
|
"quota-objects-pvc": {&api.PersistentVolumeClaim{}},
|
||||||
|
"quota-objects-pvc-2": {&api.PersistentVolumeClaim{}},
|
||||||
|
"quota-pod": {&api.ResourceQuota{}},
|
||||||
|
"quota-pod-deployment": {&extensions.Deployment{}},
|
||||||
},
|
},
|
||||||
"docs/concepts/overview/working-with-objects": {
|
"admin/sched": {
|
||||||
"nginx-deployment": {&extensions.Deployment{}},
|
|
||||||
},
|
|
||||||
"docs/concepts/services-networking": {
|
|
||||||
"curlpod": {&extensions.Deployment{}},
|
|
||||||
"custom-dns": {&api.Pod{}},
|
|
||||||
"hostaliases-pod": {&api.Pod{}},
|
|
||||||
"ingress": {&extensions.Ingress{}},
|
|
||||||
"nginx-secure-app": {&api.Service{}, &extensions.Deployment{}},
|
|
||||||
"nginx-svc": {&api.Service{}},
|
|
||||||
"run-my-nginx": {&extensions.Deployment{}},
|
|
||||||
},
|
|
||||||
"docs/tutorials/clusters": {
|
|
||||||
"hello-apparmor-pod": {&api.Pod{}},
|
|
||||||
},
|
|
||||||
"docs/tutorials/configuration/configmap/redis": {
|
|
||||||
"redis-pod": {&api.Pod{}},
|
|
||||||
},
|
|
||||||
"docs/concepts/overview/object-management-kubectl": {
|
|
||||||
"simple_deployment": {&extensions.Deployment{}},
|
|
||||||
"update_deployment": {&extensions.Deployment{}},
|
|
||||||
},
|
|
||||||
"examples/admin": {
|
|
||||||
"namespace-dev": {&api.Namespace{}},
|
|
||||||
"namespace-prod": {&api.Namespace{}},
|
|
||||||
},
|
|
||||||
"examples/admin/cloud": {
|
|
||||||
"ccm-example": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.DaemonSet{}},
|
|
||||||
"pvl-initializer-config": {&admissionregistration.InitializerConfiguration{}},
|
|
||||||
},
|
|
||||||
"examples/admin/dns": {
|
|
||||||
"busybox": {&api.Pod{}},
|
|
||||||
"dns-horizontal-autoscaler": {&extensions.Deployment{}},
|
|
||||||
},
|
|
||||||
"examples/admin/resource": {
|
|
||||||
"cpu-constraints": {&api.LimitRange{}},
|
|
||||||
"cpu-constraints-pod": {&api.Pod{}},
|
|
||||||
"cpu-constraints-pod-2": {&api.Pod{}},
|
|
||||||
"cpu-constraints-pod-3": {&api.Pod{}},
|
|
||||||
"cpu-constraints-pod-4": {&api.Pod{}},
|
|
||||||
"cpu-defaults": {&api.LimitRange{}},
|
|
||||||
"cpu-defaults-pod": {&api.Pod{}},
|
|
||||||
"cpu-defaults-pod-2": {&api.Pod{}},
|
|
||||||
"cpu-defaults-pod-3": {&api.Pod{}},
|
|
||||||
"memory-constraints": {&api.LimitRange{}},
|
|
||||||
"memory-constraints-pod": {&api.Pod{}},
|
|
||||||
"memory-constraints-pod-2": {&api.Pod{}},
|
|
||||||
"memory-constraints-pod-3": {&api.Pod{}},
|
|
||||||
"memory-constraints-pod-4": {&api.Pod{}},
|
|
||||||
"memory-defaults": {&api.LimitRange{}},
|
|
||||||
"memory-defaults-pod": {&api.Pod{}},
|
|
||||||
"memory-defaults-pod-2": {&api.Pod{}},
|
|
||||||
"memory-defaults-pod-3": {&api.Pod{}},
|
|
||||||
"quota-mem-cpu": {&api.ResourceQuota{}},
|
|
||||||
"quota-mem-cpu-pod": {&api.Pod{}},
|
|
||||||
"quota-mem-cpu-pod-2": {&api.Pod{}},
|
|
||||||
"quota-objects": {&api.ResourceQuota{}},
|
|
||||||
"quota-objects-pvc": {&api.PersistentVolumeClaim{}},
|
|
||||||
"quota-objects-pvc-2": {&api.PersistentVolumeClaim{}},
|
|
||||||
"quota-pod": {&api.ResourceQuota{}},
|
|
||||||
"quota-pod-deployment": {&extensions.Deployment{}},
|
|
||||||
},
|
|
||||||
"examples/admin/sched": {
|
|
||||||
"my-scheduler": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.Deployment{}},
|
"my-scheduler": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.Deployment{}},
|
||||||
"pod1": {&api.Pod{}},
|
"pod1": {&api.Pod{}},
|
||||||
"pod2": {&api.Pod{}},
|
"pod2": {&api.Pod{}},
|
||||||
"pod3": {&api.Pod{}},
|
"pod3": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"examples/application": {
|
"application": {
|
||||||
"deployment": {&extensions.Deployment{}},
|
"deployment": {&extensions.Deployment{}},
|
||||||
"deployment-patch": {&extensions.Deployment{}},
|
"deployment-patch": {&extensions.Deployment{}},
|
||||||
"deployment-scale": {&extensions.Deployment{}},
|
"deployment-scale": {&extensions.Deployment{}},
|
||||||
"deployment-update": {&extensions.Deployment{}},
|
"deployment-update": {&extensions.Deployment{}},
|
||||||
|
"nginx-app": {&api.Service{}, &extensions.Deployment{}},
|
||||||
"nginx-with-request": {&extensions.Deployment{}},
|
"nginx-with-request": {&extensions.Deployment{}},
|
||||||
"shell-demo": {&api.Pod{}},
|
"shell-demo": {&api.Pod{}},
|
||||||
|
"simple_deployment": {&extensions.Deployment{}},
|
||||||
|
"update_deployment": {&extensions.Deployment{}},
|
||||||
},
|
},
|
||||||
"examples/application/cassandra": {
|
"application/cassandra": {
|
||||||
"cassandra-service": {&api.Service{}},
|
"cassandra-service": {&api.Service{}},
|
||||||
"cassandra-statefulset": {&apps.StatefulSet{}, &storage.StorageClass{}},
|
"cassandra-statefulset": {&apps.StatefulSet{}, &storage.StorageClass{}},
|
||||||
},
|
},
|
||||||
"examples/application/guestbook": {
|
"application/guestbook": {
|
||||||
"frontend-deployment": {&extensions.Deployment{}},
|
"frontend-deployment": {&extensions.Deployment{}},
|
||||||
"frontend-service": {&api.Service{}},
|
"frontend-service": {&api.Service{}},
|
||||||
"redis-master-deployment": {&extensions.Deployment{}},
|
"redis-master-deployment": {&extensions.Deployment{}},
|
||||||
@@ -394,40 +368,44 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||||||
"redis-slave-deployment": {&extensions.Deployment{}},
|
"redis-slave-deployment": {&extensions.Deployment{}},
|
||||||
"redis-slave-service": {&api.Service{}},
|
"redis-slave-service": {&api.Service{}},
|
||||||
},
|
},
|
||||||
"examples/application/hpa": {
|
"application/hpa": {
|
||||||
"php-apache": {&autoscaling.HorizontalPodAutoscaler{}},
|
"php-apache": {&autoscaling.HorizontalPodAutoscaler{}},
|
||||||
},
|
},
|
||||||
"examples/application/job": {
|
"application/nginx": {
|
||||||
|
"nginx-deployment": {&extensions.Deployment{}},
|
||||||
|
"nginx-svc": {&api.Service{}},
|
||||||
|
},
|
||||||
|
"application/job": {
|
||||||
"cronjob": {&batch.CronJob{}},
|
"cronjob": {&batch.CronJob{}},
|
||||||
"job-tmpl": {&batch.Job{}},
|
"job-tmpl": {&batch.Job{}},
|
||||||
},
|
},
|
||||||
"examples/application/job/rabbitmq": {
|
"application/job/rabbitmq": {
|
||||||
"job": {&batch.Job{}},
|
"job": {&batch.Job{}},
|
||||||
},
|
},
|
||||||
"examples/application/job/redis": {
|
"application/job/redis": {
|
||||||
"job": {&batch.Job{}},
|
"job": {&batch.Job{}},
|
||||||
"redis-pod": {&api.Pod{}},
|
"redis-pod": {&api.Pod{}},
|
||||||
"redis-service": {&api.Service{}},
|
"redis-service": {&api.Service{}},
|
||||||
},
|
},
|
||||||
"examples/application/mysql": {
|
"application/mysql": {
|
||||||
"mysql-configmap": {&api.ConfigMap{}},
|
"mysql-configmap": {&api.ConfigMap{}},
|
||||||
"mysql-deployment": {&api.Service{}, &extensions.Deployment{}},
|
"mysql-deployment": {&api.Service{}, &extensions.Deployment{}},
|
||||||
"mysql-pv": {&api.PersistentVolume{}, &api.PersistentVolumeClaim{}},
|
"mysql-pv": {&api.PersistentVolume{}, &api.PersistentVolumeClaim{}},
|
||||||
"mysql-services": {&api.Service{}, &api.Service{}},
|
"mysql-services": {&api.Service{}, &api.Service{}},
|
||||||
"mysql-statefulset": {&apps.StatefulSet{}},
|
"mysql-statefulset": {&apps.StatefulSet{}},
|
||||||
},
|
},
|
||||||
"examples/application/web": {
|
"application/web": {
|
||||||
"web": {&api.Service{}, &apps.StatefulSet{}},
|
"web": {&api.Service{}, &apps.StatefulSet{}},
|
||||||
"web-parallel": {&api.Service{}, &apps.StatefulSet{}},
|
"web-parallel": {&api.Service{}, &apps.StatefulSet{}},
|
||||||
},
|
},
|
||||||
"examples/application/wordpress": {
|
"application/wordpress": {
|
||||||
"mysql-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}},
|
"mysql-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}},
|
||||||
"wordpress-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}},
|
"wordpress-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}},
|
||||||
},
|
},
|
||||||
"examples/application/zookeeper": {
|
"application/zookeeper": {
|
||||||
"zookeeper": {&api.Service{}, &api.Service{}, &policy.PodDisruptionBudget{}, &apps.StatefulSet{}},
|
"zookeeper": {&api.Service{}, &api.Service{}, &policy.PodDisruptionBudget{}, &apps.StatefulSet{}},
|
||||||
},
|
},
|
||||||
"examples/controllers": {
|
"controllers": {
|
||||||
"daemonset": {&extensions.DaemonSet{}},
|
"daemonset": {&extensions.DaemonSet{}},
|
||||||
"frontend": {&extensions.ReplicaSet{}},
|
"frontend": {&extensions.ReplicaSet{}},
|
||||||
"hpa-rs": {&autoscaling.HorizontalPodAutoscaler{}},
|
"hpa-rs": {&autoscaling.HorizontalPodAutoscaler{}},
|
||||||
@@ -436,7 +414,7 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||||||
"replication": {&api.ReplicationController{}},
|
"replication": {&api.ReplicationController{}},
|
||||||
"nginx-deployment": {&extensions.Deployment{}},
|
"nginx-deployment": {&extensions.Deployment{}},
|
||||||
},
|
},
|
||||||
"examples/debug": {
|
"debug": {
|
||||||
"counter-pod": {&api.Pod{}},
|
"counter-pod": {&api.Pod{}},
|
||||||
"event-exporter": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.Deployment{}},
|
"event-exporter": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.Deployment{}},
|
||||||
"fluentd-gcp-configmap": {&api.ConfigMap{}},
|
"fluentd-gcp-configmap": {&api.ConfigMap{}},
|
||||||
@@ -445,7 +423,13 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||||||
"node-problem-detector-configmap": {&extensions.DaemonSet{}},
|
"node-problem-detector-configmap": {&extensions.DaemonSet{}},
|
||||||
"termination": {&api.Pod{}},
|
"termination": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"examples/podpreset": {
|
"federation": {
|
||||||
|
"policy-engine-deployment": {&extensions.Deployment{}},
|
||||||
|
"policy-engine-service": {&api.Service{}},
|
||||||
|
"replicaset-example-policy": {&extensions.ReplicaSet{}},
|
||||||
|
"scheduling-policy-admission": {&api.ConfigMap{}},
|
||||||
|
},
|
||||||
|
"podpreset": {
|
||||||
"allow-db": {&settings.PodPreset{}},
|
"allow-db": {&settings.PodPreset{}},
|
||||||
"allow-db-merged": {&api.Pod{}},
|
"allow-db-merged": {&api.Pod{}},
|
||||||
"configmap": {&api.ConfigMap{}},
|
"configmap": {&api.ConfigMap{}},
|
||||||
@@ -459,7 +443,7 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||||||
"replicaset-merged": {&api.Pod{}},
|
"replicaset-merged": {&api.Pod{}},
|
||||||
"replicaset": {&extensions.ReplicaSet{}},
|
"replicaset": {&extensions.ReplicaSet{}},
|
||||||
},
|
},
|
||||||
"examples/pods": {
|
"pods": {
|
||||||
"commands": {&api.Pod{}},
|
"commands": {&api.Pod{}},
|
||||||
"init-containers": {&api.Pod{}},
|
"init-containers": {&api.Pod{}},
|
||||||
"lifecycle-events": {&api.Pod{}},
|
"lifecycle-events": {&api.Pod{}},
|
||||||
@@ -469,32 +453,35 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||||||
"private-reg-pod": {&api.Pod{}},
|
"private-reg-pod": {&api.Pod{}},
|
||||||
"share-process-namespace": {&api.Pod{}},
|
"share-process-namespace": {&api.Pod{}},
|
||||||
"simple-pod": {&api.Pod{}},
|
"simple-pod": {&api.Pod{}},
|
||||||
"two-container-pod": {&api.Pod{}},
|
"two-container-pod": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"examples/pods/inject": {
|
"pods/config": {
|
||||||
"dapi-envars-container": {&api.Pod{}},
|
"redis-pod": {&api.Pod{}},
|
||||||
"dapi-envars-pod": {&api.Pod{}},
|
|
||||||
"dapi-volume": {&api.Pod{}},
|
|
||||||
"dapi-volume-resources": {&api.Pod{}},
|
|
||||||
"envars": {&api.Pod{}},
|
|
||||||
"secret": {&api.Secret{}},
|
|
||||||
"secret-envars-pod": {&api.Pod{}},
|
|
||||||
"secret-pod": {&api.Pod{}},
|
|
||||||
},
|
},
|
||||||
"examples/pods/probe": {
|
"pods/inject": {
|
||||||
"exec-liveness": {&api.Pod{}},
|
"dapi-envars-container": {&api.Pod{}},
|
||||||
"http-liveness": {&api.Pod{}},
|
"dapi-envars-pod": {&api.Pod{}},
|
||||||
"pod-with-http-healthcheck": {&api.Pod{}},
|
"dapi-volume": {&api.Pod{}},
|
||||||
|
"dapi-volume-resources": {&api.Pod{}},
|
||||||
|
"envars": {&api.Pod{}},
|
||||||
|
"secret": {&api.Secret{}},
|
||||||
|
"secret-envars-pod": {&api.Pod{}},
|
||||||
|
"secret-pod": {&api.Pod{}},
|
||||||
|
},
|
||||||
|
"pods/probe": {
|
||||||
|
"exec-liveness": {&api.Pod{}},
|
||||||
|
"http-liveness": {&api.Pod{}},
|
||||||
|
"pod-with-http-healthcheck": {&api.Pod{}},
|
||||||
"pod-with-tcp-socket-healthcheck": {&api.Pod{}},
|
"pod-with-tcp-socket-healthcheck": {&api.Pod{}},
|
||||||
"tcp-liveness-readiness": {&api.Pod{}},
|
"tcp-liveness-readiness": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"examples/pods/qos": {
|
"pods/qos": {
|
||||||
"qos-pod": {&api.Pod{}},
|
"qos-pod": {&api.Pod{}},
|
||||||
"qos-pod-2": {&api.Pod{}},
|
"qos-pod-2": {&api.Pod{}},
|
||||||
"qos-pod-3": {&api.Pod{}},
|
"qos-pod-3": {&api.Pod{}},
|
||||||
"qos-pod-4": {&api.Pod{}},
|
"qos-pod-4": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"examples/pods/resource": {
|
"pods/resource": {
|
||||||
"cpu-request-limit": {&api.Pod{}},
|
"cpu-request-limit": {&api.Pod{}},
|
||||||
"cpu-request-limit-2": {&api.Pod{}},
|
"cpu-request-limit-2": {&api.Pod{}},
|
||||||
"extended-resource-pod": {&api.Pod{}},
|
"extended-resource-pod": {&api.Pod{}},
|
||||||
@@ -503,47 +490,57 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||||||
"memory-request-limit-2": {&api.Pod{}},
|
"memory-request-limit-2": {&api.Pod{}},
|
||||||
"memory-request-limit-3": {&api.Pod{}},
|
"memory-request-limit-3": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"examples/pods/security": {
|
"pods/security": {
|
||||||
|
"hello-apparmor": {&api.Pod{}},
|
||||||
"security-context": {&api.Pod{}},
|
"security-context": {&api.Pod{}},
|
||||||
"security-context-2": {&api.Pod{}},
|
"security-context-2": {&api.Pod{}},
|
||||||
"security-context-3": {&api.Pod{}},
|
"security-context-3": {&api.Pod{}},
|
||||||
"security-context-4": {&api.Pod{}},
|
"security-context-4": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"examples/pods/storage": {
|
"pods/storage": {
|
||||||
"projected": {&api.Pod{}},
|
"projected": {&api.Pod{}},
|
||||||
"pv-claim": {&api.PersistentVolumeClaim{}},
|
"pv-claim": {&api.PersistentVolumeClaim{}},
|
||||||
"pv-pod": {&api.Pod{}},
|
"pv-pod": {&api.Pod{}},
|
||||||
"pv-volume": {&api.PersistentVolume{}},
|
"pv-volume": {&api.PersistentVolume{}},
|
||||||
"redis": {&api.Pod{}},
|
"redis": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
"examples/policy": {
|
"policy": {
|
||||||
"privileged-psp": {&policy.PodSecurityPolicy{}},
|
"privileged-psp": {&policy.PodSecurityPolicy{}},
|
||||||
"restricted-psp": {&policy.PodSecurityPolicy{}},
|
"restricted-psp": {&policy.PodSecurityPolicy{}},
|
||||||
"example-psp": {&policy.PodSecurityPolicy{}},
|
"example-psp": {&policy.PodSecurityPolicy{}},
|
||||||
},
|
},
|
||||||
"examples/service": {
|
"service": {
|
||||||
"nginx-service": {&api.Service{}},
|
"nginx-service": {&api.Service{}},
|
||||||
},
|
},
|
||||||
"examples/service/access": {
|
"service/access": {
|
||||||
"frontend": {&api.Service{}, &extensions.Deployment{}},
|
"frontend": {&api.Service{}, &extensions.Deployment{}},
|
||||||
"hello-service": {&api.Service{}},
|
"hello-service": {&api.Service{}},
|
||||||
"hello": {&extensions.Deployment{}},
|
"hello": {&extensions.Deployment{}},
|
||||||
},
|
},
|
||||||
"examples/windows": {
|
"service/networking": {
|
||||||
"configmap-pod": {&api.ConfigMap{}, &api.Pod{}},
|
"curlpod": {&extensions.Deployment{}},
|
||||||
"daemonset": {&extensions.DaemonSet{}},
|
"custom-dns": {&api.Pod{}},
|
||||||
"deploy-hyperv": {&extensions.Deployment{}},
|
"hostaliases-pod": {&api.Pod{}},
|
||||||
"deploy-resource": {&extensions.Deployment{}},
|
"ingress": {&extensions.Ingress{}},
|
||||||
"emptydir-pod": {&api.Pod{}},
|
"nginx-secure-app": {&api.Service{}, &extensions.Deployment{}},
|
||||||
|
"nginx-svc": {&api.Service{}},
|
||||||
|
"run-my-nginx": {&extensions.Deployment{}},
|
||||||
|
},
|
||||||
|
"windows": {
|
||||||
|
"configmap-pod": {&api.ConfigMap{}, &api.Pod{}},
|
||||||
|
"daemonset": {&extensions.DaemonSet{}},
|
||||||
|
"deploy-hyperv": {&extensions.Deployment{}},
|
||||||
|
"deploy-resource": {&extensions.Deployment{}},
|
||||||
|
"emptydir-pod": {&api.Pod{}},
|
||||||
"hostpath-volume-pod": {&api.Pod{}},
|
"hostpath-volume-pod": {&api.Pod{}},
|
||||||
"secret-pod": {&api.Secret{}, &api.Pod{}},
|
"secret-pod": {&api.Secret{}, &api.Pod{}},
|
||||||
"simple-pod": {&api.Pod{}},
|
"simple-pod": {&api.Pod{}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note a key in the following map has to be complete relative path
|
// Note a key in the following map has to be complete relative path
|
||||||
filesIgnore := map[string]map[string]bool{
|
filesIgnore := map[string]map[string]bool{
|
||||||
"../content/en/examples/audit": {
|
"audit": {
|
||||||
"audit-policy": true,
|
"audit-policy": true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -553,12 +550,21 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||||||
// PodShareProcessNamespace needed for example share-process-namespace.yaml
|
// PodShareProcessNamespace needed for example share-process-namespace.yaml
|
||||||
utilfeature.DefaultFeatureGate.Set("PodShareProcessNamespace=true")
|
utilfeature.DefaultFeatureGate.Set("PodShareProcessNamespace=true")
|
||||||
|
|
||||||
rootpath := "../content/en/"
|
|
||||||
for dir, expected := range cases {
|
for dir, expected := range cases {
|
||||||
tested := 0
|
tested := 0
|
||||||
numExpected := 0
|
numExpected := 0
|
||||||
path := rootpath + dir
|
path := dir
|
||||||
err := walkConfigFiles(path, func(name, path string, docs [][]byte) {
|
// Test if artifacts do exist
|
||||||
|
for name := range expected {
|
||||||
|
fn := path + "/" + name
|
||||||
|
_, err1 := os.Stat(fn + ".yaml")
|
||||||
|
_, err2 := os.Stat(fn + ".json")
|
||||||
|
if err1 != nil && err2 != nil {
|
||||||
|
t.Errorf("Test case defined for non-existent file %s", fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Logf("Checking path %s/\n", path)
|
||||||
|
err := walkConfigFiles(path, t, func(name, path string, docs [][]byte) {
|
||||||
expectedTypes, found := expected[name]
|
expectedTypes, found := expected[name]
|
||||||
if !found {
|
if !found {
|
||||||
p := filepath.Dir(path)
|
p := filepath.Dir(path)
|
||||||
@@ -582,26 +588,17 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||||||
t.Logf("skipping : %s/%s\n", path, name)
|
t.Logf("skipping : %s/%s\n", path, name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.Contains(name, "scheduler-policy-config") {
|
|
||||||
if err := runtime.DecodeInto(schedulerapilatest.Codec, data, expectedType); err != nil {
|
codec, err := getCodecForObject(expectedType)
|
||||||
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
if err != nil {
|
||||||
return
|
t.Errorf("Could not get codec for %s: %s", expectedType, err)
|
||||||
}
|
}
|
||||||
// TODO: Add validate method for
|
if err := runtime.DecodeInto(codec, data, expectedType); err != nil {
|
||||||
// &schedulerapi.Policy, and remove this
|
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
||||||
// special case
|
return
|
||||||
} else {
|
}
|
||||||
codec, err := getCodecForObject(expectedType)
|
if errors := validateObject(expectedType); len(errors) > 0 {
|
||||||
if err != nil {
|
t.Errorf("%s did not validate correctly: %v", path, errors)
|
||||||
t.Errorf("Could not get codec for %s: %s", expectedType, err)
|
|
||||||
}
|
|
||||||
if err := runtime.DecodeInto(codec, data, expectedType); err != nil {
|
|
||||||
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors := validateObject(expectedType); len(errors) > 0 {
|
|
||||||
t.Errorf("%s did not validate correctly: %v", path, errors)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
+3
@@ -7,6 +7,9 @@ metadata:
|
|||||||
namespace: federation-system
|
namespace: federation-system
|
||||||
spec:
|
spec:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: opa
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<channel>
|
<channel>
|
||||||
<title>{{ .Site.Title }} – {{ .Title }}</title>
|
<title>{{ .Site.Title }} – {{ .Title }}</title>
|
||||||
<link>{{ .Permalink }}</link>
|
<link>{{ .Permalink }}</link>
|
||||||
<description>Recent Hugo news from gohugo.io</description>
|
<description>The Kubernetes project blog</description>
|
||||||
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
|
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
|
||||||
<language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
|
<language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
|
||||||
<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
|
<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
|
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
|
||||||
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
|
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
|
||||||
<image>
|
<image>
|
||||||
<url>{{ "img/hugo.png" | absURL }}</url>
|
<url>https://raw.githubusercontent.com/kubernetes/kubernetes/master/logo/logo.png</url>
|
||||||
<title>GoHugo.io</title>
|
<title>Kubernetes.io</title>
|
||||||
<link>{{ .Permalink }}</link>
|
<link>{{ .Permalink }}</link>
|
||||||
</image>
|
</image>
|
||||||
{{ with .OutputFormats.Get "RSS" }}
|
{{ with .OutputFormats.Get "RSS" }}
|
||||||
@@ -35,4 +35,4 @@
|
|||||||
</item>
|
</item>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
|
|||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 617 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 232 KiB |
@@ -311,10 +311,15 @@ $( document ).ready(function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.onpopstate = function() {
|
||||||
|
window.history.back();
|
||||||
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
// Set up UI
|
// Set up UI
|
||||||
buildCards();
|
buildCards();
|
||||||
attachCardEvents();
|
attachCardEvents();
|
||||||
|
setupCardState();
|
||||||
}
|
}
|
||||||
|
|
||||||
// What actually executes on page load
|
// What actually executes on page load
|
||||||
|
|||||||
Reference in New Issue
Block a user