Merge branch 'master' into release-1.8
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
canonical-tags:
|
||||
- Fundamental
|
||||
- API Object
|
||||
- Metadata
|
||||
- Configuration
|
||||
- Security
|
||||
- Networking
|
||||
- Storage
|
||||
- Operation
|
||||
- Workload
|
||||
- Component
|
||||
- API
|
||||
- Extension
|
||||
|
||||
# TODO: Add list of glossary terms here
|
||||
# (to avoid writing a function that iterates through all glossary term pages)
|
||||
# e.g.
|
||||
# terms:
|
||||
# - name: StatefulSets
|
||||
# tags:
|
||||
# - Storage
|
||||
# - Workload
|
||||
# - API Object
|
||||
# - name: Aggregation Layer
|
||||
# tags:
|
||||
# - API
|
||||
# - Component
|
||||
# - Extension
|
||||
#
|
||||
# See https://github.com/kubernetes/kubernetes.github.io/projects/4 for details.
|
||||
@@ -46,6 +46,7 @@ toc:
|
||||
- docs/tasks/run-application/run-stateless-application-deployment.md
|
||||
- docs/tasks/run-application/run-single-instance-stateful-application.md
|
||||
- docs/tasks/run-application/run-replicated-stateful-application.md
|
||||
- docs/tasks/run-application/update-api-object-kubectl-patch.md
|
||||
- docs/tasks/run-application/upgrade-pet-set-to-stateful-set.md
|
||||
- docs/tasks/run-application/scale-stateful-set.md
|
||||
- docs/tasks/run-application/delete-stateful-set.md
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Instructions for Glossary snippets
|
||||
|
||||
Markdown snippets of glossary terms to be reused throughout the documentation should be placed in this directory.
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
---
|
||||
term: Some Fancy K8s Term
|
||||
formerly:
|
||||
- Slang K8s Term
|
||||
- Misnomer
|
||||
- Formerly Known as Prince
|
||||
related:
|
||||
- Less Fancy K8s Term
|
||||
- Tangential Term
|
||||
- Commonly Used With
|
||||
---
|
||||
|
||||
{% capture short-description %}
|
||||
Required. One or two lines that provide a minimum definition. Do not repeat the term. Prefer fragments. Model after tooltips.
|
||||
{% endcapture %}
|
||||
|
||||
{% capture long-description %}
|
||||
Optional. Longer additional text to appear after (in conjunction with) short description. Provide where the short description is not sufficient as the intro paragraph to a topic. Write complete but concise sentences.
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed hendrerit dictum nisi quis posuere. Integer eleifend neque lobortis ultrices viverra. Praesent viverra placerat ex sit amet aliquet. Aliquam non ipsum ut lectus viverra pulvinar id vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse aliquet congue tristique. Pellentesque at condimentum orci, iaculis pellentesque urna. Aliquam ut rhoncus lorem, a tristique est. Quisque eu est sem.
|
||||
|
||||
Suspendisse id feugiat orci. Etiam in posuere arcu, id euismod velit. Etiam pulvinar lectus at diam porta, non lobortis dolor blandit. Donec id faucibus elit. Suspendisse auctor ligula purus, id aliquam odio vehicula a. Donec pretium ligula at nulla pulvinar, sed ultrices ligula dapibus. Cras lacinia mauris ut metus rutrum volutpat. Sed fermentum lobortis ipsum, in hendrerit lectus consectetur sed. Aliquam pulvinar tortor tellus, ac luctus est euismod congue. Maecenas enim ipsum, maximus a turpis eu, blandit imperdiet lacus.
|
||||
{% endcapture %}
|
||||
@@ -14,6 +14,12 @@ cid: caseStudies
|
||||
<main>
|
||||
<div class="content">
|
||||
<div class="case-studies">
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/peardeck.png" alt="peardeck">
|
||||
<p class="quote">"In terms of the cloud, Kubernetes and Prometheus have so much to offer."</p>
|
||||
<!--<p class="attrib">— Riley Eynon-Lynch, CEO of Pear Deck</p>-->
|
||||
<a href="/case-studies/peardeck/">Read about Pear Deck</a>
|
||||
</div>
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/buffer.png" alt="Buffer">
|
||||
<p class="quote">"It’s amazing that we can use the Kubernetes solution off the shelf with our team. And it just keeps getting better."</p>
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
title: Pear Deck Case Study
|
||||
layout: basic
|
||||
case_study_styles: true
|
||||
cid: caseStudies
|
||||
css: /css/style_peardeck.css
|
||||
---
|
||||
|
||||
<div class="banner1">
|
||||
<h1> CASE STUDY:<img src="/images/peardeck_logo.png" width="22%" style="margin-bottom:-0px"><br> <div class="subhead">Infrastructure for a Growing EdTech Startup</div></h1>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="details">
|
||||
Company <b>Pear Deck</b> Location <b>Iowa City, Iowa</b> Industry <b>Educational Software</b>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<section class="section1">
|
||||
<div class="cols">
|
||||
<div class="col1">
|
||||
<h2>Challenge</h2>
|
||||
The three-year-old startup provides a web app for teachers to interact with their students in the classroom. The JavaScript app was built on Google’s web app development platform <a href="https://firebase.google.com/">Firebase</a>, using <a href="https://www.heroku.com/">Heroku</a>. As the user base steadily grew, so did the development team. "We outgrew Heroku when we started wanting to have multiple services, and the deploying story got pretty horrendous. We were frustrated that we couldn’t have the developers quickly stage a version," says CEO Riley Eynon-Lynch. "Tracing and monitoring became basically impossible." On top of that, many of Pear Deck’s customers are behind government firewalls and connect through Firebase, not Pear Deck’s servers, making troubleshooting even more difficult.
|
||||
</div>
|
||||
|
||||
<div class="col2">
|
||||
<h2>Solution</h2>
|
||||
In 2016, the company began moving their code from Heroku to <a href="https://www.docker.com/">Docker</a> containers running on <a href="https://cloud.google.com/container-engine/">Google Container Engine</a>, orchestrated by <a href="http://kubernetes.io/">Kubernetes</a> and monitored with <a href="https://prometheus.io/">Prometheus</a>.
|
||||
<br>
|
||||
<br>
|
||||
<h2>Impact</h2>
|
||||
The new cloud native stack immediately improved the development workflow, speeding up deployments. Prometheus gave Pear Deck "a lot of confidence, knowing that people are still logging into the app and using it all the time," says Eynon-Lynch. "The biggest impact is being able to work as a team on the configuration in git in a pull request, and the biggest confidence comes from the solidity of the abstractions and the trust that we have in Kubernetes actually making our yaml files a reality."
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="banner2">
|
||||
<div class="banner2text">
|
||||
"We didn’t even realize how stressed out we were about our lack of insight into what was happening with the app. I’m really excited and have more and more confidence in the actual state of our application for our actual users, and not just what the CPU graphs are saying, because of Prometheus and Kubernetes."<br><br><span style="font-size:16px;letter-spacing:2px;">– RILEY EYNON-LYNCH, CEO OF PEAR DECK</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="section2">
|
||||
<div class="fullcol">
|
||||
<h2>With the speed befitting a startup, Pear Deck delivered its first prototype to customers within three months of incorporating.</h2>
|
||||
As a former high school math teacher, CEO Riley Eynon-Lynch felt an urgency to provide a tech solution to classes where instructors struggle to interact with every student in a short amount of time. "Pear Deck is an app that students can use to interact with the teacher all at once," he says. "When the teacher asks a question, instead of just the kid at the front of the room answering again, everybody can answer every single question. It’s a huge fundamental shift in the messaging to the students about how much we care about them and how much they are a part of the classroom."<br><br>
|
||||
Eynon-Lynch and his partners quickly built a JavaScript web app on Google’s web app development platform <a href="https://firebase.google.com/">Firebase</a>, and launched the minimum viable product [MVP] on <a href="https://www.heroku.com/">Heroku</a> "because it was fast and easy," he says. "We made everything as easy as we could."
|
||||
<br><br>
|
||||
But once it launched, the user base began growing steadily at a rate of 30 percent a month. "Our Heroku bill was getting totally insane," Eynon-Lynch says. But even more crucially, as the company hired more developers to keep pace, "we outgrew Heroku. We wanted to have multiple services and the deploying story got pretty horrendous. We were frustrated that we couldn’t have the developers quickly stage a version. Tracing and monitoring became basically impossible."
|
||||
<br><br>
|
||||
On top of that, many of Pear Deck’s customers are behind government firewalls and connect through Firebase, not Pear Deck’s servers, making troubleshooting even more difficult.
|
||||
<br><br>
|
||||
The team began looking around for another solution, and finally decided in early 2016 to start moving the app from Heroku to <a href="https://www.docker.com/">Docker</a> containers running on <a href="https://cloud.google.com/container-engine/">Google Container Engine</a>, orchestrated by <a href="http://kubernetes.io/">Kubernetes</a> and monitored with <a href="https://prometheus.io/">Prometheus</a>.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="banner3">
|
||||
<div class="banner3text">
|
||||
"When it became clear that Google Container Engine was going to have a lot of support from Google and be a fully-managed Kubernetes platform, it seemed very obvious to us that was the way to go," says Eynon-Lynch.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="section3">
|
||||
<div class="fullcol">
|
||||
They had considered other options like Google’s App Engine (which they were already using for one service) and Amazon’s <a href="https://aws.amazon.com/ec2/">Elastic Compute Cloud</a> (EC2), while experimenting with running one small service that wasn’t accessible to the Internet in Kubernetes. "When it became clear that Google Container Engine was going to have a lot of support from Google and be a fully-managed Kubernetes platform, it seemed very obvious to us that was the way to go," says Eynon-Lynch. "We didn’t really consider Terraform and the other competitors because the abstractions offered by Kubernetes just jumped off the page to us."<br><br>
|
||||
Once the team started porting its Heroku apps into Kubernetes, which was "super easy," he says, the impact was immediate. "Before, to make a new version of the app meant going to Heroku and reconfiguring 10 new services, so basically no one was willing to do it, and we never staged things," he says. "Now we can deploy our exact same configuration in lots of different clusters in 30 seconds. We have a full set up that’s always running, and then any of our developers or designers can stage new versions with one command, including their recent changes. We stage all the time now, and everyone stopped talking about how cool it is because it’s become invisible how great it is."
|
||||
<br><br>
|
||||
Along with Kubernetes came Prometheus. "Until pretty recently we didn’t have any kind of visibility into aggregate server metrics or performance," says Eynon-Lynch. The team had tried to use GKE’s <a href="https://cloud.google.com/stackdriver/">Stackdriver</a> monitoring, but had problems making it work, and considered <a href="https://newrelic.com/">New Relic</a>. When they started looking at Prometheus in the fall of 2016, "the fit between the abstractions in Prometheus and the way we think about how our system works, was so clear and obvious," he says.<br><br>
|
||||
The integration with Kubernetes made set-up easy. Once Helm installed Prometheus, "We started getting a graph of the health of all our Kubernetes nodes and pods immediately. I think we were pretty hooked at that point," Eynon-Lynch says. "Then we got our own custom instrumentation working in 15 minutes, and had an actively updated count of requests that we could do, rate on and get a sense of how many users are connected at a given point. And then it was another hour before we had alarms automatically showing up in our Slack channel. All that was in one afternoon. And it was an afternoon of gasping with delight, basically!"
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="banner4">
|
||||
<div class="banner4text">
|
||||
"We started getting a graph of the health of all our Kubernetes nodes and pods immediately. I think we were pretty hooked at that point," Eynon-Lynch says. "Then we got our own custom instrumentation working in 15 minutes, and had an actively updated count of requests that we could do, rate on and get a sense of how many users are connected at a given point. And then it was another hour before we had alarms automatically showing up in our Slack channel. All that was in one afternoon. And it was an afternoon of gasping with delight, basically!"
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="section4">
|
||||
<div class="fullcol">
|
||||
With Pear Deck’s specific challenges—traffic through Firebase as well as government firewalls—Prometheus was a game-changer. "We didn’t even realize how stressed out we were about our lack of insight into what was happening with the app," Eynon-Lynch says. Before, when a customer would report that the app wasn’t working, the team had to manually investigate the problem without knowing whether customers were affected all over the world, or whether Firebase was down, and where.<br><br>
|
||||
To help solve that problem, the team wrote a script that pings Firebase from several different geographical locations, and then reports the responses to Prometheus in a histogram. "A huge impact that Prometheus had on us was just an amazing sigh of relief, of feeling like we knew what was happening," he says. "It took 45 minutes to implement [the Firebase alarm] because we knew that we had this trustworthy metrics platform in Prometheus. We weren’t going to have to figure out, ‘Where do we send these metrics? How do we aggregate the metrics? How do we understand them?’"<br><br>
|
||||
Plus, Prometheus has allowed Pear Deck to build alarms for business goals. One measures the rate of successful app loads and goes off if the day’s loads are less than 90 percent of the loads from seven days before. "We run a JavaScript app behind ridiculous firewalls and all kinds of crazy browser extensions messing with it—Chrome will push a feature that breaks some CSS that we’re using," Eynon-Lynch says. "So that gives us a lot of confidence, and we at least know that people are still logging into the app and using it all the time."<br><br>
|
||||
Now, when a customer complains, and none of the alarms have gone off, the team can feel confident that it’s not a widespread problem. "Just to be sure, we can go and double check the graphs and say, ‘Yep, there’s currently 10,000 people connected to that Firebase node. It’s definitely working. Let’s investigate your network settings, customer,’" he says. "And we can pass that back off to our support reps instead of the whole development team freaking out that Firebase is down."<br><br>
|
||||
Pear Deck is also giving back to the community, building and open-sourcing a <a href="https://github.com/peardeck/prometheus-user-metrics">metrics aggregator</a> that enables end-user monitoring in Prometheus. "We can measure, for example, the time to interactive-dom on the web clients," he says. "The users all report that to our aggregator, then the aggregator reports to Prometheus. So we can set an alarm for some client side errors."<br><br>
|
||||
Most of Pear Deck’s services have now been moved onto Kubernetes. And all of the team’s new code is going on Kubernetes. "Kubernetes lets us experiment with service configurations and stage them on a staging cluster all at once, and test different scenarios and talk about them as a development team looking at code, not just talking about the steps we would eventually take as humans," says Eynon-Lynch.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="banner5">
|
||||
<div class="banner5text">
|
||||
"A huge impact that Prometheus had on us was just an amazing sigh of relief, of feeling like we knew what was happening. It took 45 minutes to implement [the Firebase alarm] because we knew that we had this trustworthy metrics platform in Prometheus...in terms of the cloud, Kubernetes and Prometheus have so much to offer," he says.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="section5">
|
||||
<div class="fullcol">
|
||||
Looking ahead, the team is planning to explore autoscaling on Kubernetes. With users all over the world but mostly in the United States, there are peaks and valleys in the traffic. One service that’s still on App Engine can get as many as 10,000 requests a second during the day but far less at night. "We pay for the same servers at night, so I understand there’s autoscaling that we can be taking advantage of," he says. "Implementing it is a big worry, exposing the rest of our Kubernetes cluster to us and maybe messing that up. But it’s definitely our intention to move everything over, because now none of the developers want to work on that app anymore because it’s such a pain to deploy it."
|
||||
<br><br>
|
||||
They’re also eager to explore the work that Kubernetes is doing with stateful sets. "Right now all of the services we run in Kubernetes are stateless, and Google basically runs our databases for us and manages backups," Eynon-Lynch says. "But we’re interested in building our own web-socket solution that doesn’t have to be super stateful but will have maybe an hour’s worth of state on it."
|
||||
<br><br>
|
||||
That project will also involve Prometheus, for a dark launch of web socket connections. "We don’t know how reliable web socket connections behind all these horrible firewalls will be to our servers," he says. "We don’t know what work Firebase has done to make them more reliable. So I’m really looking forward to trying to get persistent connections with web sockets to our clients and have optional tools to understand if it’s working. That’s our next new adventure, into stateful servers."
|
||||
<br><br>
|
||||
As for Prometheus, Eynon-Lynch thinks the company has only gotten started. "We haven’t instrumented all our important features, especially those that depend on third parties," he says. "We have to wait for those third parties to tell us they’re down, which sometimes they don’t do for a long time. So I’m really excited and have more and more confidence in the actual state of our application for our actual users, and not just what the CPU graphs are saying, because of Prometheus and Kubernetes."
|
||||
<br><br>
|
||||
For a spry startup that’s continuing to grow rapidly—and yes, they’re <a href="https://www.peardeck.com/careers/">hiring</a>!—Pear Deck is notably satisfied with how its infrastructure has evolved in the cloud native ecosystem. "Usually I have some angsty thing where I want to get to the new, better technology," says Eynon-Lynch, "but in terms of the cloud, Kubernetes and Prometheus have so much to offer."
|
||||
|
||||
<br><br>
|
||||
</div>
|
||||
</section>
|
||||
+1
-1
@@ -56,7 +56,7 @@
|
||||
min-height: 152px;
|
||||
}
|
||||
|
||||
.case-study:nth-child(7), .case-study:nth-child(8) {
|
||||
.case-study:nth-child(9), .case-study:nth-child(10) {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,459 @@
|
||||
|
||||
.golfnow {
|
||||
width:100%;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family:"Roboto", sans-serif;
|
||||
padding:5%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration:none;
|
||||
color:#3366ff;
|
||||
}
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
background-color:#ffffff !important;
|
||||
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color:#ffffff !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:bold;
|
||||
letter-spacing:0.025em;
|
||||
font-size:42px;
|
||||
padding-bottom:0px;
|
||||
}
|
||||
|
||||
.subhead {
|
||||
font-size:26px;
|
||||
font-weight:100;
|
||||
line-height:40px;
|
||||
padding-bottom:1%;
|
||||
|
||||
}
|
||||
|
||||
.banner1 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:12%;
|
||||
padding-bottom:0.5%;
|
||||
padding-left:10%;
|
||||
font-size:32px;
|
||||
background: url('/images/CaseStudy_peardeck_banner3.jpg');
|
||||
background-size:100% auto;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
|
||||
.banner2 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:3%;
|
||||
padding-bottom:3%;
|
||||
font-size:21px;
|
||||
letter-spacing:0.03em;
|
||||
line-height:32px;
|
||||
float:left;
|
||||
background-size:100% auto;
|
||||
background-color:#666666;
|
||||
background-repeat:no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.banner3 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-left:5%;
|
||||
padding-right:5%;
|
||||
padding-top:6%;
|
||||
padding-bottom:6%;
|
||||
font-size:21px;
|
||||
letter-spacing:0.03em;
|
||||
line-height:32px;
|
||||
float:left;
|
||||
background: url('/images/CaseStudy_peardeck_banner1.jpg');
|
||||
background-size:100% auto;
|
||||
}
|
||||
|
||||
.banner4 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:5%;
|
||||
padding-bottom:5%;
|
||||
font-size:21px;
|
||||
letter-spacing:0.03em;
|
||||
line-height:32px;
|
||||
float:left;
|
||||
background: url('/images/CaseStudy_peardeck_banner2.jpg');
|
||||
background-size:100% auto;
|
||||
}
|
||||
|
||||
.banner5 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:3%;
|
||||
padding-bottom:3%;
|
||||
font-size:21px;
|
||||
letter-spacing:0.03em;
|
||||
line-height:32px;
|
||||
float:left;
|
||||
background-size:100% auto;
|
||||
background-color:#666666;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
|
||||
.banner2text {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
width:60%;
|
||||
padding-left:19%;
|
||||
float:left;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.banner3text {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
width:70%;
|
||||
padding-left:15%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.banner4text {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
width:55%;
|
||||
padding-left:21%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.banner5text {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
width:60%;
|
||||
padding-left:19%;
|
||||
float:left;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
|
||||
h2 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
font-size:24px;
|
||||
line-height:34px;
|
||||
color:#3366ff;
|
||||
}
|
||||
|
||||
.quote {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
font-size:22px;
|
||||
line-height:32px;
|
||||
color:#3366ff;
|
||||
}
|
||||
|
||||
.details {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
font-size:18px;
|
||||
color:#3366ff;
|
||||
letter-spacing:0.03em;
|
||||
padding-bottom:1.5%;
|
||||
padding-top:2%;
|
||||
padding-left:10%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
hr {
|
||||
border-bottom:0px solid;
|
||||
width:100%;
|
||||
opacity:0.5;
|
||||
color:#aaaaaa;
|
||||
height:1px;
|
||||
}
|
||||
|
||||
.col1 {
|
||||
|
||||
width: 38%;
|
||||
padding-left:5%;
|
||||
padding-right:8%;
|
||||
float:left;
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:100;
|
||||
color:#606060;
|
||||
line-height:20px;
|
||||
letter-spacing:0.03em;
|
||||
font-size:14px;
|
||||
|
||||
}
|
||||
|
||||
.col2 {
|
||||
|
||||
width: 44%;
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
float:left;
|
||||
line-height:20px;
|
||||
color:#606060;
|
||||
letter-spacing:0.03em;
|
||||
font-size:14px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.fullcol {
|
||||
width:77%;
|
||||
margin-left:11%;
|
||||
margin-right:10%;
|
||||
margin-top:4%;
|
||||
margin-bottom:6%;
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
float:left;
|
||||
line-height:22px;
|
||||
color:#606060;
|
||||
letter-spacing:0.03em;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.cols {
|
||||
width:77%;
|
||||
margin-left:6%;
|
||||
margin-top:1%;
|
||||
margin-bottom:4%;
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
float:left;
|
||||
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:400;
|
||||
letter-spacing:0.9;
|
||||
font-size:20px;
|
||||
padding-bottom:0px;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 910px){
|
||||
|
||||
h1 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:bold;
|
||||
line-height:36px;
|
||||
letter-spacing:0.03em;
|
||||
font-size:30px !important;
|
||||
padding-bottom:0px;
|
||||
width:80%;
|
||||
}
|
||||
|
||||
.subhead {
|
||||
font-size:18px;
|
||||
font-weight:100;
|
||||
line-height:27px;
|
||||
}
|
||||
|
||||
.details {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
font-size:16px;
|
||||
color:#3366ff;
|
||||
letter-spacing:0.03em;
|
||||
padding-bottom:2%;
|
||||
line-height:28px;
|
||||
padding-top:4%;
|
||||
padding-left:10%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width:8%;
|
||||
}
|
||||
|
||||
.col1 {
|
||||
width: 100%;
|
||||
padding-left:5%;
|
||||
padding-right:8%;
|
||||
float:left;
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#606060;
|
||||
line-height:20px;
|
||||
letter-spacing:0.03em;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.col2 {
|
||||
width: 100%;
|
||||
padding-left:5%;
|
||||
padding-top:5%;
|
||||
padding-bottom:5%;
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
float:left;
|
||||
line-height:20px;
|
||||
color:#606060;
|
||||
letter-spacing:0.03em;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.banner1 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:15%;
|
||||
padding-bottom:2%;
|
||||
padding-left:10%;
|
||||
font-size:18px;
|
||||
background: url('/images/CaseStudy_peardeck_banner1.jpg');
|
||||
background-size:100% auto;
|
||||
}
|
||||
|
||||
.banner2 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:4%;
|
||||
padding-bottom:4%;
|
||||
padding-left:0%;
|
||||
font-size:18px;
|
||||
letter-spacing:0.03em;
|
||||
line-height:24px;
|
||||
width:100%;
|
||||
float:left;
|
||||
background:none;
|
||||
background-color:#666666;
|
||||
}
|
||||
|
||||
.banner3 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:5%;
|
||||
padding-bottom:5%;
|
||||
font-size:18px;
|
||||
letter-spacing:0.03em;
|
||||
line-height:24px;
|
||||
width:80%;
|
||||
padding-left:15%;
|
||||
padding-right:10%;
|
||||
float:left;
|
||||
background: url('/images/CaseStudy_peardeck_banner3.jpg');
|
||||
}
|
||||
|
||||
.banner4 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:5%;
|
||||
padding-bottom:5%;
|
||||
font-size:18px;
|
||||
letter-spacing:0.03em;
|
||||
line-height:24px;
|
||||
width:100%;
|
||||
float:left;
|
||||
background: url('/images/CaseStudy_peardeck_banner2.jpg');
|
||||
}
|
||||
|
||||
.banner5 {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
padding-top:4%;
|
||||
padding-bottom:4%;
|
||||
padding-left:0%;
|
||||
font-size:18px;
|
||||
letter-spacing:0.03em;
|
||||
line-height:24px;
|
||||
width:100%;
|
||||
float:left;
|
||||
background:none;
|
||||
background-color:#666666;
|
||||
}
|
||||
|
||||
.banner2text {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
width:80%;
|
||||
padding-left:10%;
|
||||
float:left;
|
||||
text-align:center;
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
.banner3text {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
width:80%;
|
||||
padding-left:2%;
|
||||
padding-right:10%;
|
||||
padding-top:5%;
|
||||
padding-bottom:5%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.banner4text {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
width:80%;
|
||||
padding-left:10%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.banner5text {
|
||||
font-family:"Roboto", sans-serif;
|
||||
font-weight:300;
|
||||
color:#ffffff;
|
||||
width:80%;
|
||||
padding-left:10%;
|
||||
float:left;
|
||||
text-align:center;
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
.fullcol {
|
||||
margin-top:6%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
line-height:26px;
|
||||
font-size:18px;
|
||||
}
|
||||
|
||||
.quote {
|
||||
font-size:18px;
|
||||
line-height:24px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width:35%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px){
|
||||
|
||||
.logo {
|
||||
width:50%;
|
||||
padding-bottom:5%;
|
||||
}
|
||||
}
|
||||
@@ -26,17 +26,17 @@ When multiple authorization modules are configured, each is checked in sequence,
|
||||
## Review Your Request Attributes
|
||||
Kubernetes reviews only the following API request attributes:
|
||||
|
||||
* **user** - The `user` string provided during authentication
|
||||
* **group** - The list of group names to which the authenticated user belongs
|
||||
* **"extra"** - A map of arbitrary string keys to string values, provided by the authentication layer
|
||||
* **API** - Indicates whether the request is for an API resource
|
||||
* **user** - The `user` string provided during authentication.
|
||||
* **group** - The list of group names to which the authenticated user belongs.
|
||||
* **"extra"** - A map of arbitrary string keys to string values, provided by the authentication layer.
|
||||
* **API** - Indicates whether the request is for an API resource.
|
||||
* **Request path** - Path to miscellaneous non-resource endpoints like `/api` or `/healthz`.
|
||||
* **API request verb** - API verbs `get`, `list`, `create`, `update`, `patch`, `watch`, `proxy`, `redirect`, `delete`, and `deletecollection` are used for resource requests. To determine the request verb for a resource API endpoint, see **Determine the request verb** below.
|
||||
* **HTTP request verb** - HTTP verbs `get`, `post`, `put`, and `delete` are used for non-resource requests
|
||||
* **HTTP request verb** - HTTP verbs `get`, `post`, `put`, and `delete` are used for non-resource requests.
|
||||
* **Resource** - The ID or name of the resource that is being accessed (for resource requests only)
|
||||
--* For resource requests using `get`, `update`, `patch`, and `delete` verbs, you must provide the resource name.
|
||||
* **Subresource** - The subresource that is being accessed (for resource requests only)
|
||||
* **Namespace** - The namespace of the object that is being accessed (for namespaced resource requests only)
|
||||
* **Subresource** - The subresource that is being accessed (for resource requests only).
|
||||
* **Namespace** - The namespace of the object that is being accessed (for namespaced resource requests only).
|
||||
* **API group** - The API group being accessed (for resource requests only). An empty string designates the [core API group](/docs/api/).
|
||||
|
||||
## Determine the Request Verb
|
||||
@@ -58,13 +58,13 @@ of the `bind` verb on `roles` and `clusterroles` resources in the `rbac.authoriz
|
||||
* [Authentication](/docs/admin/authentication/) layer checks for authorization of the `impersonate` verb on `users`, `groups`, and `serviceaccounts` in the core API group, and the `userextras` in the `authentication.k8s.io` API group.
|
||||
|
||||
## Authorization Modules
|
||||
* **Node** - A special-purpose authorizer that grants permissions to kubelets based on the pods they are scheduled to run. To learn more about using the Node authorization mode, see [Node Authorization](/docs/admin/authorization/node/)
|
||||
* **ABAC** - Attribute-based access control (ABAC) defines an access control paradigm whereby access rights are granted to users through the use of policies which combine attributes together. The policies can use any type of attributes (user attributes, resource attributes, object, environment attributes etc). To learn more about using the ABAC mode, see [ABAC Mode](/docs/admin/authorization/abac/)
|
||||
* **Node** - A special-purpose authorizer that grants permissions to kubelets based on the pods they are scheduled to run. To learn more about using the Node authorization mode, see [Node Authorization](/docs/admin/authorization/node/).
|
||||
* **ABAC** - Attribute-based access control (ABAC) defines an access control paradigm whereby access rights are granted to users through the use of policies which combine attributes together. The policies can use any type of attributes (user attributes, resource attributes, object, environment attributes etc). To learn more about using the ABAC mode, see [ABAC Mode](/docs/admin/authorization/abac/).
|
||||
* **RBAC** - Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within an enterprise. In this context, access is the ability of an individual user to perform a specific task, such as view, create, or modify a file. To learn more about using the RBAC mode, see [RBAC Mode](/docs/admin/authorization/rbac/)
|
||||
..* When specified "RBAC" (Role-Based Access Control) uses the "rbac.authorization.k8s.io" API group to drive authorization decisions, allowing admins to dynamically configure permission policies through the Kubernetes API.
|
||||
..* As of 1.6 RBAC mode is in beta.
|
||||
..* To enable RBAC, start the apiserver with `--authorization-mode=RBAC`.
|
||||
* **Webhook** - A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen. To learn more about using the Webhook mode, see [Webhook Mode](/docs/admin/authorization/webhook/)
|
||||
* **Webhook** - A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen. To learn more about using the Webhook mode, see [Webhook Mode](/docs/admin/authorization/webhook/).
|
||||
* **Custom Modules** - You can create custom modules for using with Kubernetes. To learn more, see **Custom Modules** below.
|
||||
|
||||
### Custom Modules
|
||||
|
||||
@@ -141,7 +141,7 @@ Access to other non-resource paths can be disallowed without restricting access
|
||||
to the REST api.
|
||||
|
||||
For further documentation refer to the authorization.v1beta1 API objects and
|
||||
[webhook.go](https://git.k8s.io/kubernetes/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go).
|
||||
[webhook.go](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go).
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Authorization: Bearer 07401b.f395accd246ae52d
|
||||
|
||||
Each valid token is backed by a secret in the `kube-system` namespace. You can
|
||||
find the full design doc
|
||||
[here](https://git.k8s.io/community/contributors/design-proposals/bootstrap-discovery.md).
|
||||
[here](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/bootstrap-discovery.md).
|
||||
|
||||
Here is what the secret looks like. Note that `base64(string)` indicates the
|
||||
value should be base64 encoded. The undecoded version is provided here for
|
||||
|
||||
@@ -23,7 +23,7 @@ At {{page.version}}, Kubernetes supports clusters with up to 5000 nodes. More sp
|
||||
|
||||
A cluster is a set of nodes (physical or virtual machines) running Kubernetes agents, managed by a "master" (the cluster-level control plane).
|
||||
|
||||
Normally the number of nodes in a cluster is controlled by the the value `NUM_NODES` in the platform-specific `config-default.sh` file (for example, see [GCE's `config-default.sh`](http://releases.k8s.io/{{page.githubbranch}}/cluster/gce/config-default.sh)).
|
||||
Normally the number of nodes in a cluster is controlled by the value `NUM_NODES` in the platform-specific `config-default.sh` file (for example, see [GCE's `config-default.sh`](http://releases.k8s.io/{{page.githubbranch}}/cluster/gce/config-default.sh)).
|
||||
|
||||
Simply changing that value to something very large, however, may cause the setup script to fail for many cloud providers. A GCE deployment, for example, will run in to quota issues and fail to bring the cluster up.
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@ kubefed init FEDERATION_NAME --host-cluster-context=HOST_CONTEXT
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Initialize federation control plane for a federation
|
||||
# named foo in the host cluster whose local kubeconfig
|
||||
# context is bar.
|
||||
kubefed init foo --host-cluster-context=bar
|
||||
# Initialize federation control plane for a federation
|
||||
# named foo in the host cluster whose local kubeconfig
|
||||
# context is bar.
|
||||
kubefed init foo --host-cluster-context=bar
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
@@ -15,7 +15,7 @@ kubefed options
|
||||
|
||||
```
|
||||
# Print flags inherited by all commands
|
||||
kubectl options
|
||||
kubefed options
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
@@ -15,7 +15,7 @@ kubefed version
|
||||
|
||||
```
|
||||
# Print the client and server versions for the current context
|
||||
kubectl version
|
||||
kubefed version
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
@@ -11,7 +11,7 @@ title: Running in Multiple Zones
|
||||
Kubernetes 1.2 adds support for running a single cluster in multiple failure zones
|
||||
(GCE calls them simply "zones", AWS calls them "availability zones", here we'll refer to them as "zones").
|
||||
This is a lightweight version of a broader Cluster Federation feature (previously referred to by the affectionate
|
||||
nickname ["Ubernetes"](https://git.k8s.io/community/contributors/design-proposals/federation.md)).
|
||||
nickname ["Ubernetes"](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/federation.md)).
|
||||
Full Cluster Federation allows combining separate
|
||||
Kubernetes clusters running in different regions or cloud providers
|
||||
(or on-premises data centers). However, many
|
||||
|
||||
@@ -84,7 +84,7 @@ sudo docker run -it --rm --privileged --net=host \
|
||||
gcr.io/google_containers/node-test:0.2
|
||||
```
|
||||
|
||||
Node conformance test is a containerized version of [node e2e test](https://git.k8s.io/community/contributors/devel/e2e-node-tests.md).
|
||||
Node conformance test is a containerized version of [node e2e test](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/devel/e2e-node-tests.md).
|
||||
By default, it runs all conformance tests.
|
||||
|
||||
Theoretically, you can run any node e2e test if you configure the container and
|
||||
|
||||
@@ -18,7 +18,7 @@ The aggregation layer allows Kubernetes to be extended with additional APIs, bey
|
||||
|
||||
The aggregation layer enables installing additional Kubernetes-style APIs in your cluster. These can either be pre-built, existing 3rd party solutions, such as [service-catalog](https://github.com/kubernetes-incubator/service-catalog/blob/master/README.md), or user-created APIs like [apiserver-builder](https://github.com/kubernetes-incubator/apiserver-builder/blob/master/README.md), which can get you started.
|
||||
|
||||
In 1.7 the aggregation layer runs in-process with the kube-apiserver. Until an extension resource is registered, the aggregation layer will do nothing. To register their API, users must add an APIService object, which "claims" the URL path in the Kubernetes API. At that point, the aggregation layer will proxy anything sent to that API path (e.g. /apis/myextension.mycompany.io/v1/…) to the registered APIService.
|
||||
In 1.7 the aggregation layer runs in-process with the kube-apiserver. Until an extension resource is registered, the aggregation layer will do nothing. To register an API, users must add an APIService object, which "claims" the URL path in the Kubernetes API. At that point, the aggregation layer will proxy anything sent to that API path (e.g. /apis/myextension.mycompany.io/v1/…) to the registered APIService.
|
||||
|
||||
Ordinarily, the APIService will be implemented by an *extension-apiserver* in a pod running in the cluster. This extension-apiserver will normally need to be paired with one or more controllers if active management of the added resources is needed. As a result, the apiserver-builder will actually provide a skeleton for both. As another example, when the service-catalog is installed, it provides both the extension-apiserver and controller for the services it provides.
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ which makes the connection subject to man-in-the-middle attacks, and
|
||||
**unsafe** to run over untrusted and/or public networks.
|
||||
|
||||
To verify this connection, use the `--kubelet-certificate-authority` flag to
|
||||
provide the apiserver with a root certificates bundle to use to verify the
|
||||
provide the apiserver with a root certificate bundle to use to verify the
|
||||
kubelet's serving certificate.
|
||||
|
||||
If that is not possible, use [SSH tunneling](/docs/concepts/architecture/master-node-communication/#ssh-tunnels)
|
||||
|
||||
@@ -63,7 +63,7 @@ The node condition is represented as a JSON object. For example, the following r
|
||||
]
|
||||
```
|
||||
|
||||
If the Status of the Ready condition is "Unknown" or "False" for longer than the `pod-eviction-timeout`, an argument passed to the [kube-controller-manager](/docs/admin/kube-controller-manager/), all of the Pods on the node are scheduled for deletion by the Node Controller. The default eviction timeout duration is **five minutes**. In some cases when the node is unreachable, the apiserver is unable to communicate with the kubelet on it. The decision to delete the pods cannot be communicated to the kubelet until it re-establishes communication with the apiserver. In the meantime, the pods which are scheduled for deletion may continue to run on the partitioned node.
|
||||
If the Status of the Ready condition is "Unknown" or "False" for longer than the `pod-eviction-timeout`, an argument is passed to the [kube-controller-manager](/docs/admin/kube-controller-manager) and all of the Pods on the node are scheduled for deletion by the Node Controller. The default eviction timeout duration is **five minutes**. In some cases when the node is unreachable, the apiserver is unable to communicate with the kubelet on it. The decision to delete the pods cannot be communicated to the kubelet until it re-establishes communication with the apiserver. In the meantime, the pods which are scheduled for deletion may continue to run on the partitioned node.
|
||||
|
||||
In versions of Kubernetes prior to 1.5, the node controller would [force delete](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods) these unreachable pods from the apiserver. However, in 1.5 and higher, the node controller does not force delete pods until it is confirmed that they have stopped running in the cluster. One can see these pods which may be running on an unreachable node as being in the "Terminating" or "Unknown" states. In cases where Kubernetes cannot deduce from the underlying infrastructure if a node has permanently left a cluster, the cluster administrator may need to delete the node object by hand. Deleting the node object from Kubernetes causes all the Pod objects running on it to be deleted from the apiserver, freeing up their names.
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@ It assumes some familiarity with concepts in the [User Guide](/docs/user-guide/)
|
||||
{% capture body %}
|
||||
## Planning a cluster
|
||||
|
||||
See the guides in [Picking the Right Solution](/docs/setup/pick-right-solution/) for examples of how to plan, set up, and configure Kubernetes clusters. The solutions listed this article are called *distros*.
|
||||
See the guides in [Picking the Right Solution](/docs/setup/pick-right-solution/) for examples of how to plan, set up, and configure Kubernetes clusters. The solutions listed in this article are called *distros*.
|
||||
|
||||
Before choosing a guide, here are some considerations:
|
||||
|
||||
- Do you just want to try out Kubernetes on your computer, or do you want to build a high-availability, multi-node cluster? Choose distros best suited for your needs.
|
||||
- **If you are designing for very high-availability**, learn about configuring [clusters in multiple zones](/docs/admin/multi-cluster).
|
||||
- **If you are designing for high-availability**, learn about configuring [clusters in multiple zones](/docs/admin/multi-cluster).
|
||||
- Will you be using **a hosted Kubernetes cluster**, such as [Google Container Engine (GKE)](https://cloud.google.com/container-engine/), or **hosting your own cluster**?
|
||||
- Will your cluster be **on-premises**, or **in the cloud (IaaS)**? Kubernetes does not directly support hybrid clusters. Instead, you can set up multiple clusters.
|
||||
- **If you are configuring Kubernetes on-premises**, consider which [networking model](/docs/admin/networking) fits best. One option for custom networking is [*OpenVSwitch GRE/VxLAN networking*](/docs/admin/ovs-networking/), which uses OpenVSwitch to set up networking between pods across Kubernetes nodes.
|
||||
|
||||
@@ -6,7 +6,7 @@ approvers:
|
||||
title: Managing Resources
|
||||
---
|
||||
|
||||
You've deployed your application and exposed it via a service. Now what? Kubernetes provides a number of tools to help you manage your application deployment, including scaling and updating. Among the features we'll discuss in more depth are [configuration files](/docs/user-guide/configuring-containers/#configuration-in-kubernetes) and [labels](/docs/user-guide/deploying-applications/#labels).
|
||||
You've deployed your application and exposed it via a service. Now what? Kubernetes provides a number of tools to help you manage your application deployment, including scaling and updating. Among the features that we will discuss in more depth are [configuration files](/docs/concepts/configuration/overview/) and [labels](/docs/concepts/overview/working-with-objects/labels/).
|
||||
|
||||
You can find all the files for this example [in our docs
|
||||
repo here](https://github.com/kubernetes/kubernetes.github.io/tree/{{page.docsbranch}}/docs/user-guide/).
|
||||
@@ -102,7 +102,7 @@ project/k8s/development
|
||||
└── my-pvc.yaml
|
||||
```
|
||||
|
||||
By default, performing a bulk operation on `project/k8s/development` will stop at the first level of the directory, not processing any subdirectories. If we tried to create the resources in this directory using the following command, we'd encounter an error:
|
||||
By default, performing a bulk operation on `project/k8s/development` will stop at the first level of the directory, not processing any subdirectories. If we had tried to create the resources in this directory using the following command, we would have encountered an error:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f project/k8s/development
|
||||
@@ -354,51 +354,11 @@ For more information, please see [kubectl edit](/docs/user-guide/kubectl/{{page.
|
||||
|
||||
### kubectl patch
|
||||
|
||||
Suppose you want to fix a typo of the container's image of a Deployment. One way to do that is with `kubectl patch`:
|
||||
|
||||
```shell
|
||||
# Suppose you have a Deployment with a container named "nginx" and its image "nignx" (typo),
|
||||
# use container name "nginx" as a key to update the image from "nignx" (typo) to "nginx"
|
||||
$ kubectl get deployment my-nginx -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
...
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nignx
|
||||
name: nginx
|
||||
...
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl patch deployment my-nginx -p'{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx"}]}}}}'
|
||||
"my-nginx" patched
|
||||
$ kubectl get pod my-nginx-1jgkf -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
...
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
name: nginx
|
||||
...
|
||||
```
|
||||
|
||||
The patch is specified using json.
|
||||
|
||||
The system ensures that you don't clobber changes made by other users or components by confirming that the `resourceVersion` doesn't differ from the version you edited. If you want to update regardless of other changes, remove the `resourceVersion` field when you edit the resource. However, if you do this, don't use your original configuration file as the source since additional fields most likely were set in the live state.
|
||||
|
||||
For more information, please see [kubectl patch](/docs/user-guide/kubectl/{{page.version}}/#patch) document.
|
||||
You can use `kubectl patch` to update API objects in place. This command supports JSON patch,
|
||||
JSON merge patch, and strategic merge patch. See
|
||||
[Update API Objects in Place Using kubectl patch](/docs/tasks/run-application/update-api-object-kubectl-patch/)
|
||||
and
|
||||
[kubectl patch](/docs/user-guide/kubectl/{{page.version}}/#patch).
|
||||
|
||||
## Disruptive updates
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ as are any environment variables specified statically in the Docker image.
|
||||
|
||||
### Cluster information
|
||||
|
||||
A list of all services that were running when a Container was created are available to that Container as environment variables.
|
||||
A list of all services that were running when a Container was created is available to that Container as environment variables.
|
||||
Those environment variables match the syntax of Docker links.
|
||||
|
||||
For a service named *foo* that maps to a container port named *bar*,
|
||||
|
||||
@@ -91,7 +91,7 @@ Even though Kubernetes provides a lot of functionality, there are always new sce
|
||||
|
||||
[Labels](/docs/concepts/overview/working-with-objects/labels/) empower users to organize their resources however they please. [Annotations](/docs/concepts/overview/working-with-objects/annotations/) enable users to decorate resources with custom information to facilitate their workflows and provide an easy way for management tools to checkpoint state.
|
||||
|
||||
Additionally, the [Kubernetes control plane](/docs/concepts/overview/components/) is built upon the same [APIs](/docs/reference/api-overview/) that are available to developers and users. Users can write their own controllers, such as [schedulers](https://git.k8s.io/community/contributors/devel/scheduler.md), with [their own APIs](https://git.k8s.io/community/contributors/design-proposals/extending-api.md) that can be targeted by a general-purpose [command-line tool](/docs/user-guide/kubectl-overview/).
|
||||
Additionally, the [Kubernetes control plane](/docs/concepts/overview/components/) is built upon the same [APIs](/docs/reference/api-overview/) that are available to developers and users. Users can write their own controllers, such as [schedulers](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/devel/scheduler.md), with [their own APIs](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/extending-api.md) that can be targeted by a general-purpose [command-line tool](/docs/user-guide/kubectl-overview/).
|
||||
|
||||
This [design](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/principles.md) has enabled a number of other systems to build atop Kubernetes.
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ We did this in a previous example, but let's do it once again and focus on the n
|
||||
{% include code.html language="yaml" file="run-my-nginx.yaml" ghlink="/docs/concepts/services-networking/run-my-nginx.yaml" %}
|
||||
|
||||
This makes it accessible from any node in your cluster. Check the nodes the pod is running on:
|
||||
user
|
||||
|
||||
```shell
|
||||
$ kubectl create -f ./run-my-nginx.yaml
|
||||
$ kubectl get pods -l run=my-nginx -o wide
|
||||
|
||||
@@ -33,7 +33,7 @@ an application. Examples are:
|
||||
- cloud provider or hypervisor failure makes VM disappear
|
||||
- a kernel panic
|
||||
- if the node to disappears from the cluster due to cluster network partition
|
||||
- eviction of a pod due to the node being [out-of-resources](/docs/tasks/administer-cluster/out-of-resource.md).
|
||||
- eviction of a pod due to the node being [out-of-resources](/docs/tasks/administer-cluster/out-of-resource/).
|
||||
|
||||
Except for the out-of-resources condition, all these conditions
|
||||
should be familiar to most users; they are not specific
|
||||
@@ -49,7 +49,7 @@ Administrator. Typical application owner actions include:
|
||||
|
||||
Cluster Administrator actions include:
|
||||
|
||||
- [Draining a node](/docs//tasks/administer-cluster/safely-drain-node.md) for repair or upgrade.
|
||||
- [Draining a node](/docs/tasks/administer-cluster/safely-drain-node/) for repair or upgrade.
|
||||
- Draining a node from a cluster to scale the cluster down (learn about
|
||||
[Cluster Autoscaling](/docs/tasks/administer-cluster/cluster-management/#cluster-autoscaler)
|
||||
).
|
||||
@@ -68,8 +68,8 @@ Here are some ways to mitigate involuntary disruptions:
|
||||
|
||||
- Ensure your pod [requests the resources](/docs/tasks/configure-pod-container/assign-cpu-ram-container) it needs.
|
||||
- Replicate your application if you need higher availability. (Learn about running replicated
|
||||
[stateless](/docs/tasks/run-application/run-stateless-application-deployment.md)
|
||||
and [stateful](/docs/tasks/run-application/run-replicated-stateful-application.md) applications.)
|
||||
[stateless](/docs/tasks/run-application/run-stateless-application-deployment/)
|
||||
and [stateful](/docs/tasks/run-application/run-replicated-stateful-application/) applications.)
|
||||
- For even higher availability when running replicated applications,
|
||||
spread applications across racks (using
|
||||
[anti-affinity](/docs/user-guide/node-selection/#inter-pod-affinity-and-anti-affinity-beta-feature))
|
||||
@@ -259,9 +259,9 @@ the nodes in your cluster, such as a node or system software upgrade, here are s
|
||||
|
||||
{% capture whatsnext %}
|
||||
|
||||
* Follow steps to protect your application by [configuring a Pod Disruption Budget](/docs/tasks/run-application//configure-pdb.md).
|
||||
* Follow steps to protect your application by [configuring a Pod Disruption Budget](/docs/tasks/run-application/configure-pdb/).
|
||||
|
||||
* Learn more about [draining nodes](/docs/tasks/administer-cluster//safely-drain-node.md)
|
||||
* Learn more about [draining nodes](/docs/tasks/administer-cluster/safely-drain-node/)
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ managed in Kubernetes.
|
||||
## What is a Pod?
|
||||
|
||||
A _pod_ (as in a pod of whales or pea pod) is a group of one or more containers
|
||||
(such as Docker containers), the shared storage for those containers, and
|
||||
options about how to run the containers. A pod's contents are always co-located and
|
||||
(such as Docker containers), with shared storage/network, and a specification
|
||||
for how to run the containers. A pod's contents are always co-located and
|
||||
co-scheduled, and run in a shared context. A pod models an
|
||||
application-specific "logical host" - it contains one or more application
|
||||
containers which are relatively tightly coupled — in a pre-container
|
||||
|
||||
@@ -71,22 +71,22 @@ guide to install the requirements and install the script.
|
||||
|
||||
```shell
|
||||
# system
|
||||
apt-get update
|
||||
apt-get install -y git python python-crypto
|
||||
curl -O https://bootstrap.pypa.io/get-pip.py
|
||||
python get-pip.py
|
||||
apt-get update
|
||||
apt-get install -y git python python-crypto
|
||||
curl -O https://bootstrap.pypa.io/get-pip.py
|
||||
python get-pip.py
|
||||
|
||||
# installing this repository
|
||||
mkdir -p ~home/k8s-on-clc
|
||||
cd ~home/k8s-on-clc
|
||||
git clone https://github.com/CenturyLinkCloud/adm-kubernetes-on-clc.git
|
||||
cd adm-kubernetes-on-clc/
|
||||
pip install -r requirements.txt
|
||||
mkdir -p ~home/k8s-on-clc
|
||||
cd ~home/k8s-on-clc
|
||||
git clone https://github.com/CenturyLinkCloud/adm-kubernetes-on-clc.git
|
||||
cd adm-kubernetes-on-clc/
|
||||
pip install -r requirements.txt
|
||||
|
||||
# getting started
|
||||
cd ansible
|
||||
cp credentials.sh.template credentials.sh; vi credentials.sh
|
||||
source credentials.sh
|
||||
cd ansible
|
||||
cp credentials.sh.template credentials.sh; vi credentials.sh
|
||||
source credentials.sh
|
||||
```
|
||||
|
||||
|
||||
@@ -252,9 +252,9 @@ kubectl cluster-info
|
||||
|
||||
### Accessing the cluster programmatically
|
||||
|
||||
It's possible to use the locally stored client certificates to access the api server. For example, you may want to use any of the [Kubernetes API client libraries](/docs/reference/client-libraries/) to program against your Kubernetes cluster in the programming language of your choice.
|
||||
It's possible to use the locally stored client certificates to access the apiserver. For example, you may want to use any of the [Kubernetes API client libraries](/docs/reference/client-libraries/) to program against your Kubernetes cluster in the programming language of your choice.
|
||||
|
||||
To demonstrate how to use these locally stored certificates, we provide the following example of using ```curl``` to communicate to the master api server via https:
|
||||
To demonstrate how to use these locally stored certificates, we provide the following example of using ```curl``` to communicate to the master apiserver via https:
|
||||
|
||||
```shell
|
||||
curl \
|
||||
|
||||
@@ -42,7 +42,7 @@ Explore the following resources for more information about Kubernetes, Kubernete
|
||||
## Prerequisites
|
||||
|
||||
- A running [DCOS cluster](https://mesosphere.com/product/)
|
||||
- [DCOS Community Edition](https://docs.mesosphere.com/install/) is currently available on [AWS](https://mesosphere.com/amazon/).
|
||||
- [DCOS Community Edition](https://docs.mesosphere.com/1.7/archived-dcos-enterprise-edition/installing-enterprise-edition-1-6/cloud/) is currently available on [AWS](https://mesosphere.com/amazon/).
|
||||
- [DCOS Enterprise Edition](https://mesosphere.com/product/) can be deployed on virtual or bare metal machines. Contact sales@mesosphere.com for more info and to set up an engagement.
|
||||
- [DCOS CLI](https://docs.mesosphere.com/install/cli/) installed locally
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ up example apps.
|
||||
|
||||
You can use` gcloud` to install the `kubectl` command-line tool on your workstation:
|
||||
|
||||
gcloud components install kubectl
|
||||
gcloud components install kubectl
|
||||
|
||||
**Note:** The kubectl version bundled with `gcloud` may be older than the one
|
||||
downloaded by the get.k8s.io install script. See [Installing kubectl](/docs/tasks/kubectl/install/)
|
||||
|
||||
@@ -152,7 +152,7 @@ This flag is repeated, so you can pass it several times with several different v
|
||||
This flag takes a string of the form `component.key=value`, where `component` is one of the strings from the below list, `key` is a value on the
|
||||
configuration struct and `value` is the value to set.
|
||||
|
||||
Valid `key`s can be found by examining the documentation for the Kubernetes `componentconfigs` for each component.
|
||||
Valid keys can be found by examining the documentation for the Kubernetes `componentconfigs` for each component.
|
||||
Here is the documentation for each supported configuration:
|
||||
|
||||
* [kubelet](https://godoc.org/k8s.io/kubernetes/pkg/apis/componentconfig#KubeletConfiguration)
|
||||
|
||||
@@ -197,7 +197,7 @@ See the [OpenStack CLI Reference](http://docs.openstack.org/cli-reference/) for
|
||||
### Salt
|
||||
|
||||
The OpenStack-Heat provider uses a [standalone Salt configuration](/docs/admin/salt/#standalone-salt-configuration-on-gce-and-others).
|
||||
It only uses Salt for bootstraping the machines and creates no salt-master and does not auto-start the salt-minion service on the nodes.
|
||||
It only uses Salt for bootstrapping the machines and creates no salt-master and does not auto-start the salt-minion service on the nodes.
|
||||
|
||||
## SSHing to your nodes
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ $ cat <<EOF >/etc/rkt/net.d/k8s_flannel_example.conf
|
||||
EOF
|
||||
```
|
||||
|
||||
For more information on flannel configuration, see the [CNI/flannel README](https://github.com/containernetworking/cni/blob/master/Documentation/flannel.md).
|
||||
For more information on flannel configuration, see the [CNI/flannel README](https://github.com/containernetworking/plugins/blob/master/plugins/meta/flannel/README.md).
|
||||
|
||||
#### Contained network caveats:
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ You will install these packages on all of your machines:
|
||||
**Note:** If you already have kubeadm installed, you should do a `apt-get update &&
|
||||
apt-get upgrade` or `yum update` to get the latest version of kubeadm. See the
|
||||
kubeadm release notes if you want to read about the different [kubeadm
|
||||
releases](https://git.k8s.io/kubeadm/CHANGELOG.md)
|
||||
releases](https://github.com/kubernetes/kubeadm/blob/master/CHANGELOG.md)
|
||||
|
||||
For each machine:
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ See documentation for other libraries for how they authenticate.
|
||||
### Accessing the API from a Pod
|
||||
|
||||
When accessing the API from a pod, locating and authenticating
|
||||
to the api server are somewhat different.
|
||||
to the apiserver are somewhat different.
|
||||
|
||||
The recommended way to locate the apiserver within the pod is with
|
||||
the `kubernetes` DNS name, which resolves to a Service IP which in turn
|
||||
|
||||
@@ -64,11 +64,11 @@ for database debugging.
|
||||
|
||||
1. Start the Redis command line interface:
|
||||
|
||||
redis-cli
|
||||
redis-cli
|
||||
|
||||
1. At the Redis command line prompt, enter the `ping` command:
|
||||
|
||||
127.0.0.1:6379>ping
|
||||
127.0.0.1:6379>ping
|
||||
|
||||
A successful ping request returns PONG.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ but is not allowed to use more CPU than its limit.
|
||||
|
||||
{% include task-tutorial-prereqs.md %}
|
||||
|
||||
Each node in your cluster must have at least 1 CPU.
|
||||
Each node in your cluster must have at least 1 cpu.
|
||||
|
||||
A few of the steps on this page require that the
|
||||
[Heapster](https://github.com/kubernetes/heapster) service is running
|
||||
@@ -55,7 +55,7 @@ kubectl create namespace cpu-example
|
||||
To specify a CPU request for a Container, include the `resources:requests` field
|
||||
in the Container's resource manifest. To specify a CPU limit, include `resources:limits`.
|
||||
|
||||
In this exercise, you create a Pod that has one Container. The container has a CPU
|
||||
In this exercise, you create a Pod that has one Container. The Container has a CPU
|
||||
request of 0.5 cpu and a CPU limit of 1 cpu. Here's the configuration file
|
||||
for the Pod:
|
||||
|
||||
@@ -116,7 +116,7 @@ the limit of 1 cpu specified in the Pod's configuration file.
|
||||
```
|
||||
|
||||
Recall that by setting `-cpu "2"`, you configured the Container to attempt to use 2 cpus.
|
||||
But the container is only being allowed to use about 1 cpu. The Container's CPU use is being
|
||||
But the Container is only being allowed to use about 1 cpu. The Container's CPU use is being
|
||||
throttled, because the Container is attempting to use more CPU resources than its limit.
|
||||
|
||||
Note: There's another possible explanation for the CPU throttling. The Node might not have
|
||||
|
||||
@@ -54,7 +54,7 @@ kubectl create namespace mem-example
|
||||
To specify a memory request for a Container, include the `resources:requests` field
|
||||
in the Container's resource manifest. To specify a memory limit, include `resources:limits`.
|
||||
|
||||
In this exercise, you create a Pod that has one Container. The container has a memory
|
||||
In this exercise, you create a Pod that has one Container. The Container has a memory
|
||||
request of 100 MiB and a memory limit of 200 MiB. Here's the configuration file
|
||||
for the Pod:
|
||||
|
||||
@@ -127,7 +127,7 @@ kubectl delete pod memory-demo --namespace=mem-example
|
||||
## Exceed a Container's memory limit
|
||||
|
||||
A Container can exceed its memory request if the Node has memory available. But a Container
|
||||
is not allowed to use more than its memory limit. If a container allocates more memory than
|
||||
is not allowed to use more than its memory limit. If a Container allocates more memory than
|
||||
its limit, the Container becomes a candidate for termination. If the Container continues to
|
||||
to consume memory beyond its limit, the Container is terminated. If a terminated Container is
|
||||
restartable, the kubelet will restart it, as with any other type of runtime failure.
|
||||
@@ -341,15 +341,15 @@ kubectl delete namespace mem-example
|
||||
|
||||
### For app developers
|
||||
|
||||
* [Assign CPU Resources to Containers and Pods](docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
* [Assign CPU Resources to Containers and Pods](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
* [Configure Quality of Service for Pods](/docs/tasks/configure-pod-container/quality-service-pod/)
|
||||
|
||||
### For cluster administrators
|
||||
|
||||
* [Configure Default Memory Requests and Limits for a Namespace](docs/tasks/administer-cluster/default-memory-request-limit/)
|
||||
* [Configure Default Memory Requests and Limits for a Namespace](/docs/tasks/administer-cluster/memory-default-namespace/)
|
||||
|
||||
* [Configure Default CPU Requests and Limits for a Namespace](docs/tasks/administer-cluster/default-cpu-request-limit/)
|
||||
* [Configure Default CPU Requests and Limits for a Namespace](/docs/tasks/administer-cluster/cpu-default-namespace/)
|
||||
|
||||
* [Configure Minimum and Maximum Memory Constraints for a Namespace](/docs/tasks/administer-cluster/memory-constraint-namespace/)
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ When a ConfigMap already being consumed in a volume is updated, projected keys a
|
||||
|
||||
### Restrictions
|
||||
|
||||
1. You must create a ConfigMap before referencing it in a Pod specification (unless you mark the ConfigMap as "optional"). If you reference a ConfigMaps that doesn't exist, the Pod won't start. Likewise, references to keys that don't exist in the ConfigMap will prevent the pod from starting.
|
||||
1. You must create a ConfigMap before referencing it in a Pod specification (unless you mark the ConfigMap as "optional"). If you reference a ConfigMap that doesn't exist, the Pod won't start. Likewise, references to keys that don't exist in the ConfigMap will prevent the pod from starting.
|
||||
|
||||
1. If you use `envFrom` to define environment variables from ConfigMaps, keys that are considered invalid will be skipped. The pod will be allowed to start, but the invalid names will be recorded in the event log (`InvalidVariableNames`). The log message lists each skipped key. For example:
|
||||
|
||||
|
||||
@@ -240,13 +240,13 @@ kubectl delete namespace qos-example
|
||||
|
||||
* [Assign Memory Resources to Containers and Pods](/docs/tasks/configure-pod-container/assign-memory-resource/)
|
||||
|
||||
* [Assign CPU Resources to Containers and Pods](docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
* [Assign CPU Resources to Containers and Pods](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
### For cluster administrators
|
||||
|
||||
* [Configure Default Memory Requests and Limits for a Namespace](docs/tasks/administer-cluster/default-memory-request-limit/)
|
||||
* [Configure Default Memory Requests and Limits for a Namespace](/docs/tasks/administer-cluster/default-memory-request-limit/)
|
||||
|
||||
* [Configure Default CPU Requests and Limits for a Namespace](docs/tasks/administer-cluster/default-cpu-request-limit/)
|
||||
* [Configure Default CPU Requests and Limits for a Namespace](/docs/tasks/administer-cluster/default-cpu-request-limit/)
|
||||
|
||||
* [Configure Minimum and Maximum Memory Constraints for a Namespace](/docs/tasks/administer-cluster/memory-constraint-namespace/)
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ coredns-provider.conf has below format:
|
||||
|
||||
- `etcd-endpoints` is the endpoint to access etcd.
|
||||
- `zones` is the federation domain for which CoreDNS is authoritative and is same as --dns-zone-name flag of `kubefed init`.
|
||||
- `coredns-endpoints` is the endpoint to access coredns server. This is an optional parameter introduced from v1.7 onwards.
|
||||
- `coredns-endpoints` is the endpoint to access CoreDNS server. This is an optional parameter introduced from v1.7 onwards.
|
||||
|
||||
*Note: middleware.etcd.zones in CoreDNS configuration and --dns-zone-name
|
||||
flag to kubefed init should match.*
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: patch-demo
|
||||
spec:
|
||||
replicas: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: patch-demo-ctr
|
||||
image: nginx
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"spec": {
|
||||
"template": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "patch-demo-ctr-2",
|
||||
"image": "redis"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
---
|
||||
title: Update API Objects in Place Using kubectl patch
|
||||
description: Use kubectl patch to update Kubernetes API objects in place. Do a strategic merge patch or a JSON merge patch.
|
||||
---
|
||||
|
||||
{% capture overview %}
|
||||
|
||||
This task shows how to use `kubectl patch` to update an API object in place. The exercises
|
||||
in this task demonstrate a strategic merge patch and a JSON merge patch.
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
{% capture prerequisites %}
|
||||
|
||||
{% include task-tutorial-prereqs.md %}
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
|
||||
{% capture steps %}
|
||||
|
||||
## Use a strategic merge patch to update a Deployment
|
||||
|
||||
Here's the configuration file for a Deployment that has two replicas. Each replica
|
||||
is a Pod that has one container:
|
||||
|
||||
{% include code.html language="yaml" file="deployment-patch-demo.yaml" ghlink="/docs/tasks/run-application/deployment-patch-demo.yaml" %}
|
||||
|
||||
Create the Deployment:
|
||||
|
||||
```shell
|
||||
kubectl create -f https://k8s.io/docs/tasks/run-application/deployment-patch-demo.yaml
|
||||
```
|
||||
|
||||
View the Pods associated with your Deployment:
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
The output shows that the Deployment has two Pods. The `1/1` indicates that
|
||||
each Pod has one container:
|
||||
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
patch-demo-28633765-670qr 1/1 Running 0 23s
|
||||
patch-demo-28633765-j5qs3 1/1 Running 0 23s
|
||||
```
|
||||
|
||||
Make a note of the names of the running Pods. Later, you will see that these Pods
|
||||
get terminated and replaced by new ones.
|
||||
|
||||
At this point, each Pod has one Container that runs the nginx image. Now suppose
|
||||
you want each Pod to have two containers: one that runs nginx and one that runs redis.
|
||||
|
||||
Create a file named `patch-file.yaml` that has this content:
|
||||
|
||||
```shell
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: patch-demo-ctr-2
|
||||
image: redis
|
||||
```
|
||||
|
||||
Patch your Deployment:
|
||||
|
||||
```shell
|
||||
kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)"
|
||||
```
|
||||
|
||||
View the patched Deployment:
|
||||
|
||||
```shell
|
||||
kubectl get deployment patch-demo --output yaml
|
||||
```
|
||||
|
||||
The output shows that the PodSpec in the Deployment has two Containers:
|
||||
|
||||
```shell
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: Always
|
||||
name: patch-demo-ctr
|
||||
...
|
||||
- image: redis
|
||||
imagePullPolicy: Always
|
||||
name: patch-demo-ctr-2
|
||||
...
|
||||
```
|
||||
|
||||
View the Pods associated with your patched Deployment:
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
The output shows that the running Pods have different names from the Pods that
|
||||
were running previously. The Deployment terminated the old Pods and created two
|
||||
new Pods that comply with the updated Deployment spec. The `2/2` indicates that
|
||||
each Pod has two Containers:
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
patch-demo-1081991389-2wrn5 2/2 Running 0 1m
|
||||
patch-demo-1081991389-jmg7b 2/2 Running 0 1m
|
||||
```
|
||||
|
||||
Take a closer look at one of the patch-demo Pods:
|
||||
|
||||
```shell
|
||||
kubectl get pod <your-pod-name> --output yaml
|
||||
```
|
||||
|
||||
The output shows that the Pod has two Containers: one running nginx and one running redis:
|
||||
|
||||
```
|
||||
containers:
|
||||
- image: nginx
|
||||
...
|
||||
- image: redis
|
||||
...
|
||||
```
|
||||
|
||||
### Notes on the strategic merge patch
|
||||
|
||||
With a patch, you do not have to specify an entire object; you specify only the portion
|
||||
of the object that you want to change. For example, in the preceding exercise, you specified
|
||||
one Container in the `containers` list in a `PodSpec`.
|
||||
|
||||
The patch you did in the preceding exercise is called a *strategic merge patch*.
|
||||
With a strategic merge patch, you can update a list by specifying only the elements
|
||||
that you want to add to the list. The existing list elements remain, and the new elements
|
||||
are merged with the existing elements. In the preceding exercise, the resulting `containers`
|
||||
list has both the original nginx Container and the new redis Container.
|
||||
|
||||
## Use a JSON merge patch to update a Deployment
|
||||
|
||||
A strategic merge patch is different from a
|
||||
[JSON merge patch](https://tools.ietf.org/html/rfc6902).
|
||||
With a JSON merge patch, if you
|
||||
want to update a list, you have to specify the entire new list. And the new list completely
|
||||
replaces the existing list.
|
||||
|
||||
The `kubectl patch` command has a `type` parameter that you can set to one of these values:
|
||||
|
||||
<table>
|
||||
<tr><th>Parameter value</th><th>Merge type</th></tr>
|
||||
<tr><td>json</td><td><a href="https://tools.ietf.org/html/rfc6902">JSON Patch, RFC 6902</a></td></tr>
|
||||
<tr><td>merge</td><td><a href="https://tools.ietf.org/html/rfc7386">JSON Merge Patch, RFC 7386</a></td></tr>
|
||||
<tr><td>strategic</td><td>Strategic merge patch</td></tr>
|
||||
</table>
|
||||
|
||||
For a comparison of JSON patch and JSON merge patch, see
|
||||
[JSON Patch and JSON Merge Patch](http://erosb.github.io/post/json-patch-vs-merge-patch/).
|
||||
|
||||
The default value for the `type` parameter is `strategic`. So in the preceding exercise, you
|
||||
did a strategic merge patch.
|
||||
|
||||
Next, do a JSON merge patch on your same Deployment. Create a file named `patch-file-2.yaml`
|
||||
that has this content:
|
||||
|
||||
```shell
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: patch-demo-ctr-3
|
||||
image: gcr.io/google-samples/node-hello:1.0
|
||||
```
|
||||
|
||||
In your patch command, set `type` to `merge`:
|
||||
|
||||
```shell
|
||||
kubectl patch deployment patch-demo --type merge --patch "$(cat patch-file-2.yaml)"
|
||||
```
|
||||
|
||||
View the patched Deployment:
|
||||
|
||||
```shell
|
||||
kubectl get deployment patch-demo --output yaml
|
||||
```
|
||||
|
||||
The `containers` list that you specified in the patch has only one Container.
|
||||
The output shows that your list of one Container replaced the existing `containers` list.
|
||||
|
||||
```shell
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/google-samples/node-hello:1.0
|
||||
...
|
||||
name: patch-demo-ctr-3
|
||||
```
|
||||
|
||||
List the running Pods:
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
In the output, you can see that the existing Pods were terminated, and new Pods
|
||||
were created. The `1/1` indicates that each new Pod is running only one Container.
|
||||
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
patch-demo-1307768864-69308 1/1 Running 0 1m
|
||||
patch-demo-1307768864-c86dc 1/1 Running 0 1m
|
||||
```
|
||||
|
||||
## Alternate forms of the kubectl patch command
|
||||
|
||||
The `kubectl patch` command takes YAML or JSON. It can take the patch as a file or
|
||||
directly on the command line.
|
||||
|
||||
Create a file named `patch-file.json` that has this content:
|
||||
|
||||
```shell
|
||||
{
|
||||
"spec": {
|
||||
"template": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "patch-demo-ctr-2",
|
||||
"image": "redis"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The following commands are equivalent:
|
||||
|
||||
|
||||
```shell
|
||||
kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)"
|
||||
kubectl patch deployment patch-demo --patch $'spec:\n template:\n spec:\n containers:\n - name: patch-demo-ctr-2\n image: redis'
|
||||
|
||||
kubectl patch deployment patch-demo --patch "$(cat patch-file.json)"
|
||||
kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "patch-demo-ctr-2","image": "redis"}]}}}}'
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
In this exercise, you `kubectl patch` to change the live configuration
|
||||
of a Deployment object. You did not change the configuration file that you originally used to
|
||||
create the Deployment object. Other commands for updating API objects include
|
||||
[kubectl annotate](/docs/user-guide/kubectl/{{page.version}}/#annotate),
|
||||
[kubectl edit](/docs/user-guide/kubectl/v1.7/#edit),
|
||||
[kubectl replace](/docs/user-guide/kubectl/v1.7/#replace),
|
||||
[kubectl scale](/docs/user-guide/kubectl/v1.7/#scale),
|
||||
[kubectl update](/docs/user-guide/kubectl/v1.7/#update). and
|
||||
[kubectl apply](/docs/user-guide/kubectl/v1.7/#apply).
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
|
||||
{% capture whatsnext %}
|
||||
|
||||
* [Kubernetes Object Management](/docs/tutorials/object-management-kubectl/object-management/)
|
||||
* [Managing Kubernetes Objects Using Imperative Commands](/docs/tutorials/object-management-kubectl/imperative-object-management-command/)
|
||||
* [Imperative Management of Kubernetes Objects Using Configuration Files](/docs/tutorials/object-management-kubectl/imperative-object-management-configuration/)
|
||||
* [Declarative Management of Kubernetes Objects Using Configuration Files](/docs/tutorials/object-management-kubectl/declarative-object-management-configuration/)
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
{% include templates/task.md %}
|
||||
@@ -119,7 +119,7 @@ kubectl is available as a [snap](https://snapcraft.io/) application.
|
||||
choco install kubernetes-cli
|
||||
|
||||
2. Run `kubectl version` to verify that the verison you've installed is sufficiently up-to-date.
|
||||
3. Configure kubectl to use a remote kubernetes cluster:
|
||||
3. Configure kubectl to use a remote Kubernetes cluster:
|
||||
|
||||
cd C:\users\yourusername (Or wherever your %HOME% directory is)
|
||||
mkdir .kube
|
||||
@@ -185,7 +185,7 @@ If you have installed kubectl manually, you need to add kubectl autocompletion t
|
||||
kubectl completion bash > $(brew --prefix)/etc/bash_completion.d/kubectl
|
||||
```
|
||||
|
||||
The Homebrew project is independent from kubernetes, so the bash-completion packages are not guaranteed to work.
|
||||
The Homebrew project is independent from Kubernetes, so the bash-completion packages are not guaranteed to work.
|
||||
|
||||
### Using Oh-My-Zsh
|
||||
When using [Oh-My-Zsh](http://ohmyz.sh/), edit the ~/.zshrc file and update the `plugins=` line to include the kubectl plugin.
|
||||
|
||||
@@ -29,7 +29,7 @@ title: Using a Service to Expose Your App
|
||||
|
||||
<p>Kubernetes <a href="/docs/concepts/workloads/pods/pod-overview/">Pods</a> are mortal. Pods in fact have a <a href="/docs/concepts/workloads/pods/pod-lifecycle/">lifecycle</a>. When a worker node dies, the Pods running on the Node are also lost. A <a href="/docs/user-guide/replication-controller/#what-is-a-replicationcontroller">ReplicationController</a> might then dynamically drive the cluster back to desired state via creation of new Pods to keep your application running. As another example, consider an image-processing backend with 3 replicas. Those replicas are fungible; the front-end system should not care about backend replicas or even if a Pod is lost and recreated. That said, each Pod in a Kubernetes cluster has a unique IP address, even Pods on the same Node, so there needs to be a way of automatically reconciling changes among Pods so that your applications continue to function.</p>
|
||||
|
||||
<p>Enter <i>Services</i>. A Service in Kubernetes is an abstraction which defines a logical set of Pods and a policy by which to access them. Services enable a loose coupling between dependent Pods. A Service is defined using YAML <a href="/docs/concepts/configuration/overview/#general-config-tips">(preferred)</a> or JSON, like all Kubernetes objects. The set of Pods targeted by a Service is usually determined by a <i>LabelSelector</i> (see below for why you might want a Service without including <code>selector</code> in the spec).</p>
|
||||
<p>A Service in Kubernetes is an abstraction which defines a logical set of Pods and a policy by which to access them. Services enable a loose coupling between dependent Pods. A Service is defined using YAML <a href="/docs/concepts/configuration/overview/#general-config-tips">(preferred)</a> or JSON, like all Kubernetes objects. The set of Pods targeted by a Service is usually determined by a <i>LabelSelector</i> (see below for why you might want a Service without including <code>selector</code> in the spec).</p>
|
||||
|
||||
<p>Although Pods each have a unique IP address, those IPs are not exposed outside the cluster without a Service. Services allow your applications to receive traffic. Services can be exposed in different ways by specifying a <code>type</code> in the ServiceSpec:</p>
|
||||
<ul>
|
||||
|
||||
+3
-3
@@ -20,7 +20,7 @@ The `kubectl` tool supports three kinds of object management:
|
||||
* Imperative object configuration
|
||||
* Declarative object configuration
|
||||
|
||||
See [Kubernetes Object Management](/docs/concepts/tools/kubectl/object-management-overview/)
|
||||
See [Kubernetes Object Management](/docs/tutorials/object-management-kubectl/object-management/)
|
||||
for a discussion of the advantages and disadvantage of each kind of object management.
|
||||
|
||||
## Before you begin
|
||||
@@ -29,8 +29,8 @@ Declarative object configuration requires a firm understanding of
|
||||
the Kubernetes object definitions and configuration. Read and complete
|
||||
the following documents if you have not already:
|
||||
|
||||
- [Managing Kubernetes Objects Using Imperative Commands](/docs/concepts/tools/kubectl/object-management-using-imperative-commands/)
|
||||
- [Imperative Management of Kubernetes Objects Using Configuration Files](/docs/concepts/tools/kubectl/object-management-using-imperative-config/)
|
||||
- [Managing Kubernetes Objects Using Imperative Commands](/docs/tutorials/object-management-kubectl/imperative-object-management-command/)
|
||||
- [Imperative Management of Kubernetes Objects Using Configuration Files](docs/tutorials/object-management-kubectl/imperative-object-management-configuration/)
|
||||
|
||||
Following are definitions for terms used in this document:
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ The `kubectl` tool supports three kinds of object management:
|
||||
* Imperative object configuration
|
||||
* Declarative object configuration
|
||||
|
||||
See [Kubernetes Object Management](/docs/concepts/tools/kubectl/object-management-overview/)
|
||||
See [Kubernetes Object Management](/docs/tutorials/object-management-kubectl/object-management/)
|
||||
for a discussion of the advantages and disadvantage of each kind of object management.
|
||||
|
||||
## How to create objects
|
||||
|
||||
@@ -121,7 +121,7 @@ $ NODEPORT=$(kubectl get -o jsonpath="{.spec.ports[0].nodePort}" services nodepo
|
||||
$ NODES=$(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="ExternalIP")].address }')
|
||||
```
|
||||
|
||||
if you're running on a cloudprovider, you may need to open up a firewall-rule
|
||||
If you're running on a cloudprovider, you may need to open up a firewall-rule
|
||||
for the `nodes:nodeport` reported above.
|
||||
Now you can try reaching the Service from outside the cluster through the node
|
||||
port allocated above.
|
||||
@@ -181,7 +181,7 @@ client_address=104.132.1.79
|
||||
```
|
||||
|
||||
Note that you only got one reply, with the *right* client IP, from the one node on which the endpoint pod
|
||||
is running on.
|
||||
is running.
|
||||
|
||||
This is what happens:
|
||||
|
||||
@@ -293,7 +293,7 @@ client_address=104.132.1.79
|
||||
|
||||
__Cross platform support__
|
||||
|
||||
As of Kubernetes 1.5 support for source IP preservation through Services
|
||||
As of Kubernetes 1.5, support for source IP preservation through Services
|
||||
with Type=LoadBalancer is only implemented in a subset of cloudproviders
|
||||
(GCP and Azure). The cloudprovider you're running on might fulfill the
|
||||
request for a loadbalancer in a few different ways:
|
||||
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Reference in New Issue
Block a user