merge upstream master

This commit is contained in:
Zach Arnold
2018-09-24 21:41:24 -07:00
73 changed files with 1078 additions and 753 deletions
+3 -3
View File
@@ -12,15 +12,15 @@ RUN apk add --no-cache \
curl \
git \
openssh-client \
rsync
rsync \
build-base \
libc6-compat
ARG HUGO_VERSION
RUN mkdir -p /usr/local/src && \
cd /usr/local/src && \
curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz && \
apk add build-base && \
apk add libc6-compat && \
mv hugo /usr/local/bin/hugo && \
curl -L https://bin.equinox.io/c/dhgbqpS8Bvy/minify-stable-linux-amd64.tgz | tar -xz && \
mv minify /usr/local/bin && \
@@ -148,7 +148,7 @@ Highly available apps, here we come.
### Deploying a multi-zone application 
Create the guestbook-go example, which includes a ReplicationController of size 3, running a simple web app. Download all the files from [here](https://github.com/kubernetes/kubernetes/tree/master/examples/guestbook-go), and execute the following command (the command assumes you downloaded them to a directory named “guestbook-go”:
Create the guestbook-go example, which includes a ReplicationController of size 3, running a simple web app. Download all the files from [here](https://github.com/kubernetes/examples/tree/master/guestbook-go), and execute the following command (the command assumes you downloaded them to a directory named “guestbook-go”:
```
kubectl create -f guestbook-go/
@@ -0,0 +1,140 @@
---
layout: blog
title: 'Hands On With Linkerd 2.0'
date: 2018-09-18
---
**Author**: Thomas Rampelberg (Buoyant)
Linkerd 2.0 was recently announced as generally available (GA), signaling its readiness for production use. In this tutorial, well walk you through how to get Linkerd 2.0 up and running on your Kubernetes cluster in a matter seconds.
But first, what is Linkerd and why should you care? Linkerd is a service sidecar that augments a Kubernetes service, providing zero-config dashboards and UNIX-style CLI tools for runtime debugging, diagnostics, and reliability. Linkerd is also a service mesh, applied to multiple (or all) services in a cluster to provide a uniform layer of telemetry, security, and control across them.
Linkerd works by installing ultralight proxies into each pod of a service. These proxies report telemetry data to, and receive signals from, a control plane. This means that using Linkerd doesnt require any code changes, and can even be installed live on a running service. Linkerd is fully open source, Apache v2 licensed, and is hosted by the Cloud Native Computing Foundation (just like Kubernetes itself!)
Without further ado, lets see just how quickly you can get Linkerd running on your Kubernetes cluster. In this tutorial, well walk you through how to deploy Linkerd on any Kubernetes 1.9+ cluster and how to use it to debug failures in a sample gRPC application.
## Step 1: Install the demo app 🚀
Before we install Linkerd, lets start by installing a basic gRPC demo application called Emojivoto onto your Kubernetes cluster. To install Emojivoto, run:
`curl https://run.linkerd.io/emojivoto.yml | kubectl apply -f -`
This command downloads the Kubernetes manifest for Emojivoto, and uses kubectl to apply it to your Kubernetes cluster. Emojivoto is comprised of several services that run in the “emojivoto” namespace. You can see the services by running:
`kubectl get -n emojivoto deployments`
You can also see the app live by running
`minikube -n emojivoto service web-svc --url # if youre on minikube`
… or:
`kubectl get svc web-svc -n emojivoto -o jsonpath="{.status.loadBalancer.ingress[0].*}" #`
… if youre somewhere else
Click around. You might notice that some parts of the application are broken! If you were to inspect your handly local Kubernetes dashboard, you wouldnt see very much interesting---as far as Kubernetes is concerned, the app is running just fine. This is a very common situation! Kubernetes understands whether your pods are running, but not whether they are responding properly.
In the next few steps, well walk you through how to use Linkerd to diagnose the problem.
## Step 2: Install Linkerds CLI
Well start by installing Linkerds command-line interface (CLI) onto your local machine. Visit the [Linkerd releases page](https://github.com/linkerd/linkerd2/releases/), or simply run:
`curl -sL https://run.linkerd.io/install | sh`
Once installed, add the `linkerd` command to your path with:
`export PATH=$PATH:$HOME/.linkerd2/bin`
You should now be able to run the command `linkerd version`, which should display:
```
Client version: v2.0
Server version: unavailable
```
“Server version: unavailable” means that we need to add Linkerds control plane to the cluster, which well do next. But first, lets validate that your cluster is prepared for Linkerd by running:
`linkerd check --pre`
This handy command will report any problems that will interfere with your ability to install Linkerd. Hopefully everything looks OK and youre ready to move on to the next step.
## Step 3: Install Linkerds control plane onto the cluster
In this step, well install Linkerds lightweight control plane into its own namespace (“linkerd”) on your cluster. To do this, run:
`linkerd install | kubectl apply -f -`
This command generates a Kubernetes manifest and uses `kubectl` command to apply it to your Kubernetes cluster. (Feel free to inspect the manifest before you apply it.)
(Note: if your Kubernetes cluster is on GKE with RBAC enabled, youll need an extra step: you must grant a ClusterRole of cluster-admin to your Google Cloud account first, in order to install certain telemetry features in the control plane. To do that, run: `kubectl create clusterrolebinding cluster-admin-binding-$USER --clusterrole=cluster-admin --user=$(gcloud config get-value account)`.)
Depending on the speed of your internet connection, it may take a minute or two for your Kubernetes cluster to pull the Linkerd images. While thats happening, we can validate that everythings happening correctly by running:
`linkerd check`
This command will patiently wait until Linkerd has been installed and is running.
Finally, were ready to view Linkerds dashboard! Just run:
`linkerd dashboard`
If you see something like below, Linkerd is now running on your cluster. 🎉
<center><img src="/images/blog/2018-09-18-2018-linkerd-2.0/1-dashboard.png" width="700"></center>
## Step 4: Add Linkerd to the web service
At this point we have the Linkerd control plane installed in the “linkerd” namespace, and we have our emojivoto demo app installed in the “emojivoto” namespace. But we havent actually added Linkerd to our service yet. So lets do that.
In this example, lets pretend we are the owners of the “web” service. Other services, like “emoji” and “voting”, are owned by other teams--so we dont want to touch them.
There are a couple ways to add Linkerd to our service. For demo purposes, the easiest is to do something like this:
`kubectl get -n emojivoto deploy/web -o yaml | linkerd inject - | kubectl apply -f -`
This command retrieves the manifest of the “web” service from Kubernetes, runs this manifest through `linkerd inject`, and finally reapplies it to the Kubernetes cluster. The `linkerd inject` command augments the manifest to include Linkerds data plane proxies. As with `linkerd install`, `linkerd inject` is a pure text operation, meaning that you can inspect the input and output before you use it. Since “web” is a Deployment, Kubernetes is kind enough to slowly roll the service one pod at a time--meaning that “web” can be serving traffic live while we add Linkerd to it!
We now have a service sidecar running on the “web” service!
## Step 5: Debugging for Fun and for Profit
Congratulations! You now have a full gRPC application running on your Kubernetes cluster with Linkerd installed on the “web” service. Of course, that application is failing when you use it--so now lets use Linkerd to track down those errors.
If you glance at the Linkerd dashboard (the `linkerd dashboard` command), you should see all services in the “emojivoto” namespace show up. Since “web” has the Linkerd service sidecar installed on it, youll also see success rate, requests per second, and latency percentiles show up.
<center><img src="/images/blog/2018-09-18-2018-linkerd-2.0/2-web-overview.png" width="700"></center>
Thats pretty neat, but the first thing you might notice is that success rate is well below 100%! Click on “web” and lets dig in.
You should now be looking at the Deployment page for the web service. The first thing youll see here is that web is taking traffic from vote-bot (a service included in the Emojivoto manifest to continually generate a low level of live traffic), and has two outgoing dependencies, emoji and voting.
<center><img src="/images/blog/2018-09-18-2018-linkerd-2.0/3-web-detail.png" width="700"></center>
The emoji service is operating at 100%, but the voting service is failing! A failure in a dependent service may be exactly whats causing the errors that web is returning.
Lets scroll a little further down the page, well see a live list of all traffic endpoints that “web” is receiving. This is interesting:
<center><img src="/images/blog/2018-09-18-2018-linkerd-2.0/4-web-top.png" width="700"></center>
There are two calls that are not at 100%: the first is vote-bots call the “/api/vote” endpoint. The second is the “VotePoop” call from the web service to the voting service. Very interesting! Since /api/vote is an incoming call, and “/VotePoop” is an outgoing call, this is a good clue that that the failure of the vote services VotePoop endpoint is whats causing the problem!
Finally, if we click on the “tap” icon for that row in the far right column, well be taken to live list of requests that match this endpoint. This allows us to confirm that the requests are failing (they all have [gRPC status code 2](https://godoc.org/google.golang.org/grpc/codes#Code), indicating an error).
<center><img src="/images/blog/2018-09-18-2018-linkerd-2.0/5-web-tap.png" width="700"></center>
At this point we have the ammunition we need to talk to the owners of the vote “voting” service. Weve identified an endpoint on their service that consistently returns an error, and have found no other obvious sources of failures in the system.
We hope youve enjoyed this journey through Linkerd 2.0. There is much more for you to explore. For example, everything we did above using the web UI can also be accomplished via pure CLI commands, e.g. `linkerd top`, `linkerd stat`, and `linkerd tap`.
Also, did you notice the little Grafana icon on the very first page we looked at? Linkerd ships with automatic Grafana dashboards for all those metrics, allowing you to view everything youre seeing in the Linkerd dashboard in a time series format. Check it out!
<center><img src="/images/blog/2018-09-18-2018-linkerd-2.0/6-grafana.png" width="700"></center>
## Want more?
In this tutorial, weve shown you how to install Linkerd on a cluster, add it as a service sidecar to just one service--while the service is receiving live traffic!---and use it to debug a runtime issue. But this is just the tip of the iceberg. We havent even touched any of Linkerds reliability or security features!
Linkerd has a thriving community of adopters and contributors, and wed love for YOU to be a part of it. For more, check out the [docs](https://linkerd.io/docs) and [GitHub](https://github.com/linkerd/linkerd) repo, join the [Linkerd Slack](https://slack.linkerd.io/) and mailing lists ([users](https://lists.cncf.io/g/cncf-linkerd-users), [developers](https://lists.cncf.io/g/cncf-linkerd-dev), [announce](https://lists.cncf.io/g/cncf-linkerd-announce)), and, of course, follow [@linkerd](https://twitter.com/linkerd) on Twitter! We cant wait to have you aboard!
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

+111
View File
@@ -0,0 +1,111 @@
---
title: IBM Case Study
linkTitle: IBM
case_study_styles: true
cid: caseStudies
css: /css/style_case_studies.css
logo: ibm_featured_logo.png
featured: true
weight: 2
quote: >
We see CNCF as a safe haven for cloud native open source, providing stability, longevity, and expected maintenance for member projects—no matter the originating vendor or project.
---
<div class="banner1" style="background-image: url('/images/CaseStudy_ibm_banner1.jpg')">
<h1> CASE STUDY:<img src="/images/ibm_logo.png" class="header_logo" style="width:10%"><br> <div class="subhead">Building an Image Trust Service on Kubernetes with Notary and TUF</div></h1>
</div>
<div class="details">
Company &nbsp;<b>IBM</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Location &nbsp;<b>Armonk, New York</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Industry &nbsp;<b>Cloud Computing</b>
</div>
<hr>
<section class="section1">
<div class="cols">
<div class="col1" style="width:95%">
<h2>Challenge</h2>
<a href="https://www.ibm.com/cloud/">IBM Cloud</a> offers public, private, and hybrid cloud functionality across a diverse set of runtimes from its OpenWhisk-based function as a service (FaaS) offering, managed <a href="https://kubernetes.io">Kubernetes</a> and containers, to <a href="https://www.cloudfoundry.org">Cloud Foundry</a> platform as a service (PaaS). These runtimes are combined with the power of the companys enterprise technologies, such as MQ and DB2, its modern artificial intelligence (AI) Watson, and data analytics services. Users of IBM Cloud can exploit capabilities from more than 170 different cloud native services in its catalog, including capabilities such as IBMs Weather Company API and data services. In the later part of 2017, the IBM Cloud Container Registry team wanted to build out an image trust service.
<br><br>
<h2>Solution</h2>
The work on this new service culminated with its public availability in the IBM Cloud in February 2018. The image trust service, called Portieris, is fully based on the <a href="https://www.cncf.io">Cloud Native Computing Foundation (CNCF)</a> open source project <a href="https://github.com/theupdateframework/notary">Notary</a>, according to Michael Hough, a software developer with the IBM Cloud Container Registry team. Portieris is a Kubernetes admission controller for enforcing content trust. Users can create image security policies for each Kubernetes namespace, or at the cluster level, and enforce different levels of trust for different images. Portieris is a key part of IBMs trust story, since it makes it possible for users to consume the companys Notary offering from within their IKS clusters. The offering is that Notary server runs in IBMs cloud, and then Portieris runs inside the IKS cluster. This enables users to be able to have their IKS cluster verify that the image they're loading containers from contains exactly what they expect it to, and Portieris is what allows an IKS cluster to apply that verification.
</div>
<div class="col2" style="width:95%">
<h2>Impact</h2>
IBM's intention in offering a managed Kubernetes container service and image registry is to provide a fully secure end-to-end platform for its enterprise customers. "Image signing is one key part of that offering, and our container registry team saw Notary as the de facto way to implement that capability in the current Docker and container ecosystem," Hough says. The company had not been offering image signing before, and Notary is the tool it used to implement that capability. "We had a multi-tenant Docker Registry with private image hosting," Hough says. "The Docker Registry uses hashes to ensure that image content is correct, and data is encrypted both in flight and at rest. But it does not provide any guarantees of who pushed an image. We used Notary to enable users to sign images in their private registry namespaces if they so choose."
</div>
</div>
</section>
<div class="banner2">
<div class="banner2text">
"We see CNCF as a safe haven for cloud native open source, providing stability, longevity, and expected maintenance for member projects—no matter the originating vendor or project."<br style="height:25px"><span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br>- Michael Hough, a software developer with the IBM Container Registry team</span>
</div>
</div>
<section class="section2">
<div class="fullcol">
<h2>Docker had already created the Notary project as an implementation of <a href="https://github.com/theupdateframework/specification" style="text-decoration:underline">The Update Framework (TUF)</a>, and this implementation of TUF provided the capabilities for Docker Content Trust.</h2> "After contribution to CNCF of both TUF and Notary, we perceived that it was becoming the de facto standard for image signing in the container ecosystem", says Michael Hough, a software developer with the IBM Cloud Container Registry team.
<br><br>
The key reason for selecting Notary was that it was already compatible with the existing authentication stack IBMs container registry was using. So was the design of TUF, which does not require the registry team to have to enter the business of key management. Both of these were "attractive design decisions that confirmed our choice of Notary," he says.
<br><br>
The introduction of Notary to implement image signing capability in IBM Cloud encourages increased security across IBM's cloud platform, "where we expect it will include both the signing of official IBM images as well as expected use by security-conscious enterprise customers," Hough says. "When combined with security policy implementations, we expect an increased use of deployment policies in CI/CD pipelines that allow for fine-grained control of service deployment based on image signers."
The availability of image signing "is a huge benefit to security-conscious customers who require this level of image provenance and security," Hough says. "With our IBM Cloud Kubernetes as-a-service offering and the admission controller we have made available, it allows both IBM services as well as customers of the IBM public cloud to use security policies to control service deployment."
</div>
</section>
<div class="banner3" style="background-image: url('/images/CaseStudy_ibm_banner3.jpg')">
<div class="banner3text">
"Image signing is one key part of our Kubernetes container service offering, and our container registry team saw Notary as the de facto way to implement that capability in the current Docker and container ecosystem"<span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br><br>- Michael Hough, a software developer with the IBM Cloud Container Registry team</span>
</div>
</div>
<section class="section3">
<div class="fullcol">
Now that the Notary-implemented service is generally available in IBMs public cloud as a component of its existing IBM Cloud Container Registry, it is deployed as a highly available service across five IBM Cloud regions. This high-availability deployment has three instances across two zones in each of the five regions, load balanced with failover support. "We have also deployed it with end-to-end TLS support through to our back-end IBM Cloudant persistence storage service," Hough says.
<br><br>
The IBM team has created and open sourced a Kubernetes admission controller called Portieris, which uses Notary signing information combined with customer-defined security policies to control image deployment into their cluster. "We are hoping to drive adoption of Portieris through its use of our Notary offering," Hough says.
<br><br>
IBM has been a key player in the creation and support of open source foundations, including CNCF. Todd Moore, IBM's vice president of Open Technology, is the current CNCF governing board chair and a number of IBMers are active across many of the CNCF member projects.
</div>
</section>
<div class="banner4" style="background-image: url('/images/CaseStudy_ibm_banner4.jpg')">
<div class="banner4text">
"With our IBM Cloud Kubernetes as-a-service offering and the admission controller we have made available, it allows both IBM services as well as customers of the IBM public cloud to use security policies to control service deployment."<span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br><br>- Michael Hough, a software developer with the IBM Cloud Container Registry team</span>
</div>
</div>
</div>
<section class="section4">
<div class="fullcol">
"Given that, we see CNCF as a safe haven for cloud native open source, providing stability, longevity, and expected maintenance for member projects—no matter the originating vendor or project," Hough says. Because the entire cloud native world is a fast-moving area with many competing vendors and solutions, "we see the CNCF model as an arbiter of openness and fair play across the ecosystem," he says.
<br><br>
With both TUF and Notary as part of CNCF, IBM expects there to be standardization around these capabilities beyond just de facto standards for signing and provenance. IBM has determined to not simply consume Notary, but also to contribute to the open source project where applicable. "IBMers have contributed a CouchDB backend to support our use of IBM Cloudant as the persistent store; and are working on generalization of the pkcs11 provider, allowing support of other security hardware devices beyond Yubikey," Hough says.
</div>
</section>
<div class="banner5">
<div class="banner5text">
"There are new projects addressing these challenges, including within CNCF. We will definitely be following these advancements with interest. We found the Notary community to be an active and friendly community open to changes, such as our addition of a CouchDB backend for persistent storage." <span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br><br>- Michael Hough, a software developer with the IBM Cloud Container Registry team</span>
</div>
</div>
<section class="section5" style="padding:0px !important">
<div class="fullcol">
The company has used other CNCF projects <a href="https://containerd.io">containerd</a>, <a href="https://www.envoyproxy.io">Envoy</a>, <a href="https://prometheus.io">Prometheus</a>, <a href="https://grpc.io">gRPC</a>, and <a href="https://github.com/containernetworking">CNI</a>, and is looking into <a href="https://github.com/spiffe">SPIFFE</a> and <a href="https://github.com/spiffe/spire">SPIRE</a> as well for potential future use.
<br><br>
What advice does Hough have for other companies that are looking to deploy Notary or a cloud native infrastructure?
<br><br>
"While this is true for many areas of cloud native infrastructure software, we found that a high-availability, multi-region deployment of Notary requires a solid implementation to handle certificate management and rotation," he says. "There are new projects addressing these challenges, including within CNCF. We will definitely be following these advancements with interest. We found the Notary community to be an active and friendly community open to changes, such as our addition of a CouchDB backend for persistent storage."
</div>
</section>
+116
View File
@@ -0,0 +1,116 @@
---
title: NAIC Case Study
linkTitle: NAIC
case_study_styles: true
cid: caseStudies
css: /css/style_case_studies.css
logo: naic_featured_logo.png
featured: true
weight: 3
quote: >
Our culture and technology transition is a strategy embraced by our top leaders. It has already proven successful by allowing us to accelerate our value pipeline by more than double while decreasing our costs by more than half.
---
<div class="banner1" style="background-image: url('/images/CaseStudy_naic_banner1.jpg')">
<h1> CASE STUDY:<img src="/images/naic_logo.png" class="header_logo" style="width:18%"><br> <div class="subhead" style="margin-top:1%">A Culture and Technology Transition Enabled by Kubernetes</div></h1>
</div>
<div class="details" style="font-size:1em">
Company &nbsp;<b>National Association of Insurance Commissioners (NAIC)</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Location &nbsp;<b>Washington, DC</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Industry &nbsp;<b>Regulatory</b>
</div>
<hr>
<section class="section1">
<div class="cols">
<div class="col1">
<h2>Challenge</h2>
The <a href="http://www.naic.org/">National Association of Insurance Commissioners (NAIC)</a>, the U.S. standard-setting and regulatory support organization, was looking for a way to deliver new services faster to provide more value for members and staff. It also needed greater agility to improve productivity internally.
<br><br>
<h2>Solution</h2>
Beginning in 2016, they started using <a href="https://www.cncf.io/">Cloud Native Computing Foundation (CNCF)</a> tools such as <a href="https://prometheus.io/">Prometheus</a>. NAIC began hosting internal systems and development systems on <a href="https://kubernetes.io/">Kubernetes</a> at the beginning of 2018, as part of a broad move toward the public cloud. "Our culture and technology transition is a strategy embraced by our top leaders," says Dan Barker, Chief Enterprise Architect. "It has already proven successful by allowing us to accelerate our value pipeline by more than double while decreasing our costs by more than half. We are also seeing customer satisfaction increase as we add more and more applications to these new technologies."
</div>
<div class="col2">
<h2>Impact</h2>
Leveraging Kubernetes, "our development teams can create rapid prototypes far faster than they used to," Barker said. Applications running on Kubernetes are more resilient than those running in other environments. The deployment of open source solutions is helping influence company culture, as NAIC becomes a more open and transparent organization.
<br><br>
"We completed a small prototype in two days that would have previously taken at least a month," Barker says. Resiliency is currently measured in how much downtime systems have. "Theyve basically had none, and the occasional issue is remedied in minutes," he says.
</div>
</div>
</section>
<div class="banner2">
<div class="banner2text">
"Our culture and technology transition is a strategy embraced by our top leaders. It has already proven successful by allowing us to accelerate our value pipeline by more than double while decreasing our costs by more than half. We are also seeing customer satisfaction increase as we add more and more applications to these new technologies." <br style="height:25px"><span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br>- Dan Barker, Chief Enterprise Architect, NAIC</span>
</div>
</div>
<section class="section2">
<div class="fullcol">
NAIC—which was created and overseen by the chief insurance regulators from the 50 states, the District of Columbia and five U.S. territories—provides a means through which state insurance regulators establish standards and best practices, conduct peer reviews, and coordinate their regulatory oversight. Their staff supports these efforts and represents the collective views of regulators in the United States and internationally. NAIC members, together with the organizations central resources, form the national system of state-based insurance regulation in the United States.<br><br>
The organization has been using the cloud for years, and wanted to find more ways to quickly deliver new services that provide more value for members and staff. They looked to Kubernetes for a solution. Within NAIC, several groups are leveraging Kubernetes, one being the Platform Engineering Team. "The team building out these tools are not only deploying and operating Kubernetes, but theyre also using them," Barker says. "In fact, were using GitLab to deploy Kubernetes with a pipeline using <a href="https://github.com/kubernetes/kops">kops</a>. This team was created from developers, operators, and quality engineers from across the company, so their jobs have changed quite a bit."<br><br>
In addition, NAIC is onboarding teams to the new platform, and those teams have seen a lot of change in how they work and what they can do. "They now have more power in creating their own infrastructure and deploying their own applications," Barker says. They also use pipelines to facilitate their currently manual processes. NAIC has consumers who are using GitLab heavily, and theyre starting to use Kubernetes to deploy simple applications that help their internal processes.
</div>
</section>
<div class="banner3" style="background-image: url('/images/CaseStudy_naic_banner3.jpg')">
<div class="banner3text">
"In our experience, vendor lock-in and tooling that is highly specific results in less resilient technology with fewer minds working to solve problems and grow the community." <br style="height:25px"><span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br>- Dan Barker, Chief Enterprise Architect, NAIC</span>
</div>
</div>
<section class="section3">
<div class="fullcol">
"We needed greater agility to enable our own productivity internally," he says. "We decided it was right for us to move everything to the public cloud [Amazon Web Services] to help with that process and be able to access many of the native tools that allows us to move faster by not needing to build everything."
The NAIC also wanted to be cloud-agnostic, "and Kubernetes helps with this for our compute layer," Barker says. "Compute is pretty standard across the clouds, and now we can take advantage of any of them while getting all of the other features Kubernetes offers."<br><br>
The NAIC currently hosts internal systems and development systems on Kubernetes, and has already seen how impactful it can be. "Our development teams can create rapid prototypes in minutes instead of weeks," Barker says. "This recently happened with an internal tool that had no measurable wait time on the infrastructure. It was solely development bound. There is now a central shared resource that lives in AWS, which means it can grow as needed."
The native integrations into Kubernetes at NAIC has made it easy to write code and have it running in minutes instead of weeks. Applications running on Kubernetes have also proven to be more resilient than those running in other environments. "We even have teams using this to create more internal tools to help with communication or automating some of their current tasks," Barker says.
<br><br>
"We knew that Kubernetes had become the de facto standard for container orchestration," he says. "Two major factors for selecting this were the three major cloud vendors hosting their own versions and having it hosted in a neutral party as fully open source."
<br><br>
As for other CNCF projects, NAIC is using Prometheus on a small scale and hopes to continue using it moving forward because of the seamless integration with Kubernetes. The Association also is considering <a href="https://grpc.io/">gRPC</a> as its internal communications standard, <a href="https://www.envoyproxy.io/">Envoy</a> in conjunction with Istio for service mesh, <a href="http://opentracing.io/">OpenTracing</a> and <a href="https://www.jaegertracing.io">Jaeger</a> for tracing aggregation, and <a href="https://www.fluentd.org/">Fluentd</a> with its Elasticsearch cluster.
</div>
</section>
<div class="banner4" style="background-image: url('/images/CaseStudy_naic_banner4.jpg')">
<div class="banner4text">
"We knew that Kubernetes had become the de facto standard for container orchestration. Two major factors for selecting this were the three major cloud vendors hosting their own versions and having it hosted in a neutral party as fully open source."<span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br><br>- Dan Barker, Chief Enterprise Architect, NAIC</span>
</div>
</div>
</div>
<section class="section5" style="padding:0px !important">
<div class="fullcol">
The open governance and broad industry participation in CNCF provided a comfort level with the technology, Barker says. "We also see it as helping to influence our own company culture," he says. "Were moving to be a more open and transparent company, and we are encouraging our staff to get involved with the different working groups and codebases. We recently became CNCF members to help further our commitment to community contribution and transparency."<br><br>
Factors such as vendor-neutrality and cross-industry investment were important in the selection. "In our experience, vendor lock-in and tooling that is highly specific results in less resilient technology with fewer minds working to solve problems and grow the community," Barker says.<br><br>
NAIC is a largely Oracle shop, Barker says, and has been running mostly Java on JBoss. "However, we have years of history with other applications," he says. "Some of these have been migrated by completely rewriting the application, while others are just being modified slightly to fit into this new paradigm."<br><br>
Running on AWS cloud, the Association has not specifically taken a microservices approach. "We are moving to microservices where practical, but we havent found that its a necessity to operate them within Kubernetes," Barker says<br><br>
All of its databases are currently running within public cloud services, but they have explored eventually running those in Kubernetes, as it makes sense. "Were doing this to get more reuse from common components and to limit our failure domains to something more manageable and observable," Barker says.
</div>
<div class="banner5">
<div class="banner5text">
"We have been able to move much faster at lower cost than we were able to in the past," Barker says. "We were able to complete one of our projects in a year, when the previous version took over two years. And the new project cost $500,000 while the original required $3 million, and with fewer defects. We are also able to push out new features much faster."<span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br><br>- Dan Barker, Chief Enterprise Architect, NAIC</span>
</div>
</div>
<div class="fullcol">
NAIC has seen a significant business impact from its efforts. "We have been able to move much faster at lower cost than we were able to in the past," Barker says. "We were able to complete one of our projects in a year, when the previous version took over two years. And the new project cost $500,000 while the original required $3 million, and with fewer defects. We are also able to push out new features much faster."
He says the organization is moving toward continuous deployment "because the business case makes sense. The research is becoming very hard to argue with. We want to reduce our batch sizes and optimize on delivering value to customers and not feature count. This is requiring a larger cultural shift than just a technology shift."
NAIC is "becoming more open and transparent, as well as more resilient to failure," Barker says. "Even our customers are wanting more and more of this and trying to figure out how they can work with us to accomplish our mutual goals faster. Members of the insurance industry have reached out so that we can better learn together and grow as an industry."
</div>
</section>
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

+99
View File
@@ -0,0 +1,99 @@
---
title: Ocado Case Study
linkTitle: Ocado
case_study_styles: true
cid: caseStudies
css: /css/style_case_studies.css
logo: ocado_featured_logo.png
featured: true
weight: 4
quote: >
People at Ocado Technology have been quite amazed. They ask, Can we do this on a Dev cluster? and 10 minutes later we have rolled out something that is deployed across the cluster. The speed from idea to implementation to deployment is amazing.
---
<div class="banner1" style="background-image: url('/images/CaseStudy_ocado_banner1.jpg')">
<h1> CASE STUDY:<img src="/images/ocado_logo.png" class="header_logo"><br> <div class="subhead">Ocado: Running Grocery Warehouses with a Cloud Native Platform</div></h1>
</div>
<div class="details">
Company &nbsp;<b>Ocado Technology</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Location &nbsp;<b>Hatfield, England</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Industry &nbsp;<b>Grocery retail technology and platforms</b>
</div>
<hr>
<section class="section1">
<div class="cols">
<div class="col1">
<h2>Challenge</h2>
The worlds largest online-only grocery retailer, <a href="http://www.ocadogroup.com/">Ocado</a> developed the Ocado Smart Platform to manage its own operations, from websites to warehouses, and is now licensing the technology to other retailers such as <a href="http://fortune.com/2018/05/17/ocado-kroger-warehouse-automation-amazon-walmart/">Kroger</a>. To set up the first warehouses for the platform, Ocado shifted from virtual machines and <a href="https://puppet.com/">Puppet</a> infrastructure to <a href="https://www.docker.com/">Docker</a> containers, using CoreOSs <a href="https://github.com/coreos/fleet">fleet</a> scheduler to provision all the services on its <a href="https://www.openstack.org/">OpenStack</a>-based private cloud on bare metal. As the Smart Platform grew and "fleet was going end-of-life," says Platform Engineer Mike Bryant, "we started looking for a more complete platform, with all of these disparate infrastructure services being brought together in one unified API."<br><br>
<h2>Solution</h2>
The team decided to migrate from fleet to <a href="https://www.kubernetes.io">Kubernetes</a> on Ocados private cloud. The Kubernetes stack currently uses <a href="https://github.com/kubernetes/kubeadm/">kubeadm</a> for bootstrapping, <a href="https://github.com/containernetworking">CNI</a> with <a href="https://www.weave.works/oss/net/">Weave Net</a> for networking, <a href="https://coreos.com/operators/prometheus/docs/latest/user-guides/getting-started.html">Prometheus Operator</a> for monitoring, <a href="https://www.fluentd.org/">Fluentd</a> for logging, and <a href="http://opentracing.io/">OpenTracing</a> for distributed tracing. The first app on Kubernetes, a business-critical service in the warehouses, went into production in the summer of 2017, with a mass migration continuing into 2018. Hundreds of Ocado engineers working on the Smart Platform are now deploying on Kubernetes.
</div>
<div class="col2">
<h2>Impact</h2>
With Kubernetes, "the speed from idea to implementation to deployment is amazing," says Bryant. "Ive seen features go from development to production inside of a week now. In the old world, a new application deployment could easily take over a month." And because there are no longer restrictive deployment windows in the warehouses, the rate of deployments has gone from as few as two per week to dozens per week. Ocado has also achieved cost savings because Kubernetes gives the team the ability to have more fine-grained resource allocation. Says DevOps Team Leader Kevin McCormack: "We have more confidence in the resource allocation/separation features of Kubernetes, so we have been able to migrate from around 10 fleet clusters to one Kubernetes cluster." The team also uses <a href="https://prometheus.io/">Prometheus</a> and <a href="https://grafana.com/">Grafana</a> to visualize resource allocation, and makes the data available to developers. "The increased visibility offered by Prometheus means developers are more aware of what they are using and how their use impacts others, especially since we now have one shared cluster," says McCormack. "Id estimate that we use about 15-25% less hardware resources to host the same applications in Kubernetes in our test environments."
</div>
</div>
</section>
<div class="banner2">
<div class="banner2text">
"People at Ocado Technology have been quite amazed. They ask, Can we do this on a Dev cluster? and 10 minutes later we have rolled out something that is deployed across the cluster. The speed from idea to implementation to deployment is amazing." <br style="height:25px"><span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br>- Mike Bryant, Platform Engineer, Ocado</span>
</div>
</div>
<section class="section2">
<div class="fullcol">
<h2>When it was founded in 2000, Ocado was an online-only grocery retailer in the U.K. In the years since, it has expanded from delivering produce to families to providing technology to other grocery retailers.</h2>
The company began developing its Ocado Smart Platform to manage its own operations, from websites to warehouses, and is now licensing the technology to other grocery chains around the world, such as <a href="http://fortune.com/2018/05/17/ocado-kroger-warehouse-automation-amazon-walmart/">Kroger</a>. To set up the first warehouses on the platform, Ocado shifted from virtual machines and Puppet infrastructure to Docker containers, using CoreOSs fleet scheduler to provision all the services on its OpenStack-based private cloud on bare metal. As the Smart Platform grew, and "fleet was going end-of-life," says Platform Engineer Mike Bryant, "we started looking for a more complete platform, with all of these disparate infrastructure services being brought together in one unified API."<br><br>
Bryant had already been using Kubernetes with <a href="https://www.codeforlife.education/">Code for Life</a>, a childrens education project thats part of Ocados charity arm. "We really liked it, so we started looking at it seriously for our production workloads," says Bryant. The team that managed fleet had researched orchestration solutions and landed on Kubernetes as well. "We were looking for a platform with wide adoption, and that was where the momentum was," says DevOps Team Leader Kevin McCormack. The two paths converged, and "We didnt even go through any proof-of-concept stage. The Code for Life work served that purpose," says Bryant.
</div>
</section>
<div class="banner3" style="background-image: url('/images/CaseStudy_ocado_banner3.jpg')">
<div class="banner3text">
"We were looking for a platform with wide adoption, and that was where the momentum was, the two paths converged, and we didnt even go through any proof-of-concept stage. The Code for Life work served that purpose," <span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br><br>- Kevin McCormack, DevOps Team Leader, Ocado</span>
</div>
</div>
<section class="section3">
<div class="fullcol">
In the summer of 2016, the team began migrating from fleet to <a href="https://kubernetes.io/">Kubernetes</a> on Ocados private cloud. The Kubernetes stack currently uses <a href="https://github.com/kubernetes/kubeadm">kubeadm</a> for bootstrapping, <a href="https://github.com/containernetworking">CNI</a> with <a href="https://www.weave.works/oss/net/">Weave Net</a> for networking, <a href="https://coreos.com/operators/prometheus/docs/latest/user-guides/getting-started.html">Prometheus Operator</a> for monitoring, <a href="https://www.fluentd.org/">Fluentd</a> for logging, and <a href="http://opentracing.io/">OpenTracing</a> for distributed tracing. <br><br>
The first app on Kubernetes, a business-critical service in the warehouses, went into production a year later. Once that app was running smoothly, a mass migration continued into 2018. Hundreds of Ocado engineers working on the Smart Platform are now deploying on Kubernetes, and the platform is live in Ocados warehouses, managing tens of thousands of orders a week. At full capacity, Ocados latest warehouse in Erith, southeast London, will deliver more than 200,000 orders per week, making it the worlds largest facility for online grocery. <br><br>
There are about 150 microservices now running on Kubernetes, with multiple instances of many of them. "Were not just deploying all these microservices at once. Were deploying them all for one warehouse, and then theyre all being deployed again for the next warehouse, and again and again," says Bryant.<br><br>
The move to Kubernetes was eye-opening for many people at Ocado Technology. "In the early days of putting the platform into our test infrastructure, the technical architect asked what network performance was like on <a href="https://www.weave.works/oss/net/">Weave Net</a> with encryption turned on," recalls Bryant. "So we found a Docker container for <a href="https://iperf.fr/">iPerf</a>, wrote a daemon set, deployed it. A few moments later, weve deployed the entire thing across this cluster. He was pretty blown away by that."
</div>
</section>
<div class="banner4" style="background-image: url('/images/CaseStudy_ocado_banner4.jpg')">
<div class="banner4text">
"The unified API of Kubernetes means this is all in one place, and its one flow for approval and rollout. Ive seen features go from development to production inside of a week now. In the old world, a new application deployment could easily take over a month." <span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br><br>- Mike Bryant, Platform Engineer, Ocado</span>
</div>
</div>
</div>
<section class="section5" style="padding:0px !important">
<div class="fullcol">
Indeed, the impact has been profound. "Prior to containerization, we had quite restrictive deployment windows in our warehouses," says Bryant. "Moving to microservices, weve been able to deploy much more frequently. Weve been able to move towards continuous delivery in a number of areas. In our older warehouse, new application deployments involve talking to a bunch of different teams for different levels of the stack: from VM provisioning, to storage, to load balancers, and so on. The unified API of Kubernetes means this is all in one place, and its one flow for approval and rollout. Ive seen features go from development to production inside of a week now. In the old world, a new application deployment could easily take over a month."<br><br>
The rate of deployment has gone from as few as two per week to dozens per week. "With Kubernetes, some of our development teams have been able to deploy their application to production on the new platform without us noticing," says Bryant, "which means theyre faster at doing what they need to do and we have less work."<br><br>
Ocado has also achieved cost savings because Kubernetes gives the team the ability to have more fine-grained resource allocation. "That lets us shrink quite a lot of our deployments from being per-core VM deployments to having fractions of the core," says Bryant. Adds McCormack: "We have more confidence in the resource allocation/separation features of Kubernetes, so we have been able to migrate from around 10 fleet clusters to one Kubernetes cluster. This means we use our hardware better since if we have to always have two nodes of excess capacity available in case of node failures then we only need two extra instead of 20."
</div>
<div class="banner5">
<div class="banner5text">
"CNCF have provided us with support of different technologies. Weve been able to adopt those in a very easy fashion. We do like that CNCF is vendor agnostic. Were not being asked to commit to this one way of doing things. The vast diversity of viewpoints in CNCF lead to better technology." <span style="font-size:14px;letter-spacing:2px;text-transform:uppercase;margin-top:5% !important;"><br><br>- Mike Bryant, Platform Engineer, Ocado</span>
</div>
</div>
<div class="fullcol">
The team also uses <a href="https://prometheus.io/">Prometheus</a> and <a href="https://grafana.com/">Grafana</a> to visualize resource allocation, and makes the data available to developers. "The increased visibility offered by Prometheus means developers are more aware of what they are using and how their use impacts others, especially since we now have one shared cluster," says McCormack. "Id estimate that we use about 15-25% less hardware resource to host the same applications in Kubernetes in our test environments."<br><br>
One of the broader benefits of cloud native, says Bryant, is the unified API. "We have one method of doing our deployments that covers the wide range of things we need to do, and we can extend the API," he says. In addition to using Prometheus Operator, the Ocado team has started writing its own operators, some of which have been <a href="https://github.com/ocadotechnology">open sourced</a>. Plus, "CNCF has provided us with support of these different technologies. Weve been able to adopt those in a very easy fashion. We do like that CNCF is vendor agnostic. Were not being asked to commit to this one way of doing things. The vast diversity of viewpoints in the CNCF leads to better technology."<br><br>
Ocados own technology, in the form of its Smart Platform, will soon be used <a href="http://fortune.com/2018/05/17/ocado-kroger-warehouse-automation-amazon-walmart/">around</a> the world. And cloud native plays a crucial role in this global expansion. "I wouldnt have wanted to try it without Kubernetes," says Bryant. "Kubernetes has made it so much nicer, especially to have that consistent way of deploying all of the applications, then taking the same thing and being able to replicate it. Its very valuable."
</div>
</section>
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

@@ -251,11 +251,11 @@ rules:
The following cloud providers have implemented CCMs:
* Digital Ocean
* [Digital Ocean](https://github.com/digitalocean/digitalocean-cloud-controller-manager)
* [Oracle](https://github.com/oracle/oci-cloud-controller-manager)
* Azure
* GCE
* AWS
* [Azure](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/azure)
* [GCE](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/gce)
* [AWS](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/aws)
## Cluster Administration
@@ -32,8 +32,6 @@ Before choosing a guide, here are some considerations:
Note: Not all distros are actively maintained. Choose distros which have been tested with a recent version of Kubernetes.
-If you are using a guide involving Salt, see [Configuring Kubernetes with Salt](/docs/setup/salt/).
## Managing a cluster
* [Managing a cluster](/docs/tasks/administer-cluster/cluster-management/) describes several topics related to the lifecycle of a cluster: creating a new cluster, upgrading your clusters master and worker nodes, performing node maintenance (e.g. kernel upgrades), and upgrading the Kubernetes API version of a running cluster.
@@ -71,15 +71,29 @@ A desired state of an object is described by a Deployment, and if changes to tha
## Container Images
- The default [imagePullPolicy](/docs/concepts/containers/images/#updating-images) for a container is `IfNotPresent`, which causes the [kubelet](/docs/admin/kubelet/) to pull an image only if it does not already exist locally. If you want the image to be pulled every time Kubernetes starts the container, specify `imagePullPolicy: Always`.
The [imagePullPolicy](/docs/concepts/containers/images/#updating-images) and the tag of the image affect when the [kubelet](/docs/admin/kubelet/) attempts to pull the specified image.
An alternative, but deprecated way to have Kubernetes always pull the image is to use the `:latest` tag, which will implicitly set the `imagePullPolicy` to `Always`.
- `imagePullPolicy: IfNotPresent`: the image is pulled only if it is not already present locally.
- `imagePullPolicy: Always`: the image is pulled every time the pod is started.
- `imagePullPolicy` is omitted and either the image tag is `:latest` or it is omitted: `Always` is applied.
- `imagePullPolicy` is omitted and the image tag is present but not `:latest`: `IfNotPresent` is applied.
- `imagePullPolicy: Never`: the image is assumed to exist locally. No attempt is made to pull the image.
{{< note >}}
**Note:** You should avoid using the `:latest` tag when deploying containers in production, because this makes it hard to track which version of the image is running and hard to roll back.
**Note:** To make sure the container always uses the same version of the image, you can specify its [digest](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier), for example `sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2`. The digest uniquely identifies a specific version of the image, so it is never updated by Kubernetes unless you change the digest value.
{{< /note >}}
- To make sure the container always uses the same version of the image, you can specify its [digest](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier) (for example `sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2`). This uniquely identifies a specific version of the image, so it will never be updated by Kubernetes unless you change the digest value.
{{< note >}}
**Note:** You should avoid using the `:latest` tag when deploying containers in production as it is harder to track which version of the image is running and more difficult to roll back properly.
{{< /note >}}
{{< note >}}
**Note:** The caching semantics of the underlying image provider make even `imagePullPolicy: Always` efficient. With Docker, for example, if the image already exists, the pull attempt is fast because all image layers are cached and no image download is needed.
{{< /note >}}
## Using kubectl
@@ -25,13 +25,11 @@ The default pull policy is `IfNotPresent` which causes the Kubelet to skip
pulling an image if it already exists. If you would like to always force a pull,
you can do one of the following:
- set the `imagePullPolicy` of the container to `Always`;
- use `:latest` as the tag for the image to use;
- set the `imagePullPolicy` of the container to `Always`.
- omit the `imagePullPolicy` and use `:latest` as the tag for the image to use.
- omit the `imagePullPolicy` and the tag for the image to use.
- enable the [AlwaysPullImages](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages) admission controller.
If you did not specify tag of your image, it will be assumed as `:latest`, with
pull image policy of `Always` correspondingly.
Note that you should avoid using `:latest` tag, see [Best Practices for Configuration](/docs/concepts/configuration/overview/#container-images) for more information.
## Using a Private Registry
@@ -95,6 +95,8 @@ In order for the Ingress resource to work, the cluster must have an Ingress cont
* [Traefik](https://github.com/containous/traefik) is a fully featured ingress controller
([Let's Encrypt](https://letsencrypt.org), secrets, http2, websocket...), and it also comes with commercial support by [Containous](https://containo.us/services)
* [NGINX, Inc.](https://www.nginx.com/) offers support and maintenance for the [NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx/kubernetes-ingress-controller)
* [HAProxy](http://www.haproxy.org/) based ingress controller [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress) which is mentioned on this blog post [HAProxy Ingress Controller for Kubernetes](https://www.haproxy.com/blog/haproxy_ingress_controller_for_kubernetes/)
* [Istio](https://istio.io/) based ingress controller [Control Ingress Traffic](https://istio.io/docs/tasks/traffic-management/ingress/)
{{< note >}}
**Note:** Review the documentation for your controller to find its specific support policy.
@@ -92,13 +92,70 @@ __egress__: Each `NetworkPolicy` may include a list of whitelist `egress` rules.
So, the example NetworkPolicy:
1. isolates "role=db" pods in the "default" namespace for both ingress and egress traffic (if they weren't already isolated)
2. allows connections to TCP port 6379 of "role=db" pods in the "default" namespace from any pod in the "default" namespace with the label "role=frontend"
3. allows connections to TCP port 6379 of "role=db" pods in the "default" namespace from any pod in a namespace with the label "project=myproject"
4. allows connections to TCP port 6379 of "role=db" pods in the "default" namespace from IP addresses that are in CIDR 172.17.0.0/16 and not in 172.17.1.0/24
5. allows connections from any pod in the "default" namespace with the label "role=db" to CIDR 10.0.0.0/24 on TCP port 5978
2. allows connections to TCP port 6379 of "role=db" pods in the "default" namespace from:
* any pod in the "default" namespace with the label "role=frontend"
* any pod in a namespace with the label "project=myproject"
* IP addresses in the ranges 172.17.0.0172.17.0.255 and 172.17.2.0172.17.255.255 (ie, all of 172.17.0.0/16 except 172.17.1.0/24)
3. allows connections from any pod in the "default" namespace with the label "role=db" to CIDR 10.0.0.0/24 on TCP port 5978
See the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/) walkthrough for further examples.
## Behavior of `to` and `from` selectors
There are four kinds of selectors that can be specified in an `ingress` `from` section or `egress` `to` section:
__podSelector__: This selects particular Pods in the same namespace as the `NetworkPolicy` which should be allowed as ingress sources or egress destinations.
__namespaceSelector__: This selects particular namespaces for which all Pods should be allowed as ingress sources or egress destinations.
__namespaceSelector__ *and* __podSelector__: A single `to`/`from` entry that specifies both `namespaceSelector` and `podSelector` selects particular Pods within particular namespaces. Be careful to use correct YAML syntax; this policy:
```yaml
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
```
contains a single `from` element allowing connections from Pods with the label `role=client` in namespaces with the label `user=alice`. But *this* policy:
```yaml
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...
```
contains two elements in the `from` array, and allows connections from Pods in the local Namespace with the label `role=client`, *or* from any Pod in any namespace with the label `user=alice`.
When in doubt, use `kubectl describe` to see how Kubernetes has interpreted the policy.
__ipBlock__: This selects particular IP CIDR ranges to allow as ingress sources or egress destinations. These should be cluster-external IPs, since Pod IPs are ephemeral and unpredictable.
Cluster ingress and egress mechanisms often require rewriting the source or destination IP
of packets. In cases where this happens, it is not defined whether this happens before or
after NetworkPolicy processing, and the behavior may be different for different
combinations of network plugin, cloud provider, `Service` implementation, etc.
In the case of ingress, this means that in some cases you may be able to filter incoming
packets based on the actual original source IP, while in other cases, the "source IP" that
the NetworkPolicy acts on may be the IP of a `LoadBalancer` or of the Pod's node, etc.
For egress, this means that connections from pods to `Service` IPs that get rewritten to
cluster-external IPs may or may not be subject to `ipBlock`-based policies.
## Default policies
By default, if no policies exist in a namespace, then all ingress and egress traffic is allowed to and from pods in that namespace. The following examples let you change the default behavior
@@ -383,18 +383,19 @@ A Kubernetes administrator can specify additional mount options for when a Persi
The following volume types support mount options:
* GCEPersistentDisk
* AWSElasticBlockStore
* AzureFile
* AzureDisk
* NFS
* iSCSI
* RBD (Ceph Block Device)
* AzureFile
* CephFS
* Cinder (OpenStack block storage)
* GCEPersistentDisk
* Glusterfs
* VsphereVolume
* NFS
* Quobyte Volumes
* RBD (Ceph Block Device)
* StorageOS
* VsphereVolume
* iSCSI
Mount options are not validated, so mount will simply fail if one is invalid.
@@ -514,7 +515,7 @@ metadata:
spec:
containers:
- name: myfrontend
image: dockerfile/nginx
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
+1 -1
View File
@@ -972,7 +972,7 @@ spec:
For more information including Dynamic Provisioning and Persistent Volume Claims, please see the
[StorageOS examples](https://github.com/kubernetes/examples/blob/master/staging/volumes/storageos).
### vsphereVolume {#vsphereVolume}
### vsphereVolume {#vspherevolume}
{{< note >}}
**Prerequisite:** Kubernetes with vSphere Cloud Provider configured. For cloudprovider
@@ -21,7 +21,7 @@ Some typical uses of a DaemonSet are:
- running a cluster storage daemon, such as `glusterd`, `ceph`, on each node.
- running a logs collection daemon on every node, such as `fluentd` or `logstash`.
- running a node monitoring daemon on every node, such as [Prometheus Node Exporter](
https://github.com/prometheus/node_exporter), `collectd`, Dynatrace OneAgent, Datadog agent, New Relic agent, or Ganglia `gmond`.
https://github.com/prometheus/node_exporter), `collectd`, Dynatrace OneAgent, Datadog agent, New Relic agent, Ganglia `gmond` or Instana agent.
In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon.
A more complex setup might use multiple DaemonSets for a single type of daemon, but with
@@ -116,136 +116,83 @@ need to work with someone who can set the label and milestone for you.
## Overview of update-imported-docs
The `update-imported-docs` tool performs these steps:
The website repository contains a `update-imported-docs` tool under the
`kubernetes/website/update-imported-docs/` directory that performs the
following steps:
1. Clone the `kubernetes/kubernetes` repository.
1. Run several scripts under `kubernetes/kubernetes/hack`. These scripts
generate Markdown files and place the files under `kubernetes/kubernetes/docs`.
1. Copy the generated Markdown files to a local clone of the `kubernetes/website`
repository under `kubernetes/website/docs/reference/generated`.
1. Clone the `kubernetes/federation` repository.
1. Run several scripts under `kubernetes/federation/hack`. These scripts
generate Markdown files and place the files under `kubernetes/federation/docs`.
1. Copy the generated Markdown files to a local clone of the `kubernetes/website`
repository under `kubernetes/website/docs/reference/generated`.
1. Clones the related repositories specified in a configuration file. For the
purpose of generating reference docs, the repositories that are cloned by
default are `kubernetes-incubator/reference-docs` and `kubernetes/federation`.
1. Runs commands under the cloned repositories to prepare the docs generator and
then generates the Markdown files.
1. Copies the generated Markdown files to a local clone of the `kubernetes/website`
repository under locations specified in the configuration file.
After the Markdown files are in your local clone of the `kubernetes/website`
When the Markdown files are in your local clone of the `kubernetes/website`
repository, you can submit them in a
[pull request](https://kubernetes.io/docs/home/contribute/create-pull-request/)
to `kubernetes/website`.
## Setting the branch
## Customizing the config file
Open `<web-base>/update-imported-docs/config.yaml` for editing.
Set the value of `branch` to the Kubernetes release that you want to document.
For example, if you want to generate docs for the Kubernetes 1.9 release,
set `branch` to `release-1.9`.
Open `<web-base>/update-imported-docs/reference.yaml` for editing.
Do not change the content for the `generate-command` entry unless you undertand
what it is doing and need to change the specified release branch.
```shell
repos:
- name: kubernetes
remote: https://github.com/kubernetes/kubernetes.git
branch: release-1.9
- name: reference-docs
remote: https://github.com/kubernetes-incubator/reference-docs.git
# This and the generate-command below needs a change when reference-docs has
# branches properly defined
branch: master
generate-command: |
cd $GOPATH
git clone https://github.com/kubernetes/kubernetes.git src/k8s.io/kubernetes
cd src/k8s.io/kubernetes
git checkout release-1.11
make generated_files
cp -L -R vendor $GOPATH/src
rm -r vendor
cd $GOPATH
go get -v github.com/kubernetes-incubator/reference-docs/gen-compdocs
cd src/github.com/kubernetes-incubator/reference-docs/
make comp
```
## Setting sources and destinations
The `update-imported-docs` tool uses `src` and `dst` fields in a configuration
to decide the source and target location for doc files to be copied.
For example:
The `update-imported-docs` tool uses `src` and `dst` fields
in `config.yaml` to know which files to copy from the `kubernetes/kubernetes`
repository and where to place those files in the `kubernetes/website`
repository.
For example, suppose you want the tool to copy the `kube-apiserver.md` file
from the `docs/admin` directory of the `kubernetes/kubernetes` repository
to the `docs/reference/generated/` directory of the `kubernetes/website`
repository. Then you would include a `src` and `dst` in your `config.yaml`
file like this:
```shell
```yaml
repos:
- name: kubernetes
remote: https://github.com/kubernetes/kubernetes.git
branch: release-1.9
- name: reference-docs
remote: https://github.com/kubernetes-incubator/reference-docs.git
files:
- src: docs/admin/kube-apiserver.md
dst: docs/reference/generated/kube-apiserver.md
- src: gen-compdocs/build/kube-apiserver.md
dst: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md
...
```
The configuration is similar for files in the `kubernetes/federation`
repository. Here's an example that configures the tool to copy `kubefed_init.md`
from the `docs/admin` directory of the `kubernetes/federation` repository
to the `docs/reference/generated` directory of the `kubernetes/website` repository:
Note that when there are many files to be copied from the same source directory
to the same destination directory, you can use wildcards in the value given to
`src` and you can just provide the directory name as the value for `dst`.
For example:
```shell
- name: federation
remote: https://github.com/kubernetes/federation.git
# # Change this to a release branch when federation has release branches.
branch: master
files:
- src: docs/admin/kubefed_init.md
dst: docs/reference/generated/kubefed_init.md
...
- src: gen-compdocs/build/kubeadm*.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/
```
Here's an example a `config.yaml` file that shows the sources and
destinations of all the Markdown files that were generated and copied
by the `update-imported-docs` tool at the beginning of the Kubernetes
1.9 release.
```shell
repos:
- name: kubernetes
remote: https://github.com/kubernetes/kubernetes.git
branch: release-1.9
files:
- src: docs/admin/cloud-controller-manager.md
dst: docs/reference/generated/cloud-controller-manager.md
- src: docs/admin/kube-apiserver.md
dst: docs/reference/generated/kube-apiserver.md
- src: docs/admin/kube-controller-manager.md
dst: docs/reference/generated/kube-controller-manager.md
- src: docs/admin/kubelet.md
dst: docs/reference/generated/kubelet.md
- src: docs/admin/kube-proxy.md
dst: docs/reference/generated/kube-proxy.md
- src: docs/admin/kube-scheduler.md
dst: docs/reference/generated/kube-scheduler.md
- src: docs/user-guide/kubectl/kubectl.md
dst: docs/reference/generated/kubectl/kubectl.md
- name: federation
remote: https://github.com/kubernetes/federation.git
# # Change this to a release branch when federation has release branches.
branch: master
files:
- src: docs/admin/federation-apiserver.md
dst: docs/reference/generated/federation-apiserver.md
- src: docs/admin/federation-controller-manager.md
dst: docs/reference/generated/federation-controller-manager.md
- src: docs/admin/kubefed_init.md
dst: docs/reference/generated/kubefed_init.md
- src: docs/admin/kubefed_join.md
dst: docs/reference/generated/kubefed_join.md
- src: docs/admin/kubefed.md
dst: docs/reference/generated/kubefed.md
- src: docs/admin/kubefed_options.md
dst: docs/reference/generated/kubefed_options.md
- src: docs/admin/kubefed_unjoin.md
dst: docs/reference/generated/kubefed_unjoin.md
- src: docs/admin/kubefed_version.md
dst: docs/reference/generated/kubefed_version.md
```
## Running the update-imported-docs tool
Now that your `config.yaml` file contains your sources and destinations,
you can run the `update-imported-docs` tool:
After having reviewed and/or customized the `reference.yaml` file, you can run
the `update-imported-docs` tool:
```shell
cd <web-base>
go get ./update-imported-docs
go run update-imported-docs/update-imported-docs.go
cd <web-base>/update-imported-docs
./update-imported-docs reference.yml
```
## Adding and committing changes in kubernetes/website
@@ -263,21 +210,15 @@ might look like this:
```shell
...
modified: docs/reference/generated/cloud-controller-manager.md
modified: docs/reference/generated/federation-apiserver.md
modified: docs/reference/generated/federation-controller-manager.md
modified: docs/reference/generated/kube-apiserver.md
modified: docs/reference/generated/kube-controller-manager.md
modified: docs/reference/generated/kube-proxy.md
modified: docs/reference/generated/kube-scheduler.md
modified: docs/reference/generated/kubectl/kubectl.md
modified: docs/reference/generated/kubefed.md
modified: docs/reference/generated/kubefed_init.md
modified: docs/reference/generated/kubefed_join.md
modified: docs/reference/generated/kubefed_options.md
modified: docs/reference/generated/kubefed_unjoin.md
modified: docs/reference/generated/kubefed_version.md
modified: docs/reference/generated/kubelet.md
modified: content/en/docs/reference/command-line-tools-reference/cloud-controller-manager.md
modified: content/en/docs/reference/command-line-tools-reference/federation-apiserver.md
modified: content/en/docs/reference/command-line-tools-reference/federation-controller-manager.md
modified: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md
modified: content/en/docs/reference/command-line-tools-reference/kube-controller-manager.md
modified: content/en/docs/reference/command-line-tools-reference/kube-proxy.md
modified: content/en/docs/reference/command-line-tools-reference/kube-scheduler.md
...
```
Run `git add` and `git commit` to commit the files.
@@ -303,4 +244,3 @@ topics will be visible in the
{{% /capture %}}
@@ -730,6 +730,7 @@ the techniques described in
[Commit into another person's PR](#commit-into-another-persons-pr).
If you need to write a new topic, the following links are useful:
- [Writing a New Topic](/docs/contribute/style/write-new-topic/)
- [Using Page Templates](/docs/contribute/style/page-templates/)
- [Documentation Style Guide](/docs/contribute/style/style-guide/)
@@ -764,6 +765,11 @@ deadlines. Some deadlines related to documentation are:
documentation and the docs are not ready, the feature may be removed from the
milestone.
If your feature is an Alpha feature and is behind a feature gate, make sure you
add it to [Feature gates](/docs/reference/command-line-tools-reference/feature-gates/)
as part of your pull request. If your feature is moving out of Alpha, make sure to
remove it from that file.
## Contribute to other repos
The [Kubernetes project](https://github.com/kubernetes) contains more than 50
+1 -1
View File
@@ -28,7 +28,7 @@ The Kubernetes documentation is written in Markdown and processed and deployed
using Hugo. The source is in Github at
[https://github.com/kubernetes/website](https://github.com/kubernetes/website).
Most of the documentation source is stored in `/content/en/docs/`. Some of the
reference documentation is automatically generated from scripts, mostly in the
reference documentation is automatically generated from scripts in the
`update-imported-docs/` directory.
You can file issues, edit content, and review changes from others, all from the
@@ -81,6 +81,20 @@ The Kubernetes API server flag `disable-admission-plugins` takes a comma-delimit
kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny ...
```
## Which plugins are enabled by default?
To see which admission plugins are enabled:
```shell
kube-apiserver -h | grep enable-admission-plugins
```
In 1.11, they are:
```shell
NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,Priority
```
## What does each admission controller do?
### AlwaysAdmit (DEPRECATED) {#alwaysadmit}
@@ -342,7 +342,7 @@ Setup instructions for specific systems:
The first option is to use the kubectl `oidc` authenticator, which sets the `id_token` as a bearer token for all requests and refreshes the token once it expires. After you've logged into your provider, use kubectl to add your `id_token`, `refresh_token`, `client_id`, and `client_secret` to configure the plugin.
Providers that don't return an `id_token` as part of their refresh token response (e.g. [Okta](https://developer.okta.com/docs/api/resources/oidc.html#response-parameters-4)) aren't supported by this plugin and should use "Option 2" below.
Providers that don't return an `id_token` as part of their refresh token response aren't supported by this plugin and should use "Option 2" below.
```bash
kubectl config set-credentials USER_NAME \
@@ -452,7 +452,7 @@ Auto-reconciliation is enabled in Kubernetes version 1.6+ when the RBAC authoriz
### Discovery Roles
Default role bindings authorize unauthenticated and authenticated users to read API information that is deemed safe to be publicly accessible. To disable anonymous unauthenticated access add `--anonymous-auth=false` to the API server configuration.
Default role bindings authorize unauthenticated and authenticated users to read API information that is deemed safe to be publicly accessible (including CustomResourceDefinitions). To disable anonymous unauthenticated access add `--anonymous-auth=false` to the API server configuration.
To view the configuration of these roles via `kubectl` run:
@@ -114,6 +114,9 @@ For more details on each field in the configuration you can navigate to our
For information about kube-proxy parameters in the kubeadm configuration see:
- [kube-proxy](https://godoc.org/k8s.io/kubernetes/pkg/proxy/apis/config#KubeProxyConfiguration)
For information about enabling IPVS mode with kubeadm see:
- [IPVS](https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/ipvs/README.md)
### Passing custom flags to control plane components {#control-plane-flags}
For information about passing flags to control plane components see:
@@ -5,13 +5,19 @@ content_template: templates/concept
{{% capture overview %}}
This quickstart helps to install a Kubernetes cluster hosted on GCE, Azure, OpenStack, AWS, or Baremetal with [Kubespray](https://github.com/kubernetes-incubator/kubespray).
This quickstart helps to install a Kubernetes cluster hosted on GCE, Azure, OpenStack, AWS, vSphere, Oracle Cloud Infrastructure (Experimental) or Baremetal with [Kubespray](https://github.com/kubernetes-incubator/kubespray).
Kubespray is a composition of [Ansible](http://docs.ansible.com/) playbooks, [inventory](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/ansible.md), provisioning tools, and domain knowledge for generic OS/Kubernetes clusters configuration management tasks. Kubespray provides:
* a highly available cluster
* composable attributes
* support for most popular Linux distributions (CoreOS, Debian Jessie, Ubuntu 16.04, CentOS/RHEL 7, Fedora/CentOS Atomic)
* support for most popular Linux distributions
* Container Linux by CoreOS
* Debian Jessie, Stretch, Wheezy
* Ubuntu 16.04, 18.04
* CentOS/RHEL 7
* Fedora/CentOS Atomic
* openSUSE Leap 42.3/Tumbleweed
* continuous integration tests
To choose a tool which best fits your use case, read [this comparison](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/comparisons.md) to [kubeadm](/docs/admin/kubeadm/) and [kops](../kops).
@@ -48,12 +54,16 @@ After you provision your servers, create an [inventory file for Ansible](http://
Kubespray provides the ability to customize many aspects of the deployment:
* Choice deployment mode: kubeadm or non-kubeadm
* CNI (networking) plugins
* DNS configuration
* Choice of control plane: native/binary or containerized with docker or rkt)
* Choice of control plane: native/binary or containerized with docker or rkt
* Component versions
* Calico route reflectors
* Component runtime options
* docker
* rkt
* cri-o
* Certificate generation methods
Kubespray customizations can be made to a [variable file](http://docs.ansible.com/ansible/playbooks_variables.html). If you are just getting started with Kubespray, consider using the Kubespray defaults to deploy your cluster and explore Kubernetes.
@@ -261,7 +261,7 @@ Please select one of the tabs to see installation instructions for the respectiv
{{% tab name="Calico" %}}
For more information about using Calico, see [Quickstart for Calico on Kubernetes](https://docs.projectcalico.org/latest/getting-started/kubernetes/), [Installing Calico for policy and networking](https://docs.projectcalico.org/latest/getting-started/kubernetes/installation/calico), and other related resources.
In order for Network Policy to work correctly, you need to pass `--pod-network-cidr=192.168.0.0/16` to `kubeadm init`. Note that Calico works on `amd64` only.
For Calico to work correctly, you need to pass `--pod-network-cidr=192.168.0.0/16` to `kubeadm init` or update the `calico.yml` file to match your Pod network. Note that Calico works on `amd64` only.
```shell
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
@@ -279,6 +279,35 @@ kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/canal.yaml
```
{{% /tab %}}
{{% tab name="Cilium" %}}
For more information about using Cilium with Kubernetes, see [Quickstart for Cilium on Kubernetes](http://docs.cilium.io/en/v1.2/kubernetes/quickinstall/) and [Kubernetes Install guide for Cilium](http://docs.cilium.io/en/v1.2/kubernetes/install/).
Passing `--pod-network-cidr` option to `kubeadm init` is not required, but highly recommended.
These commands will deploy Cilium with its own etcd managed by etcd operator.
```shell
# Download required manifests from Cilium repository
wget https://github.com/cilium/cilium/archive/v1.2.0.zip
unzip v1.2.0.zip
cd cilium-1.2.0/examples/kubernetes/addons/etcd-operator
# Generate and deploy etcd certificates
export CLUSTER_DOMAIN=$(kubectl get ConfigMap --namespace kube-system coredns -o yaml | awk '/kubernetes/ {print $2}')
tls/certs/gen-cert.sh $CLUSTER_DOMAIN
tls/deploy-certs.sh
# Label kube-dns with fixed identity label
kubectl label -n kube-system pod $(kubectl -n kube-system get pods -l k8s-app=kube-dns -o jsonpath='{range .items[]}{.metadata.name}{" "}{end}') io.cilium.fixed-identity=kube-dns
kubectl create -f ./
# Wait several minutes for Cilium, coredns and etcd pods to converge to a working state
```
{{% /tab %}}
{{% tab name="Flannel" %}}
@@ -74,30 +74,30 @@ run as root.
1. Enable ssh-agent on your main device that has access to all other nodes in
the system:
```
eval $(ssh-agent)
```
```
eval $(ssh-agent)
```
1. Add your SSH identity to the session:
```
ssh-add ~/.ssh/path_to_private_key
```
```
ssh-add ~/.ssh/path_to_private_key
```
1. SSH between nodes to check that the connection is working correctly.
- When you SSH to any node, make sure to add the `-A` flag:
```
ssh -A 10.0.0.7
```
```
ssh -A 10.0.0.7
```
- When using sudo on any node, make sure to preserve the environment so SSH
forwarding works:
```
sudo -E -s
```
```
sudo -E -s
```
### Create load balancer for kube-apiserver
@@ -260,54 +260,54 @@ done
1. Move the copied files to the correct locations:
```sh
USER=ubuntu # customizable
mkdir -p /etc/kubernetes/pki/etcd
mv /home/${USER}/ca.crt /etc/kubernetes/pki/
mv /home/${USER}/ca.key /etc/kubernetes/pki/
mv /home/${USER}/sa.pub /etc/kubernetes/pki/
mv /home/${USER}/sa.key /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/
mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key
mv /home/${USER}/admin.conf /etc/kubernetes/admin.conf
```
```sh
USER=ubuntu # customizable
mkdir -p /etc/kubernetes/pki/etcd
mv /home/${USER}/ca.crt /etc/kubernetes/pki/
mv /home/${USER}/ca.key /etc/kubernetes/pki/
mv /home/${USER}/sa.pub /etc/kubernetes/pki/
mv /home/${USER}/sa.key /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/
mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key
mv /home/${USER}/admin.conf /etc/kubernetes/admin.conf
```
1. Run the kubeadm phase commands to bootstrap the kubelet:
```sh
kubeadm alpha phase certs all --config kubeadm-config.yaml
kubeadm alpha phase kubelet config write-to-disk --config kubeadm-config.yaml
kubeadm alpha phase kubelet write-env-file --config kubeadm-config.yaml
kubeadm alpha phase kubeconfig kubelet --config kubeadm-config.yaml
systemctl start kubelet
```
```sh
kubeadm alpha phase certs all --config kubeadm-config.yaml
kubeadm alpha phase kubelet config write-to-disk --config kubeadm-config.yaml
kubeadm alpha phase kubelet write-env-file --config kubeadm-config.yaml
kubeadm alpha phase kubeconfig kubelet --config kubeadm-config.yaml
systemctl start kubelet
```
1. Run the commands to add the node to the etcd cluster:
```sh
export CP0_IP=10.0.0.7
export CP0_HOSTNAME=cp0
export CP1_IP=10.0.0.8
export CP1_HOSTNAME=cp1
```sh
export CP0_IP=10.0.0.7
export CP0_HOSTNAME=cp0
export CP1_IP=10.0.0.8
export CP1_HOSTNAME=cp1
export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl exec -n kube-system etcd-${CP0_HOSTNAME} -- etcdctl --ca-file /etc/kubernetes/pki/etcd/ca.crt --cert-file /etc/kubernetes/pki/etcd/peer.crt --key-file /etc/kubernetes/pki/etcd/peer.key --endpoints=https://${CP0_IP}:2379 member add ${CP1_HOSTNAME} https://${CP1_IP}:2380
kubeadm alpha phase etcd local --config kubeadm-config.yaml
```
export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl exec -n kube-system etcd-${CP0_HOSTNAME} -- etcdctl --ca-file /etc/kubernetes/pki/etcd/ca.crt --cert-file /etc/kubernetes/pki/etcd/peer.crt --key-file /etc/kubernetes/pki/etcd/peer.key --endpoints=https://${CP0_IP}:2379 member add ${CP1_HOSTNAME} https://${CP1_IP}:2380
kubeadm alpha phase etcd local --config kubeadm-config.yaml
```
- This command causes the etcd cluster to become unavailable for a
- This command causes the etcd cluster to become unavailable for a
brief period, after the node is added to the running cluster, and before the
new node is joined to the etcd cluster.
1. Deploy the control plane components and mark the node as a master:
```sh
kubeadm alpha phase kubeconfig all --config kubeadm-config.yaml
kubeadm alpha phase controlplane all --config kubeadm-config.yaml
kubeadm alpha phase mark-master --config kubeadm-config.yaml
```
```sh
kubeadm alpha phase kubeconfig all --config kubeadm-config.yaml
kubeadm alpha phase controlplane all --config kubeadm-config.yaml
kubeadm alpha phase mark-master --config kubeadm-config.yaml
```
### Add the third stacked control plane node
@@ -351,50 +351,50 @@ done
1. Move the copied files to the correct locations:
```sh
USER=ubuntu # customizable
mkdir -p /etc/kubernetes/pki/etcd
mv /home/${USER}/ca.crt /etc/kubernetes/pki/
mv /home/${USER}/ca.key /etc/kubernetes/pki/
mv /home/${USER}/sa.pub /etc/kubernetes/pki/
mv /home/${USER}/sa.key /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/
mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key
mv /home/${USER}/admin.conf /etc/kubernetes/admin.conf
```
```sh
USER=ubuntu # customizable
mkdir -p /etc/kubernetes/pki/etcd
mv /home/${USER}/ca.crt /etc/kubernetes/pki/
mv /home/${USER}/ca.key /etc/kubernetes/pki/
mv /home/${USER}/sa.pub /etc/kubernetes/pki/
mv /home/${USER}/sa.key /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/
mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key
mv /home/${USER}/admin.conf /etc/kubernetes/admin.conf
```
1. Run the kubeadm phase commands to bootstrap the kubelet:
```sh
kubeadm alpha phase certs all --config kubeadm-config.yaml
kubeadm alpha phase kubelet config write-to-disk --config kubeadm-config.yaml
kubeadm alpha phase kubelet write-env-file --config kubeadm-config.yaml
kubeadm alpha phase kubeconfig kubelet --config kubeadm-config.yaml
systemctl start kubelet
```
```sh
kubeadm alpha phase certs all --config kubeadm-config.yaml
kubeadm alpha phase kubelet config write-to-disk --config kubeadm-config.yaml
kubeadm alpha phase kubelet write-env-file --config kubeadm-config.yaml
kubeadm alpha phase kubeconfig kubelet --config kubeadm-config.yaml
systemctl start kubelet
```
1. Run the commands to add the node to the etcd cluster:
```sh
export CP0_IP=10.0.0.7
export CP0_HOSTNAME=cp0
export CP2_IP=10.0.0.9
export CP2_HOSTNAME=cp2
```sh
export CP0_IP=10.0.0.7
export CP0_HOSTNAME=cp0
export CP2_IP=10.0.0.9
export CP2_HOSTNAME=cp2
export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl exec -n kube-system etcd-${CP0_HOSTNAME} -- etcdctl --ca-file /etc/kubernetes/pki/etcd/ca.crt --cert-file /etc/kubernetes/pki/etcd/peer.crt --key-file /etc/kubernetes/pki/etcd/peer.key --endpoints=https://${CP0_IP}:2379 member add ${CP2_HOSTNAME} https://${CP2_IP}:2380
kubeadm alpha phase etcd local --config kubeadm-config.yaml
```
export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl exec -n kube-system etcd-${CP0_HOSTNAME} -- etcdctl --ca-file /etc/kubernetes/pki/etcd/ca.crt --cert-file /etc/kubernetes/pki/etcd/peer.crt --key-file /etc/kubernetes/pki/etcd/peer.key --endpoints=https://${CP0_IP}:2379 member add ${CP2_HOSTNAME} https://${CP2_IP}:2380
kubeadm alpha phase etcd local --config kubeadm-config.yaml
```
1. Deploy the control plane components and mark the node as a master:
```sh
kubeadm alpha phase kubeconfig all --config kubeadm-config.yaml
kubeadm alpha phase controlplane all --config kubeadm-config.yaml
kubeadm alpha phase mark-master --config kubeadm-config.yaml
```
```sh
kubeadm alpha phase kubeconfig all --config kubeadm-config.yaml
kubeadm alpha phase controlplane all --config kubeadm-config.yaml
kubeadm alpha phase mark-master --config kubeadm-config.yaml
```
## External etcd
@@ -86,6 +86,7 @@ few commands. These solutions are actively developed and have active community s
* [Tectonic by CoreOS](https://coreos.com/tectonic)
* [CenturyLink Cloud](/docs/setup/turnkey/clc/)
* [IBM Cloud](https://github.com/patrocinio/kubernetes-softlayer)
* [IBM Cloud Private Running on Multiple Clouds](https://www.ibm.com/developerworks/community/wikis/home?lang=en-us#!/wiki/W1559b1be149d_43b0_881e_9783f38faaff/page/IBM%20Cloud%20Private%20running%20on%20multiple%20clouds)
* [Stackpoint.io](/docs/setup/turnkey/stackpoint/)
* [Madcore.Ai](https://madcore.ai/)
* [Kubermatic](https://cloud.kubermatic.io)
@@ -183,6 +184,7 @@ Madcore.Ai | Jenkins DSL | Ubuntu | flannel | [docs](https://madc
Platform9 | | multi-support | multi-support | [docs](https://platform9.com/managed-kubernetes/) | Commercial
Kublr | custom | multi-support | multi-support | [docs](http://docs.kublr.com/) | Commercial
Kubermatic | | multi-support | multi-support | [docs](http://docs.kubermatic.io/) | Commercial
IBM Cloud Kubernetes Service | | Ubuntu | IBM Cloud Networking + Calico | [docs](https://console.bluemix.net/docs/containers/) | Commercial
Giant Swarm | | CoreOS | flannel and/or Calico | [docs](https://docs.giantswarm.io/) | Commercial
GCE | Saltstack | Debian | GCE | [docs](/docs/setup/turnkey/gce/) | Project
Azure Kubernetes Service | | Ubuntu | Azure | [docs](https://docs.microsoft.com/en-us/azure/aks/) | Commercial
+21 -19
View File
@@ -5,7 +5,7 @@ content_template: templates/concept
{{% capture overview %}}
[Documentation](https://docs.k8s.io) & [Examples](https://releases.k8s.io/release-1.11/examples)
[Documentation](https://docs.k8s.io) & [Examples](https://github.com/kubernetes/examples)
## Downloads for v1.11.0
@@ -200,24 +200,26 @@ or `/etc/sysconfig/kubelet`, depending on the system you're running on.
The following PRs changed the API spec:
* In the new v1alpha2 kubeadm Configuration API, the `.CloudProvider` and `.PrivilegedPods` fields don't exist anymore. Instead, you should use the out-of-tree cloud provider implementations, which are beta in v1.11.
* If you have to use the legacy in-tree cloud providers, you can rearrange your config like the example below. If you need the `cloud-config` file (located in `{cloud-config-path}`), you can mount it into the API Server and controller-manager containers using ExtraVolumes, as in:
```yaml
kind: MasterConfiguration
apiVersion: kubeadm.k8s.io/v1alpha2
apiServerExtraArgs:
cloud-provider: "{cloud}"
cloud-config: "{cloud-config-path}"
apiServerExtraVolumes:
- name: cloud
hostPath: "{cloud-config-path}"
mountPath: "{cloud-config-path}"
controllerManagerExtraArgs:
cloud-provider: "{cloud}"
cloud-config: "{cloud-config-path}"
controllerManagerExtraVolumes:
- name: cloud
hostPath: "{cloud-config-path}"
mountPath: "{cloud-config-path}"
```
kind: MasterConfiguration
apiVersion: kubeadm.k8s.io/v1alpha2
apiServerExtraArgs:
cloud-provider: "{cloud}"
cloud-config: "{cloud-config-path}"
apiServerExtraVolumes:
- name: cloud
hostPath: "{cloud-config-path}"
mountPath: "{cloud-config-path}"
controllerManagerExtraArgs:
cloud-provider: "{cloud}"
cloud-config: "{cloud-config-path}"
controllerManagerExtraVolumes:
- name: cloud
hostPath: "{cloud-config-path}"
mountPath: "{cloud-config-path}"
* If you need to use the `.PrivilegedPods` functionality, you can still edit the manifests in `/etc/kubernetes/manifests/`, and set `.SecurityContext.Privileged=true` for the apiserver and controller manager.
([#63866](https://github.com/kubernetes/kubernetes/pull/63866), [@luxas](https://github.com/luxas))
* kubeadm: The Token-related fields in the `MasterConfiguration` object have now been refactored. Instead of the top-level `.Token`, `.TokenTTL`, `.TokenUsages`, `.TokenGroups` fields, there is now a `BootstrapTokens` slice of `BootstrapToken` objects that support the same features under the `.Token`, `.TTL`, `.Usages`, `.Groups` fields. ([#64408](https://github.com/kubernetes/kubernetes/pull/64408), [@luxas](https://github.com/luxas))
+2 -2
View File
@@ -465,7 +465,7 @@ traffic to the internet, but have no problem with them inside your GCE Project.
The previous steps all involved "conventional" system administration techniques for setting up
machines. You may want to use a Configuration Management system to automate the node configuration
process. There are examples of [Saltstack](/docs/setup/salt/), Ansible, Juju, and CoreOS Cloud Config in the
process. There are examples of Ansible, Juju, and CoreOS Cloud Config in the
various Getting Started Guides.
## Bootstrapping the Cluster
@@ -865,7 +865,7 @@ pinging or SSH-ing from one node to another.
### Getting Help
If you run into trouble, see the section on [troubleshooting](/docs/setup/turnkey/gce/#troubleshooting), post to the
[kubernetes-users group](https://groups.google.com/forum/#!forum/kubernetes-users), or come ask questions on [Slack](/docs/troubleshooting#slack).
[Kubernetes Forum](https://discuss.kubernetes.io), or come ask questions on [Slack](/docs/troubleshooting#slack).
## Support Level
+1 -1
View File
@@ -71,7 +71,7 @@ cluster/kube-up.sh
If you want more than one cluster running in your project, want to use a different name, or want a different number of worker nodes, see the `<kubernetes>/cluster/gce/config-default.sh` file for more fine-grained configuration before you start up your cluster.
If you run into trouble, please see the section on [troubleshooting](/docs/setup/turnkey/gce/#troubleshooting), post to the
[kubernetes-users group](https://groups.google.com/forum/#!forum/kubernetes-users), or come ask questions on [Slack](/docs/troubleshooting/#slack).
[Kubernetes Forum](https://discuss.kubernetes.io), or come ask questions on [Slack](/docs/troubleshooting/#slack).
The next few steps will show you:
@@ -42,9 +42,9 @@ with the flag `--cluster-domain=<default-local-domain>`.
The DNS server supports forward lookups (A records), port lookups (SRV records), reverse IP address lookups (PTR records),
and more. For more information see [DNS for Services and Pods] (/docs/concepts/services-networking/dns-pod-service/).
When running a Pod, kubelet prepends the cluster DNS server and searches
paths to the node's DNS settings. If the node is able to resolve DNS names
specific to the larger environment, Pods should also be able to resolve.
If a Pod's `dnsPolicy` is set to "`default`", it inherits the name resolution
configuration from the node that the Pod runs on. The Pod's DNS resolution
should behave the same as the node.
But see [Known issues](/docs/tasks/administer-cluster/dns-debugging-resolution/#known-issues).
If you don't want this, or if you want a different DNS config for pods, you can
@@ -33,7 +33,7 @@ Verify that the weave works.
Enter the following command:
```shell
kubectl get po -n kube-system -o wide
kubectl get pods -n kube-system -o wide
```
The output is similar to this:
@@ -65,7 +65,7 @@ Kubernetes cluster but inside the same GCP region.
{{% capture prerequisites %}}
This document assumes that you have a running Kubernetes Cluster
Federation installation. If not, then see the
[federation admin guide](/docs/admin/federation/) to learn how to
[federation admin guide](/docs/tasks/federation/set-up-cluster-federation-kubefed/) to learn how to
bring up a cluster federation (or have your cluster administrator do
this for you). Other tutorials, for example
[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation)
@@ -193,7 +193,7 @@ myregistrykey   kubernetes.io/.dockerconfigjson   1       1d
Next, modify the default service account for the namespace to use this secret as an imagePullSecret.
```shell
kubectl patch serviceaccount default -p '{\"imagePullSecrets\": [{\"name\": \"myregistrykey\"}]}'
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
```
Interactive version requiring manual edit:
@@ -181,7 +181,7 @@ crictl exec -i -t 1f73f2d81bf98 ls
bin dev etc home proc root sys tmp usr var
```
### Get a coontainer's logs
### Get a container's logs
Get all container logs:
@@ -623,7 +623,7 @@ us know, so we can help investigate!
Contact us on
[Slack](/docs/troubleshooting/#slack) or
[email](https://groups.google.com/forum/#!forum/kubernetes-users) or
[Forum](https://discuss.kubernetes.io) or
[GitHub](https://github.com/kubernetes/kubernetes).
{{% /capture %}}
@@ -91,8 +91,10 @@ This video shows how to configure and run a Google Cloud Monitoring backed Heaps
### Dynatrace Kubernetes monitoring
With [Dynatrace Kubernetes monitoring](https://www.dynatrace.com/technologies/cloud-and-microservices/kubernetes-monitoring/), you can monitor application and cluster health in highly-dynamic Kubernetes environments.
With [Dynatrace Kubernetes monitoring](https://www.dynatrace.com/technologies/kubernetes-monitoring/), you can monitor application and cluster health in highly-dynamic Kubernetes environments.
Dynatrace automatically discovers all containers running on Kubernetes and presents you with a real-time view of all the connections between your containerized processes, hosts, and cloud instances. Dynatrace includes root cause analysis and the ability to replay problems to see how they evolved over time.
{{< figure src="/images/docs/dynatrace.png" alt="Dynatrace Kubernetes monitoring dashboard example" title="Dynatrace Kubernetes monitoring dashboard example" caption="This dashboard shows a Node overview." >}}
{{% /capture %}}
@@ -84,9 +84,9 @@ these channels for localized support and info:
- Spain: `#es-users`
- Turkey: `#tr-users`, `#tr-events`
### Mailing List
### Forum
The Kubernetes / Google Kubernetes Engine mailing list is [kubernetes-users@googlegroups.com](https://groups.google.com/forum/#!forum/kubernetes-users)
The Kubernetes Official Forum [discuss.kubernetes.io](https://discuss.kubernetes.io)
### Bugs and Feature requests
@@ -134,7 +134,7 @@ For example, `KUBECTL_PLUGINS_GLOBAL_FLAG_NAMESPACE`, `KUBECTL_PLUGINS_GLOBAL_FL
{{% capture whatsnext %}}
* Check the repository for [some more examples](https://github.com/kubernetes/kubernetes/tree/master/pkg/kubectl/plugins/examples) of plugins.
* Check the repository for [some more examples](https://github.com/kubernetes/kubernetes/tree/release-1.11/pkg/kubectl/plugins/examples) of plugins.
* In case of any questions, feel free to reach out to the [CLI SIG team](https://github.com/kubernetes/community/tree/master/sig-cli).
* Binary plugins is still an alpha feature, so this is the time to contribute ideas and improvements to the codebase. We're also excited to hear about what you're planning to implement with plugins, so [let us know](https://github.com/kubernetes/community/tree/master/sig-cli)!
@@ -22,7 +22,6 @@ This page shows how to delete Pods which are part of a stateful set, and explain
{{% capture steps %}}
## StatefulSet considerations
In normal operation of a StatefulSet, there is **never** a need to force delete a StatefulSet Pod. The StatefulSet controller is responsible for creating, scaling and deleting members of the StatefulSet. It tries to ensure that the specified number of Pods from ordinal 0 through N-1 are alive and ready. StatefulSet ensures that, at any time, there is at most one Pod with a given identity running in a cluster. This is referred to as *at most one* semantics provided by a StatefulSet.
@@ -79,8 +78,6 @@ Always perform force deletion of StatefulSet Pods carefully and with complete kn
{{% capture whatsnext %}}
Learn more about [debugging a StatefulSet](/docs/tasks/manage-stateful-set/debugging-a-statefulset/).
Learn more about [debugging a StatefulSet](/docs/tasks/debug-application-cluster/debug-stateful-set/).
{{% /capture %}}
@@ -13,29 +13,28 @@ weight: 50
---
{{% capture overview %}}
This page shows how to scale a StatefulSet.
This task shows how to scale a StatefulSet. Scaling a StatefulSet refers to increasing or decreasing the number of replicas.
{{% /capture %}}
{{% capture prerequisites %}}
* StatefulSets are only available in Kubernetes version 1.5 or later.
* **Not all stateful applications scale nicely.** You need to understand your StatefulSets well before continuing. If you're unsure, remember that it might not be safe to scale your StatefulSets.
* You should perform scaling only when you're sure that your stateful application
To check your version of Kubernetes, run `kubectl version`.
* Not all stateful applications scale nicely. If you are unsure about whether to scale your StatefulSets, see [StatefulSet concepts](/docs/concepts/workloads/controllers/statefulset/) or [StatefulSet tutorial](/docs/tutorials/stateful-application/basic-stateful-set/) for futher information.
* You should perform scaling only when you are confident that your stateful application
cluster is completely healthy.
{{% /capture %}}
{{% capture steps %}}
## Use `kubectl` to scale StatefulSets
## Scaling StatefulSets
Make sure you have `kubectl` upgraded to Kubernetes version 1.5 or later before
continuing. If you're unsure, run `kubectl version` and check `Client Version`
for which kubectl you're using.
### Use kubectl to scale StatefulSets
### `kubectl scale`
First, find the StatefulSet you want to scale. Remember, you need to first understand if you can scale it or not.
First, find the StatefulSet you want to scale.
```shell
kubectl get statefulsets <stateful-set-name>
@@ -47,7 +46,7 @@ Change the number of replicas of your StatefulSet:
kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
```
### Alternative: `kubectl apply` / `kubectl edit` / `kubectl patch`
### Make in-place updates on your StatefulSets
Alternatively, you can do [in-place updates](/docs/concepts/cluster-administration/manage-deployment/#in-place-updates-of-resources) on your StatefulSets.
@@ -72,32 +71,29 @@ kubectl patch statefulsets <stateful-set-name> -p '{"spec":{"replicas":<new-repl
## Troubleshooting
### Scaling down doesn't work right
### Scaling down does not work right
You cannot scale down a StatefulSet when any of the stateful Pods it manages is unhealthy. Scaling down only takes place
after those stateful Pods become running and ready.
With a StatefulSet of size > 1, if there is an unhealthy Pod, there is no way
for Kubernetes to know (yet) if it is due to a permanent fault or a transient
one (upgrade/maintenance/node reboot). If the Pod is unhealthy due to a permanent fault, scaling
If spec.replicas > 1, Kubernetes cannot determine the reason for an unhealthy Pod. It might be the result of a permanent fault or of a transient fault. A transient fault can be caused by a restart required by upgrading or maintenance.
If the Pod is unhealthy due to a permanent fault, scaling
without correcting the fault may lead to a state where the StatefulSet membership
drops below a certain minimum number of "replicas" that are needed to function
drops below a certain minimum number of replicas that are needed to function
correctly. This may cause your StatefulSet to become unavailable.
If the Pod is unhealthy due to a transient fault and the Pod might become available again,
the transient error may interfere with your scale-up/scale-down operation. Some distributed
the transient error may interfere with your scale-up or scale-down operation. Some distributed
databases have issues when nodes join and leave at the same time. It is better
to reason about scaling operations at the application level in these cases, and
perform scaling only when you're sure that your stateful application cluster is
perform scaling only when you are sure that your stateful application cluster is
completely healthy.
{{% /capture %}}
{{% capture whatsnext %}}
Learn more about [deleting a StatefulSet](/docs/tasks/manage-stateful-set/deleting-a-statefulset/).
* Learn more about [deleting a StatefulSet](/docs/tasks/run-application/delete-stateful-set/).
{{% /capture %}}
+11 -8
View File
@@ -99,8 +99,7 @@ If you are on macOS and using [Macports](https://macports.org/) package manager,
If you are on Windows and using [Powershell Gallery](https://www.powershellgallery.com/) package manager, you can install and update kubectl with Powershell.
To install:
* Run the installation commands (making sure to specify a DownloadLocation):
1. Run the installation commands (making sure to specify a `DownloadLocation`):
```
Install-Script -Name install-kubectl -Scope CurrentUser -Force
@@ -108,17 +107,21 @@ To install:
```
{{< note >}}
**Note:** If you do not specify a DownloadLocation, kubectl will be installed in the user's temp Directory.
**Note:** If you do not specify a `DownloadLocation`, `kubectl` will be installed in the user's temp Directory.
{{< /note >}}
The installer creates $HOME/.kube and instructs it to create a config file
To update:
* Run the update commands:
The installer creates `$HOME/.kube` and instructs it to create a config file
2. Test to ensure the version you installed is sufficiently up-to-date:
```
re-run Install-Script to update the installer
re-run install-kubectl.ps1 to install latest binaries
kubectl version
```
{{< note >}}
**Note:** Updating the installation is performed by rerunning the two commands listed in step 1.
{{< /note >}}
## Install with Chocolatey on Windows
If you are on Windows and using [Chocolatey](https://chocolatey.org) package manager, you can install kubectl with Chocolatey.
@@ -24,7 +24,11 @@ weight: 20
<div class="katacoda__box" id="inline-terminal-1" data-katacoda-id="kubernetes-bootcamp/6" data-katacoda-color="326de6" data-katacoda-secondary="273d6d" data-katacoda-hideintro="false" data-katacoda-font="Roboto" data-katacoda-fontheader="Roboto Slab" data-katacoda-prompt="Kubernetes Bootcamp Terminal" style="height: 600px;">
</div>
</div>
<div class="row">
<div class="col-md-12">
<a class="btn btn-lg btn-success" href="/docs/tutorials/kubernetes-basics/" role="button">Back to Kubernetes Basics<span class="btn__next"></span></a>
</div>
</div>
</main>
</div>
@@ -96,17 +96,6 @@ data:
</store>
</match>
system.input.conf: |-
# Example:
# 2015-12-21 23:17:22,066 [salt.state ][INFO ] Completed state [net.ipv4.ip_forward] at time 23:17:22.066081
<source>
type tail
format /^(?<time>[^ ]* [^ ,]*)[^\[]*\[[^\]]*\]\[(?<severity>[^ \]]*) *\] (?<message>.*)$/
time_format %Y-%m-%d %H:%M:%S
path /var/log/salt/minion
pos_file /var/log/gcp-salt.pos
tag salt
</source>
# Example:
# Dec 21 23:17:22 gke-foo-1-1-4b5cbd14-node-4eoj startupscript: Finished running startup script /var/run/google.startup.script
<source>
-3
View File
@@ -127,9 +127,6 @@ toc:
- title: Installing Addons
path: /docs/concepts/cluster-administration/addons/
- title: Configuring Kubernetes with Salt
path: /docs/admin/salt/
- title: Building Large Clusters
path: /docs/admin/cluster-large/
-1
View File
@@ -14,7 +14,6 @@
<a href="http://slack.k8s.io/" class="slack"><span>Slack</span></a>
</div>
<div>
<a href="http://stackoverflow.com/questions/tagged/kubernetes" class="stack-overflow"><span>
<a href="http://stackoverflow.com/questions/tagged/kubernetes" class="stack-overflow"><span>{{ T "community_stack_overflow_name" }}</span></a>
<a href="https://discuss.kubernetes.io" class="mailing-list"><span>{{ T "community_forum_name" }}</span></a>
<a href="https://calendar.google.com/calendar/embed?src=nt2tcnbtbied3l6gi2h29slvc0%40group.calendar.google.com" class="calendar"><span>{{ T "community_events_calendar" }}</span></a>
Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

+26 -33
View File
@@ -1,12 +1,15 @@
# Update imported docs
This script updates the target files generated from other repos listed in the <config.yml> file, which is specified as the command line argument.
This script updates the docs files that are generated from other repos.
It accepts a YAML file name as its input which can be customized on a per-repo
basis.
## Requirements
Imported docs must follow these guidelines:
1. Be listed somewhere in the `/_data/imported.yml` table of contents file.
1. Adhere to the [Documentation Style Guide](/docs/home/contribute/style-guide/).
1. Have `title` defined in the front matter. For example:
```
@@ -16,49 +19,36 @@ Imported docs must follow these guidelines:
Rest of the .md file...
```
1. Be listed somewhere in a file under the `data` subdirectory, for example,
the `data/imported.yml` file.
1. Adhere to the [Documentation Style Guide](/docs/home/contribute/style-guide/).
1. Make sure the `PyYAML` package is installed:
```
sudo apt-get install python-pip
pip install PyYAML
```
## Usage
From within this directory, run the following command:
```
+./update-imported-docs-[linux|macos] <config.yaml>
+./update-imported-docs <CONFIG-FILE>
```
The output should look similar to the following:
where `<CONFIG-FILE>` can be any YAML configuration file in this directory.
```
Website root directory: /Users/someuser/git/kubernetes-website
## Configuration file format
* * *
Cloning repo "community"...
* * *
Docs imported! Run 'git add .' 'git commit -m <comment>' and 'git push' to upload them.
```
## Config file format
Each config file may contain multiple repos, which will be imported together. You should modify the corresponding `update-imported-docs/<config.yml>` file to reflect the desired `src` and `dst` paths.
You may also create new config files for different groups of documents to import. The following is an example of the YAML file format:
Each config file may contain multiple repos that will be imported together.
When necessary, you can customize the configuration file by manually editing
it. You may create new config files for importing other groups of documents.
The following is an example of the YAML configuration file:
```
repos:
- name: kubernetes #tmp directory name
remote: https://github.com/kubernetes/kubernetes.git
branch: release-1.9
generate-command: hack/generate-docs.sh #optional command to run
files:
- src: docs/admin/cloud-controller-manager.md
dst: docs/reference/generated/cloud-controller-manager.md
- src: docs/admin/kube-apiserver.md
dst: docs/reference/generated/kube-apiserver.md
- name: community #tmp directory name
- name: community
remote: https://github.com/kubernetes/community.git
branch: master
files:
@@ -68,8 +58,11 @@ repos:
dst: docs/imported/community/guide.md
```
Note: `generate-command` is an optional entry, which can be used to run a given command to auto-generate the docs from within that repo.
Note: `generate-command` is an optional entry, which can be used to run a
given command or a short script to generate the docs from within a repo.
## Fixing Links
To fix relative links within your imported files, set the repo config's `gen-absolute-links` value to `true`. You can see an example of this in [`community.yml`](community.yml).
To fix relative links within your imported files, set the repo config's
`gen-absolute-links` property to `true`. You can find an example of this in
[`community.yml`](community.yml).
+42 -184
View File
@@ -1,186 +1,44 @@
repos:
- name: kubernetes
remote: https://github.com/kubernetes/kubernetes.git
branch: release-1.11
generate-command: hack/generate-docs.sh
- name: reference-docs
remote: https://github.com/kubernetes-incubator/reference-docs.git
# This and the generate-command below needs a change when reference-docs has
# branches properly defined
branch: master
generate-command: |
cd $GOPATH
git clone https://github.com/kubernetes/kubernetes.git src/k8s.io/kubernetes
cd src/k8s.io/kubernetes
git checkout release-1.11
make generated_files
cp -L -R vendor $GOPATH/src
rm -r vendor
cd $GOPATH
go get -v github.com/kubernetes-incubator/reference-docs/gen-compdocs
cd src/github.com/kubernetes-incubator/reference-docs/
make comp
files:
- src: docs/admin/cloud-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/kube-controller-manager.md
- src: docs/admin/kube-apiserver.md
dst: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md
- src: docs/admin/kube-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/kube-controller-manager.md
- src: docs/admin/kubelet.md
dst: content/en/docs/reference/command-line-tools-reference/kubelet.md
- src: docs/admin/kube-proxy.md
dst: content/en/docs/reference/command-line-tools-reference/kube-proxy.md
- src: docs/admin/kube-scheduler.md
dst: content/en/docs/reference/command-line-tools-reference/kube-scheduler.md
- src: docs/user-guide/kubectl/kubectl.md
dst: content/en/docs/reference/kubectl/kubectl.md
- src: docs/admin/kubeadm_alpha.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha.md
- src: docs/admin/kubeadm_alpha_phase_addon_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_addon_all.md
- src: docs/admin/kubeadm_alpha_phase_addon_coredns.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_addon_coredns.md
- src: docs/admin/kubeadm_alpha_phase_addon_kube-proxy.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_addon_kube-proxy.md
- src: docs/admin/kubeadm_alpha_phase_addon.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_addon.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_all.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_cluster-info.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_cluster-info.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_create.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_create.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_node.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_node.md
- src: docs/admin/kubeadm_alpha_phase_certs_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_all.md
- src: docs/admin/kubeadm_alpha_phase_certs_apiserver-etcd-client.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_apiserver-etcd-client.md
- src: docs/admin/kubeadm_alpha_phase_certs_apiserver-kubelet-client.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_apiserver-kubelet-client.md
- src: docs/admin/kubeadm_alpha_phase_certs_apiserver.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_apiserver.md
- src: docs/admin/kubeadm_alpha_phase_certs_ca.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_ca.md
- src: docs/admin/kubeadm_alpha_phase_certs_etcd-ca.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_etcd-ca.md
- src: docs/admin/kubeadm_alpha_phase_certs_etcd-healthcheck-client.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_etcd-healthcheck-client.md
- src: docs/admin/kubeadm_alpha_phase_certs_etcd-peer.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_etcd-peer.md
- src: docs/admin/kubeadm_alpha_phase_certs_etcd-server.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_etcd-server.md
- src: docs/admin/kubeadm_alpha_phase_certs_front-proxy-ca.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_front-proxy-ca.md
- src: docs/admin/kubeadm_alpha_phase_certs_front-proxy-client.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_front-proxy-client.md
- src: docs/admin/kubeadm_alpha_phase_certs.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs.md
- src: docs/admin/kubeadm_alpha_phase_certs_sa.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_sa.md
- src: docs/admin/kubeadm_alpha_phase_controlplane_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane_all.md
- src: docs/admin/kubeadm_alpha_phase_controlplane_apiserver.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane_apiserver.md
- src: docs/admin/kubeadm_alpha_phase_controlplane_controller-manager.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane_controller-manager.md
- src: docs/admin/kubeadm_alpha_phase_controlplane.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane.md
- src: docs/admin/kubeadm_alpha_phase_controlplane_scheduler.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane_scheduler.md
- src: docs/admin/kubeadm_alpha_phase_etcd_local.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_etcd_local.md
- src: docs/admin/kubeadm_alpha_phase_etcd.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_etcd.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_admin.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_admin.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_all.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_controller-manager.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_controller-manager.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_kubelet.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_kubelet.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_scheduler.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_scheduler.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_user.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_user.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config_download.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config_download.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config_enable-dynamic.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config_enable-dynamic.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config_upload.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config_upload.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config_write-to-disk.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config_write-to-disk.md
- src: docs/admin/kubeadm_alpha_phase_kubelet.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_write-env-file.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_write-env-file.md
- src: docs/admin/kubeadm_alpha_phase_mark-master.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_mark-master.md
- src: docs/admin/kubeadm_alpha_phase.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase.md
- src: docs/admin/kubeadm_alpha_phase_preflight_master.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_preflight_master.md
- src: docs/admin/kubeadm_alpha_phase_preflight.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_preflight.md
- src: docs/admin/kubeadm_alpha_phase_preflight_node.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_preflight_node.md
- src: docs/admin/kubeadm_alpha_phase_selfhosting_convert-from-staticpods.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_selfhosting_convert-from-staticpods.md
- src: docs/admin/kubeadm_alpha_phase_selfhosting.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_selfhosting.md
- src: docs/admin/kubeadm_alpha_phase_upload-config.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_upload-config.md
- src: docs/admin/kubeadm_completion.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_completion.md
- src: docs/admin/kubeadm_config_images_list.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_images_list.md
- src: docs/admin/kubeadm_config_images.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_images.md
- src: docs/admin/kubeadm_config_images_pull.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_images_pull.md
- src: docs/admin/kubeadm_config.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config.md
- src: docs/admin/kubeadm_config_migrate.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_migrate.md
- src: docs/admin/kubeadm_config_print-default.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_print-default.md
- src: docs/admin/kubeadm_config_upload_from-file.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_upload_from-file.md
- src: docs/admin/kubeadm_config_upload_from-flags.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_upload_from-flags.md
- src: docs/admin/kubeadm_config_upload.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_upload.md
- src: docs/admin/kubeadm_config_view.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_view.md
- src: docs/admin/kubeadm_init.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md
- src: docs/admin/kubeadm_join.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_join.md
- src: docs/admin/kubeadm_reset.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset.md
- src: docs/admin/kubeadm_token_create.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_create.md
- src: docs/admin/kubeadm_token_delete.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_delete.md
- src: docs/admin/kubeadm_token_generate.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_generate.md
- src: docs/admin/kubeadm_token_list.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_list.md
- src: docs/admin/kubeadm_token.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token.md
- src: docs/admin/kubeadm_upgrade_apply.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md
- src: docs/admin/kubeadm_upgrade_diff.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md
- src: docs/admin/kubeadm_upgrade.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade.md
- src: docs/admin/kubeadm_upgrade_node_config.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node_config.md
- src: docs/admin/kubeadm_upgrade_node.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md
- src: docs/admin/kubeadm_upgrade_plan.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md
- src: docs/admin/kubeadm_version.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_version.md
- src: gen-compdocs/build/cloud-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kube-apiserver.md
dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kube-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/
# We have problems generating docs for kubelet, it is done manually now
# - src: gen-compdocs/build/kubelet.md
# dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kube-proxy.md
dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kube-scheduler.md
dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kubectl.md
dst: content/en/docs/reference/kubectl/
- src: gen-compdocs/build/kubeadm*.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/
- name: federation
remote: https://github.com/kubernetes/federation.git
# # Change this to a release branch when federation has release branches.
# Change this to a release branch when federation has release branches.
branch: master
generate-command: hack/generate-docs.sh
files:
@@ -189,14 +47,14 @@ repos:
- src: docs/admin/federation-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/federation-controller-manager.md
- src: docs/admin/kubefed_init.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-init.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_init.md
- src: docs/admin/kubefed_join.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-join.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_join.md
- src: docs/admin/kubefed.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed.md
- src: docs/admin/kubefed_options.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-options.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_options.md
- src: docs/admin/kubefed_unjoin.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-unjoin.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_unjoin.md
- src: docs/admin/kubefed_version.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-version.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_version.md
+158
View File
@@ -0,0 +1,158 @@
#!/usr/bin/env python
import glob
import os
import re
import shutil
import subprocess
import sys
try:
import yaml
except Exception:
print("Please ensure PyYAML package is installed. This can be done, for "
"example, by executing the following command:\n\n"
" pip install pyyaml\n")
sys.exit(-1)
def processLinks(content, remotePrefix, subPath):
"""Process markdown links found in the docs."""
def analyze(matchObj):
ankor = matchObj.group('ankor')
target = matchObj.group('target')
if not (target.startswith("https://") or
target.startswith("mailto:") or
target.startswith("#")):
if target.startswith("/"):
target = "/".join(remotePrefix, target[1:])
else:
target = "/".join(remotePrefix, subPath, target)
return "[%s](%s)" % (ankor, target)
# Links are in the form '[text](url)'
linkRegex = re.compile(r"\[(?P<ankor>.*)\]\((?P<target>.*)\)")
content = re.sub(linkRegex, analyze, content)
h1Regex = re.compile("^(# .*)?\n")
content = re.sub(h1Regex, "", content)
return content
def processFile(src, dst, repoPath, repoDir, rootDir, genAbsoluteLinks):
"""Process a file element.
:param src: A string containing the relative path of a source file. The
string may contain wildcard characters such as '*' or '?'.
:param dst: The path for the destination file. The string can be a
directory name or a file name.
"""
pattern = os.path.join(repoDir, repoPath, src)
dstPath = os.path.join(rootDir, dst)
for src in glob.glob(pattern):
# we don't dive into subdirectories
if not os.path.isfile(src):
print("[Error] skipping non-regular path %s" % src)
continue
content = ""
try:
with open(src, "r") as srcFile:
content = srcFile.read()
except Exception as ex:
print("[Error] failed in reading source file: " + str(ex))
continue
dst = dstPath
if dstPath.endswith("/"):
baseName = os.path.basename(src)
dst = os.path.join(dst, baseName)
try:
print("Writing doc: " + dst)
with open(dst, "w") as dstFile:
if genAbsoluteLinks:
srcDir = os.path.dirname(src)
remotePrefix = repoPath + "/tree/master"
content = processLinks(content, remotePrefix, srcDir)
dstFile.write(content)
except Exception as ex:
print("[Error] failed in writing target file '%s': %s"
"" % (dst, str(ex)))
continue
def main():
"""The main entry of the program."""
if len(sys.argv) < 2:
print("[Error] Please specify a config file")
return -1
configFile = sys.argv[1]
currDir = os.path.dirname(__file__)
rootDir = os.path.realpath(os.path.join(currDir, '..'))
try:
configData = yaml.load(open(configFile, 'r'))
except Exception as ex:
print("[Error] failed in loading config file - %s" % str(ex))
return -2
os.chdir(rootDir)
workDir = "/tmp/update_docs"
shutil.rmtree(workDir, True)
os.mkdir(workDir, 0750)
for repo in configData["repos"]:
if "name" not in repo:
print("[Error] repo missing name")
continue
repoName = repo["name"]
if "remote" not in repo:
print("[Error] repo '%s' missing repo path" % repoName)
continue
repoRemote = repo["remote"]
remoteRegex = re.compile(r"^https://(?P<prefix>.*)\.git$")
matches = remoteRegex.search(repoRemote)
if not matches:
print("[Error] repo path for '%s' is invalid" % repoName)
continue
repoPath = os.path.join("src", matches.group('prefix'))
os.chdir(workDir)
print("Cloning repo %s..." % repoName)
cmd = "git clone --depth=1 -b {0} {1} {2}".format(
repo["branch"], repoRemote, repoPath)
res = subprocess.call(cmd, shell=True)
if res != 0:
print("[Error] failed in cloning repo '%s'" % repoName)
continue
os.chdir(repoPath)
if "generate-command" in repo:
genCmd = repo["generate-command"]
genCmd = "export GOPATH=" + workDir + "\n" + genCmd
print("Generating docs for %s with %s" % (repoName, genCmd))
res = subprocess.call(genCmd, shell=True)
if res != 0:
print("[Error] failed in generating docs for '%s'" % repoName)
continue
os.chdir(rootDir)
for f in repo["files"]:
processFile(f['src'], f['dst'], repoPath, workDir, rootDir,
"gen-absolute-links" in repo)
print("Completed docs update. Now run the following command to commit:\n\n"
" git add .\n"
" git commit -m <comment>\n"
" git push\n")
if __name__ == '__main__':
sys.exit(main())
Binary file not shown.
Binary file not shown.
@@ -1,213 +0,0 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"strings"
"github.com/ghodss/yaml"
)
func main() {
//get command line arguments without executable
clArgs := os.Args[1:]
//check that an argument has been passed in
if len(clArgs) == 0 {
fmt.Fprintf(os.Stderr, "Please specify a config file as a command line argument.\n")
os.Exit(1)
}
configFile := clArgs[0]
//get directory of executable
ex, err := os.Executable()
checkError(err)
exPath := filepath.Dir(ex) //file path of updated-imported-docs executable
suffix := filepath.Base(exPath) //should be "updated-imported-docs"
//check if suffix is "updated-imported-docs"
if suffix != "update-imported-docs" {
fmt.Fprintf(os.Stderr, "Instead of `go run update-imported-docs.go <config.yml>`, use the compiled binary `./update-imported-docs <config.yml>`\n")
os.Exit(1)
}
//set root directory of website
websiteRepo := filepath.Clean(strings.TrimSuffix(exPath,suffix)) //path of parent directory
fmt.Fprintf(os.Stdout, "Website root directory: %s\n", websiteRepo)
//read config.yaml file specified by first command line argument
content, err := ioutil.ReadFile(configFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error when reading file: %v\n", err)
os.Exit(1)
}
//convert contents of config.yml file into a map
var config map[string]interface{}
err = yaml.Unmarshal(content, &config)
if err != nil {
fmt.Fprintf(os.Stderr, "Error when unmarshal the config file: %v\n", err)
os.Exit(1)
}
//change working directory to website root
err = os.Chdir(websiteRepo)
checkError(err)
//clean out temp directory
tmpDir := "/tmp/update_docs"
os.RemoveAll(tmpDir)
os.Mkdir(tmpDir, 0750)
// Match the content between 2 `---`
// It mostly have something like:
// ---
// title: ***
// notile: ***
// ---
titleRegex := regexp.MustCompile("^---\ntitle:(.*\n)*?---\n")
// To extract repo path prefix from `remote`
remoteGitRegex := regexp.MustCompile("(https://.*)\\.git$")
//execute for each repo
repos := config["repos"].([]interface{})
for _, repo := range repos {
err = os.Chdir(tmpDir)
checkError(err)
//get config info for repo, clone repo locally
r := repo.(map[string]interface{})
repoName := r["name"].(string)
remotePathMatch := remoteGitRegex.FindAllStringSubmatch(r["remote"].(string), -1)
if (len(remotePathMatch) == 0) {
fmt.Fprintf(os.Stderr, "\n\t\t\t!\t!\t!\n\nInvalid remote path %q. Schema should look like: https://<url>.git\n", r["remote"].(string))
os.Exit(1)
}
remotePrefix := fmt.Sprintf("%s/tree/master", remotePathMatch[0][1])
cmd := "git"
args := []string{"clone", "--depth=1", "-b", r["branch"].(string), r["remote"].(string), repoName}
fmt.Fprintf(os.Stdout, "\n\t\t\t*\t*\t*\n\nCloning repo %q...\n", repoName)
if err := exec.Command(cmd, args...).Run(); err != nil {
fmt.Fprintf(os.Stderr, "\n\t\t\t!\t!\t!\n\nError when cloning repo %q: %v\n", repoName, err)
os.Exit(1)
}
err = os.Chdir(repoName)
checkError(err)
//if generate-command is specified in the repo config,
//run the command for that repo, e.g. "hack/generate-docs.sh"
if r["generate-command"] != nil {
genCmd := r["generate-command"].(string)
fmt.Fprintf(os.Stdout, "Generating docs for repo %q with %q...\n\n", repoName, genCmd)
cmd := exec.Command(genCmd)
cmdReader, err := cmd.StdoutPipe()
if err != nil {
fmt.Fprintf(os.Stderr, "\n\t\t\t!\t!\t!\n\nError when generating docs for repo %q: %v\n", repoName, err)
os.Exit(1)
}
//display running output of generate command
scanner := bufio.NewScanner(cmdReader)
go func() {
for scanner.Scan() {
fmt.Printf("generator output | %s\n", scanner.Text())
}
}()
err = cmd.Start()
if err != nil {
fmt.Fprintln(os.Stderr, "Error starting %q command\n", genCmd, err)
os.Exit(1)
}
err = cmd.Wait()
if err != nil {
fmt.Fprintln(os.Stderr, "Error waiting for %q command\n", genCmd, err)
os.Exit(1)
}
}
//copy and rename files from src -> dst specified in config
err = os.Chdir(websiteRepo)
checkError(err)
files := r["files"].([]interface{})
for _, file := range files {
f := file.(map[string]interface{})
src := f["src"].(string)
dst := f["dst"].(string)
srcDir := filepath.Dir(src)
absSrc, err := filepath.Abs(path.Join(tmpDir, repoName, src))
checkError(err)
absDst, err := filepath.Abs(dst)
checkError(err)
// Ignore the error if the old file is not found/
content, _ := ioutil.ReadFile(absDst)
titleBlock := titleRegex.Find(content)
content, err = ioutil.ReadFile(absSrc)
checkError(err)
// Write to new output file
dstFile, err := os.OpenFile(absDst, os.O_RDWR|os.O_CREATE, 0755)
checkError(err)
defer dstFile.Close()
_, err = dstFile.Write(titleBlock)
checkError(err)
// Process content if necessary
if r["gen-absolute-links"] != nil {
content = processLinks(content, remotePrefix, srcDir)
}
_, err = dstFile.Write(content)
checkError(err)
dstFile.Sync()
}
}
fmt.Fprintf(os.Stdout, "\n\t\t\t*\t*\t*\n\nDocs imported! Run 'git add .' 'git commit -m <comment>' and 'git push' to upload them.\n")
}
//
func processLinks(content []byte, remotePrefix string, subPath string) []byte {
// To catch anything of the form [text](url)
linkRegex := regexp.MustCompile("(\\[.+?\\])\\(([^\\s\\)]+)\\)")
// Regexes to skip
absUrlRegex := regexp.MustCompile("https*://")
mailRegex := regexp.MustCompile("mailto:")
processedContent := linkRegex.ReplaceAllFunc(content, func(b []byte) []byte {
if (absUrlRegex.Match(b) || mailRegex.Match(b)) {
return b // no processing needed
}
match := linkRegex.FindAllStringSubmatch(string(b), -1)
url := match[0][2]
if url[0] == '#' { // link on current page
return b
} else if url[0] == '/' { // link at root of repo
return []byte(fmt.Sprintf("%s(%s/%s)", match[0][1], remotePrefix, url[1:]))
} else { // link relative to current page
return []byte(fmt.Sprintf("%s(%s/%s/%s)", match[0][1], remotePrefix, subPath, url))
}
})
h1Regex := regexp.MustCompile("^(# .*)?\n")
processedContent = h1Regex.ReplaceAll(processedContent, []byte(""))
return processedContent
}
func checkError(err error) {
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}