Fix merge conflict
@@ -25,5 +25,5 @@ docker-image:
|
|||||||
docker-build:
|
docker-build:
|
||||||
$(DOCKER_RUN) $(DOCKER_IMAGE) hugo
|
$(DOCKER_RUN) $(DOCKER_IMAGE) hugo
|
||||||
|
|
||||||
stage:
|
docker-serve:
|
||||||
$(DOCKER_RUN) -p 1313:1313 $(DOCKER_IMAGE) hugo server --watch --bind 0.0.0.0
|
$(DOCKER_RUN) -p 1313:1313 $(DOCKER_IMAGE) hugo server --watch --bind 0.0.0.0
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ docker run \
|
|||||||
--volume $(PWD):/src \
|
--volume $(PWD):/src \
|
||||||
-p 1313:1313 \
|
-p 1313:1313 \
|
||||||
kubernetes-hugo \
|
kubernetes-hugo \
|
||||||
hugo server --watch --bind 0.0.0.0
|
hugo server \
|
||||||
|
--watch \
|
||||||
|
--bind 0.0.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
As when building without using a Docker container, the results of the build will be published to the `public` directory (the default output directory for [Hugo](https://gohugo.io), the static site generator used to build this site).
|
As when building without using a Docker container, the results of the build will be published to the `public` directory (the default output directory for [Hugo](https://gohugo.io), the static site generator used to build this site).
|
||||||
|
|||||||
@@ -34,14 +34,27 @@ blog = "/:section/:year/:month/:day/:slug/"
|
|||||||
|
|
||||||
# Be explicit about the output formats. We (currently) only want an RSS feed for the home page.
|
# Be explicit about the output formats. We (currently) only want an RSS feed for the home page.
|
||||||
[outputs]
|
[outputs]
|
||||||
home = [ "HTML", "RSS"]
|
home = [ "HTML", "RSS", "HEADERS" ]
|
||||||
page = [ "HTML"]
|
page = [ "HTML"]
|
||||||
section = [ "HTML"]
|
section = [ "HTML"]
|
||||||
|
|
||||||
|
# Add a "text/netlify" media type for auto-generating the _headers file
|
||||||
|
[mediaTypes]
|
||||||
|
[mediaTypes."text/netlify"]
|
||||||
|
suffix = ""
|
||||||
|
delimiter = ""
|
||||||
|
|
||||||
[outputFormats]
|
[outputFormats]
|
||||||
[outputFormats.RSS]
|
[outputFormats.RSS]
|
||||||
baseName = "feed"
|
baseName = "feed"
|
||||||
|
|
||||||
|
# _headers file output (uses the template at layouts/index.headers)
|
||||||
|
[outputFormats.HEADERS]
|
||||||
|
mediatype = "text/netlify"
|
||||||
|
baseName = "_headers"
|
||||||
|
isPlainText = true
|
||||||
|
notAlternative = true
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
time_format_blog = "Monday, January 02, 2006"
|
time_format_blog = "Monday, January 02, 2006"
|
||||||
@@ -67,6 +80,17 @@ githubbranch = "v1.11.0"
|
|||||||
docsbranch = "release-1.11"
|
docsbranch = "release-1.11"
|
||||||
url = "https://kubernetes.io"
|
url = "https://kubernetes.io"
|
||||||
|
|
||||||
|
[params.pushAssets]
|
||||||
|
css = [
|
||||||
|
"callouts",
|
||||||
|
"styles",
|
||||||
|
"custom-jekyll/tags"
|
||||||
|
]
|
||||||
|
js = [
|
||||||
|
"custom-jekyll/tags",
|
||||||
|
"script"
|
||||||
|
]
|
||||||
|
|
||||||
[[params.versions]]
|
[[params.versions]]
|
||||||
fullversion = "v1.10.3"
|
fullversion = "v1.10.3"
|
||||||
version = "v1.10"
|
version = "v1.10"
|
||||||
@@ -95,7 +119,6 @@ githubbranch = "v1.7.6"
|
|||||||
docsbranch = "release-1.7"
|
docsbranch = "release-1.7"
|
||||||
url = "https://v1-7.docs.kubernetes.io"
|
url = "https://v1-7.docs.kubernetes.io"
|
||||||
|
|
||||||
|
|
||||||
# Language definitions.
|
# Language definitions.
|
||||||
|
|
||||||
[languages]
|
[languages]
|
||||||
@@ -108,8 +131,7 @@ weight = 1
|
|||||||
[languages.cn]
|
[languages.cn]
|
||||||
title = "Kubernetes"
|
title = "Kubernetes"
|
||||||
description = "Production-Grade Container Orchestration"
|
description = "Production-Grade Container Orchestration"
|
||||||
languageName ="Chinese"
|
languageName = "Chinese"
|
||||||
weight = 2
|
weight = 2
|
||||||
contentDir = "content/cn"
|
contentDir = "content/cn"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,15 @@ cid: home
|
|||||||
<main>
|
<main>
|
||||||
<h3>Case Studies</h3>
|
<h3>Case Studies</h3>
|
||||||
<div id="caseStudiesWrapper">
|
<div id="caseStudiesWrapper">
|
||||||
|
<div>
|
||||||
|
<p>Pinning Its Past, Present, and Future on Cloud Native</p>
|
||||||
|
<a href="/case-studies/pinterest">Read more</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>Reinventing the World’s Largest Education Company With Kubernetes</p>
|
||||||
|
<a href="/case-studies/pearson">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>
|
||||||
@@ -129,14 +138,6 @@ cid: home
|
|||||||
<p>Driving Banking Innovation with Cloud Native</p>
|
<p>Driving Banking Innovation with Cloud Native</p>
|
||||||
<a href="/case-studies/ing">Read more</a>
|
<a href="/case-studies/ing">Read more</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<p>Cloud Native at Northwestern Mutual</p>
|
|
||||||
<a href="/case-studies/northwestern-mutual/">Read more</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>Launching and Scaling Up Experiments, Made Simple</p>
|
|
||||||
<a href="/case-studies/openai/">Read more</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ url: /blog/2015/05/Kubernetes-On-Openstack
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[](http://3.bp.blogspot.com/-EOrCHChZJZE/VVZzq43g6CI/AAAAAAAAF-E/JUilRHk369E/s1600/Untitled%2Bdrawing.jpg)
|
[](https://3.bp.blogspot.com/-EOrCHChZJZE/VVZzq43g6CI/AAAAAAAAF-E/JUilRHk369E/s1600/Untitled%2Bdrawing.jpg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ In the spirit of minimum viability, the first version of Jenkins-on-Kubernetes I
|
|||||||
|
|
||||||
Here’s a visual of that first version:
|
Here’s a visual of that first version:
|
||||||
|
|
||||||
[](http://1.bp.blogspot.com/-ccmpTmulrng/VaVxOs7gysI/AAAAAAAAAU8/bCEzgGGm-pE/s1600/0.png)
|
[](https://1.bp.blogspot.com/-ccmpTmulrng/VaVxOs7gysI/AAAAAAAAAU8/bCEzgGGm-pE/s1600/0.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ The pod will have a service exposing TCP 80 and 443 to a public load balancer. H
|
|||||||
|
|
||||||
And here’s an overview with the SSL termination proxy in place. Notice that Jenkins is no longer directly exposed to the public Internet:
|
And here’s an overview with the SSL termination proxy in place. Notice that Jenkins is no longer directly exposed to the public Internet:
|
||||||
|
|
||||||
[](http://3.bp.blogspot.com/-0B1BEQo_fWc/VaVxVUBkf3I/AAAAAAAAAVE/5yCCnA29C88/s1600/0%2B%25281%2529.png)
|
[](https://3.bp.blogspot.com/-0B1BEQo_fWc/VaVxVUBkf3I/AAAAAAAAAVE/5yCCnA29C88/s1600/0%2B%25281%2529.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ url: /blog/2015/11/Kubernetes-As-Foundation-For-Cloud-Native-Paas
|
|||||||
---
|
---
|
||||||
With Kubernetes continuing to gain momentum as a critical tool for building and scaling container based applications, we’ve been thrilled to see a growing number of platform as a service (PaaS) offerings adopt it as a foundation. PaaS developers have been drawn to Kubernetes by its rapid rate of maturation, the soundness of its core architectural concepts, and the strength of its contributor community. The [Kubernetes ecosystem](https://kubernetes.io/blog/2015/07/the-growing-kubernetes-ecosystem) continues to grow, and these PaaS projects are great additions to it.
|
With Kubernetes continuing to gain momentum as a critical tool for building and scaling container based applications, we’ve been thrilled to see a growing number of platform as a service (PaaS) offerings adopt it as a foundation. PaaS developers have been drawn to Kubernetes by its rapid rate of maturation, the soundness of its core architectural concepts, and the strength of its contributor community. The [Kubernetes ecosystem](https://kubernetes.io/blog/2015/07/the-growing-kubernetes-ecosystem) continues to grow, and these PaaS projects are great additions to it.
|
||||||
|
|
||||||
[](http://1.bp.blogspot.com/-xX93tnoIlGo/Vjj2fSc_CDI/AAAAAAAAAi0/lvTkT9jyFog/s1600/k8%2Bipaas%2B1.png)
|
[](https://1.bp.blogspot.com/-xX93tnoIlGo/Vjj2fSc_CDI/AAAAAAAAAi0/lvTkT9jyFog/s1600/k8%2Bipaas%2B1.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ With Kubernetes continuing to gain momentum as a critical tool for building and
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[](http://1.bp.blogspot.com/-1XZFGRHGb34/Vjj2wUtA6pI/AAAAAAAAAi8/SD-qRhVIiIs/s1600/k8%2Bipaas%2B2.png)
|
[](https://1.bp.blogspot.com/-1XZFGRHGb34/Vjj2wUtA6pI/AAAAAAAAAi8/SD-qRhVIiIs/s1600/k8%2Bipaas%2B2.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ With Kubernetes continuing to gain momentum as a critical tool for building and
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-t3L1CANyhUs/Vjj28Zpf9WI/AAAAAAAAAjE/Ef-PLLmHGvU/s1600/k8%2Bipaas%2B3.png)
|
[](https://2.bp.blogspot.com/-t3L1CANyhUs/Vjj28Zpf9WI/AAAAAAAAAjE/Ef-PLLmHGvU/s1600/k8%2Bipaas%2B3.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ Huawei has made Kubernetes the core runtime engine for container based applicati
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-Ys0Zn4IQzn0/Vjj3JIE0BVI/AAAAAAAAAjM/ktwltzVa1GE/s1600/k8%2Bipaas%2B4.png)
|
[](https://2.bp.blogspot.com/-Ys0Zn4IQzn0/Vjj3JIE0BVI/AAAAAAAAAjM/ktwltzVa1GE/s1600/k8%2Bipaas%2B4.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ The easiest way to take advantage of sysdig’s Kubernetes support is by launchi
|
|||||||
Now that csysdig is running, hit F2 to bring up the views panel, and you'll notice the presence of a bunch of new views. The **k8s Namespaces** view can be used to see the list of namespaces and observe the amount of CPU, memory, network and disk resources each of them is using on this machine:
|
Now that csysdig is running, hit F2 to bring up the views panel, and you'll notice the presence of a bunch of new views. The **k8s Namespaces** view can be used to see the list of namespaces and observe the amount of CPU, memory, network and disk resources each of them is using on this machine:
|
||||||
|
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-9kXfpo76r0k/Vkz8AkpctEI/AAAAAAAAAss/yvf9oc759Wg/s1600/sisdig%2B6.png)
|
[](https://2.bp.blogspot.com/-9kXfpo76r0k/Vkz8AkpctEI/AAAAAAAAAss/yvf9oc759Wg/s1600/sisdig%2B6.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ Now that csysdig is running, hit F2 to bring up the views panel, and you'll noti
|
|||||||
Similarly, you can select **k8s Services** to see the same information broken up by service:
|
Similarly, you can select **k8s Services** to see the same information broken up by service:
|
||||||
|
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-Ya1W3Z_ETcs/Vkz8AN3XtfI/AAAAAAAAAs8/HNv_TvHpfHU/s1600/sisdig%2B2.png)
|
[](https://2.bp.blogspot.com/-Ya1W3Z_ETcs/Vkz8AN3XtfI/AAAAAAAAAs8/HNv_TvHpfHU/s1600/sisdig%2B2.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ Similarly, you can select **k8s Services** to see the same information broken up
|
|||||||
or **k8s Controllers** to see the replication controllers:
|
or **k8s Controllers** to see the replication controllers:
|
||||||
|
|
||||||
|
|
||||||
[](http://3.bp.blogspot.com/-gGkgXRC5P6g/Vkz8A1RVyAI/AAAAAAAAAtQ/SFlHQeNrDjQ/s1600/sysdig%2B1.png)
|
[](https://3.bp.blogspot.com/-gGkgXRC5P6g/Vkz8A1RVyAI/AAAAAAAAAtQ/SFlHQeNrDjQ/s1600/sysdig%2B1.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ or **k8s Controllers** to see the replication controllers:
|
|||||||
or **k8s Pods** to see the list of pods running on this machine and the resources they use:
|
or **k8s Pods** to see the list of pods running on this machine and the resources they use:
|
||||||
|
|
||||||
|
|
||||||
[](http://3.bp.blogspot.com/-PrDfWzi9F3c/Vkz8H6rPlII/AAAAAAAAAtc/f46tE6EKvoo/s1600/sisdig%2B7.png)
|
[](https://3.bp.blogspot.com/-PrDfWzi9F3c/Vkz8H6rPlII/AAAAAAAAAtc/f46tE6EKvoo/s1600/sisdig%2B7.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ or **k8s Pods** to see the list of pods running on this machine and the resource
|
|||||||
A cool feature in csysdig is the ability to drill down: just select an element, click on enter and – boom – now you're looking inside it. Drill down is also aware of the Kubernetes hierarchy, which means I can start from a service, get the list of its pods, see which containers run inside one of the pods, and go inside one of the containers to explore files, network connections, processes or even threads. Check out the video below.
|
A cool feature in csysdig is the ability to drill down: just select an element, click on enter and – boom – now you're looking inside it. Drill down is also aware of the Kubernetes hierarchy, which means I can start from a service, get the list of its pods, see which containers run inside one of the pods, and go inside one of the containers to explore files, network connections, processes or even threads. Check out the video below.
|
||||||
|
|
||||||
|
|
||||||
[](http://1.bp.blogspot.com/-lQ-P2gLywlY/Vkz9MOoTgGI/AAAAAAAAAtk/UB6pW7sUbQA/s1600/image09.gif)
|
[](https://1.bp.blogspot.com/-lQ-P2gLywlY/Vkz9MOoTgGI/AAAAAAAAAtk/UB6pW7sUbQA/s1600/image09.gif)
|
||||||
|
|
||||||
|
|
||||||
### Actions!
|
### Actions!
|
||||||
@@ -90,7 +90,7 @@ Let’s start with a quick review of Kubernetes’ architecture. From the physic
|
|||||||
|
|
||||||
On the other hand, from the logical/application point of view, Kubernetes clusters are arranged in the hierarchical fashion shown in this picture:
|
On the other hand, from the logical/application point of view, Kubernetes clusters are arranged in the hierarchical fashion shown in this picture:
|
||||||
|
|
||||||
[](http://1.bp.blogspot.com/-p_x0bLRdFJo/Vkz8IPR5q4I/AAAAAAAAAtg/D9UU2MfPmcI/s1600/sisdig%2B4.png)
|
[](https://1.bp.blogspot.com/-p_x0bLRdFJo/Vkz8IPR5q4I/AAAAAAAAAtg/D9UU2MfPmcI/s1600/sisdig%2B4.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ One of the core features of Sysdig Cloud is groups, which allow you to define th
|
|||||||
|
|
||||||
If you’re interested in the utilization of your underlying physical resource – e.g., identifying noisy neighbors – then the physical hierarchy is great. But if you’re looking to explore the performance of your applications and microservices, then the logical hierarchy is often the best place to start.
|
If you’re interested in the utilization of your underlying physical resource – e.g., identifying noisy neighbors – then the physical hierarchy is great. But if you’re looking to explore the performance of your applications and microservices, then the logical hierarchy is often the best place to start.
|
||||||
|
|
||||||
[](http://4.bp.blogspot.com/-80u3oSEi_Fw/Vkz8AZgE6eI/AAAAAAAAAtE/3iRDMJKBNmc/s1600/sisdig%2B5.png)
|
[](https://4.bp.blogspot.com/-80u3oSEi_Fw/Vkz8AZgE6eI/AAAAAAAAAtE/3iRDMJKBNmc/s1600/sisdig%2B5.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ If you’re interested in the utilization of your underlying physical resource&n
|
|||||||
|
|
||||||
For example: here you can see the overall performance of our WordPress service:
|
For example: here you can see the overall performance of our WordPress service:
|
||||||
|
|
||||||
[](http://4.bp.blogspot.com/-QAsedrM2UxI/Vkz8Aas-26I/AAAAAAAAAtM/9B7Z33vUQrg/s1600/sisdig%2B3.png)
|
[](https://4.bp.blogspot.com/-QAsedrM2UxI/Vkz8Aas-26I/AAAAAAAAAtM/9B7Z33vUQrg/s1600/sisdig%2B3.png)
|
||||||
|
|
||||||
Keep in mind that the pods implementing this service are scattered across multiple machines, but we can still total request counts, response times and URL statistics aggregated together for this service. And don’t forget: this doesn’t require any configuration or instrumentation of wordpress, apache, or the underlying containers!
|
Keep in mind that the pods implementing this service are scattered across multiple machines, but we can still total request counts, response times and URL statistics aggregated together for this service. And don’t forget: this doesn’t require any configuration or instrumentation of wordpress, apache, or the underlying containers!
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ And from this view, I can now easily create alerts for these service-level metri
|
|||||||
|
|
||||||
We’ve also included Kubernetes awareness in Sysdig Cloud’s famous topology view, at both the physical and logical level.
|
We’ve also included Kubernetes awareness in Sysdig Cloud’s famous topology view, at both the physical and logical level.
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-2is-UJatmPk/Vk0AtdfvYvI/AAAAAAAAAt0/9SEsl2LCpYI/s1600/image02.gif)
|
[](https://2.bp.blogspot.com/-2is-UJatmPk/Vk0AtdfvYvI/AAAAAAAAAt0/9SEsl2LCpYI/s1600/image02.gif)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ We’ve also included Kubernetes awareness in Sysdig Cloud’s famous topology v
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-hGQtaIV9XTA/Vk0RnwtlcGI/AAAAAAAAAuM/7ndiyAWpSvU/s1600/image08.gif)
|
[](https://2.bp.blogspot.com/-hGQtaIV9XTA/Vk0RnwtlcGI/AAAAAAAAAuM/7ndiyAWpSvU/s1600/image08.gif)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ Fortunately, for developers, our infrastructure is evolving along with the requi
|
|||||||
|
|
||||||
To demonstrate exactly what we mean by this, I've developed a simple demo of a Container Engine cluster serving 1 million HTTP requests per second. In all honesty, serving 1 million requests per second isn’t really that exciting. In fact, it’s really so very [2013](http://googlecloudplatform.blogspot.com/2013/11/compute-engine-load-balancing-hits-1-million-requests-per-second.html).
|
To demonstrate exactly what we mean by this, I've developed a simple demo of a Container Engine cluster serving 1 million HTTP requests per second. In all honesty, serving 1 million requests per second isn’t really that exciting. In fact, it’s really so very [2013](http://googlecloudplatform.blogspot.com/2013/11/compute-engine-load-balancing-hits-1-million-requests-per-second.html).
|
||||||
|
|
||||||
[](http://4.bp.blogspot.com/-eACCKAzuQFQ/VkO1rwW1DRI/AAAAAAAAAko/zKu-19QCCBU/s1600/image01.gif)
|
[](https://4.bp.blogspot.com/-eACCKAzuQFQ/VkO1rwW1DRI/AAAAAAAAAko/zKu-19QCCBU/s1600/image01.gif)
|
||||||
|
|
||||||
|
|
||||||
What _is_ exciting is that while successfully handling 1 million HTTP requests per second with uninterrupted availability, we have Kubernetes perform a zero-downtime rolling upgrade of the service to a new version of the software _while we're **still** serving 1 million requests per second_.
|
What _is_ exciting is that while successfully handling 1 million HTTP requests per second with uninterrupted availability, we have Kubernetes perform a zero-downtime rolling upgrade of the service to a new version of the software _while we're **still** serving 1 million requests per second_.
|
||||||
|
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-_96_QwNRHLo/VkO1oDAyLLI/AAAAAAAAAkk/B_y5Uh5ngPU/s1600/image00.gif)
|
[](https://2.bp.blogspot.com/-_96_QwNRHLo/VkO1oDAyLLI/AAAAAAAAAkk/B_y5Uh5ngPU/s1600/image00.gif)
|
||||||
|
|
||||||
|
|
||||||
This is only possible due to a large number of performance tweaks and enhancements that have gone into the [Kubernetes 1.1 release](https://kubernetes.io/blog/2015/11/Kubernetes-1-1-Performance-upgrades-improved-tooling-and-a-growing-community). I’m incredibly proud of all of the features that our community has built into this release. Indeed in addition to making it possible to serve 1 million requests per second, we’ve also added an auto-scaler, so that you won’t even have to wake up in the middle of the night to scale your service in response to load or memory pressures.
|
This is only possible due to a large number of performance tweaks and enhancements that have gone into the [Kubernetes 1.1 release](https://kubernetes.io/blog/2015/11/Kubernetes-1-1-Performance-upgrades-improved-tooling-and-a-growing-community). I’m incredibly proud of all of the features that our community has built into this release. Indeed in addition to making it possible to serve 1 million requests per second, we’ve also added an auto-scaler, so that you won’t even have to wake up in the middle of the night to scale your service in response to load or memory pressures.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Use your existing tools of choice to actually build your containers
|
|||||||
|
|
||||||
Use ElasticKube to run, deploy and manage your containers and services
|
Use ElasticKube to run, deploy and manage your containers and services
|
||||||
|
|
||||||
[](http://cl.ly/0i3M2L3Q030z/Image%202016-03-11%20at%209.49.12%20AM.png)
|
[](http://cl.ly/0i3M2L3Q030z/Image%202016-03-11%20at%209.49.12%20AM.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ slug: certified-kubernetes-conformance
|
|||||||
url: /blog/2017/11/Certified-Kubernetes-Conformance
|
url: /blog/2017/11/Certified-Kubernetes-Conformance
|
||||||
---
|
---
|
||||||
|
|
||||||
[](http://1.bp.blogspot.com/-YasPeoIh8tA/Wg28rH4dzXI/AAAAAAAAAHg/Hfk2dnUoav4XMefGyjzMWdJMZbu1QJFagCK4BGAYYCw/s1600/certified_kubernetes_color.png)This week the CNCFⓇ [certified the first group](https://www.cncf.io/announcement/2017/11/13/cloud-native-computing-foundation-launches-certified-kubernetes-program-32-conformant-distributions-platforms/) of KubernetesⓇ offerings under the [Certified Kubernetes Conformance Program](https://www.cncf.io/certification/software-conformance/). These first certifications follow a [beta phase](https://kubernetes.io/blog/2017/10/software-conformance-certification) during which we invited participants to submit conformance results. The community response was overwhelming: CNCF certified offerings from 32 vendors!
|
[](https://1.bp.blogspot.com/-YasPeoIh8tA/Wg28rH4dzXI/AAAAAAAAAHg/Hfk2dnUoav4XMefGyjzMWdJMZbu1QJFagCK4BGAYYCw/s1600/certified_kubernetes_color.png)This week the CNCFⓇ [certified the first group](https://www.cncf.io/announcement/2017/11/13/cloud-native-computing-foundation-launches-certified-kubernetes-program-32-conformant-distributions-platforms/) of KubernetesⓇ offerings under the [Certified Kubernetes Conformance Program](https://www.cncf.io/certification/software-conformance/). These first certifications follow a [beta phase](https://kubernetes.io/blog/2017/10/software-conformance-certification) during which we invited participants to submit conformance results. The community response was overwhelming: CNCF certified offerings from 32 vendors!
|
||||||
|
|
||||||
The new Certified Kubernetes Conformance Program gives enterprise organizations the confidence that workloads running on any Certified Kubernetes distribution or platform will work correctly on other Certified Kubernetes distributions or platforms. A Certified Kubernetes product guarantees that the complete Kubernetes API functions as specified, so users can rely on a seamless, stable experience.
|
The new Certified Kubernetes Conformance Program gives enterprise organizations the confidence that workloads running on any Certified Kubernetes distribution or platform will work correctly on other Certified Kubernetes distributions or platforms. A Certified Kubernetes product guarantees that the complete Kubernetes API functions as specified, so users can rely on a seamless, stable experience.
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ On October 12th, Google and partners [announced](https://cloudplatform.googleblo
|
|||||||
Grafeas allows build, auditing and compliance tools to exchange comprehensive metadata on container images using a central API. This allows enforcing policies that provide central control over the software supply process.
|
Grafeas allows build, auditing and compliance tools to exchange comprehensive metadata on container images using a central API. This allows enforcing policies that provide central control over the software supply process.
|
||||||
|
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-TDD4slMA7gg/WfzDeKVLr2I/AAAAAAAAAGw/dhfWOrCMdmogSNhGr5RrA2ovr02K5nn8ACK4BGAYYCw/s1600/Screen%2BShot%2B2017-11-03%2Bat%2B12.28.13%2BPM.png)
|
[](https://2.bp.blogspot.com/-TDD4slMA7gg/WfzDeKVLr2I/AAAAAAAAAGw/dhfWOrCMdmogSNhGr5RrA2ovr02K5nn8ACK4BGAYYCw/s1600/Screen%2BShot%2B2017-11-03%2Bat%2B12.28.13%2BPM.png)
|
||||||
|
|
||||||
|
|
||||||
## Example application: PaymentProcessor
|
## Example application: PaymentProcessor
|
||||||
@@ -24,13 +24,13 @@ Let’s consider a simple application, _PaymentProcessor_, that retrieves, proce
|
|||||||
Due to the sensitive nature of the payment data, the developers and DevOps team really want to make sure that the code meets certain security and compliance requirements, with detailed records on the provenance of this code. There are CI/CD stages that validate the quality of the PaymentProcessor release, but there is no easy way to centrally view/manage this information:
|
Due to the sensitive nature of the payment data, the developers and DevOps team really want to make sure that the code meets certain security and compliance requirements, with detailed records on the provenance of this code. There are CI/CD stages that validate the quality of the PaymentProcessor release, but there is no easy way to centrally view/manage this information:
|
||||||
|
|
||||||
|
|
||||||
[](http://1.bp.blogspot.com/-WeI6zpGd42A/WfzDkkIonFI/AAAAAAAAAG4/wKUaNaXYvaQ-an9p4_9T9J3EQB_zHkRXwCK4BGAYYCw/s1600/Screen%2BShot%2B2017-11-03%2Bat%2B12.28.23%2BPM.png)
|
[](https://1.bp.blogspot.com/-WeI6zpGd42A/WfzDkkIonFI/AAAAAAAAAG4/wKUaNaXYvaQ-an9p4_9T9J3EQB_zHkRXwCK4BGAYYCw/s1600/Screen%2BShot%2B2017-11-03%2Bat%2B12.28.23%2BPM.png)
|
||||||
|
|
||||||
|
|
||||||
## Visibility and governance over the PaymentProcessor Code
|
## Visibility and governance over the PaymentProcessor Code
|
||||||
Grafeas provides an API for customers to centrally manage metadata created by various CI/CD components and enables deploy time policy enforcement through a Kritis implementation.
|
Grafeas provides an API for customers to centrally manage metadata created by various CI/CD components and enables deploy time policy enforcement through a Kritis implementation.
|
||||||
|
|
||||||
[](http://4.bp.blogspot.com/-SRMfm5z606M/WfzDpHqlz-I/AAAAAAAAAHA/y2suaInhr9E0hU0u78PacBT_kZj2D7DKgCK4BGAYYCw/s1600/Screen%2BShot%2B2017-11-03%2Bat%2B12.28.34%2BPM.png)
|
[](https://4.bp.blogspot.com/-SRMfm5z606M/WfzDpHqlz-I/AAAAAAAAAHA/y2suaInhr9E0hU0u78PacBT_kZj2D7DKgCK4BGAYYCw/s1600/Screen%2BShot%2B2017-11-03%2Bat%2B12.28.34%2BPM.png)
|
||||||
|
|
||||||
|
|
||||||
Let’s consider a basic example of how Grafeas can provide deploy time control for the PaymentProcessor app using a demo verification pipeline.
|
Let’s consider a basic example of how Grafeas can provide deploy time control for the PaymentProcessor app using a demo verification pipeline.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ The admission stage of API server processing is one of the most powerful tools f
|
|||||||
## What is Admission?
|
## What is Admission?
|
||||||
[Admission](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-are-they) is the phase of [handling an API server request](https://blog.openshift.com/kubernetes-deep-dive-api-server-part-1/) that happens before a resource is persisted, but after authorization. Admission gets access to the same information as authorization (user, URL, etc) and the complete body of an API request (for most requests).
|
[Admission](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-are-they) is the phase of [handling an API server request](https://blog.openshift.com/kubernetes-deep-dive-api-server-part-1/) that happens before a resource is persisted, but after authorization. Admission gets access to the same information as authorization (user, URL, etc) and the complete body of an API request (for most requests).
|
||||||
|
|
||||||
[](http://2.bp.blogspot.com/-p8WGg2BATsY/WlfywbD_tAI/AAAAAAAAAJw/mDqZV0dB4_Y0gXXQp_1tQ7CtMRSd6lHVwCK4BGAYYCw/s1600/Screen%2BShot%2B2018-01-11%2Bat%2B3.22.07%2BPM.png)
|
[](https://2.bp.blogspot.com/-p8WGg2BATsY/WlfywbD_tAI/AAAAAAAAAJw/mDqZV0dB4_Y0gXXQp_1tQ7CtMRSd6lHVwCK4BGAYYCw/s1600/Screen%2BShot%2B2018-01-11%2Bat%2B3.22.07%2BPM.png)
|
||||||
|
|
||||||
The admission phase is composed of individual plugins, each of which are narrowly focused and have semantic knowledge of what they are inspecting. Examples include: PodNodeSelector (influences scheduling decisions), PodSecurityPolicy (prevents escalating containers), and ResourceQuota (enforces resource allocation per namespace).
|
The admission phase is composed of individual plugins, each of which are narrowly focused and have semantic knowledge of what they are inspecting. Examples include: PodNodeSelector (influences scheduling decisions), PodSecurityPolicy (prevents escalating containers), and ResourceQuota (enforces resource allocation per namespace).
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: 'KubeVirt: Extending Kubernetes with CRDs for Virtualized Workloads'
|
||||||
|
date: 2018-07-27
|
||||||
|
---
|
||||||
|
|
||||||
|
**Author**: David Vossel (Red Hat)
|
||||||
|
|
||||||
|
## What is KubeVirt?
|
||||||
|
|
||||||
|
[KubeVirt](https://github.com/kubevirt/kubevirt) is a Kubernetes addon that provides users the ability to schedule traditional virtual machine workloads side by side with container workloads. Through the use of [Custom Resource Definitions](https://Kubernetes.io/docs/concepts/extend-Kubernetes/api-extension/custom-resources/) (CRDs) and other Kubernetes features, KubeVirt seamlessly extends existing Kubernetes clusters to provide a set of virtualization APIs that can be used to manage virtual machines.
|
||||||
|
|
||||||
|
## Why Use CRDs Over an Aggregated API Server?
|
||||||
|
|
||||||
|
Back in the middle of 2017, those of us working on KubeVirt were at a crossroads. We had to make a decision whether or not to extend Kubernetes using an aggregated API server or to make use of the new Custom Resource Definitions (CRDs) feature.
|
||||||
|
|
||||||
|
At the time, CRDs lacked much of the functionality we needed to deliver our feature set. The ability to create our own aggregated API server gave us all the flexibility we needed, but it had one major flaw. **An aggregated API server significantly increased the complexity involved with installing and operating KubeVirt.**
|
||||||
|
|
||||||
|
The crux of the issue for us was that aggregated API servers required access to etcd for object persistence. This meant that cluster admins would have to either accept that KubeVirt needs a separate etcd deployment which increases complexity, or provide KubeVirt with shared access to the Kubernetes etcd store which introduces risk.
|
||||||
|
|
||||||
|
We weren’t okay with this tradeoff. Our goal wasn’t to just extend Kubernetes to run virtualization workloads, it was to do it in the most seamless and effortless way possible. We felt that the added complexity involved with an aggregated API server sacrificed the part of the user experience involved with installing and operating KubeVirt.
|
||||||
|
|
||||||
|
**Ultimately we chose to go with CRDs and trust that the Kubernetes ecosystem would grow with us to meet the needs of our use case.** Our bets were well placed. At this point there are either solutions in place or solutions under discussion that solve every feature gap we encountered back in 2017 when were evaluating CRDs vs an aggregated API server.
|
||||||
|
|
||||||
|
## Building Layered “Kubernetes like” APIs with CRDs
|
||||||
|
|
||||||
|
We designed KubeVirt’s API to follow the same patterns users are already familiar with in the Kubernetes core API.
|
||||||
|
|
||||||
|
For example, in Kubernetes the lowest level unit that users create to perform work is a Pod. Yes, Pods do have multiple containers but logically the Pod is the unit at the bottom of the stack. A Pod represents a mortal workload. The Pod gets scheduled, eventually the Pod’s workload terminates, and that’s the end of the Pod’s lifecycle.
|
||||||
|
|
||||||
|
Workload controllers such as the ReplicaSet and StatefulSet are layered on top of the Pod abstraction to help manage scale out and stateful applications. From there we have an even higher level controller called a Deployment which is layered on top of ReplicaSets help manage things like rolling updates.
|
||||||
|
|
||||||
|
In KubeVirt, this concept of layering controllers is at the very center of our design. The KubeVirt VirtualMachineInstance (VMI) object is the lowest level unit at the very bottom of the KubeVirt stack. Similar in concept to a Pod, a VMI represents a single mortal virtualized workload that executes once until completion (powered off).
|
||||||
|
|
||||||
|
Layered on top of VMIs we have a workload controller called a VirtualMachine (VM). The VM controller is where we really begin to see the differences between how users manage virtualized workloads vs containerized workloads. Within the context of existing Kubernetes functionality, the best way to describe the VM controller’s behavior is to compare it to a StatefulSet of size one. This is because the VM controller represents a single stateful (immortal) virtual machine capable of persisting state across both node failures and multiple restarts of its underlying VMI. This object behaves in the way that is familiar to users who have managed virtual machines in AWS, GCE, OpenStack or any other similar IaaS cloud platform. The user can shutdown a VM, then choose to start that exact same VM up again at a later time.
|
||||||
|
|
||||||
|
In addition to VMs, we also have a VirtualMachineInstanceReplicaSet (VMIRS) workload controller which manages scale out of identical VMI objects. This controller behaves nearly identically to the Kubernetes ReplicSet controller. The primary difference being that the VMIRS manages VMI objects and the ReplicaSet manages Pods. Wouldn’t it be nice if we could come up with a way to [use the Kubernetes ReplicaSet controller to scale out CRDs?](https://github.com/kubernetes/kubernetes/issues/65622)
|
||||||
|
|
||||||
|
Each one of these KubeVirt objects (VMI, VM, VMIRS) are registered with Kubernetes as a CRD when the KubeVirt install manifest is posted to the cluster. By registering our APIs as CRDs with Kubernetes, all the tooling involved with managing Kubernetes clusters (like kubectl) have access to the KubeVirt APIs just as if they are native Kubernetes objects.
|
||||||
|
|
||||||
|
## Dynamic Webhooks for API Validation
|
||||||
|
|
||||||
|
One of the responsibilities of the Kubernetes API server is to intercept and validate requests prior to allowing objects to be persisted into etcd. For example, if someone tries to create a Pod using a malformed Pod specification, the Kubernetes API server immediately catches the error and rejects the POST request. This all occurs before the object is persistent into etcd preventing the malformed Pod specification from making its way into the cluster.
|
||||||
|
|
||||||
|
This validation occurs during a process called admission control. Until recently, it was not possible to extend the default Kubernetes admission controllers without altering code and compiling/deploying an entirely new Kubernetes API server. This meant that if we wanted to perform admission control on KubeVirt’s CRD objects while they are posted to the cluster, we’d have to build our own version of the Kubernetes API server and convince our users to use that instead. That was not a viable solution for us.
|
||||||
|
|
||||||
|
Using the new [Dynamic Admission Control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) feature that first landed in Kubernetes 1.9, we now have a path for performing custom validation on KubeVirt API through the use of a [ValidatingAdmissionWebhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#external-admission-webhooks). This feature allows KubeVirt to dynamically register an HTTPS webhook with Kubernetes at KubeVirt install time. After registering the custom webhook, all requests related to KubeVirt API objects are forwarded from the Kubernetes API server to our HTTPS endpoint for validation. If our endpoint rejects a request for any reason, the object will not be persisted into etcd and the client receives our response outlining the reason for the rejection.
|
||||||
|
|
||||||
|
For example, if someone posts a malformed VirtualMachine object, they’ll receive an error indicating what the problem is.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl create -f my-vm.yaml
|
||||||
|
Error from server: error when creating "my-vm.yaml": admission webhook "virtualmachine-validator.kubevirt.io" denied the request: spec.template.spec.domain.devices.disks[0].volumeName 'registryvolume' not found.
|
||||||
|
```
|
||||||
|
|
||||||
|
In the example output above, that error response is coming directly from KubeVirt’s admission control webhook.
|
||||||
|
|
||||||
|
## CRD OpenAPIv3 Validation
|
||||||
|
|
||||||
|
In addition to the validating webhook, KubeVirt also uses the ability to provide an [OpenAPIv3 validation schema](https://kubernetes.io/docs/tasks/access-kubernetes-API/extend-api-custom-resource-definitions/#advanced-topics) when registering a CRD with the cluster. While the OpenAPIv3 schema does not let us express some of the more advanced validation checks that the validation webhook provides, it does offer the ability to enforce simple validation checks involving things like required fields, max/min value lengths, and verifying that values are formatted in a way that matches a regular expression string.
|
||||||
|
|
||||||
|
## Dynamic Webhooks for “PodPreset Like” Behavior
|
||||||
|
|
||||||
|
The Kubernetes Dynamic Admission Control feature is not only limited to validation logic, it also provides the ability for applications like KubeVirt to both intercept and mutate requests as they enter the cluster. This is achieved through the use of a **MutatingAdmissionWebhook** object. In KubeVirt, we are looking to use a mutating webhook to support our VirtualMachinePreset (VMPreset) feature.
|
||||||
|
|
||||||
|
A VMPreset acts in a similar way to a PodPreset. Just like a PodPreset allows users to define values that should automatically be injected into pods at creation time, a VMPreset allows users to define values that should be injected into VMs at creation time. Through the use of a mutating webhook, KubeVirt can intercept a request to create a VM, apply VMPresets to the VM spec, and then validate that the resulting VM object. This all occurs before the VM object is persisted into etcd which allows KubeVirt to immediately notify the user of any conflicts at the time the request is made.
|
||||||
|
|
||||||
|
## Subresources for CRDs
|
||||||
|
|
||||||
|
When comparing the use of CRDs to an aggregated API server, one of the features CRDs lack is the ability to support subresources. Subresources are used to provide additional resource functionality. For example, the `pod/logs` and `pod/exec` subresource endpoints are used behind the scenes to provide the `kubectl logs` and `kubectl exec` command functionality.
|
||||||
|
|
||||||
|
Just like Kubernetes uses the `pod/exec` subresource to provide access to a pod’s environment, in KubeVirt we want subresources to provide serial-console, VNC, and SPICE access to a virtual machine. By adding virtual machine guest access through subresources, we can leverage RBAC to provide access control for these features.
|
||||||
|
|
||||||
|
So, given that the KubeVirt team decided to use CRD’s instead of an aggregated API server for custom resource support, how can we have subresources for CRDs when the CRD feature expiclity does not support subresources?
|
||||||
|
|
||||||
|
We created a workaround for this limitation by implementing a stateless aggregated API server that exists only to serve subresource requests. With no state, we don’t have to worry about any of the issues we identified earlier with regards to access to etcd. This means the KubeVirt API is actually supported through a combination of both CRDs for resources and an aggregated API server for stateless subresources.
|
||||||
|
|
||||||
|
This isn’t a perfect solution for us. Both aggregated API servers and CRDs require us to register an API GroupName with Kubernetes. This API GroupName field essentially namespaces the API’s REST path in a way that prevents API naming conflicts between other third party applications. Because CRDs and aggregated API servers can’t share the same GroupName, we have to register two separate GroupNames. One is used by our CRDs and the other is used by the aggregated API server for subresource requests.
|
||||||
|
|
||||||
|
Having two GroupNames in our API is slightly inconvenient because it means the REST path for the endpoints that serve the KubeVirt subresource requests have a slightly different base path than the resources.
|
||||||
|
|
||||||
|
For example, the endpoint to create a VMI object is as follows.
|
||||||
|
|
||||||
|
**/apis/kubevirt.io/v1alpha2/namespaces/my-namespace/virtualmachineinstances/my-vm**
|
||||||
|
|
||||||
|
However, the subresource endpoint to access graphical VNC looks like this.
|
||||||
|
|
||||||
|
**/apis/subresources.kubevirt.io/v1alpha2/namespaces/my-namespace/virtualmachineinstances/my-vm/vnc**
|
||||||
|
|
||||||
|
Notice that the first request uses **kubevirt.io** and the second request uses **subresource.kubevirt.io**. We don’t like that, but that’s how we’ve managed to combine CRDs with a stateless aggregated API server for subresources.
|
||||||
|
|
||||||
|
One thing worth noting is that in Kubernetes 1.10 a very basic form of CRD subresource support was added in the form of the `/status` and `/scale` subresources. This support does not help us deliver the virtualization features we want subresources for. However, there have been discussions about exposing custom CRD subresources as webhooks in a future Kubernetes version. If this functionality lands, we will gladly transition away from our stateless aggregated API server workaround to use a subresource webhook feature.
|
||||||
|
|
||||||
|
## CRD Finalizers
|
||||||
|
|
||||||
|
A [CRD finalizer](https://kubernetes.io/docs/tasks/access-kubernetes-API/extend-api-custom-resource-definitions/#advanced-topics) is a feature that lets us provide a pre-delete hook in order to perform actions before allowing a CRD object to be removed from persistent storage. In KubeVirt, we use finalizers to guarantee a virtual machine has completely terminated before we allow the corresponding VMI object to be removed from etcd.
|
||||||
|
|
||||||
|
## API Versioning for CRDs
|
||||||
|
|
||||||
|
The Kubernetes core APIs have the ability to support multiple versions for a single object type and perform conversions between those versions. This gives the Kubernetes core APIs a path for advancing the `v1alpha1` version of an object to a `v1beta1` version and so forth.
|
||||||
|
|
||||||
|
Prior to Kubernetes 1.11, CRDs did not not have support for multiple versions. This meant when we wanted to progress a CRD from `kubevirt.io/v1alpha1` to `kubevirt.io/v1beta1`, the only path available to was to backup our CRD objects, delete the registered CRD from Kubernetes, register a new CRD with the updated version, convert the backed up CRD objects to the new version, and finally post the migrated CRD objects back to the cluster.
|
||||||
|
|
||||||
|
That strategy was not exactly a viable option for us.
|
||||||
|
|
||||||
|
Fortunately thanks to some recent [work to rectify this issue in Kubernetes](https://github.com/kubernetes/features/issues/544), the latest Kubernetes v1.11 now supports [CRDs with multiple versions](https://github.com/kubernetes/kubernetes/pull/63830). Note however that this initial multi version support is limited. While a CRD can now have multiple versions, the feature does not currently contain a path for performing conversions between versions. In KubeVirt, the lack of conversion makes it difficult us to evolve our API as we progress versions. Luckily, support for conversions between versions is underway and we look forward to taking advantage of that feature once it lands in a future Kubernetes release.
|
||||||
|
|
||||||
@@ -12,6 +12,19 @@ cid: caseStudies
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="case-studies">
|
<div class="case-studies">
|
||||||
|
|
||||||
|
<div class="case-study">
|
||||||
|
<img src="/images/case_studies/pinterest_feature.png" alt="Pinterest">
|
||||||
|
<p class="quote"> "We are in the position to run things at scale, in a public cloud environment, and test things out in way that a lot of people might not be able to do."</p>
|
||||||
|
<!--<p class="attrib">— MICHEAL BENEDICT, PRODUCT MANAGER FOR THE CLOUD AND THE DATA INFRASTRUCTURE GROUP AT PINTEREST</p>-->
|
||||||
|
<a href="/case-studies/pinterest/">Read about Pinterest</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="case-study">
|
||||||
|
<img src="/images/case_studies/pearson_feature.png" alt="Pearson">
|
||||||
|
<p class="quote">"We’re already seeing tremendous benefits with Kubernetes—improved engineering productivity, faster delivery of applications and a simplified infrastructure. But this is just the beginning. Kubernetes will help transform the way that educational content is delivered online."</p>
|
||||||
|
<!--<p class="attrib">— CHRIS JACKSON, DIRECTOR FOR CLOUD PLATFORMS & SRE AT PEARSON</p>-->
|
||||||
|
<a href="/case-studies/pearson/">Read about Pearson</a>
|
||||||
|
</div>
|
||||||
<div class="case-study">
|
<div class="case-study">
|
||||||
<img src="/images/case_studies/ing_feature.png" alt="ING">
|
<img src="/images/case_studies/ing_feature.png" alt="ING">
|
||||||
<p class="quote">"The big cloud native promise to our business is the ability to go from idea to production within 48 hours. We are some years away from this, but that’s quite feasible to us."</p>
|
<p class="quote">"The big cloud native promise to our business is the ability to go from idea to production within 48 hours. We are some years away from this, but that’s quite feasible to us."</p>
|
||||||
@@ -26,20 +39,6 @@ cid: caseStudies
|
|||||||
<a href="/case-studies/capital-one/">Read about Capital One</a>
|
<a href="/case-studies/capital-one/">Read about Capital One</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="case-study">
|
|
||||||
<img src="/images/case_studies/northwestern_feature.png" alt="Northwestern Mutual">
|
|
||||||
<p class="quote">"No one would think a company that’s 160-plus years old is foraying this deep into the cloud and infrastructure stack."</p>
|
|
||||||
<!--<p class="attrib">— APP PLATFORM TEAMS MANAGER, BRYAN PFREMMER</p>-->
|
|
||||||
<a href="/case-studies/northwestern-mutual/">Read about Northwestern Mutual</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="case-study">
|
|
||||||
<img src="/images/case_studies/openai_feature.png" alt="openAI">
|
|
||||||
<p class="quote">"Research teams can now take advantage of the frameworks we’ve built on top of Kubernetes, which make it easy to launch experiments, scale them by 10x or 50x, and take little effort to manage."</p>
|
|
||||||
<!--<p class="attrib">— Christopher Berner, Head of Infrastructure for OpenAI</p>-->
|
|
||||||
<a href="/case-studies/openai/">Read about OpenAI</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@@ -115,6 +114,8 @@ cid: caseStudies
|
|||||||
|
|
||||||
<a target="_blank" href="https://cloud.google.com/customers/philips/"><img src="/images/case_studies/philips_logo.png" alt="Philips"></a>
|
<a target="_blank" href="https://cloud.google.com/customers/philips/"><img src="/images/case_studies/philips_logo.png" alt="Philips"></a>
|
||||||
|
|
||||||
|
<a target="_blank" href="/case-studies/pinterest/"><img src="/images/case_studies/pinterest.png" alt="Pinterest"></a>
|
||||||
|
|
||||||
<a target="_blank" href="https://cloudplatform.googleblog.com/2016/09/bringing-Pokemon-GO-to-life-on-Google-Cloud.html"><img src="/images/case_studies/pokemon_go_logo.png" alt="Pokemon GO"></a>
|
<a target="_blank" href="https://cloudplatform.googleblog.com/2016/09/bringing-Pokemon-GO-to-life-on-Google-Cloud.html"><img src="/images/case_studies/pokemon_go_logo.png" alt="Pokemon GO"></a>
|
||||||
|
|
||||||
<a target="_blank" href="https://youtu.be/4gyeixJLabo"><img src="/images/case_studies/sap.png" alt="SAP"></a>
|
<a target="_blank" href="https://youtu.be/4gyeixJLabo"><img src="/images/case_studies/sap.png" alt="SAP"></a>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ css: /css/style_ancestry.css
|
|||||||
---
|
---
|
||||||
|
|
||||||
<div class="banner1">
|
<div class="banner1">
|
||||||
<h1> CASE STUDY:<img src="http://c.mfcreative.com/i/logo/ancestry-on-dark.svg" width="22%" style="margin-bottom:-12px;margin-left:3px;"><br> <div class="subhead">Digging Into the Past With New Technology</div></h1>
|
<h1> CASE STUDY:<img src="https://c.mfcreative.com/i/logo/ancestry-on-dark.svg" width="22%" style="margin-bottom:-12px;margin-left:3px;"><br> <div class="subhead">Digging Into the Past With New Technology</div></h1>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
title: Pinterest Case Study
|
||||||
|
case_study_styles: true
|
||||||
|
cid: caseStudies
|
||||||
|
css: /css/style_case_studies.css
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
<div class="banner1 desktop" style="background-image: url('/images/CaseStudy_pinterest_banner1.jpg')">
|
||||||
|
<h1> CASE STUDY:<img src="/images/pinterest_logo.png" style="margin-bottom:-1%" class="header_logo"><br> <div class="subhead">Pinning Its Past, Present, and Future on Cloud Native
|
||||||
|
|
||||||
|
</div></h1>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="details">
|
||||||
|
Company <b>Pinterest</b> Location <b>San Francisco, California</b> Industry <b>Web and Mobile App</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<section class="section1">
|
||||||
|
<div class="cols">
|
||||||
|
<div class="col1">
|
||||||
|
<h2>Challenge</h2>
|
||||||
|
After eight years in existence, Pinterest had grown into 1,000 microservices and multiple layers of infrastructure and diverse set-up tools and platforms. In 2016 the company launched a roadmap towards a new compute platform, led by the vision of creating the fastest path from an idea to production, without making engineers worry about the underlying infrastructure.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<h2>Solution</h2>
|
||||||
|
The first phase involved moving services to Docker containers. Once these services went into production in early 2017, the team began looking at orchestration to help create efficiencies and manage them in a decentralized way. After an evaluation of various solutions, Pinterest went with Kubernetes.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col2">
|
||||||
|
|
||||||
|
<h2>Impact</h2>
|
||||||
|
"By moving to Kubernetes the team was able to build on-demand scaling and new failover policies, in addition to simplifying the overall deployment and management of a complicated piece of infrastructure such as Jenkins," says Micheal Benedict, Product Manager for the Cloud and the Data Infrastructure Group at Pinterest. "We not only saw reduced build times but also huge efficiency wins. For instance, the team reclaimed over 80 percent of capacity during non-peak hours. As a result, the Jenkins Kubernetes cluster now uses 30 percent less instance-hours per-day when compared to the previous static cluster."
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="banner2">
|
||||||
|
<div class="banner2text">
|
||||||
|
"So far it’s been good, especially the elasticity around how we can configure our Jenkins workloads on that Kubernetes shared cluster. That is the win we were pushing for." <span style="font-size:14px;letter-spacing:0.12em;padding-top:20px;text-transform:uppercase;line-height:14px"><br><br>— Micheal Benedict, Product Manager for the Cloud and the Data Infrastructure Group at Pinterest</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section class="section2">
|
||||||
|
<div class="fullcol">
|
||||||
|
<h2></h2>Pinterest was born on the cloud—running on <a href="https://aws.amazon.com/">AWS</a> since day one in 2010—but even cloud native companies can experience some growing pains.</h2> Since its launch, Pinterest has become a household name, with more than 200 million active monthly users and 100 billion objects saved. Underneath the hood, there are 1,000 microservices running and hundreds of thousands of data jobs.<br><br>
|
||||||
|
With such growth came layers of infrastructure and diverse set-up tools and platforms for the different workloads, resulting in an inconsistent and complex end-to-end developer experience, and ultimately less velocity to get to production.
|
||||||
|
So in 2016, the company launched a roadmap toward a new compute platform, led by the vision of having the fastest path from an idea to production, without making engineers worry about the underlying infrastructure. <br><br>
|
||||||
|
The first phase involved moving to Docker. "Pinterest has been heavily running on virtual machines, on EC2 instances directly, for the longest time," says Micheal Benedict, Product Manager for the Cloud and the Data Infrastructure Group. "To solve the problem around packaging software and not make engineers own portions of the fleet and those kinds of challenges, we standardized the packaging mechanism and then moved that to the container on top of the VM. Not many drastic changes. We didn’t want to boil the ocean at that point."
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="banner3" style="background-image: url('/images/CaseStudy_pinterest_banner3.jpg')">
|
||||||
|
<div class="banner3text">
|
||||||
|
"Though Kubernetes lacked certain things we wanted, we realized that by the time we get to productionizing many of those things, we’ll be able to leverage what the community is doing." <span style="font-size:14px;letter-spacing:0.12em;padding-top:20px;text-transform:uppercase;line-height:14px"><br><br>— MICHEAL BENEDICT, PRODUCT MANAGER FOR THE CLOUD AND THE DATA INFRASTRUCTURE GROUP AT PINTEREST</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section class="section3">
|
||||||
|
<div class="fullcol">
|
||||||
|
|
||||||
|
The first service that was migrated was the monolith API fleet that powers most of Pinterest. At the same time, Benedict’s infrastructure governance team built chargeback and capacity planning systems to analyze how the company uses its virtual machines on AWS. "It became clear that running on VMs is just not sustainable with what we’re doing," says Benedict. "A lot of resources were underutilized. There were efficiency efforts, which worked fine at a certain scale, but now you have to move to a more decentralized way of managing that. So orchestration was something we thought could help solve that piece."<br><br>
|
||||||
|
That led to the second phase of the roadmap. In July 2017, after an eight-week evaluation period, the team chose Kubernetes over other orchestration platforms. "Kubernetes lacked certain things at the time—for example, we wanted Spark on Kubernetes," says Benedict. "But we realized that the dev cycles we would put in to even try building that is well worth the outcome, both for Pinterest as well as the community. We’ve been in those conversations in the Big Data SIG. We realized that by the time we get to productionizing many of those things, we’ll be able to leverage what the community is doing."<br><br>
|
||||||
|
At the beginning of 2018, the team began onboarding its first use case into the Kubernetes system: Jenkins workloads. "Although we have builds happening during a certain period of the day, we always need to allocate peak capacity," says Benedict. "They don’t have any auto-scaling capabilities, so that capacity stays constant. It is difficult to speed up builds because ramping up takes more time. So given those kind of concerns, we thought that would be a perfect use case for us to work on."
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="banner4" style="background-image: url('/images/CaseStudy_pinterest_banner4.jpg')">
|
||||||
|
<div class="banner4text">
|
||||||
|
"So far it’s been good, especially the elasticity around how we can configure our Jenkins workloads on Kubernetes shared cluster. That is the win we were pushing for." <span style="font-size:14px;letter-spacing:0.12em;padding-top:20px;text-transform:uppercase;line-height:14px"><br><br>— MICHEAL BENEDICT, PRODUCT MANAGER FOR THE CLOUD AND THE DATA INFRASTRUCTURE GROUP AT PINTEREST</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="section5" style="padding:0px !important">
|
||||||
|
<div class="fullcol">
|
||||||
|
They ramped up the cluster, and working with a team of four people, got the Jenkins Kubernetes cluster ready for production. "We still have our static Jenkins cluster," says Benedict, "but on Kubernetes, we are doing similar builds, testing the entire pipeline, getting the artifact ready and just doing the comparison to see, how much time did it take to build over here. Is the SLA okay, is the artifact generated correct, are there issues there?" <br><br>
|
||||||
|
"So far it’s been good," he adds, "especially the elasticity around how we can configure our Jenkins workloads on Kubernetes shared cluster. That is the win we were pushing for."<br><br>
|
||||||
|
By the end of Q1 2018, the team successfully migrated Jenkins Master to run natively on Kubernetes and also collaborated on the <a href="https://github.com/jenkinsci/kubernetes-plugin">Jenkins Kubernetes Plugin</a> to manage the lifecycle of workers. "We’re currently building the entire Pinterest JVM stack (one of the larger monorepos at Pinterest which was recently bazelized) on this new cluster," says Benedict. "At peak, we run thousands of pods on a few hundred nodes. Overall, by moving to Kubernetes the team was able to build on-demand scaling and new failover policies, in addition to simplifying the overall deployment and management of a complicated piece of infrastructure such as Jenkins. We not only saw reduced build times but also huge efficiency wins. For instance, the team reclaimed over 80 percent of capacity during non-peak hours. As a result, the Jenkins Kubernetes cluster now uses 30 percent less instance-hours per-day when compared to the previous static cluster."
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="banner5">
|
||||||
|
<div class="banner5text">
|
||||||
|
"We are in the position to run things at scale, in a public cloud environment, and test things out in way that a lot of people might not be able to do." <span style="font-size:14px;letter-spacing:0.12em;padding-top:20px;text-transform:uppercase;line-height:14px"><br><br>— MICHEAL BENEDICT, PRODUCT MANAGER FOR THE CLOUD AND THE DATA INFRASTRUCTURE GROUP AT PINTEREST</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fullcol">
|
||||||
|
Benedict points to a "pretty robust roadmap" going forward. In addition to the Pinterest big data team’s experiments with Spark on Kubernetes, the company collaborated with Amazon’s EKS team on an ENI/CNI plug in. <br><br>
|
||||||
|
Once the Jenkins cluster is up and running out of dark mode, Benedict hopes to establish best practices, including having governance primitives established—including integration with the chargeback system—before moving on to migrating the next service. "We have a healthy pipeline of use-cases to be on-boarded. After Jenkins, we want to enable support for Tensorflow and Apache Spark. At some point, we aim to move the company’s monolithic API service. If we move that and understand the complexity around that, it builds our confidence," says Benedict. "It sets us up for migration of all our other services."<br><br>
|
||||||
|
After years of being a cloud native pioneer, Pinterest is eager to share its ongoing journey. "We are in the position to run things at scale, in a public cloud environment, and test things out in way that a lot of people might not be able to do," says Benedict. "We’re in a great position to contribute back some of those learnings."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
@@ -12,36 +12,37 @@ weight: 70
|
|||||||
{{< feature-state for_k8s_version="1.8" state="alpha" >}}
|
{{< feature-state for_k8s_version="1.8" state="alpha" >}}
|
||||||
{{< feature-state for_k8s_version="1.11" state="beta" >}}
|
{{< feature-state for_k8s_version="1.11" state="beta" >}}
|
||||||
|
|
||||||
[Pods](/docs/user-guide/pods) can have _priority_. Priority
|
[Pods](/docs/user-guide/pods) can have _priority_. Priority indicates the
|
||||||
indicates the importance of a Pod relative to other Pods. If a Pod cannot be scheduled,
|
importance of a Pod relative to other Pods. If a Pod cannot be scheduled, the
|
||||||
the scheduler tries to preempt (evict) lower priority Pods to make scheduling of the
|
scheduler tries to preempt (evict) lower priority Pods to make scheduling of the
|
||||||
pending Pod possible.
|
pending Pod possible.
|
||||||
|
|
||||||
In Kubernetes 1.9 and later, Priority also affects scheduling
|
In Kubernetes 1.9 and later, Priority also affects scheduling order of Pods and
|
||||||
order of Pods and out-of-resource eviction ordering on the Node.
|
out-of-resource eviction ordering on the Node.
|
||||||
|
|
||||||
Pod priority and preemption are moved to beta since Kubernetes 1.11 and are enabled by default in
|
Pod priority and preemption are moved to beta since Kubernetes 1.11 and are
|
||||||
this release and later.
|
enabled by default in this release and later.
|
||||||
|
|
||||||
In Kubernetes versions where Pod priority and preemption is still an alpha-level
|
In Kubernetes versions where Pod priority and preemption is still an alpha-level
|
||||||
feature, you need to explicitly enable it. To use these features in the older versions of
|
feature, you need to explicitly enable it. To use these features in the older
|
||||||
Kubernetes, follow the instructions in the documentation for your Kubernetes version, by
|
versions of Kubernetes, follow the instructions in the documentation for your
|
||||||
going to the documentation archive version for your Kubernetes version.
|
Kubernetes version, by going to the documentation archive version for your
|
||||||
|
Kubernetes version.
|
||||||
|
|
||||||
| Kubernetes Version | Priority and Preemption State | Enabled by default |
|
Kubernetes Version | Priority and Preemption State | Enabled by default
|
||||||
| -------- |:-----:|:----:|
|
------------------ | :---------------------------: | :----------------:
|
||||||
| 1.8 | alpha | no |
|
1.8 | alpha | no
|
||||||
| 1.9 | alpha | no |
|
1.9 | alpha | no
|
||||||
| 1.10 | alpha | no |
|
1.10 | alpha | no
|
||||||
| 1.11 | beta | yes |
|
1.11 | beta | yes
|
||||||
|
|
||||||
{{< warning >}}
|
{{< warning >}} **Warning**: In a cluster where not all users are trusted, a
|
||||||
**Warning**: In a cluster where not all users are trusted, a malicious
|
malicious user could create pods at the highest possible priorities, causing
|
||||||
user could create pods at the highest possible priorities, causing
|
|
||||||
other pods to be evicted/not get scheduled. To resolve this issue,
|
other pods to be evicted/not get scheduled. To resolve this issue,
|
||||||
[ResourceQuota](https://kubernetes.io/docs/concepts/policy/resource-quotas/) is augmented to support
|
[ResourceQuota](https://kubernetes.io/docs/concepts/policy/resource-quotas/) is
|
||||||
Pod priority. An admin can create ResourceQuota for users at specific priority levels, preventing
|
augmented to support Pod priority. An admin can create ResourceQuota for users
|
||||||
them from creating pods at high priorities. However, this feature is in alpha as of Kubernetes 1.11.
|
at specific priority levels, preventing them from creating pods at high
|
||||||
|
priorities. However, this feature is in alpha as of Kubernetes 1.11.
|
||||||
{{< /warning >}}
|
{{< /warning >}}
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
@@ -49,37 +50,52 @@ them from creating pods at high priorities. However, this feature is in alpha as
|
|||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
|
|
||||||
## How to use priority and preemption
|
## How to use priority and preemption
|
||||||
|
|
||||||
To use priority and preemption in Kubernetes 1.11 and later, follow these steps:
|
To use priority and preemption in Kubernetes 1.11 and later, follow these steps:
|
||||||
|
|
||||||
1. Add one or more [PriorityClasses](#priorityclass).
|
1. Add one or more [PriorityClasses](#priorityclass).
|
||||||
|
|
||||||
1. Create Pods with[`priorityClassName`](#pod-priority) set to one of the added PriorityClasses.
|
1. Create Pods with[`priorityClassName`](#pod-priority) set to one of the added
|
||||||
Of course you do not need to create the Pods directly; normally you would add
|
PriorityClasses. Of course you do not need to create the Pods directly;
|
||||||
`priorityClassName` to the Pod template of a collection object like a Deployment.
|
normally you would add `priorityClassName` to the Pod template of a
|
||||||
|
collection object like a Deployment.
|
||||||
|
|
||||||
Keep reading for more information about these steps.
|
Keep reading for more information about these steps.
|
||||||
|
|
||||||
If you try the feature and then decide to disable it, you must remove the PodPriority
|
If you try the feature and then decide to disable it, you must remove the
|
||||||
command-line flag or set it to `false`, and then restart the API server and
|
PodPriority command-line flag or set it to `false`, and then restart the API
|
||||||
scheduler. After the feature is disabled, the existing Pods keep their priority
|
server and scheduler. After the feature is disabled, the existing Pods keep
|
||||||
fields, but preemption is disabled, and priority fields are ignored. If the feature
|
their priority fields, but preemption is disabled, and priority fields are
|
||||||
is disabled, you cannot set `priorityClassName` in new Pods.
|
ignored. If the feature is disabled, you cannot set `priorityClassName` in new
|
||||||
|
Pods.
|
||||||
|
|
||||||
## How to disable preemption
|
## How to disable preemption
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}} **Note**: In Kubernetes 1.11, critical pods (except DaemonSet pods,
|
||||||
**Note**: In Kubernetes 1.11, critical pods (except DaemonSet pods, which are
|
which are still scheduled by the DaemonSet controller) rely on scheduler
|
||||||
still scheduled by the DaemonSet controller) rely on scheduler preemption to be
|
preemption to be scheduled when a cluster is under resource pressure. For this
|
||||||
scheduled when a cluster is under resource pressure. For this reason, we do not
|
reason, you will need to run an older version of Rescheduler if you decide to
|
||||||
recommend disabling this feature. If you still have to disable this feature,
|
disable preemption. More on this is provided below. {{< /note >}}
|
||||||
follow the instructions below.
|
|
||||||
{{< /note >}}
|
#### Option 1: Disable both Pod priority and preemption
|
||||||
|
|
||||||
|
Disabling Pod priority disables preemption as well. In order to disable Pod
|
||||||
|
Priority, set the feature to false for API server, Scheduler, and Kubelet.
|
||||||
|
Disabling the feature on Kubelets is not vital. You can leave the feature on for
|
||||||
|
Kubelets if rolling out is hard.
|
||||||
|
|
||||||
|
```
|
||||||
|
--feature-gates=PodPriority=false
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Option 2: Disable Preemption only
|
||||||
|
|
||||||
In Kubernetes 1.11 and later, preemption is controlled by a kube-scheduler flag
|
In Kubernetes 1.11 and later, preemption is controlled by a kube-scheduler flag
|
||||||
`disablePreemption`, which is set to `false` by default.
|
`disablePreemption`, which is set to `false` by default.
|
||||||
|
|
||||||
To disable preemption, set `disablePreemption` to true. This keeps pod priority
|
This option is available in component configs only and is not available in
|
||||||
enabled but disables preemption. Here is a sample configuration:
|
old-style command line options. Below is a sample component config to disable
|
||||||
|
preemption:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: componentconfig/v1alpha1
|
apiVersion: componentconfig/v1alpha1
|
||||||
@@ -90,44 +106,57 @@ algorithmSource:
|
|||||||
...
|
...
|
||||||
|
|
||||||
disablePreemption: true
|
disablePreemption: true
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Although preemption of the scheduler is enabled by default, it is disabled if `PodPriority`
|
### Start an older version of Rescheduler in the cluster
|
||||||
feature is disabled.
|
|
||||||
|
When priority or preemption is disabled, we must run Rescheduler v0.3.1 (instead
|
||||||
|
of v0.4.0) to ensure that critical Pods are scheduled when nodes or cluster are
|
||||||
|
under resource pressure. Since critical Pod annotation is still supported in
|
||||||
|
this release, running Rescheduler should be enough and no other changes to the
|
||||||
|
configuration of Pods should be needed.
|
||||||
|
|
||||||
|
Rescheduler images can be found at:
|
||||||
|
[gcr.io/k8s-image-staging/rescheduler](http://gcr.io/k8s-image-staging/rescheduler).
|
||||||
|
|
||||||
|
In the code, changing the Rescheduler version back to v.0.3.1 is the reverse of
|
||||||
|
[this PR](https://github.com/kubernetes/kubernetes/pull/65454).
|
||||||
|
|
||||||
## PriorityClass
|
## PriorityClass
|
||||||
|
|
||||||
A PriorityClass is a non-namespaced object that defines a mapping from a priority
|
A PriorityClass is a non-namespaced object that defines a mapping from a
|
||||||
class name to the integer value of the priority. The name is specified in the `name`
|
priority class name to the integer value of the priority. The name is specified
|
||||||
field of the PriorityClass object's metadata. The value is specified in the required
|
in the `name` field of the PriorityClass object's metadata. The value is
|
||||||
`value` field. The higher the value, the higher the priority.
|
specified in the required `value` field. The higher the value, the higher the
|
||||||
|
priority.
|
||||||
|
|
||||||
A PriorityClass object can have any 32-bit integer value smaller than or equal to
|
A PriorityClass object can have any 32-bit integer value smaller than or equal
|
||||||
1 billion. Larger numbers are reserved for critical system Pods that should not
|
to 1 billion. Larger numbers are reserved for critical system Pods that should
|
||||||
normally be preempted or evicted. A cluster admin should create one PriorityClass
|
not normally be preempted or evicted. A cluster admin should create one
|
||||||
object for each such mapping that they want.
|
PriorityClass object for each such mapping that they want.
|
||||||
|
|
||||||
PriorityClass also has two optional fields: `globalDefault` and `description`.
|
PriorityClass also has two optional fields: `globalDefault` and `description`.
|
||||||
The `globalDefault` field indicates that the value of this PriorityClass should
|
The `globalDefault` field indicates that the value of this PriorityClass should
|
||||||
be used for Pods without a `priorityClassName`. Only one PriorityClass with
|
be used for Pods without a `priorityClassName`. Only one PriorityClass with
|
||||||
`globalDefault` set to true can exist in the system. If there is no PriorityClass
|
`globalDefault` set to true can exist in the system. If there is no
|
||||||
with `globalDefault` set, the priority of Pods with no `priorityClassName` is zero.
|
PriorityClass with `globalDefault` set, the priority of Pods with no
|
||||||
|
`priorityClassName` is zero.
|
||||||
|
|
||||||
The `description` field is an arbitrary string. It is meant to tell users of
|
The `description` field is an arbitrary string. It is meant to tell users of the
|
||||||
the cluster when they should use this PriorityClass.
|
cluster when they should use this PriorityClass.
|
||||||
|
|
||||||
### Notes about PodPriority and existing clusters
|
### Notes about PodPriority and existing clusters
|
||||||
- If you upgrade your existing cluster and enable this feature, the priority
|
|
||||||
of your existing Pods is effectively zero.
|
|
||||||
|
|
||||||
- Addition of a PriorityClass with `globalDefault` set to `true` does not
|
- If you upgrade your existing cluster and enable this feature, the priority
|
||||||
change the priorities of existing Pods. The value of such a PriorityClass is used only
|
of your existing Pods is effectively zero.
|
||||||
for Pods created after the PriorityClass is added.
|
|
||||||
|
|
||||||
- If you delete a PriorityClass, existing Pods that use the name of the
|
- Addition of a PriorityClass with `globalDefault` set to `true` does not
|
||||||
deleted PriorityClass remain unchanged, but you cannot create more Pods
|
change the priorities of existing Pods. The value of such a PriorityClass is
|
||||||
that use the name of the deleted PriorityClass.
|
used only for Pods created after the PriorityClass is added.
|
||||||
|
|
||||||
|
- If you delete a PriorityClass, existing Pods that use the name of the
|
||||||
|
deleted PriorityClass remain unchanged, but you cannot create more Pods that
|
||||||
|
use the name of the deleted PriorityClass.
|
||||||
|
|
||||||
### Example PriorityClass
|
### Example PriorityClass
|
||||||
|
|
||||||
@@ -145,13 +174,13 @@ description: "This priority class should be used for XYZ service pods only."
|
|||||||
|
|
||||||
After you have one or more PriorityClasses, you can create Pods that specify one
|
After you have one or more PriorityClasses, you can create Pods that specify one
|
||||||
of those PriorityClass names in their specifications. The priority admission
|
of those PriorityClass names in their specifications. The priority admission
|
||||||
controller uses the `priorityClassName` field and populates the integer value
|
controller uses the `priorityClassName` field and populates the integer value of
|
||||||
of the priority. If the priority class is not found, the Pod is rejected.
|
the priority. If the priority class is not found, the Pod is rejected.
|
||||||
|
|
||||||
The following YAML is an example of a Pod configuration that uses the PriorityClass
|
|
||||||
created in the preceding example. The priority admission controller checks the
|
|
||||||
specification and resolves the priority of the Pod to 1000000.
|
|
||||||
|
|
||||||
|
The following YAML is an example of a Pod configuration that uses the
|
||||||
|
PriorityClass created in the preceding example. The priority admission
|
||||||
|
controller checks the specification and resolves the priority of the Pod to
|
||||||
|
1000000.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
@@ -170,36 +199,40 @@ spec:
|
|||||||
|
|
||||||
### Effect of Pod priority on scheduling order
|
### Effect of Pod priority on scheduling order
|
||||||
|
|
||||||
In Kubernetes 1.9 and later, when Pod priority is enabled, scheduler orders pending
|
In Kubernetes 1.9 and later, when Pod priority is enabled, scheduler orders
|
||||||
Pods by their priority and a pending Pod is placed ahead of other pending Pods with
|
pending Pods by their priority and a pending Pod is placed ahead of other
|
||||||
lower priority in the scheduling queue. As a result, the higher priority Pod may
|
pending Pods with lower priority in the scheduling queue. As a result, the
|
||||||
by scheduled sooner that Pods with lower priority if its scheduling requirements
|
higher priority Pod may by scheduled sooner that Pods with lower priority if its
|
||||||
are met. If such Pod cannot be scheduled, scheduler will continue and tries to
|
scheduling requirements are met. If such Pod cannot be scheduled, scheduler will
|
||||||
schedule other lower priority Pods.
|
continue and tries to schedule other lower priority Pods.
|
||||||
|
|
||||||
## Preemption
|
## Preemption
|
||||||
|
|
||||||
When Pods are created, they go to a queue and wait to be scheduled. The scheduler
|
When Pods are created, they go to a queue and wait to be scheduled. The
|
||||||
picks a Pod from the queue and tries to schedule it on a Node. If no Node is found
|
scheduler picks a Pod from the queue and tries to schedule it on a Node. If no
|
||||||
that satisfies all the specified requirements of the Pod, preemption logic is triggered
|
Node is found that satisfies all the specified requirements of the Pod,
|
||||||
for the pending Pod. Let's call the pending Pod P. Preemption logic tries to find a Node
|
preemption logic is triggered for the pending Pod. Let's call the pending Pod P.
|
||||||
where removal of one or more Pods with lower priority than P would enable P to be scheduled
|
Preemption logic tries to find a Node where removal of one or more Pods with
|
||||||
on that Node. If such a Node is found, one or more lower priority Pods get
|
lower priority than P would enable P to be scheduled on that Node. If such a
|
||||||
deleted from the Node. After the Pods are gone, P can be scheduled on the Node.
|
Node is found, one or more lower priority Pods get deleted from the Node. After
|
||||||
|
the Pods are gone, P can be scheduled on the Node.
|
||||||
|
|
||||||
### User exposed information
|
### User exposed information
|
||||||
|
|
||||||
When Pod P preempts one or more Pods on Node N, `nominatedNodeName` field of Pod P's status is set to
|
When Pod P preempts one or more Pods on Node N, `nominatedNodeName` field of Pod
|
||||||
the name of Node N. This field helps scheduler track resources reserved for Pod P and also gives
|
P's status is set to the name of Node N. This field helps scheduler track
|
||||||
users information about preemptions in their clusters.
|
resources reserved for Pod P and also gives users information about preemptions
|
||||||
|
in their clusters.
|
||||||
|
|
||||||
Please note that Pod P is not necessarily scheduled to the "nominated Node". After victim Pods are
|
Please note that Pod P is not necessarily scheduled to the "nominated Node".
|
||||||
preempted, they get their graceful termination period. If another node becomes available while
|
After victim Pods are preempted, they get their graceful termination period. If
|
||||||
scheduler is waiting for the victim Pods to terminate, scheduler will use the other node to schedule
|
another node becomes available while scheduler is waiting for the victim Pods to
|
||||||
Pod P. As a result `nominatedNodeName` and `nodeName` of Pod spec are not always the same. Also, if
|
terminate, scheduler will use the other node to schedule Pod P. As a result
|
||||||
scheduler preempts Pods on Node N, but then a higher priority Pod than Pod P arrives, scheduler may
|
`nominatedNodeName` and `nodeName` of Pod spec are not always the same. Also, if
|
||||||
give Node N to the new higher priority Pod. In such a case, scheduler clears `nominatedNodeName` of
|
scheduler preempts Pods on Node N, but then a higher priority Pod than Pod P
|
||||||
Pod P. By doing this, scheduler makes Pod P eligible to preempt Pods on another Node.
|
arrives, scheduler may give Node N to the new higher priority Pod. In such a
|
||||||
|
case, scheduler clears `nominatedNodeName` of Pod P. By doing this, scheduler
|
||||||
|
makes Pod P eligible to preempt Pods on another Node.
|
||||||
|
|
||||||
### Limitations of preemption
|
### Limitations of preemption
|
||||||
|
|
||||||
@@ -212,67 +245,127 @@ killed. This graceful termination period creates a time gap between the point
|
|||||||
that the scheduler preempts Pods and the time when the pending Pod (P) can be
|
that the scheduler preempts Pods and the time when the pending Pod (P) can be
|
||||||
scheduled on the Node (N). In the meantime, the scheduler keeps scheduling other
|
scheduled on the Node (N). In the meantime, the scheduler keeps scheduling other
|
||||||
pending Pods. As victims exit or get terminated, the scheduler tries to schedule
|
pending Pods. As victims exit or get terminated, the scheduler tries to schedule
|
||||||
Pods in the pending queue. Therefore, there is usually a time gap between the point
|
Pods in the pending queue. Therefore, there is usually a time gap between the
|
||||||
that scheduler preempts victims and the time that Pod P is scheduled. In order to
|
point that scheduler preempts victims and the time that Pod P is scheduled. In
|
||||||
minimize this gap, one can set graceful termination period of lower priority Pods
|
order to minimize this gap, one can set graceful termination period of lower
|
||||||
to zero or a small number.
|
priority Pods to zero or a small number.
|
||||||
|
|
||||||
#### PodDisruptionBudget is supported, but not guaranteed!
|
#### PodDisruptionBudget is supported, but not guaranteed!
|
||||||
|
|
||||||
A [Pod Disruption Budget (PDB)](/docs/concepts/workloads/pods/disruptions/)
|
A [Pod Disruption Budget (PDB)](/docs/concepts/workloads/pods/disruptions/)
|
||||||
allows application owners to limit the number Pods of a replicated application that
|
allows application owners to limit the number Pods of a replicated application
|
||||||
are down simultaneously from voluntary disruptions. Kubernetes 1.9 supports PDB
|
that are down simultaneously from voluntary disruptions. Kubernetes 1.9 supports
|
||||||
when preempting Pods, but respecting PDB is best effort. The Scheduler tries to
|
PDB when preempting Pods, but respecting PDB is best effort. The Scheduler tries
|
||||||
find victims whose PDB are not violated by preemption, but if no such victims are
|
to find victims whose PDB are not violated by preemption, but if no such victims
|
||||||
found, preemption will still happen, and lower priority Pods will be removed
|
are found, preemption will still happen, and lower priority Pods will be removed
|
||||||
despite their PDBs being violated.
|
despite their PDBs being violated.
|
||||||
|
|
||||||
#### Inter-Pod affinity on lower-priority Pods
|
#### Inter-Pod affinity on lower-priority Pods
|
||||||
|
|
||||||
A Node is considered for preemption only when
|
A Node is considered for preemption only when the answer to this question is
|
||||||
the answer to this question is yes: "If all the Pods with lower priority than
|
yes: "If all the Pods with lower priority than the pending Pod are removed from
|
||||||
the pending Pod are removed from the Node, can the pending Pod be scheduled on
|
the Node, can the pending Pod be scheduled on the Node?"
|
||||||
the Node?"
|
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}} **Note:** Preemption does not necessarily remove all lower-priority
|
||||||
**Note:** Preemption does not necessarily remove all lower-priority Pods. If the
|
Pods. If the pending Pod can be scheduled by removing fewer than all
|
||||||
pending Pod can be scheduled by removing fewer than all lower-priority Pods, then
|
lower-priority Pods, then only a portion of the lower-priority Pods are removed.
|
||||||
only a portion of the lower-priority Pods are removed. Even so, the answer to the
|
Even so, the answer to the preceding question must be yes. If the answer is no,
|
||||||
preceding question must be yes. If the answer is no, the Node is not considered
|
the Node is not considered for preemption. {{< /note >}}
|
||||||
for preemption.
|
|
||||||
{{< /note >}}
|
|
||||||
|
|
||||||
If a pending Pod has inter-pod affinity to one or more of the lower-priority Pods
|
If a pending Pod has inter-pod affinity to one or more of the lower-priority
|
||||||
on the Node, the inter-Pod affinity rule cannot be satisfied in the absence of those
|
Pods on the Node, the inter-Pod affinity rule cannot be satisfied in the absence
|
||||||
lower-priority Pods. In this case, the scheduler does not preempt any Pods on the
|
of those lower-priority Pods. In this case, the scheduler does not preempt any
|
||||||
Node. Instead, it looks for another Node. The scheduler might find a suitable Node
|
Pods on the Node. Instead, it looks for another Node. The scheduler might find a
|
||||||
or it might not. There is no guarantee that the pending Pod can be scheduled.
|
suitable Node or it might not. There is no guarantee that the pending Pod can be
|
||||||
|
scheduled.
|
||||||
|
|
||||||
Our recommended solution for this problem is to create inter-Pod affinity only towards
|
Our recommended solution for this problem is to create inter-Pod affinity only
|
||||||
equal or higher priority Pods.
|
towards equal or higher priority Pods.
|
||||||
|
|
||||||
#### Cross node preemption
|
#### Cross node preemption
|
||||||
|
|
||||||
Suppose a Node N is being considered for preemption so that a pending Pod P
|
Suppose a Node N is being considered for preemption so that a pending Pod P can
|
||||||
can be scheduled on N. P might become feasible on N only if a Pod on another
|
be scheduled on N. P might become feasible on N only if a Pod on another Node is
|
||||||
Node is preempted. Here's an example:
|
preempted. Here's an example:
|
||||||
|
|
||||||
* Pod P is being considered for Node N.
|
* Pod P is being considered for Node N.
|
||||||
* Pod Q is running on another Node in the same Zone as Node N.
|
* Pod Q is running on another Node in the same Zone as Node N.
|
||||||
* Pod P has Zone-wide anti-affinity with Pod Q
|
* Pod P has Zone-wide anti-affinity with Pod Q (`topologyKey:
|
||||||
(`topologyKey: failure-domain.beta.kubernetes.io/zone`).
|
failure-domain.beta.kubernetes.io/zone`).
|
||||||
* There are no other cases of anti-affinity between Pod P and other Pods in the Zone.
|
* There are no other cases of anti-affinity between Pod P and other Pods in
|
||||||
* In order to schedule Pod P on Node N, Pod Q can be preempted, but scheduler
|
the Zone.
|
||||||
does not perform cross-node preemption. So, Pod P will be deemed unschedulable
|
* In order to schedule Pod P on Node N, Pod Q can be preempted, but scheduler
|
||||||
on Node N.
|
does not perform cross-node preemption. So, Pod P will be deemed
|
||||||
|
unschedulable on Node N.
|
||||||
|
|
||||||
If Pod Q were removed from its Node, the Pod anti-affinity violation would be gone,
|
If Pod Q were removed from its Node, the Pod anti-affinity violation would be
|
||||||
and Pod P could possibly be scheduled on Node N.
|
gone, and Pod P could possibly be scheduled on Node N.
|
||||||
|
|
||||||
We may consider adding cross Node preemption in future versions if we find an
|
We may consider adding cross Node preemption in future versions if we find an
|
||||||
algorithm with reasonable performance. We cannot promise anything at this point,
|
algorithm with reasonable performance. We cannot promise anything at this point,
|
||||||
and cross Node preemption will not be considered a blocker for Beta or GA.
|
and cross Node preemption will not be considered a blocker for Beta or GA.
|
||||||
|
|
||||||
|
## Debugging Pod Priority and Preemption
|
||||||
|
|
||||||
|
Pod Priority and Preemption is a major feature that could potentially disrupt
|
||||||
|
Pod scheduling if it has bugs.
|
||||||
|
|
||||||
|
### Potential problems caused by Priority and Preemption
|
||||||
|
|
||||||
|
The followings are some of the potential problems that could be caused by bugs
|
||||||
|
in the implementation of the feature. This list is not exhaustive.
|
||||||
|
|
||||||
|
#### Pods are preempted unnecessarily
|
||||||
|
|
||||||
|
Preemption removes existing Pods from a cluster under resource pressure to make
|
||||||
|
room for higher priority pending Pods. If a user gives high priorities to
|
||||||
|
certain Pods by mistake, these unintentional high priority Pods may cause
|
||||||
|
preemption in the cluster. As mentioned above, Pod priority is specified by
|
||||||
|
setting the `priorityClassName` field of `podSpec`. The integer value of
|
||||||
|
priority is then resolved and populated to the `priority` field of `podSpec`.
|
||||||
|
|
||||||
|
To resolve the problem, `priorityClassName` of the Pods must be changed to use
|
||||||
|
lower priority classes or should be left empty. Empty `priorityClassName` is
|
||||||
|
resolved to zero by default.
|
||||||
|
|
||||||
|
When a Pod is preempted, there will be events recorded for the preempted Pod.
|
||||||
|
Preemption should happen only when a cluster does not have enough resources for
|
||||||
|
a Pod. In such cases, preemption happens only when the priority of the pending
|
||||||
|
Pod (preemptor) is higher than the victim Pods. Preemption must not happen when
|
||||||
|
there is no pending Pod, or when the pending Pods have equal or higher priority
|
||||||
|
than the victims. If preemption happens in such scenarios, please file an issue.
|
||||||
|
|
||||||
|
#### Pods are preempted, but the preemptor is not scheduled
|
||||||
|
|
||||||
|
When pods are preempted, they receive their requested graceful termination
|
||||||
|
period, which is by default 30 seconds, but it can be any different value as
|
||||||
|
specified in the PodSpec. If the victim Pods do not terminate within this period
|
||||||
|
they are force-terminated. Once all the victims go away, the preemptor Pod can
|
||||||
|
be scheduled.
|
||||||
|
|
||||||
|
While the preemptor Pod is waiting for the victims to go away, a higher priority
|
||||||
|
Pod may be created that fits on the same node. In this case, the scheduler will
|
||||||
|
schedule the higher priority Pod instead of the preemptor.
|
||||||
|
|
||||||
|
In the absence of such a higher priority Pod, we expect the preemptor Pod to be
|
||||||
|
scheduled after the graceful termination period of the victims is over.
|
||||||
|
|
||||||
|
#### Higher priority Pods are preempted before lower priority pods
|
||||||
|
|
||||||
|
The scheduler tries to find nodes that can run a pending Pod and if no node is
|
||||||
|
found, it tries to remove Pods with lower priority from one node to make room
|
||||||
|
for the pending pod. If a node with low priority Pods is not feasible to run the
|
||||||
|
pending Pod, the scheduler may choose another node with higher priority Pods
|
||||||
|
(compared to the Pods on the other node) for preemption. The victims must still
|
||||||
|
have lower priority than the preemptor Pod.
|
||||||
|
|
||||||
|
When there are multiple nodes available for preemption, the scheduler tries to
|
||||||
|
choose the node with a set of Pods with lowest priority. However, if such Pods
|
||||||
|
have PodDisruptionBudget that would be violated if they are preempted then the
|
||||||
|
scheduler may choose another node with higher priority Pods.
|
||||||
|
|
||||||
|
When multiple nodes exist for preemption and none of the above scenarios apply,
|
||||||
|
we expect the scheduler to choose a node with the lowest priority. If that is
|
||||||
|
not the case, it may indicate a bug in the scheduler.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ The `Terminating`, `NotTerminating`, and `NotBestEffort` scopes restrict a quota
|
|||||||
|
|
||||||
### Resource Quota Per PriorityClass
|
### Resource Quota Per PriorityClass
|
||||||
|
|
||||||
{{< feature-state for_k8s_version="1.11" state="beta" >}}
|
{{< feature-state for_k8s_version="1.11" state="alpha" >}}
|
||||||
|
|
||||||
Pods can be created at a specific [priority](/docs/concepts/configuration/pod-priority-preemption/#pod-priority).
|
Pods can be created at a specific [priority](/docs/concepts/configuration/pod-priority-preemption/#pod-priority).
|
||||||
You can control a pod's consumption of system resources based on a pod's priority, by using the `scopeSelector`
|
You can control a pod's consumption of system resources based on a pod's priority, by using the `scopeSelector`
|
||||||
|
|||||||
@@ -8,9 +8,13 @@ approvers:
|
|||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
|
|
||||||
We're happy to add localizations (l10n) of Kubernetes documentation to the website!
|
The Kubernetes documentation is currently available in [multiple languages](#supported-languages) and we encourage you to add new localizations ([l10n](https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/))!
|
||||||
|
|
||||||
Localizations must meet the following requirements for _workflow_ (how to localize) and _output_ (what to localize).
|
Currently available languages:
|
||||||
|
|
||||||
|
{{< language-repos-list >}}
|
||||||
|
|
||||||
|
In order for localizations to be accepted, however, they must fulfill some requirements related to workflow (*how* to localize) and output (*what* to localize).
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
@@ -18,73 +22,120 @@ Localizations must meet the following requirements for _workflow_ (how to locali
|
|||||||
|
|
||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
All l10n work must be stored and tracked within the [Kubernetes organization](https://github.com/kubernetes).
|
The Kubernetes documentation for all languages is built from the [kubernetes/website](https://github.com/kubernetes/website) repository on GitHub. Most day-to-work work on translations, however, happens in separate translation repositories. Changes to those repositories are then [periodically](#upstream-contributions) synced to the main kubernetes/website repository via [pull request](../create-pull-request).
|
||||||
|
|
||||||
### Basis for localizations
|
Work on the Chinese translation, for example, happens in the [kubernetes/kubernetes-docs-zh](https://github.com/kubernetes/kubernetes-docs-zh) repository.
|
||||||
|
|
||||||
Localizations must source from the English files for the [most recent major release](https://kubernetes.io/docs/home/supported-doc-versions/#current-version).
|
|
||||||
|
|
||||||
**Note:** To find the most recent release's documentation source files:
|
|
||||||
1. Navigate to https://github.com/kubernetes/website.
|
|
||||||
2. Select the `release-1.X` branch for the most recent version.
|
|
||||||
|
|
||||||
For example, the branch for Kubernetes v1.9 docs is `release-1.9`.
|
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
Source files reside in the `/docs/` directory.
|
**Note**: For an example localization-related [pull request](../create-pull-request), see [this pull request](https://github.com/kubernetes/website/pull/8636) to the [Kubernetes website repo](https://github.com/kubernetes/website) adding Korean localization to the Kubernetes docs.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
### Repository
|
## Source Files
|
||||||
|
|
||||||
A l10n team will have a repository specifically dedicated to its work, for example: [kubernetes/kubernetes-docs-zh](https://github.com/kubernetes/kubernetes-docs-zh).
|
Localizations must use English files from the most recent major release as sources. To find the most recent release's documentation source files:
|
||||||
|
|
||||||
{{< note >}}
|
1. Navigate to the Kubernetes website repository at https://github.com/kubernetes/website.
|
||||||
**Note:** To open a l10n repository, [contact the SIG docs lead](https://kubernetes.slack.com/messages/C1J0BPD2M) on Slack for assistance.
|
2. Select the `release-1.X` branch for the most recent version, which is currently **{{< latest-version >}}**, making the most recent release branch [`{{< release-branch >}}`](https://github.com/kubernetes/website/tree/{{< release-branch >}}).
|
||||||
{{< /note >}}
|
|
||||||
|
|
||||||
#### Repository structure
|
## Getting started
|
||||||
|
|
||||||
Each l10n repository must have branches for the different Kubernetes documentation release versions, matching the branches in the main [kubernetes/website](https://github.com/kubernetes/website) documentation repository. For example, the kubernetes/website `release-1.10` branch (https://github.com/kubernetes/website/tree/release-1.10) has a corresponding branch in the kubernetes/kubernetes-docs-zh repository (https://github.com/kubernetes/kubernetes-docs-zh/tree/release-1.10). These version branches keep track of the differences in the documentation between Kubernetes versions.
|
In order to add a new localization of the Kubernetes documentation, you'll need to make a few modifications to the site's [configuration](#configuration) and [directory structure](#new-directory), and then you can get to work [translating documents](#translating-documents)!
|
||||||
|
|
||||||
|
To get started, clone the website repo and `cd` into it:
|
||||||
|
|
||||||
### Project
|
```shell
|
||||||
|
git clone https://github.com/kubernetes/website
|
||||||
|
cd website
|
||||||
|
git checkout {{< release-branch >}}
|
||||||
|
```
|
||||||
|
|
||||||
Teams must track their overall progress with a [GitHub project](https://help.github.com/articles/creating-a-project-board/).
|
## Configuration
|
||||||
|
|
||||||
Projects must include columns for:
|
We'll walk you through the configuration process using the German language (language code `de`) as an example.
|
||||||
- To do
|
|
||||||
- In progress
|
|
||||||
- Done
|
|
||||||
|
|
||||||
For example: the [Chinese localization project](https://github.com/kubernetes/kubernetes-docs-zh/projects/1).
|
There's currently no translation for German, but you're welcome to create one using the instructions here.
|
||||||
|
|
||||||
### Team function
|
The Kubernetes website's configuration is in the [`config.toml`](https://github.com/kubernetes/website/tree/master/config.toml) file. You need to add a configuration block for the new language to that file, under the existing `[languages]` block. The German block, for example, looks like this:
|
||||||
|
|
||||||
L10n teams must provide a single point of contact: the name and contact information of a person who can respond to or redirect questions or concerns.
|
```toml
|
||||||
|
[languages.de]
|
||||||
|
title = "Kubernetes"
|
||||||
|
description = "Produktionsreife Container-Verwaltung"
|
||||||
|
languageName = "Deutsch"
|
||||||
|
contentDir = "content/de"
|
||||||
|
weight = 3
|
||||||
|
```
|
||||||
|
|
||||||
L10n teams must provide their own repository maintainers.
|
When assigning a `weight` parameter, see which of the current languages has the highest weight and add 1 to that value.
|
||||||
|
|
||||||
All l10n work must be self-sustaining with the team's own resources.
|
Now add a language-specific subdirectory to the [`content`](https://github.com/kubernetes/website/tree/master/content) folder. The two-letter code for German is `de`, so add a `content/de` directory:
|
||||||
|
|
||||||
Wherever possible, every localized page must be approved by a reviewer from a different company than the translator.
|
```shell
|
||||||
|
mkdir content/de
|
||||||
|
```
|
||||||
|
|
||||||
### Upstream contributions
|
## Translating documents
|
||||||
|
|
||||||
Upstream contributions are welcome and encouraged!
|
We understand that localizing *all* of the Kubernetes documentation would be an enormous task. We're okay with localizations smarting small and expanding over time.
|
||||||
|
|
||||||
For the sake of efficiency, limit upstream contributions to a single pull request per week, containing a single squashed commit.
|
As an initial requirement, all localizations must include the following documentation at a minimum:
|
||||||
|
|
||||||
## Output
|
|
||||||
|
|
||||||
All localizations must include the following documentation at a minimum:
|
|
||||||
|
|
||||||
Description | URLs
|
Description | URLs
|
||||||
-----|-----
|
-----|-----
|
||||||
Home | [All heading and subheading URLs](https://kubernetes.io/docs/home/)
|
Home | [All heading and subheading URLs](https://kubernetes.io/docs/home/)
|
||||||
Setup | [All heading and subheading URLs](https://kubernetes.io/docs/setup/)
|
Setup | [All heading and subheading URLs](https://kubernetes.io/docs/setup/)
|
||||||
Tutorials | [Kubernetes Basics](https://kubernetes.io/docs/tutorials/), [Hello Minikube](https://kubernetes.io/docs/tutorials/stateless-application/hello-minikube/)
|
Tutorials | [Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/), [Hello Minikube](https://kubernetes.io/docs/tutorials/stateless-application/hello-minikube/)
|
||||||
|
|
||||||
|
Translated documents should have the same URL endpoint as the English docs (substituting the subdirectory of the `content` folder). To translate the [Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) doc into German, for example, create the proper subfolder under the `content/de` folder and copy the English doc:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
mkdir -p content/de/docs/tutorials
|
||||||
|
cp content/en/docs/tutorials/kubernetes-basics.md content/de/docs/tutorials/kubernetes-basics.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project logistics
|
||||||
|
|
||||||
|
### Contact with project chairs
|
||||||
|
|
||||||
|
When starting a new localization effort, you should get in touch with one of the chairs of the Kubernetes [SIG Docs](https://github.com/kubernetes/community/tree/master/sig-docs) organization. The current chairs are listed [here](https://github.com/kubernetes/community/tree/master/sig-docs#chairs).
|
||||||
|
|
||||||
|
### Project information
|
||||||
|
|
||||||
|
Teams working on localization efforts must provide a single point of contact, including the name and contact information of a person who can respond to or redirect questions or concerns, listed in the translation repository's main [`README`](https://help.github.com/articles/about-readmes/). You can provide an email address, email list, [Slack channel](https://slack.com/), or some other method of contact.
|
||||||
|
|
||||||
|
### Maintainers
|
||||||
|
|
||||||
|
Each localization repository must select its own maintainers. Maintainers can be from a single organization or multiple organizations.
|
||||||
|
|
||||||
|
In addition, all l10n work must be self-sustaining with the team's own resources.
|
||||||
|
|
||||||
|
Wherever possible, every localized page must be approved by a reviewer from a different company than the translator.
|
||||||
|
|
||||||
|
### GitHub project
|
||||||
|
|
||||||
|
Each Kubernetes localization repository must track its overall progress with a [GitHub project](https://help.github.com/articles/creating-a-project-board/).
|
||||||
|
|
||||||
|
Projects must include at least these columns:
|
||||||
|
|
||||||
|
- To Do
|
||||||
|
- In Progress
|
||||||
|
- Done
|
||||||
|
|
||||||
|
{{< note >}}
|
||||||
|
**Note**: For an example GitHub project, see the [Chinese localization project](https://github.com/kubernetes/kubernetes-docs-zh/projects/1).
|
||||||
|
{{< /note >}}
|
||||||
|
|
||||||
|
### Repository structure
|
||||||
|
|
||||||
|
Each l10n repository must have branches for the different Kubernetes documentation release versions, matching the branches in the main [kubernetes/website](https://github.com/kubernetes/website) documentation repository. For example, the kubernetes/website `release-1.10` branch (https://github.com/kubernetes/website/tree/release-1.10) has a corresponding branch in the kubernetes/kubernetes-docs-zh repository (https://github.com/kubernetes/kubernetes-docs-zh/tree/release-1.10). These version branches keep track of the differences in the documentation between Kubernetes versions.
|
||||||
|
|
||||||
|
### Upstream contributions
|
||||||
|
|
||||||
|
Upstream contributions are welcome and encouraged!
|
||||||
|
|
||||||
|
For the sake of efficiency, limit upstream contributions to a single pull request per week, containing a single [squashed commit](https://github.com/todotxt/todo.txt-android/wiki/Squash-All-Commits-Related-to-a-Single-Issue-into-a-Single-Commit).
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
@@ -95,9 +146,4 @@ Once a l10n meets requirements for workflow and minimum output, SIG docs will:
|
|||||||
- Work with the localization team to implement language selection on the website.
|
- Work with the localization team to implement language selection on the website.
|
||||||
- Publicize availability through [Cloud Native Computing Foundation](https://www.cncf.io/) (CNCF) channels.
|
- Publicize availability through [Cloud Native Computing Foundation](https://www.cncf.io/) (CNCF) channels.
|
||||||
|
|
||||||
{{< note >}}
|
|
||||||
**Note:** Implementation of language selection is pending Kubernetes' first completed localization project.
|
|
||||||
{{< /note >}}
|
|
||||||
|
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -371,8 +371,8 @@ With output looking something like:
|
|||||||
|
|
||||||
```
|
```
|
||||||
node "test-01" untainted
|
node "test-01" untainted
|
||||||
taint key="dedicated" and effect="" not found.
|
taint "node-role.kubernetes.io/master:" not found
|
||||||
taint key="dedicated" and effect="" not found.
|
taint "node-role.kubernetes.io/master:" not found
|
||||||
```
|
```
|
||||||
|
|
||||||
This will remove the `node-role.kubernetes.io/master` taint from any nodes that
|
This will remove the `node-role.kubernetes.io/master` taint from any nodes that
|
||||||
|
|||||||
@@ -150,6 +150,12 @@ kubelet and the control plane is supported, but the kubelet version may never ex
|
|||||||
server version. For example, kubelets running 1.7.0 should be fully compatible with a 1.8.0 API server,
|
server version. For example, kubelets running 1.7.0 should be fully compatible with a 1.8.0 API server,
|
||||||
but not vice versa.
|
but not vice versa.
|
||||||
|
|
||||||
|
{{< warning >}}
|
||||||
|
These instructions exclude all Kubernetes packages from any system upgrades.
|
||||||
|
This is because kubeadm and Kubernetes require
|
||||||
|
[special attention to upgrade](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-11/).
|
||||||
|
{{</ warning >}}
|
||||||
|
|
||||||
For more information on version skews, please read our
|
For more information on version skews, please read our
|
||||||
[version skew policy](/docs/setup/independent/create-cluster-kubeadm/#version-skew-policy).
|
[version skew policy](/docs/setup/independent/create-cluster-kubeadm/#version-skew-policy).
|
||||||
|
|
||||||
@@ -163,6 +169,7 @@ deb http://apt.kubernetes.io/ kubernetes-xenial main
|
|||||||
EOF
|
EOF
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y kubelet kubeadm kubectl
|
apt-get install -y kubelet kubeadm kubectl
|
||||||
|
apt-mark hold kubelet kubeadm kubectl
|
||||||
```
|
```
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
{{% tab name="CentOS, RHEL or Fedora" %}}
|
{{% tab name="CentOS, RHEL or Fedora" %}}
|
||||||
@@ -175,6 +182,7 @@ enabled=1
|
|||||||
gpgcheck=1
|
gpgcheck=1
|
||||||
repo_gpgcheck=1
|
repo_gpgcheck=1
|
||||||
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
|
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
|
||||||
|
exclude=kube*
|
||||||
EOF
|
EOF
|
||||||
setenforce 0
|
setenforce 0
|
||||||
yum install -y kubelet kubeadm kubectl
|
yum install -y kubelet kubeadm kubectl
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ kube-controller-manager ... --cloud-provider=ovirt --cloud-config=/path/to/ovirt
|
|||||||
|
|
||||||
This short screencast demonstrates how the oVirt Cloud Provider can be used to dynamically add VMs to your Kubernetes cluster.
|
This short screencast demonstrates how the oVirt Cloud Provider can be used to dynamically add VMs to your Kubernetes cluster.
|
||||||
|
|
||||||
[](http://www.youtube.com/watch?v=JyyST4ZKne8)
|
[](https://www.youtube.com/watch?v=JyyST4ZKne8)
|
||||||
|
|
||||||
## Support Level
|
## Support Level
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ If you want a simplified getting started experience and GUI for managing cluster
|
|||||||
For an easy way to experiment with the Kubernetes development environment, click the button below
|
For an easy way to experiment with the Kubernetes development environment, click the button below
|
||||||
to open a Google Cloud Shell with an auto-cloned copy of the Kubernetes source repo.
|
to open a Google Cloud Shell with an auto-cloned copy of the Kubernetes source repo.
|
||||||
|
|
||||||
[](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/kubernetes/kubernetes&page=editor&open_in_editor=README.md)
|
[](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/kubernetes/kubernetes&page=editor&open_in_editor=README.md)
|
||||||
|
|
||||||
If you want to use custom binaries or pure open source Kubernetes, please continue with the instructions below.
|
If you want to use custom binaries or pure open source Kubernetes, please continue with the instructions below.
|
||||||
|
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ To keep `kube-dns`, pass `--feature-flags=CoreDNS=false` to `kubeadm upgrade app
|
|||||||
apt-get upgrade -y kubelet kubeadm
|
apt-get upgrade -y kubelet kubeadm
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
{{% tab name="CentOS, RHEL or Fedora" %}}
|
{{% tab name="CentOS, RHEL or Fedora" %}}
|
||||||
yum upgrade -y kubelet kubeadm
|
yum upgrade -y kubelet kubeadm --disableexcludes=kubernetes
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
{{< /tabs >}}
|
{{< /tabs >}}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ secrets:
|
|||||||
|
|
||||||
then you will see that a token has automatically been created and is referenced by the service account.
|
then you will see that a token has automatically been created and is referenced by the service account.
|
||||||
|
|
||||||
You may use authorization plugins to [set permissions on service accounts](docs/reference/access-authn-authz/authorization/#service-account-permissions).
|
You may use authorization plugins to [set permissions on service accounts](/docs/reference/access-authn-authz/rbac/#service-account-permissions).
|
||||||
|
|
||||||
To use a non-default service account, simply set the `spec.serviceAccountName`
|
To use a non-default service account, simply set the `spec.serviceAccountName`
|
||||||
field of a pod to the name of the service account you wish to use.
|
field of a pod to the name of the service account you wish to use.
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ from your Kubernetes cluster.
|
|||||||
|
|
||||||
This video shows how to configure and run a Google Cloud Monitoring backed Heapster:
|
This video shows how to configure and run a Google Cloud Monitoring backed Heapster:
|
||||||
|
|
||||||
[](http://www.youtube.com/watch?v=xSMNR2fcoLs)
|
[](https://www.youtube.com/watch?v=xSMNR2fcoLs)
|
||||||
|
|
||||||
|
|
||||||
{{< figure src="/images/docs/gcm.png" alt="Google Cloud Monitoring dashboard example" title="Google Cloud Monitoring dashboard example" caption="This dashboard shows cluster-wide resource usage." >}}
|
{{< figure src="/images/docs/gcm.png" alt="Google Cloud Monitoring dashboard example" title="Google Cloud Monitoring dashboard example" caption="This dashboard shows cluster-wide resource usage." >}}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ weight: 10
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
|
|
||||||
<p>Scaling out a Deployment will ensure new Pods are created and scheduled to Nodes with available resources. Scaling in will reduce the number of Pods to the new desired state. Kubernetes also supports <a href="http://kubernetes.io/docs/user-guide/horizontal-pod-autoscaling/">autoscaling</a> of Pods, but it is outside of the scope of this tutorial. Scaling to zero is also possible, and it will terminate all Pods of the specified Deployment.</p>
|
<p>Scaling out a Deployment will ensure new Pods are created and scheduled to Nodes with available resources. Scaling will increase the number of Pods to the new desired state. Kubernetes also supports <a href="http://kubernetes.io/docs/user-guide/horizontal-pod-autoscaling/">autoscaling</a> of Pods, but it is outside of the scope of this tutorial. Scaling to zero is also possible, and it will terminate all Pods of the specified Deployment.</p>
|
||||||
|
|
||||||
<p>Running multiple instances of an application will require a way to distribute the traffic to all of them. Services have an integrated load-balancer that will distribute network traffic to all Pods of an exposed Deployment. Services will monitor continuously the running Pods using endpoints, to ensure the traffic is sent only to available Pods.</p>
|
<p>Running multiple instances of an application will require a way to distribute the traffic to all of them. Services have an integrated load-balancer that will distribute network traffic to all Pods of an exposed Deployment. Services will monitor continuously the running Pods using endpoints, to ensure the traffic is sent only to available Pods.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
en: kubernetes/website
|
||||||
|
cn: kubernetes/kubernetes-docs-zh
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{{- $cssFilesFromConfig := .Site.Params.pushAssets.css -}}
|
||||||
|
{{- $jsFilesFromConfig := .Site.Params.pushAssets.js -}}
|
||||||
|
{{- $pages := .Site.RegularPages -}}
|
||||||
|
/*
|
||||||
|
X-Robots-Tag: noindex
|
||||||
|
Link: </images/favicon.png>; rel=preload; as=image
|
||||||
|
{{- range $cssFilesFromConfig -}}
|
||||||
|
{{- $cssUrl := printf "/css/%s.css" . }}
|
||||||
|
Link: <{{ $cssUrl }}>; rel=preload; as=style
|
||||||
|
{{- end -}}
|
||||||
|
{{- range $jsFilesFromConfig -}}
|
||||||
|
{{- $jsUrl := printf "/js/%s.js" . }}
|
||||||
|
Link: <{{ $jsUrl }}>; rel=preload; as=script
|
||||||
|
{{- end -}}
|
||||||
|
{{- range $pages }}
|
||||||
|
{{- if or (.Params.deprecated) (eq .Params.class "gridPage") (.Params.case_study_styles) (.Params.css) (.Params.js) }}
|
||||||
|
{{ .URL }}
|
||||||
|
{{- if .Params.deprecated }}
|
||||||
|
Link: </css/deprecation-warning.css>; rel=preload; as=style
|
||||||
|
{{- end -}}
|
||||||
|
{{- if eq .Params.class "gridPage" }}
|
||||||
|
Link: </css/gridpage.css>; rel=preload; as=style
|
||||||
|
{{- end -}}
|
||||||
|
{{- if .Params.case_study_styles }}
|
||||||
|
Link: </css/case_study_styles.css>; rel=preload; as=style
|
||||||
|
{{- end -}}
|
||||||
|
{{- with .Params.css -}}
|
||||||
|
{{- range (split . ",") }}
|
||||||
|
Link: <{{ trim . " " }}>; rel=preload; as=style
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- with .Params.js -}}
|
||||||
|
{{- range (split . ",") }}
|
||||||
|
Link: <{{ trim . " " }}>; rel=preload; as=script
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end }}
|
||||||
|
{{- end -}}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{{- $languages := .Site.Home.AllTranslations }}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Language
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Language code
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Repository
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{- range $languages.ByWeight }}
|
||||||
|
{{- $name := .Language.LanguageName }}
|
||||||
|
{{- $code := string .Language }}
|
||||||
|
{{- $repo := printf "https://github.com/%s" (index .Site.Data.repos $code) }}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ .Permalink }}">
|
||||||
|
{{ $name }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<code>{{ $code }}</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{ $repo }}">
|
||||||
|
{{ $repo }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{- end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{ .Site.Params.latest }}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{{- $latestVersion := .Site.Params.latest }}
|
||||||
|
{{- $latestReleaseBranch := printf "release-%s" (replace $latestVersion "v" "") }}
|
||||||
|
{{- $latestReleaseBranch }}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
[build]
|
[build]
|
||||||
# This default build command adds the robots noindex directive to the site headers
|
|
||||||
publish = "public"
|
publish = "public"
|
||||||
command = "hugo --enableGitInfo && cp netlify_noindex_headers.txt public/_headers"
|
command = "hugo"
|
||||||
|
|
||||||
[context.production.environment]
|
[context.production.environment]
|
||||||
HUGO_BASEURL = "https://kubernetes.io/"
|
HUGO_BASEURL = "https://kubernetes.io/"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# Prevent bots from indexing site
|
|
||||||
/*
|
|
||||||
X-Robots-Tag: noindex
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"Target":"css/styles.css","MediaType":"text/css","Data":{}}
|
||||||
@@ -1 +1 @@
|
|||||||
{"Target":"css/styles.min.cc96976ab977e15130372b9aa336567b7cd2c0cfdbacc2884d84a5f56868cc20.css","MediaType":"text/css","Data":{"Integrity":"sha256-zJaXarl34VEwNyuaozZWe3zSwM/brMKITYSl9WhozCA="}}
|
{"Target":"css/styles.min.d02f2440b9c46e9d70858ef9d01d95c96f4568fa648bbfa71dc44a5032967a62.css","MediaType":"text/css","Data":{"Integrity":"sha256-0C8kQLnEbp1whY750B2VyW9FaPpki7+nHcRKUDKWemI="}}
|
||||||
@@ -1 +1 @@
|
|||||||
{"Target":"css/styles.min.3a4a157b6c0f5130dd7ada2cc65c770a1e7b22b443594d9f713ff99fd6ca0425.css","MediaType":"text/css","Data":{"Integrity":"sha256-OkoVe2wPUTDdetosxlx3Ch57IrRDWU2fcT/5n9bKBCU="}}
|
{"Target":"css/styles.min.24d4c012d9ac488d91a75f20c259fb8dfa91247df002a99ab5313ae4d60dbcf6.css","MediaType":"text/css","Data":{"Integrity":"sha256-JNTAEtmsSI2Rp18gwln7jfqRJH3wAqmatTE65NYNvPY="}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"Target":"css/styles.css","MediaType":"text/css","Data":{}}
|
||||||
@@ -1 +1 @@
|
|||||||
{"Target":"css/styles.min.cc96976ab977e15130372b9aa336567b7cd2c0cfdbacc2884d84a5f56868cc20.css","MediaType":"text/css","Data":{"Integrity":"sha256-zJaXarl34VEwNyuaozZWe3zSwM/brMKITYSl9WhozCA="}}
|
{"Target":"css/styles.min.d02f2440b9c46e9d70858ef9d01d95c96f4568fa648bbfa71dc44a5032967a62.css","MediaType":"text/css","Data":{"Integrity":"sha256-0C8kQLnEbp1whY750B2VyW9FaPpki7+nHcRKUDKWemI="}}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
FROM alpine:3.7
|
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
|
||||||
build-base \
|
|
||||||
ca-certificates \
|
|
||||||
libffi-dev \
|
|
||||||
nodejs \
|
|
||||||
ruby-dev \
|
|
||||||
ruby-nokogiri \
|
|
||||||
zlib-dev
|
|
||||||
|
|
||||||
RUN gem install \
|
|
||||||
bundler \
|
|
||||||
github-pages \
|
|
||||||
io-console \
|
|
||||||
--no-rdoc --no-ri
|
|
||||||
|
|
||||||
VOLUME /k8sdocs
|
|
||||||
|
|
||||||
EXPOSE 4000
|
|
||||||
|
|
||||||
COPY start.sh /start.sh
|
|
||||||
WORKDIR /k8sdocs
|
|
||||||
|
|
||||||
CMD [ "/start.sh" ]
|
|
||||||
# For instructions, see http://kubernetes.io/editdocs/
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
bundle
|
|
||||||
bundle exec jekyll clean
|
|
||||||
bundle exec jekyll serve -H 0.0.0.0 -P 4000
|
|
||||||
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 5.7 KiB |