mirror of https://github.com/knative/docs.git
1597 lines
212 KiB
XML
1597 lines
212 KiB
XML
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||
<channel>
|
||
<title>Knative – Knative Serving code samples</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/</link>
|
||
<description>Recent content in Knative Serving code samples on Knative</description>
|
||
<generator>Hugo -- gohugo.io</generator>
|
||
|
||
<atom:link href="https://knative.dev/v0.21-docs/serving/samples/index.xml" rel="self" type="application/rss+xml" />
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Knative Serving 'Cloud Events' samples</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/cloudevents/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/cloudevents/</guid>
|
||
<description>
|
||
|
||
|
||
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: GitHub webhook sample - Go</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/gitwebhook-go/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/gitwebhook-go/</guid>
|
||
<description>
|
||
|
||
|
||
<p>A handler written in Go that demonstrates interacting with GitHub through a
|
||
webhook.</p>
|
||
<h2 id="before-you-begin">Before you begin</h2>
|
||
<p>You must meet the following requirements to run this sample:</p>
|
||
<ul>
|
||
<li>Own a public domain. For example, you can create a domain with
|
||
<a href="https://domains.google/">Google Domains</a>.</li>
|
||
<li>A Kubernetes cluster running with the following:
|
||
<ul>
|
||
<li>Knative Serving must be installed. For details about setting up a Knative
|
||
cluster, see the <a href="../../../install/index.html">installation guides</a>.</li>
|
||
<li>Your Knative cluster must be
|
||
<a href="../../using-a-custom-domain">configured to use your custom domain</a>.</li>
|
||
<li>You must ensure that your Knative cluster uses a static IP address:
|
||
<ul>
|
||
<li>For Google Kubernetes Engine, see
|
||
<a href="../../gke-assigning-static-ip-address">assigning a static IP address</a>.</li>
|
||
<li>For other cloud providers, refer to your provider&rsquo;s documentation.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li>An installed version of <a href="https://www.docker.com">Docker</a>.</li>
|
||
<li>A <a href="https://hub.docker.com/">Docker Hub account</a> to which you are able to
|
||
upload your sample&rsquo;s container image.</li>
|
||
</ul>
|
||
<h2 id="build-the-sample-code">Build the sample code</h2>
|
||
<ol>
|
||
<li>
|
||
<p>Download a copy of the code:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">git clone -b <span style="color:#4e9a06">&#34;{{&lt; branch &gt;}}&#34;</span> https://github.com/knative/docs knative-docs
|
||
<span style="color:#204a87">cd</span> knative-docs/docs/serving/samples/gitwebhook-go
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Use Docker to build a container image for this service. Replace
|
||
<code>{DOCKER_HUB_USERNAME}</code> with your Docker Hub username in the following
|
||
commands.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">export</span> <span style="color:#000">DOCKER_HUB_USERNAME</span><span style="color:#ce5c00;font-weight:bold">=</span>username
|
||
|
||
<span style="color:#8f5902;font-style:italic"># Build the container, run from the project folder</span>
|
||
docker build -t <span style="color:#4e9a06">${</span><span style="color:#000">DOCKER_HUB_USERNAME</span><span style="color:#4e9a06">}</span>/gitwebhook-go .
|
||
|
||
<span style="color:#8f5902;font-style:italic"># Push the container to the registry</span>
|
||
docker push <span style="color:#4e9a06">${</span><span style="color:#000">DOCKER_HUB_USERNAME</span><span style="color:#4e9a06">}</span>/gitwebhook-go
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Create a secret that holds two values from GitHub:</p>
|
||
<ul>
|
||
<li>A
|
||
<a href="https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/">personal access token</a>
|
||
that you will use to make API requests to GitHub.</li>
|
||
<li>Ensure that you grant <code>read/write</code> permission in the repo for that personal
|
||
access token.</li>
|
||
</ul>
|
||
<ol>
|
||
<li>Follow the GitHub instructions to</li>
|
||
</ol>
|
||
<ul>
|
||
<li>A webhook secret that you will use to validate requests.</li>
|
||
</ul>
|
||
<ol>
|
||
<li>
|
||
<p>Base64 encode the access token:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ <span style="color:#204a87">echo</span> -n <span style="color:#4e9a06">&#34;45d382d4a9a93c453fb7c8adc109121e7c29fa3ca&#34;</span> <span style="color:#000;font-weight:bold">|</span> base64
|
||
<span style="color:#000">NDVkMzgyZDRhOWE5M2M0NTNmYjdjOGFkYzEwOTEyMWU3YzI5ZmEzY2E</span><span style="color:#ce5c00;font-weight:bold">=</span>
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Copy the encoded access token into <code>github-secret.yaml</code> next to
|
||
<code>personalAccessToken:</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Create a webhook secret value unique to this sample, base64 encode it, and
|
||
copy it into <code>github-secret.yaml</code> next to <code>webhookSecret:</code>:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ <span style="color:#204a87">echo</span> -n <span style="color:#4e9a06">&#34;mygithubwebhooksecret&#34;</span> <span style="color:#000;font-weight:bold">|</span> base64
|
||
bXlnaXRodWJ3ZWJob29rc2VjcmV0
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Apply the secret to your cluster:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl apply --filename github-secret.yaml
|
||
</code></pre></div></li>
|
||
</ol>
|
||
</li>
|
||
<li>
|
||
<p>Next, update the <code>service.yaml</code> file in the project to reference the tagged
|
||
image from step 1.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Service</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">gitwebhook</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">containers</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#8f5902;font-style:italic"># Replace {DOCKER_HUB_USERNAME} with your actual docker hub username</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">docker.io/{DOCKER_HUB_USERNAME}/gitwebhook-go:latest</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">env</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">GITHUB_PERSONAL_TOKEN</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">valueFrom</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">secretKeyRef</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">githubsecret</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">key</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">personalAccessToken</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WEBHOOK_SECRET</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">valueFrom</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">secretKeyRef</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">githubsecret</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">key</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">webhookSecret</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div></li>
|
||
<li>
|
||
<p>Use <code>kubectl</code> to apply the <code>service.yaml</code> file.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ kubectl apply --filename service.yaml
|
||
</code></pre></div><p>Response:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">service <span style="color:#4e9a06">&#34;gitwebhook&#34;</span> created
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Create a webhook in your GitHub repo using the URL for your <code>gitwebhook</code>
|
||
service:</p>
|
||
<ol>
|
||
<li>
|
||
<p>Retrieve the hostname for this service, using the following command:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ kubectl get ksvc gitwebhook <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> --output<span style="color:#ce5c00;font-weight:bold">=</span>custom-columns<span style="color:#ce5c00;font-weight:bold">=</span>NAME:.metadata.name,DOMAIN:.status.domain
|
||
</code></pre></div><p>Example response:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">NAME DOMAIN
|
||
gitwebhook gitwebhook.default.MYCUSTOMDOMAIN.com
|
||
</code></pre></div><p>where <code>MYCUSTOMDOMAIN</code> is the domain that you set as your
|
||
<a href="../../using-a-custom-domain">custom domain</a>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Go to the GitHub repository for which you have privileges to create a
|
||
webhook.</p>
|
||
</li>
|
||
<li>
|
||
<p>Click <strong>Settings</strong> &gt; <strong>Webhooks</strong> &gt; <strong>Add webhook</strong> to open the Webhooks
|
||
page.</p>
|
||
</li>
|
||
<li>
|
||
<p>Enter the <strong>Payload URL</strong> as <code>http://{DOMAIN}</code>, where <code>{DOMAIN}</code> is the
|
||
address from the <code>kubectl get ksvc gitwebhook</code> command. For example:
|
||
<code>http://gitwebhook.default.MYCUSTOMDOMAIN.com</code></p>
|
||
</li>
|
||
<li>
|
||
<p>Set the <strong>Content type</strong> to <code>application/json</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Enter your webhook secret in <strong>Secret</strong> using the original base value that
|
||
you set in <code>webhookSecret</code> (not the base64 encoded value). For example:
|
||
<code>mygithubwebhooksecret</code></p>
|
||
</li>
|
||
<li>
|
||
<p>If you did not <a href="../../using-a-tls-cert">enabled TLS certificates</a>,
|
||
click <strong>Disable</strong> under <strong>SSL Validation</strong>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Click <strong>Add webhook</strong> to create the webhook.</p>
|
||
</li>
|
||
</ol>
|
||
</li>
|
||
</ol>
|
||
<h2 id="exploring">Exploring</h2>
|
||
<p>Once deployed, you can inspect the created resources with <code>kubectl</code> commands:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#8f5902;font-style:italic"># This will show the Knative service that we created:</span>
|
||
kubectl get ksvc --output yaml
|
||
|
||
<span style="color:#8f5902;font-style:italic"># This will show the Route, created by the service:</span>
|
||
kubectl get route --output yaml
|
||
|
||
<span style="color:#8f5902;font-style:italic"># This will show the Configuration, created by the service:</span>
|
||
kubectl get configurations --output yaml
|
||
|
||
<span style="color:#8f5902;font-style:italic"># This will show the Revision, created by the Configuration:</span>
|
||
kubectl get revisions --output yaml
|
||
</code></pre></div><h2 id="testing-the-service">Testing the service</h2>
|
||
<p>Now that you have the service running and the webhook created, send a Pull
|
||
Request to the same GitHub repo where you added the webhook. If all is working
|
||
right, you&rsquo;ll see the title of the PR will be modified, with the text
|
||
<code>(looks pretty legit)</code> appended the end of the title.</p>
|
||
<h2 id="cleaning-up">Cleaning up</h2>
|
||
<p>To clean up the sample service:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl delete --filename service.yaml
|
||
</code></pre></div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: gRPC Server - Go</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/grpc-ping-go/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/grpc-ping-go/</guid>
|
||
<description>
|
||
|
||
|
||
<p>A <a href="https://grpc.io">gRPC</a> server written in Go.</p>
|
||
<p>This sample can be used to try out gRPC, HTTP/2, and custom port configuration
|
||
in a knative service.</p>
|
||
<p>The container image is built with two binaries: the server and the client.
|
||
This is done for ease of testing and is not a recommended practice
|
||
for production containers.</p>
|
||
<h2 id="prerequisites">Prerequisites</h2>
|
||
<ul>
|
||
<li>
|
||
<p><a href="../../../install/index.html">Install the latest version of Knative Serving</a>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Install <a href="https://www.docker.com/">docker</a>.</p>
|
||
</li>
|
||
<li>
|
||
<p>A <a href="https://hub.docker.com">Docker Hub account</a> to which you can upload the sample&rsquo;s container image.</p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="build-and-deploy-the-sample-code">Build and Deploy the sample code</h2>
|
||
<ol>
|
||
<li>Download a copy of the code:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">git clone -b <span style="color:#4e9a06">&#34;{{&lt; branch &gt;}}&#34;</span> https://github.com/knative/docs knative-docs
|
||
<span style="color:#204a87">cd</span> knative-docs/docs/serving/samples/grpc-ping-go
|
||
</code></pre></div><ol start="2">
|
||
<li>Use Docker to build a container image for this service and push to Docker Hub.</li>
|
||
</ol>
|
||
<p>Replace <code>{username}</code> with your Docker Hub username then run the commands:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#8f5902;font-style:italic"># Build the container on your local machine.</span>
|
||
docker build --tag <span style="color:#4e9a06">&#34;{username}/grpc-ping-go&#34;</span> .
|
||
|
||
<span style="color:#8f5902;font-style:italic"># Push the container to docker registry.</span>
|
||
docker push <span style="color:#4e9a06">&#34;{username}/grpc-ping-go&#34;</span>
|
||
</code></pre></div><ol start="3">
|
||
<li>
|
||
<p>Update the <code>service.yaml</code> file in the project to reference the published image from step 1.</p>
|
||
<p>Replace <code>{username}</code> in <code>service.yaml</code> with your Docker Hub user name:</p>
|
||
</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Service</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">grpc-ping</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">containers</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">docker.io/{username}/grpc-ping-go</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">ports</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">h2c</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">containerPort</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">8080</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div><ol start="4">
|
||
<li>Use <code>kubectl</code> to deploy the service.</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl apply --filename service.yaml
|
||
</code></pre></div><p>Response:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">service <span style="color:#4e9a06">&#34;grpc-ping&#34;</span> created
|
||
</code></pre></div><h2 id="exploring">Exploring</h2>
|
||
<p>Once deployed, you can inspect the created resources with <code>kubectl</code> commands:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#8f5902;font-style:italic"># This will show the Knative service that we created:</span>
|
||
kubectl get ksvc --output yaml
|
||
|
||
<span style="color:#8f5902;font-style:italic"># This will show the Route, created by the service:</span>
|
||
kubectl get route --output yaml
|
||
|
||
<span style="color:#8f5902;font-style:italic"># This will show the Configuration, created by the service:</span>
|
||
kubectl get configurations --output yaml
|
||
|
||
<span style="color:#8f5902;font-style:italic"># This will show the Revision, created by the Configuration:</span>
|
||
kubectl get revisions --output yaml
|
||
</code></pre></div><h2 id="testing-the-service">Testing the service</h2>
|
||
<p>Testing the gRPC service requires using a gRPC client built from the same
|
||
protobuf definition used by the server.</p>
|
||
<p>The Dockerfile builds the client binary. To run the client you will use the
|
||
same container image deployed for the server with an override to the
|
||
entrypoint command to use the client binary instead of the server binary.</p>
|
||
<p>Replace <code>{username}</code> with your Docker Hub user name and run the command:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">docker run --rm <span style="color:#ce5c00;font-weight:bold">{</span>username<span style="color:#ce5c00;font-weight:bold">}</span>/grpc-ping-go <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> /client <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> -server_addr<span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;grpc-ping.default.1.2.3.4.xip.io:80&#34;</span> <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> -insecure
|
||
</code></pre></div><p>The arguments after the container tag <code>{username}/grpc-ping-go</code> are used
|
||
instead of the entrypoint command defined in the Dockerfile <code>CMD</code> statement.</p>
|
||
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Knative 'Hello World' samples</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/hello-world/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/hello-world/</guid>
|
||
<description>
|
||
|
||
|
||
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Knative multi-container samples</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/multi-container/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/multi-container/</guid>
|
||
<description>
|
||
|
||
|
||
<p>A simple web app written in Go that you can use for multi container testing.</p>
|
||
<h2 id="prerequisites">Prerequisites</h2>
|
||
<ul>
|
||
<li>A Kubernetes cluster with Knative installed and DNS configured. Follow the
|
||
<a href="../../../install/index.html">installation instructions</a> if you need to
|
||
create one.</li>
|
||
<li><a href="https://www.docker.com">Docker</a> installed and running on your local machine,
|
||
and a Docker Hub account configured (we&rsquo;ll use it for a container registry).</li>
|
||
<li>Make sure multi-container flag is enabled as part of <code>config-features</code> configmap.</li>
|
||
</ul>
|
||
<p>The following steps show how you can use the sample code and deploy the app to your
|
||
cluster.</p>
|
||
<p>You can download a working copy of the sample, by entering the
|
||
following command:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">git clone -b <span style="color:#4e9a06">&#34;{{&lt; branch &gt;}}&#34;</span> https://github.com/knative/docs knative-docs
|
||
</code></pre></div><h2 id="using-the-sample-code">Using the sample code</h2>
|
||
<p>To test multi container functionality, you must create two containers: a serving container, and a sidecar container.</p>
|
||
<p>The <code>multi-container</code> directory is provided in the sample code, and contains predefined code and dockerfiles for creating the containers.</p>
|
||
<p>You can update the default files and YAML by using the steps outlined in this section.</p>
|
||
<h3 id="serving-container">Serving Container</h3>
|
||
<ol>
|
||
<li>
|
||
<p>After you have cloned the sample repository, navigate to the servingcontainer directory:</p>
|
||
<p><code>cd knative-docs/docs/serving/samples/multi-container/servingcontainer</code></p>
|
||
</li>
|
||
<li>
|
||
<p>Create a basic web server which listens on port 8881.
|
||
You can do this by copying the following code into the <code>servingcontainer.go</code> file:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-go" data-lang="go"><span style="color:#204a87;font-weight:bold">package</span> <span style="color:#000">main</span>
|
||
<span style="color:#204a87;font-weight:bold">import</span> <span style="color:#000;font-weight:bold">(</span>
|
||
<span style="color:#4e9a06">&#34;fmt&#34;</span>
|
||
<span style="color:#4e9a06">&#34;io/ioutil&#34;</span>
|
||
<span style="color:#4e9a06">&#34;log&#34;</span>
|
||
<span style="color:#4e9a06">&#34;net/http&#34;</span>
|
||
<span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000">handler</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">w</span> <span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ResponseWriter</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">r</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Request</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Println</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;serving container received a request.&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000">res</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;http://127.0.0.1:8882&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fatal</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">err</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
<span style="color:#000">resp</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">ioutil</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ReadAll</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">res</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Body</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fatal</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">err</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
<span style="color:#000">fmt</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fprintln</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">w</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87">string</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">resp</span><span style="color:#000;font-weight:bold">))</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
<span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000">main</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Print</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;serving container started...&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">HandleFunc</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">handler</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fatal</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ListenAndServe</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;:8881&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">nil</span><span style="color:#000;font-weight:bold">))</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Copy the following code into the <code>Dockerfile</code> file:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-docker" data-lang="docker"><span style="color:#8f5902;font-style:italic"># Use the official Golang image to create a build artifact.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># This is based on Debian and sets the GOPATH to /go.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># https://hub.docker.com/_/golang</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">FROM</span><span style="color:#4e9a06"> golang:1.15 as builder</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Create and change to the app directory.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">WORKDIR</span><span style="color:#4e9a06"> /app</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Retrieve application dependencies using go modules.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Allows container builds to reuse downloaded dependencies.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">COPY</span> go.* ./<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">RUN</span> go mod download<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Copy local code to the container image.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">COPY</span> . ./<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Build the binary.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># -mod=readonly ensures immutable go.mod and go.sum in container builds.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">RUN</span> <span style="color:#000">CGO_ENABLED</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#0000cf;font-weight:bold">0</span> <span style="color:#000">GOOS</span><span style="color:#ce5c00;font-weight:bold">=</span>linux go build -mod<span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#204a87">readonly</span> -v -o servingcontainer<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Use the official Alpine image for a lean production container.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># https://hub.docker.com/_/alpine</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">FROM</span><span style="color:#4e9a06"> alpine:3</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">RUN</span> apk add --no-cache ca-certificates<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Copy the binary to the production image from the builder stage.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">COPY</span> --from<span style="color:#ce5c00;font-weight:bold">=</span>builder /app/servingcontainer /servingcontainer<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Run the web service on container startup.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">CMD</span> <span style="color:#000;font-weight:bold">[</span><span style="color:#4e9a06">&#34;/servingcontainer&#34;</span><span style="color:#000;font-weight:bold">]</span><span style="color:#a40000">
|
||
</span></code></pre></div></li>
|
||
</ol>
|
||
<h3 id="sidecar-container">Sidecar Container</h3>
|
||
<ol>
|
||
<li>
|
||
<p>After you have cloned the sample repository, navigate to the sidecarcontainer directory:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">cd -
|
||
cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Create a basic web server which listens on port 8882.
|
||
You can do this by copying the following code into the <code>sidecarcontainer.go</code> file:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-go" data-lang="go"><span style="color:#204a87;font-weight:bold">package</span> <span style="color:#000">main</span>
|
||
<span style="color:#204a87;font-weight:bold">import</span> <span style="color:#000;font-weight:bold">(</span>
|
||
<span style="color:#4e9a06">&#34;fmt&#34;</span>
|
||
<span style="color:#4e9a06">&#34;log&#34;</span>
|
||
<span style="color:#4e9a06">&#34;net/http&#34;</span>
|
||
<span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000">handler</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">w</span> <span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ResponseWriter</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">r</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Request</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Println</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;sidecar container received a request.&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000">fmt</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fprintln</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">w</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;Yay!! multi-container works&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
<span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000">main</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Print</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;sidecar container started...&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">HandleFunc</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">handler</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fatal</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ListenAndServe</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;:8882&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">nil</span><span style="color:#000;font-weight:bold">))</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Copy the following code into the <code>Dockerfile</code> file:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-docker" data-lang="docker"><span style="color:#8f5902;font-style:italic"># Use the official Golang image to create a build artifact.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># This is based on Debian and sets the GOPATH to /go.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># https://hub.docker.com/_/golang</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">FROM</span><span style="color:#4e9a06"> golang:1.15 as builder</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Create and change to the app directory.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">WORKDIR</span><span style="color:#4e9a06"> /app</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Retrieve application dependencies using go modules.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Allows container builds to reuse downloaded dependencies.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">COPY</span> go.* ./<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">RUN</span> go mod download<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Copy local code to the container image.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">COPY</span> . ./<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Build the binary.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># -mod=readonly ensures immutable go.mod and go.sum in container builds.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">RUN</span> <span style="color:#000">CGO_ENABLED</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#0000cf;font-weight:bold">0</span> <span style="color:#000">GOOS</span><span style="color:#ce5c00;font-weight:bold">=</span>linux go build -mod<span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#204a87">readonly</span> -v -o sidecarcontainer<span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Use the official Alpine image for a lean production container.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># https://hub.docker.com/_/alpine</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">FROM</span><span style="color:#4e9a06"> alpine:3</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">RUN</span> apk add --no-cache ca-certificates <span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Copy the binary to the production image from the builder stage.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">COPY</span> --from<span style="color:#ce5c00;font-weight:bold">=</span>builder /app/sidecarcontainer /sidecarcontainer <span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Run the web service on container startup.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">CMD</span> <span style="color:#000;font-weight:bold">[</span><span style="color:#4e9a06">&#34;/sidecarcontainer&#34;</span><span style="color:#000;font-weight:bold">]</span><span style="color:#a40000">
|
||
</span></code></pre></div></li>
|
||
</ol>
|
||
<h3 id="writing-knative-service-yaml">Writing Knative Service YAML</h3>
|
||
<ol>
|
||
<li>
|
||
<p>After you have cloned the sample repository, navigate to the <code>multi-container</code> directory:</p>
|
||
<ol>
|
||
<li><code>cd -</code></li>
|
||
<li><code>cd knative-docs/docs/serving/samples/multi-container/</code></li>
|
||
</ol>
|
||
</li>
|
||
<li>
|
||
<p>Copy the following YAML service definition into the <code>service.yaml</code> file:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Service</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">multi-container</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">containers</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">docker.io/{username}/servingcontainer</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">ports</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">containerPort</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">8881</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">docker.io/{username}/sidecarcontainer</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div></li>
|
||
</ol>
|
||
<p><strong>NOTE:</strong> Replace <code>{username}</code> with your Docker Hub username.</p>
|
||
<ol>
|
||
<li>
|
||
<p>Use Go tool to create a
|
||
<a href="https://github.com/golang/go/wiki/Modules#gomod"><code>go.mod</code></a> manifest:</p>
|
||
<p>servingcontainer</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">cd</span> -
|
||
<span style="color:#204a87">cd</span> knative-docs/docs/serving/samples/multi-container/servingcontainer
|
||
go mod init github.com/knative/docs/docs/serving/samples/multi-container/servingcontainer
|
||
</code></pre></div><p>sidecarcontainer</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">cd</span> -
|
||
<span style="color:#204a87">cd</span> knative-docs/docs/serving/samples/multi-container/sidecarcontainer
|
||
go mod init github.com/knative/docs/docs/serving/samples/multi-container/sidecarcontainer
|
||
</code></pre></div></li>
|
||
</ol>
|
||
<h2 id="building-and-deploying-the-sample">Building and deploying the sample</h2>
|
||
<p>After you have modified the sample code files you can build and deploy the sample app.</p>
|
||
<ol>
|
||
<li>
|
||
<p>Use Docker to build the sample code into a container. To build and push with
|
||
Docker Hub, run these commands replacing <code>{username}</code> with your Docker Hub
|
||
username:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#8f5902;font-style:italic"># Build the container on your local machine</span>
|
||
<span style="color:#204a87">cd</span> -
|
||
<span style="color:#204a87">cd</span> knative-docs/docs/serving/samples/multi-container/servingcontainer
|
||
docker build -t <span style="color:#ce5c00;font-weight:bold">{</span>username<span style="color:#ce5c00;font-weight:bold">}</span>/servingcontainer .
|
||
<span style="color:#204a87">cd</span> -
|
||
<span style="color:#204a87">cd</span> knative-docs/docs/serving/samples/multi-container/sidecarcontainer
|
||
docker build -t <span style="color:#ce5c00;font-weight:bold">{</span>username<span style="color:#ce5c00;font-weight:bold">}</span>/sidecarcontainer .
|
||
<span style="color:#8f5902;font-style:italic"># Push the container to docker registry</span>
|
||
docker push <span style="color:#ce5c00;font-weight:bold">{</span>username<span style="color:#ce5c00;font-weight:bold">}</span>/servingcontainer
|
||
docker push <span style="color:#ce5c00;font-weight:bold">{</span>username<span style="color:#ce5c00;font-weight:bold">}</span>/sidecarcontainer
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>After the build has completed and the container is pushed to Docker Hub, you
|
||
can deploy the app into your cluster. Ensure that the container image value
|
||
in <code>service.yaml</code> matches the container you built in the previous step. Apply
|
||
the configuration using <code>kubectl</code>:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">cd</span> -
|
||
<span style="color:#204a87">cd</span> knative-docs/docs/serving/samples/multi-container
|
||
kubectl apply --filename service.yaml
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Now that your service is created, Knative will perform the following steps:</p>
|
||
<ul>
|
||
<li>Create a new immutable revision for this version of the app.</li>
|
||
<li>Network programming to create a route, ingress, service, and load balance
|
||
for your app.</li>
|
||
<li>Automatically scale your pods up and down (including to zero active pods).</li>
|
||
</ul>
|
||
</li>
|
||
<li>
|
||
<p>Run the following command to find the domain URL for your service:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get ksvc multi-container --output<span style="color:#ce5c00;font-weight:bold">=</span>custom-columns<span style="color:#ce5c00;font-weight:bold">=</span>NAME:.metadata.name,URL:.status.url
|
||
</code></pre></div><p>Example:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"> NAME URL
|
||
multi-container http://multi-container.default.1.2.3.4.xip.io
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Now you can make a request to your app and see the result. Replace
|
||
the URL below with the URL returned in the previous command.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://multi-container.default.1.2.3.4.xip.io
|
||
Yay!! multi-container works
|
||
</code></pre></div><blockquote>
|
||
<p>Note: Add <code>-v</code> option to get more detail if the <code>curl</code> command failed.</p>
|
||
</blockquote>
|
||
</li>
|
||
</ol>
|
||
<h2 id="removing-the-sample-app-deployment">Removing the sample app deployment</h2>
|
||
<p>To remove the sample app from your cluster, delete the service record:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl delete --filename service.yaml
|
||
</code></pre></div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Creating a RESTful Service - Go</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/rest-api-go/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/rest-api-go/</guid>
|
||
<description>
|
||
|
||
|
||
<p>This &ldquo;stock ticker&rdquo; sample demonstrates how to create and run a simple RESTful
|
||
service on Knative Serving. The exposed endpoint outputs the stock price for a
|
||
given &ldquo;<a href="https://www.marketwatch.com/tools/quotes/lookup.asp">stock symbol</a>&rdquo;,
|
||
like <code>AAPL</code>,<code>AMZN</code>, <code>GOOG</code>, <code>MSFT</code>, etc.</p>
|
||
<h2 id="prerequisites">Prerequisites</h2>
|
||
<ol>
|
||
<li>
|
||
<p>A Kubernetes cluster with <a href="../../../install/index.html">Knative Serving</a> installed
|
||
and DNS configured.</p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://docs.docker.com/get-started/#prepare-your-docker-environment">Docker</a>
|
||
installed locally.</p>
|
||
</li>
|
||
<li>
|
||
<p><code>envsubst</code> installed locally. This is installed by the <code>gettext</code> package. If
|
||
not installed it can be installed by a Linux package manager, or by
|
||
<a href="https://brew.sh/">Homebrew</a> on OS X.</p>
|
||
</li>
|
||
<li>
|
||
<p>Download a copy of the code:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">git clone -b <span style="color:#4e9a06">&#34;{{&lt; branch &gt;}}&#34;</span> https://github.com/knative/docs knative-docs
|
||
<span style="color:#204a87">cd</span> knative-docs
|
||
</code></pre></div></li>
|
||
</ol>
|
||
<h2 id="setup">Setup</h2>
|
||
<p>In order to run an application on Knative Serving a container image must be
|
||
available to fetch from a container registry.</p>
|
||
<p>This sample uses Docker for both building and pushing.</p>
|
||
<p>To build and push to a container registry using Docker:</p>
|
||
<ol>
|
||
<li>
|
||
<p>From the <code>knative-docs</code> directory, run the following command to set your
|
||
container registry endpoint as an environment variable.</p>
|
||
<p>This sample uses
|
||
<a href="https://cloud.google.com/container-registry/">Google Container Registry (GCR)</a>:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">export</span> <span style="color:#000">REPO</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;gcr.io/&lt;YOUR_PROJECT_ID&gt;&#34;</span>
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Set up your container registry to make sure you are ready to push.</p>
|
||
<p>To push to GCR, you need to:</p>
|
||
<ul>
|
||
<li>Create a
|
||
<a href="https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project">Google Cloud Platform project</a>.</li>
|
||
<li>Enable the
|
||
<a href="https://console.cloud.google.com/apis/library/containerregistry.googleapis.com">Google Container Registry API</a>.</li>
|
||
<li>Setup an
|
||
<a href="https://cloud.google.com/container-registry/docs/advanced-authentication#gcloud_as_a_docker_credential_helper">auth helper</a>
|
||
to give the Docker client the permissions it needs to push.</li>
|
||
</ul>
|
||
<p>If you are using a different container registry, you will want to follow the
|
||
registry specific instructions for both setup and authorizing the image push.</p>
|
||
</li>
|
||
<li>
|
||
<p>Use Docker to build your application container:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">docker build <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> --tag <span style="color:#4e9a06">&#34;</span><span style="color:#4e9a06">${</span><span style="color:#000">REPO</span><span style="color:#4e9a06">}</span><span style="color:#4e9a06">/rest-api-go&#34;</span> <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> --file docs/serving/samples/rest-api-go/Dockerfile .
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Push your container to a container registry:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">docker push <span style="color:#4e9a06">&#34;</span><span style="color:#4e9a06">${</span><span style="color:#000">REPO</span><span style="color:#4e9a06">}</span><span style="color:#4e9a06">/rest-api-go&#34;</span>
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Substitute the image reference path in the template with our published image
|
||
path. The command below substitutes using the ${REPO} variable into a new
|
||
file called <code>docs/serving/samples/rest-api-go/sample.yaml</code>.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">envsubst &lt; docs/serving/samples/rest-api-go/sample-template.yaml &gt; <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span>docs/serving/samples/rest-api-go/sample.yaml
|
||
</code></pre></div></li>
|
||
</ol>
|
||
<h2 id="deploy-the-service">Deploy the Service</h2>
|
||
<p>Now that our image is available from the container registry, we can deploy the
|
||
Knative Serving sample:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl apply --filename docs/serving/samples/rest-api-go/sample.yaml
|
||
</code></pre></div><p>The above command creates a Knative Service within your Kubernetes cluster in
|
||
the default namespace.</p>
|
||
<h2 id="explore-the-service">Explore the Service</h2>
|
||
<p>The Knative Service creates the following child resources:</p>
|
||
<ul>
|
||
<li>Knative Route</li>
|
||
<li>Knative Configuration</li>
|
||
<li>Knative Revision</li>
|
||
<li>Kubernetes Deployment</li>
|
||
<li>Kubernetes Service</li>
|
||
</ul>
|
||
<p>You can inspect the created resources with the following <code>kubectl</code> commands:</p>
|
||
<ul>
|
||
<li>
|
||
<p>View the created Service resource:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get ksvc stock-service-example --output yaml
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>View the created Route resource:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get route -l <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span><span style="color:#4e9a06">&#34;serving.knative.dev/service=stock-service-example&#34;</span> --output yaml
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>View the Kubernetes Service created by the Route</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get service -l <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span><span style="color:#4e9a06">&#34;serving.knative.dev/service=stock-service-example&#34;</span> --output yaml
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>View the created Configuration resource:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get configuration -l <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span><span style="color:#4e9a06">&#34;serving.knative.dev/service=stock-service-example&#34;</span> --output yaml
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>View the Revision that was created by our Configuration:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get revision -l <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span><span style="color:#4e9a06">&#34;serving.knative.dev/service=stock-service-example&#34;</span> --output yaml
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>View the Deployment created by our Revision</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get deployment -l <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span><span style="color:#4e9a06">&#34;serving.knative.dev/service=stock-service-example&#34;</span> --output yaml
|
||
</code></pre></div></li>
|
||
</ul>
|
||
<h2 id="access-the-service">Access the Service</h2>
|
||
<p>To access this service and run the stock ticker, you first obtain the service URL,
|
||
and then you run <code>curl</code> commands to send request with your stock symbol.</p>
|
||
<ol>
|
||
<li>
|
||
<p>Get the URL of the service:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get ksvc stock-service-example --output<span style="color:#ce5c00;font-weight:bold">=</span>custom-columns<span style="color:#ce5c00;font-weight:bold">=</span>NAME:.metadata.name,URL:.status.url
|
||
NAME URL
|
||
stock-service-example http://stock-service-example.default.1.2.3.4.xip.io
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Send requests to the service using <code>curl</code>:</p>
|
||
<ol>
|
||
<li>
|
||
<p>Send a request to the index endpoint:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://stock-service-example.default.1.2.3.4.xip.io
|
||
</code></pre></div><p>Response body: <code>Welcome to the stock app!</code></p>
|
||
</li>
|
||
<li>
|
||
<p>Send a request to the <code>/stock</code> endpoint:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://stock-service-example.default.1.2.3.4.xip.io/stock
|
||
</code></pre></div><p>Response body: <code>stock ticker not found!, require /stock/{ticker}</code></p>
|
||
</li>
|
||
<li>
|
||
<p>Send a request to the <code>/stock</code> endpoint with your
|
||
&ldquo;<a href="https://www.marketwatch.com/tools/quotes/lookup.asp">stock symbol</a>&quot;:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://stock-service-example.default.1.2.3.4.xip.io/stock/&lt;SYMBOL&gt;
|
||
</code></pre></div><p>where <code>&lt;SYMBOL&gt;</code> is your &ldquo;stock symbol&rdquo;.</p>
|
||
<p>Response body: <code>stock price for ticker &lt;SYMBOL&gt; is &lt;PRICE&gt;</code></p>
|
||
<p><strong>Example</strong></p>
|
||
<p>Request:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://stock-service-example.default.1.2.3.4.xip.io/stock/FAKE
|
||
</code></pre></div><p>Response: <code>stock price for ticker FAKE is 0.00</code></p>
|
||
</li>
|
||
</ol>
|
||
</li>
|
||
</ol>
|
||
<h2 id="next-steps">Next Steps</h2>
|
||
<p>The <a href="../traffic-splitting/index.html">traffic splitting example</a> continues from
|
||
here to walk you through how to create new Revisions and then use traffic
|
||
splitting between those Revisions.</p>
|
||
<h2 id="clean-up">Clean Up</h2>
|
||
<p>To clean up the sample Service:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl delete --filename docs/serving/samples/rest-api-go/sample.yaml
|
||
</code></pre></div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Routing across multiple Knative services - Go</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/knative-routing-go/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/knative-routing-go/</guid>
|
||
<description>
|
||
|
||
|
||
<p>This example shows how to map multiple Knative services to different paths under
|
||
a single domain name using the Istio VirtualService concept. Istio is a
|
||
general-purpose reverse proxy, therefore these directions can also be used to
|
||
configure routing based on other request data such as headers, or even to map
|
||
Knative and external resources under the same domain name.</p>
|
||
<p>In this sample, we set up two web services: <code>Search</code> service and <code>Login</code>
|
||
service, which simply read in an env variable <code>SERVICE_NAME</code> and prints
|
||
<code>&quot;${SERVICE_NAME} is called&quot;</code>. We&rsquo;ll then create a VirtualService with host
|
||
<code>example.com</code>, and define routing rules in the VirtualService so that
|
||
<code>example.com/search</code> maps to the Search service, and <code>example.com/login</code> maps to
|
||
the Login service.</p>
|
||
<h2 id="prerequisites">Prerequisites</h2>
|
||
<ol>
|
||
<li>A Kubernetes cluster with <a href="../../../install/index.html">Knative Serving</a>
|
||
installed.</li>
|
||
<li>Install
|
||
<a href="https://docs.docker.com/get-started/#prepare-your-docker-environment">Docker</a>.</li>
|
||
<li>Acquire a domain name.
|
||
<ul>
|
||
<li>In this example, we use <code>example.com</code>. If you don&rsquo;t have a domain name, you
|
||
can modify your hosts file (on Mac or Linux) to map <code>example.com</code> to your
|
||
cluster&rsquo;s ingress IP.</li>
|
||
<li>If you have configured a custom domain for your Knative installation, we
|
||
will refer to it as &lt;YOUR_DOMAIN_NAME&gt; in the rest of this document</li>
|
||
</ul>
|
||
</li>
|
||
<li>Check out the code:</li>
|
||
</ol>
|
||
<pre><code>go get -d github.com/knative/docs/docs/serving/samples/knative-routing-go
|
||
</code></pre><h2 id="setup">Setup</h2>
|
||
<p>To check the domain name, run the following command:</p>
|
||
<pre><code>kubectl get cm -n knative-serving config-domain -o yaml
|
||
</code></pre><p>Then, check the value for <code>data</code>. The domain name should be in the format of
|
||
<code>&lt;YOUR_DOMAIN_NAME&gt;: &quot;&quot;</code>, if it is available.</p>
|
||
<p>Build the application container and publish it to a container registry:</p>
|
||
<ol>
|
||
<li>Move into the sample directory:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">cd</span> <span style="color:#000">$GOPATH</span>/src/github.com/knative/docs
|
||
</code></pre></div><ol start="2">
|
||
<li>Set your preferred container registry:</li>
|
||
</ol>
|
||
<p>If you use Google Container Registry (GCR), you will need to enable the
|
||
<a href="https://console.cloud.google.com/apis/library/containerregistry.googleapis.com">GCR API</a>
|
||
in your GCP project.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">export</span> <span style="color:#000">REPO</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;gcr.io/&lt;YOUR_PROJECT_ID&gt;&#34;</span>
|
||
</code></pre></div><p>If you use Docker Hub as your docker image registry, replace <username> with
|
||
your dockerhub username and run the following command:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">export</span> <span style="color:#000">REPO</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;docker.io/&lt;username&gt;&#34;</span>
|
||
</code></pre></div><ol start="3">
|
||
<li>Use Docker to build your application container:</li>
|
||
</ol>
|
||
<pre><code>docker build \
|
||
--tag &quot;${REPO}/knative-routing-go&quot; \
|
||
--file=docs/serving/samples/knative-routing-go/Dockerfile .
|
||
</code></pre><ol start="4">
|
||
<li>Push your container to a container registry:</li>
|
||
</ol>
|
||
<pre><code>docker push &quot;${REPO}/knative-routing-go&quot;
|
||
</code></pre><ol start="5">
|
||
<li>
|
||
<p>Replace the image reference path with our published image path in the
|
||
configuration file <code>docs/serving/samples/knative-routing-go/sample.yaml</code>:</p>
|
||
<ul>
|
||
<li>Manually replace:
|
||
<code>image: github.com/knative/docs/docs/serving/samples/knative-routing-go</code>
|
||
with <code>image: ${REPO}/knative-routing-go</code> If you manually changed the .yaml
|
||
file, you must replace ${REPO} with the correct path on your local
|
||
machine.</li>
|
||
</ul>
|
||
<p>Or</p>
|
||
<ul>
|
||
<li>Run this command:</li>
|
||
</ul>
|
||
<pre><code>perl -pi -e &quot;s@github.com/knative/docs/docs/serving/samples@${REPO}@g&quot; docs/serving/samples/knative-routing-go/sample.yaml
|
||
</code></pre></li>
|
||
</ol>
|
||
<h2 id="deploy-the-service">Deploy the Service</h2>
|
||
<p>Deploy the Knative Serving sample:</p>
|
||
<pre><code>kubectl apply --filename docs/serving/samples/knative-routing-go/sample.yaml
|
||
</code></pre><h2 id="exploring-the-routes">Exploring the Routes</h2>
|
||
<p>A shared Gateway <code>knative-ingress-gateway</code> is used within Knative service mesh
|
||
for serving all incoming traffic. You can inspect it and its corresponding
|
||
Kubernetes service with:</p>
|
||
<ul>
|
||
<li>Check the shared Gateway:</li>
|
||
</ul>
|
||
<pre><code>kubectl get Gateway --namespace knative-serving --output yaml
|
||
</code></pre><ul>
|
||
<li>Check the corresponding Kubernetes service for the shared Gateway:</li>
|
||
</ul>
|
||
<pre><code>INGRESSGATEWAY=istio-ingressgateway
|
||
|
||
kubectl get svc $INGRESSGATEWAY --namespace istio-system --output yaml
|
||
</code></pre><ul>
|
||
<li>Inspect the deployed Knative services with:</li>
|
||
</ul>
|
||
<pre><code>kubectl get ksvc
|
||
</code></pre><p>You should see 2 Knative services: <code>search-service</code> and <code>login-service</code>.</p>
|
||
<h3 id="access-the-services">Access the Services</h3>
|
||
<ol>
|
||
<li>Find the shared Gateway IP and export as an environment variable:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#000">INGRESSGATEWAY</span><span style="color:#ce5c00;font-weight:bold">=</span>istio-ingressgateway
|
||
|
||
<span style="color:#204a87">export</span> <span style="color:#000">GATEWAY_IP</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">`</span>kubectl get svc <span style="color:#000">$INGRESSGATEWAY</span> --namespace istio-system <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> --output <span style="color:#000">jsonpath</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;{.status.loadBalancer.ingress[*][&#39;ip&#39;]}&#34;</span><span style="color:#4e9a06">`</span>
|
||
</code></pre></div><ol start="2">
|
||
<li>Find the <code>Search</code> service URL with:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#8f5902;font-style:italic"># kubectl get route search-service --output=custom-columns=NAME:.metadata.name,URL:.status.url</span>
|
||
NAME URL
|
||
search-service http://search-service.default.example.com
|
||
</code></pre></div><ol start="3">
|
||
<li>Make a curl request to the service:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://<span style="color:#4e9a06">${</span><span style="color:#000">GATEWAY_IP</span><span style="color:#4e9a06">}</span> --header <span style="color:#4e9a06">&#34;Host:search-service.default.example.com&#34;</span>
|
||
</code></pre></div><p>You should see: <code>Search Service is called !</code></p>
|
||
<ol start="4">
|
||
<li>Similarly, you can also directly access &ldquo;Login&rdquo; service with:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://<span style="color:#4e9a06">${</span><span style="color:#000">GATEWAY_IP</span><span style="color:#4e9a06">}</span> --header <span style="color:#4e9a06">&#34;Host:login-service.default.example.com&#34;</span>
|
||
</code></pre></div><p>You should see: <code>Login Service is called !</code></p>
|
||
<h2 id="apply-custom-routing-rule">Apply Custom Routing Rule</h2>
|
||
<ol>
|
||
<li>Apply the custom routing rules defined in <code>routing.yaml</code> file with:</li>
|
||
</ol>
|
||
<pre><code>kubectl apply --filename docs/serving/samples/knative-routing-go/routing.yaml
|
||
</code></pre><p>If you have configured a custom domain name for your service, please replace all
|
||
mentions of &ldquo;example.com&rdquo; in <code>routing.yaml</code> with &ldquo;&lt;YOUR_DOMAIN_NAME&gt;&rdquo; for
|
||
spec.hosts and spec.http.rewrite.authority.</p>
|
||
<p>In addition, you need to verify how your domain template is defined. By default,
|
||
we use the format of {{.Name}}.{{.Namespace}}, like search-service.default and
|
||
login-service.default. However, some Knative environments may use other format
|
||
like {{.Name}}-{{.Namespace}}. You can find out the format by running the
|
||
command:</p>
|
||
<pre><code>kubectl get cm -n knative-serving config-network -o yaml
|
||
</code></pre><p>Then look for the value for <code>domainTemplate</code>. If it is
|
||
<code>{{.Name}}-{{.Namespace}}.{{.Domain}}</code>, you need to change
|
||
<code>search-service.default</code> into <code>search-service-default</code> and
|
||
<code>login-service.default</code> into <code>login-service-default</code> as well in <code>routing.yaml</code>.</p>
|
||
<ol start="2">
|
||
<li>The <code>routing.yaml</code> file will generate a new VirtualService <code>entry-route</code> for
|
||
domain <code>example.com</code> or your own domain name. View the VirtualService:</li>
|
||
</ol>
|
||
<pre><code>kubectl get VirtualService entry-route --output yaml
|
||
</code></pre><ol start="3">
|
||
<li>
|
||
<p>Send a request to the <code>Search</code> service and the <code>Login</code> service by using
|
||
corresponding URIs. You should get the same results as directly accessing
|
||
these services. Get the ingress IP:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#000">INGRESSGATEWAY</span><span style="color:#ce5c00;font-weight:bold">=</span>istio-ingressgateway
|
||
|
||
<span style="color:#204a87">export</span> <span style="color:#000">GATEWAY_IP</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">`</span>kubectl get svc <span style="color:#000">$INGRESSGATEWAY</span> --namespace istio-system <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> --output <span style="color:#000">jsonpath</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;{.status.loadBalancer.ingress[*][&#39;ip&#39;]}&#34;</span><span style="color:#4e9a06">`</span>
|
||
</code></pre></div></li>
|
||
</ol>
|
||
<ul>
|
||
<li>
|
||
<p>Send a request to the Search service:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://<span style="color:#4e9a06">${</span><span style="color:#000">GATEWAY_IP</span><span style="color:#4e9a06">}</span>/search --header <span style="color:#4e9a06">&#34;Host: example.com&#34;</span>
|
||
</code></pre></div><p>or</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://<span style="color:#4e9a06">${</span><span style="color:#000">GATEWAY_IP</span><span style="color:#4e9a06">}</span>/search --header <span style="color:#4e9a06">&#34;Host: &lt;YOUR_DOMAIN_NAME&gt;&#34;</span>
|
||
</code></pre></div><p>for the case using your own domain.</p>
|
||
</li>
|
||
<li>
|
||
<p>Send a request to the Login service:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://<span style="color:#4e9a06">${</span><span style="color:#000">GATEWAY_IP</span><span style="color:#4e9a06">}</span>/login --header <span style="color:#4e9a06">&#34;Host: example.com&#34;</span>
|
||
</code></pre></div><p>or</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://<span style="color:#4e9a06">${</span><span style="color:#000">GATEWAY_IP</span><span style="color:#4e9a06">}</span>/login --header <span style="color:#4e9a06">&#34;Host: &lt;YOUR_DOMAIN_NAME&gt;&#34;</span>
|
||
</code></pre></div><p>for the case using your own domain.</p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="how-it-works">How It Works</h2>
|
||
<p>When an external request with host <code>example.com</code> or your own domain name reaches
|
||
<code>knative-ingress-gateway</code> Gateway, the <code>entry-route</code> VirtualService will check
|
||
if it has <code>/search</code> or <code>/login</code> URI. If the URI matches, then the host of
|
||
request will be rewritten into the host of <code>Search</code> service or <code>Login</code> service
|
||
correspondingly. This resets the final destination of the request. The request
|
||
with updated host will be forwarded to <code>knative-ingress-gateway</code> Gateway again.
|
||
The Gateway proxy checks the updated host, and forwards it to <code>Search</code> or
|
||
<code>Login</code> service according to its host setting.</p>
|
||
<p><img src="./images/knative-routing-sample-flow.png" alt="Object model"></p>
|
||
<h2 id="clean-up">Clean Up</h2>
|
||
<p>To clean up the sample resources:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl delete --filename docs/serving/samples/knative-routing-go/sample.yaml
|
||
kubectl delete --filename docs/serving/samples/knative-routing-go/routing.yaml
|
||
</code></pre></div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Knative Secrets - Go</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/secrets-go/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/secrets-go/</guid>
|
||
<description>
|
||
|
||
|
||
<p>A simple web app written in Go that you can use for testing. It demonstrates how
|
||
to use a Kubernetes secret as a Volume with Knative. We will create a new Google
|
||
Service Account and place it into a Kubernetes secret, then we will mount it
|
||
into a container as a Volume.</p>
|
||
<p>Follow the steps below to create the sample code and then deploy the app to your
|
||
cluster. You can also download a working copy of the sample, by running the
|
||
following commands:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">git clone -b <span style="color:#4e9a06">&#34;{{&lt; branch &gt;}}&#34;</span> https://github.com/knative/docs knative-docs
|
||
<span style="color:#204a87">cd</span> knative-docs/docs/serving/samples/secrets-go
|
||
</code></pre></div><h2 id="before-you-begin">Before you begin</h2>
|
||
<ul>
|
||
<li>A Kubernetes cluster with Knative installed. Follow the
|
||
<a href="../../../install/index.html">installation instructions</a> if you need to create
|
||
one.</li>
|
||
<li><a href="https://www.docker.com">Docker</a> installed and running on your local machine,
|
||
and a Docker Hub account configured (we&rsquo;ll use it for a container registry).</li>
|
||
<li>Create a
|
||
<a href="https://cloud.google.com/resource-manager/docs/creating-managing-projects">Google Cloud project</a>
|
||
and install the <code>gcloud</code> CLI and run <code>gcloud auth login</code>. This sample will use
|
||
a mix of <code>gcloud</code> and <code>kubectl</code> commands. The rest of the sample assumes that
|
||
you&rsquo;ve set the <code>$PROJECT_ID</code> environment variable to your Google Cloud project
|
||
id, and also set your project ID as default using
|
||
<code>gcloud config set project $PROJECT_ID</code>.</li>
|
||
</ul>
|
||
<h2 id="recreating-the-sample-code">Recreating the sample code</h2>
|
||
<ol>
|
||
<li>
|
||
<p>Create a new file named <code>secrets.go</code> and paste the following code. This code
|
||
creates a basic web server which listens on port 8080:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-go" data-lang="go"><span style="color:#204a87;font-weight:bold">package</span> <span style="color:#000">main</span>
|
||
|
||
<span style="color:#204a87;font-weight:bold">import</span> <span style="color:#000;font-weight:bold">(</span>
|
||
<span style="color:#4e9a06">&#34;context&#34;</span>
|
||
<span style="color:#4e9a06">&#34;fmt&#34;</span>
|
||
<span style="color:#4e9a06">&#34;log&#34;</span>
|
||
<span style="color:#4e9a06">&#34;net/http&#34;</span>
|
||
<span style="color:#4e9a06">&#34;os&#34;</span>
|
||
|
||
<span style="color:#4e9a06">&#34;cloud.google.com/go/storage&#34;</span>
|
||
<span style="color:#000;font-weight:bold">)</span>
|
||
|
||
<span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000">main</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Print</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Secrets sample started.&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
|
||
<span style="color:#8f5902;font-style:italic">// This sets up the standard GCS storage client, which will pull
|
||
</span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// credentials from GOOGLE_APPLICATION_CREDENTIALS if specified.
|
||
</span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">ctx</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Background</span><span style="color:#000;font-weight:bold">()</span>
|
||
<span style="color:#000">client</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">storage</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">NewClient</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ctx</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fatalf</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Unable to initialize storage client: %v&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
|
||
<span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">HandleFunc</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">func</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">w</span> <span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ResponseWriter</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">r</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Request</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#8f5902;font-style:italic">// This GCS bucket has been configured so that any authenticated
|
||
</span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// user can access it (Read Only), so any Service Account can
|
||
</span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// run this sample.
|
||
</span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">bkt</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">client</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Bucket</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;knative-secrets-sample&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
|
||
<span style="color:#8f5902;font-style:italic">// Access the attributes of this GCS bucket, and write it back to the
|
||
</span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// user. On failure, return a 500 and the error message.
|
||
</span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">attrs</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">bkt</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Attrs</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ctx</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Error</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">w</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Error</span><span style="color:#000;font-weight:bold">(),</span> <span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">StatusInternalServerError</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#204a87;font-weight:bold">return</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
<span style="color:#000">fmt</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fprintln</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">w</span><span style="color:#000;font-weight:bold">,</span>
|
||
<span style="color:#000">fmt</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Sprintf</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;bucket %s, created at %s, is located in %s with storage class %s\n&#34;</span><span style="color:#000;font-weight:bold">,</span>
|
||
<span style="color:#000">attrs</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Name</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">attrs</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Created</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">attrs</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Location</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">attrs</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">StorageClass</span><span style="color:#000;font-weight:bold">))</span>
|
||
|
||
<span style="color:#000;font-weight:bold">})</span>
|
||
|
||
<span style="color:#000">port</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">os</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Getenv</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;PORT&#34;</span><span style="color:#000;font-weight:bold">)</span>
|
||
<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">port</span> <span style="color:#ce5c00;font-weight:bold">==</span> <span style="color:#4e9a06">&#34;&#34;</span> <span style="color:#000;font-weight:bold">{</span>
|
||
<span style="color:#000">port</span> <span style="color:#000;font-weight:bold">=</span> <span style="color:#4e9a06">&#34;8080&#34;</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
|
||
<span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Fatal</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">http</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ListenAndServe</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">fmt</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Sprintf</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;:%s&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">port</span><span style="color:#000;font-weight:bold">),</span> <span style="color:#204a87;font-weight:bold">nil</span><span style="color:#000;font-weight:bold">))</span>
|
||
<span style="color:#000;font-weight:bold">}</span>
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>In your project directory, create a file named <code>Dockerfile</code> and copy the code
|
||
block below into it. For detailed instructions on dockerizing a Go app, see
|
||
<a href="https://blog.golang.org/docker">Deploying Go servers with Docker</a>.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-docker" data-lang="docker"><span style="color:#8f5902;font-style:italic"># Use the official Golang image to create a build artifact.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># This is based on Debian and sets the GOPATH to /go.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># https://hub.docker.com/_/golang</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">FROM</span><span style="color:#4e9a06"> golang as builder</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Copy local code to the container image.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">WORKDIR</span><span style="color:#4e9a06"> /go/src/github.com/knative/docs/hellosecrets</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">COPY</span> . .<span style="color:#a40000">
|
||
</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Build the output command inside the container.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">RUN</span> <span style="color:#000">CGO_ENABLED</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#0000cf;font-weight:bold">0</span> <span style="color:#000">GOOS</span><span style="color:#ce5c00;font-weight:bold">=</span>linux go build -v -o hellosecrets<span style="color:#a40000">
|
||
</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Use a Docker multi-stage build to create a lean production image.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">FROM</span><span style="color:#4e9a06"> alpine</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Enable the use of outbound https</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">RUN</span> apk add --no-cache ca-certificates<span style="color:#a40000">
|
||
</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Copy the binary to the production image from the builder stage.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">COPY</span> --from<span style="color:#ce5c00;font-weight:bold">=</span>builder /go/src/github.com/knative/docs/hellosecrets/hellosecrets /hellosecrets<span style="color:#a40000">
|
||
</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Service must listen to $PORT environment variable.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># This default value facilitates local development.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">ENV</span> PORT <span style="color:#0000cf;font-weight:bold">8080</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#8f5902;font-style:italic"># Run the web service on container startup.</span><span style="color:#a40000">
|
||
</span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">CMD</span> <span style="color:#000;font-weight:bold">[</span><span style="color:#4e9a06">&#34;/hellosecrets&#34;</span><span style="color:#000;font-weight:bold">]</span><span style="color:#a40000">
|
||
</span></code></pre></div></li>
|
||
<li>
|
||
<p><a href="https://cloud.google.com/iam/docs/creating-managing-service-accounts">Create a new Google Service Account</a>.
|
||
This Service Account doesn&rsquo;t need any privileges, the GCS bucket has been
|
||
configured so that any authenticated identity may read it.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">gcloud iam service-accounts create knative-secrets
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Create a new JSON key for this account</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">gcloud iam service-accounts keys create robot.json <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span> --iam-account<span style="color:#ce5c00;font-weight:bold">=</span>knative-secrets@<span style="color:#000">$PROJECT_ID</span>.iam.gserviceaccount.com
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Create a new Kubernetes secret from this JSON key:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl create secret generic google-robot-secret --from-file<span style="color:#ce5c00;font-weight:bold">=</span>./robot.json
|
||
</code></pre></div><p>You can achieve a similar result by editting <code>secret.yaml</code>, copying the
|
||
contents of <code>robot.json</code> as instructed there, and running
|
||
<code>kubectl apply --filename secret.yaml</code>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Create a new file, <code>service.yaml</code> and copy the following service definition
|
||
into the file. Make sure to replace <code>{username}</code> with your Docker Hub
|
||
username.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Service</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">secrets-go</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">containers</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Replace {username} with your DockerHub username</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">docker.io/{username}/secrets-go</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">env</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># This directs the Google Cloud SDK to use the identity and project</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># defined by the Service Account (aka robot) in the JSON file at</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># this path.</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># - `/var/secret` is determined by the `volumeMounts[0].mountPath`</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># below. This can be changed if both places are changed.</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># - `robot.json` is determined by the &#34;key&#34; that is used to hold the</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># secret content in the Kubernetes secret. This can be changed</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># if both places are changed.</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">GOOGLE_APPLICATION_CREDENTIALS</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">/var/secret/robot.json</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># This section specified where in the container we want the</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># volume containing our secret to be mounted.</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">volumeMounts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">robot-secret</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">mountPath</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">/var/secret</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># This section attaches the secret &#34;google-robot-secret&#34; to</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># the Pod holding the user container.</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">volumes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">robot-secret</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">secret</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">secretName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">google-robot-secret</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div></li>
|
||
</ol>
|
||
<h2 id="building-and-deploying-the-sample">Building and deploying the sample</h2>
|
||
<p>Once you have recreated the sample code files (or used the files in the sample
|
||
folder) you&rsquo;re ready to build and deploy the sample app.</p>
|
||
<ol>
|
||
<li>
|
||
<p>Use Docker to build the sample code into a container. To build and push with
|
||
Docker Hub, run these commands replacing <code>{username}</code> with your Docker Hub
|
||
username:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#8f5902;font-style:italic"># Build the container on your local machine</span>
|
||
docker build -t <span style="color:#ce5c00;font-weight:bold">{</span>username<span style="color:#ce5c00;font-weight:bold">}</span>/secrets-go .
|
||
|
||
<span style="color:#8f5902;font-style:italic"># Push the container to docker registry</span>
|
||
docker push <span style="color:#ce5c00;font-weight:bold">{</span>username<span style="color:#ce5c00;font-weight:bold">}</span>/secrets-go
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>After the build has completed and the container is pushed to docker hub, you
|
||
can deploy the app into your cluster. Ensure that the container image value
|
||
in <code>service.yaml</code> matches the container you built in the previous step. Apply
|
||
the configuration using <code>kubectl</code>:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl apply --filename service.yaml
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Now that your service is created, Knative will perform the following steps:</p>
|
||
<ul>
|
||
<li>Create a new immutable revision for this version of the app.</li>
|
||
<li>Network programming to create a route, ingress, service, and load balance
|
||
for your app.</li>
|
||
<li>Automatically scale your pods up and down (including to zero active pods).</li>
|
||
</ul>
|
||
</li>
|
||
<li>
|
||
<p>Run the following command to find the domain URL for your service:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get ksvc secrets-go --output<span style="color:#ce5c00;font-weight:bold">=</span>custom-columns<span style="color:#ce5c00;font-weight:bold">=</span>NAME:.metadata.name,URL:.status.url
|
||
</code></pre></div><p>Example:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">NAME URL
|
||
secrets-go http://secrets-go.default.1.2.3.4.xip.io
|
||
</code></pre></div></li>
|
||
<li>
|
||
<p>Now you can make a request to your app and see the result. Replace
|
||
the URL below with the URL returned in the previous command.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl http://secrets-go.default.1.2.3.4.xip.io
|
||
bucket knative-secrets-sample, created at 2019-02-01 14:44:05.804 +0000 UTC, is located in US with storage class MULTI_REGIONAL
|
||
</code></pre></div><blockquote>
|
||
<p>Note: Add <code>-v</code> option to get more detail if the <code>curl</code> command failed.</p>
|
||
</blockquote>
|
||
</li>
|
||
</ol>
|
||
<h2 id="removing-the-sample-app-deployment">Removing the sample app deployment</h2>
|
||
<p>To remove the sample app from your cluster, delete the service record:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl delete --filename service.yaml
|
||
kubectl delete secret google-robot-secret
|
||
</code></pre></div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Tag Header Based Routing</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/tag-header-based-routing/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/tag-header-based-routing/</guid>
|
||
<description>
|
||
|
||
|
||
<p>This sample explains the use of tag header based routing.</p>
|
||
<h2 id="tag-header-based-routing-feature">Tag Header Based Routing Feature</h2>
|
||
<p>Tag header based routing allows users to send requests directly to specific tagged revisions with
|
||
the same URL of Knative Service. To do this, you must set the specific header <code>Knative-Serving-Tag: {revision-tag}</code> in the request.</p>
|
||
<p>Currently Istio, Contour and Kourier ingress support this feature.</p>
|
||
<h2 id="prerequestie">Prerequestie</h2>
|
||
<ol>
|
||
<li>
|
||
<p>A Knative cluster that has an ingress controller installed
|
||
with Knative version 0.16 and above.</p>
|
||
</li>
|
||
<li>
|
||
<p>Move into the docs directory:</p>
|
||
</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">cd</span> <span style="color:#000">$GOPATH</span>/src/github.com/knative/docs
|
||
</code></pre></div><h2 id="enabling-tag-header-based-routing">Enabling tag header based routing</h2>
|
||
<p>This feature is disabled by default. To enable this feature, run the following command:</p>
|
||
<pre><code>kubectl patch cm config-features -n knative-serving -p '{&quot;data&quot;:{&quot;tag-header-based-routing&quot;:&quot;Enabled&quot;}}'
|
||
</code></pre><h2 id="build-images">Build images</h2>
|
||
<p>Follow the instructions in <a href="../hello-world/helloworld-go">helloworld-go</a> to build the <code>helloworld</code> image and upload it
|
||
to your container repository.</p>
|
||
<p>Replace <code>{username}</code> in the <a href="./sample.yaml">sample.yaml</a> with your Docker Hub username.</p>
|
||
<h2 id="setting-up-the-revisions-with-tag">Setting up the revisions with tag</h2>
|
||
<p>In this sample, two Revisions are created. The first Revision is tagged with <code>rev1</code>.
|
||
With this configuration, users can send requests directly to the first Revision
|
||
using the URL of Knative Service plus the header <code>Knative-Serving-Tag: rev1</code>.</p>
|
||
<p>The Knative Service is configured to route all of the traffic to the second Revision, which means if users do not
|
||
provide the <code>Knative-Serving-Tag</code> or they provide an incorrect value for <code>Knative-Serving-Tag</code>, the requests will be
|
||
routed to the second Revision.</p>
|
||
<p>Run the following command to set up the Knative Service and Revisions.</p>
|
||
<pre><code>kubectl apply -f docs/serving/samples/tag-header-based-routing/sample.yaml
|
||
</code></pre><h2 id="check-the-created-resources">Check the created resources</h2>
|
||
<p>Check the two created Revisions using the following command</p>
|
||
<pre><code>kubectl get revisions
|
||
</code></pre><p>You should see there are two Revisions: <code>tag-header-revision-1</code> and <code>tag-header-revision-2</code>. It may take a few minutes
|
||
for the Revisions to become ready.</p>
|
||
<p>Check the Knative Service using the following command</p>
|
||
<pre><code>kubectl get ksvc tag-header -oyaml
|
||
</code></pre><p>You should see the following block which indicates the tag <code>rev1</code> is successfully added to the first Revision.</p>
|
||
<pre><code> - revisionName: tag-header-revision-1
|
||
percent: 0
|
||
tag: rev1
|
||
- revisionName: tag-header-revision-2
|
||
percent: 100
|
||
</code></pre><h2 id="sending-request-with-tag-header">Sending request with tag header</h2>
|
||
<ol>
|
||
<li>
|
||
<p>Run the following command to send a request to the first Revision.</p>
|
||
<pre><code>curl ${INGRESS_IP} -H &quot;Host:tag-header.default.example.com&quot; -H &quot;Knative-Serving-Tag:rev1&quot;
|
||
</code></pre><p>where <code>${INGRESS_IP}</code> is the IP of your ingress.</p>
|
||
<p>You should get the following response:</p>
|
||
<pre><code>Hello First Revision!
|
||
</code></pre></li>
|
||
<li>
|
||
<p>Run the following command to send requests without the <code>Knative-Serving-Tag</code> header:</p>
|
||
<pre><code>curl ${INGRESS_IP} -H &quot;Host:tag-header.default.example.com&quot;
|
||
</code></pre><p>You should get the response from the second Revision:</p>
|
||
<pre><code>Hello Second Revision!
|
||
</code></pre></li>
|
||
<li>
|
||
<p>Run the following command to send requests with an incorrect <code>Knative-Serving-Tag</code> header:</p>
|
||
<pre><code>curl ${INGRESS_IP} -H &quot;Host:tag-header.default.example.com&quot; -H &quot;Knative-Serving-Tag:wrongHeader&quot;
|
||
</code></pre><p>You should get the response from the second Revision:</p>
|
||
<pre><code>Hello Second Revision!
|
||
</code></pre></li>
|
||
</ol>
|
||
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Simple Traffic Splitting Between Revisions</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/traffic-splitting/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/traffic-splitting/</guid>
|
||
<description>
|
||
|
||
|
||
<p>This samples builds off of the <a href="../rest-api-go">Creating a RESTful Service</a>
|
||
sample to illustrate updating a Service to create a new Revision as well as
|
||
splitting traffic between the two created Revisions.</p>
|
||
<h2 id="prerequisites">Prerequisites</h2>
|
||
<ol>
|
||
<li>Complete the Service creation steps in
|
||
<a href="../rest-api-go">Creating a RESTful Service</a>.</li>
|
||
<li>Move into the docs directory:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#204a87">cd</span> <span style="color:#000">$GOPATH</span>/src/github.com/knative/docs
|
||
</code></pre></div><h2 id="using-the-traffic-block">Using the <code>traffic:</code> block</h2>
|
||
<p>The service was originally created without a <code>traffic:</code> block, which means that
|
||
it will automatically deploy the latest updates as they become ready. To split
|
||
traffic between multiple Revisions, we will start to use a customized <code>traffic:</code>
|
||
block. The <code>traffic:</code> block enables users to split traffic over any number of
|
||
fixed Revisions, or the floating &ldquo;latest revision&rdquo; for the Service. It also
|
||
enables users to name the specific sub-routes, so that they can be directly
|
||
addressed for qualification or debugging.</p>
|
||
<p>The first thing we will do is look at the traffic block that was defaulted for
|
||
us in the previous sample:</p>
|
||
<ol>
|
||
<li>Fetch the state of the Service, and note the <code>traffic:</code> block that will run
|
||
the latest ready revision, each time we update our template. Also note that
|
||
under <code>status:</code> we see a specific <code>revisionName:</code> here, which is what it has
|
||
resolved to (in this case the name we asked for).</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">$ kubectl get ksvc -oyaml stock-service-example
|
||
apiVersion: serving.knative.dev/v1
|
||
kind: Service
|
||
metadata:
|
||
name: stock-service-example
|
||
...
|
||
spec:
|
||
template: ... <span style="color:#8f5902;font-style:italic"># A defaulted version of what we provided.</span>
|
||
|
||
traffic:
|
||
- latestRevision: <span style="color:#204a87">true</span>
|
||
percent: <span style="color:#0000cf;font-weight:bold">100</span>
|
||
|
||
status:
|
||
...
|
||
traffic:
|
||
- percent: <span style="color:#0000cf;font-weight:bold">100</span>
|
||
revisionName: stock-service-example-first
|
||
</code></pre></div><ol>
|
||
<li>The <code>release_sample.yaml</code> in this directory overwrites the defaulted traffic
|
||
block with a block that fixes traffic to the revision
|
||
<code>stock-service-example-first</code>, while keeping the latest ready revision
|
||
available via the sub-route &ldquo;latest&rdquo;.</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl apply --filename docs/serving/samples/traffic-splitting/release_sample.yaml
|
||
</code></pre></div><ol>
|
||
<li>The <code>spec</code> of the Service should now show our <code>traffic</code> block with the
|
||
Revision name we specified above.</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get ksvc stock-service-example --output yaml
|
||
</code></pre></div><h2 id="updating-the-service">Updating the Service</h2>
|
||
<p>This section describes how to create a new Revision by updating your Service.</p>
|
||
<p>A new Revision is created every time a value in the <code>template</code> section of the
|
||
Service <code>spec</code> is updated. The <code>updated_sample.yaml</code> in this folder changes the
|
||
environment variable <code>RESOURCE</code> from <code>stock</code> to <code>share</code>. Applying this change
|
||
will result in a new Revision.</p>
|
||
<p>For comparison, you can diff the <code>release_sample.yaml</code> with the
|
||
<code>updated_sample.yaml</code>.</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">diff serving/samples/traffic-splitting/release_sample.yaml <span style="color:#4e9a06">\
|
||
</span><span style="color:#4e9a06"></span>serving/samples/traffic-splitting/updated_sample.yaml
|
||
</code></pre></div><ol>
|
||
<li>Execute the command below to update Service, resulting in a new Revision.</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl apply --filename docs/serving/samples/traffic-splitting/updated_sample.yaml
|
||
</code></pre></div><ol start="2">
|
||
<li>With our <code>traffic</code> block, traffic will <em>not</em> shift to the new Revision
|
||
automatically. However, it will be available via the URL associated with our
|
||
<code>latest</code> sub-route. This can be verified through the Service status, by
|
||
finding the entry of <code>status.traffic</code> for <code>latest</code>:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get ksvc stock-service-example --output yaml
|
||
</code></pre></div><ol start="3">
|
||
<li>The readiness of the Service can be verified through the Service Conditions.
|
||
When the Service conditions report it is ready again, you can access the new
|
||
Revision using the same method as found in the
|
||
<a href="../rest-api-go/index.html#access-the-service">previous sample</a> using the
|
||
Service hostname found above.</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#8f5902;font-style:italic"># Replace &#34;latest&#34; with whichever tag for which we want the hostname.</span>
|
||
<span style="color:#204a87">export</span> <span style="color:#000">LATEST_HOSTNAME</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">`</span>kubectl get ksvc stock-service-example --output <span style="color:#000">jsonpath</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;{.status.traffic[?(@.tag==&#39;latest&#39;)].url}&#34;</span> <span style="color:#000;font-weight:bold">|</span> cut -d<span style="color:#4e9a06">&#39;/&#39;</span> -f 3<span style="color:#4e9a06">`</span>
|
||
curl --header <span style="color:#4e9a06">&#34;Host: </span><span style="color:#4e9a06">${</span><span style="color:#000">LATEST_HOSTNAME</span><span style="color:#4e9a06">}</span><span style="color:#4e9a06">&#34;</span> http://<span style="color:#4e9a06">${</span><span style="color:#000">INGRESS_IP</span><span style="color:#4e9a06">}</span>
|
||
</code></pre></div><ul>
|
||
<li>Visiting the Service&rsquo;s domain will still hit the original Revision, since we
|
||
configured it to receive 100% of our main traffic (you can also use the
|
||
<code>current</code> sub-route).</li>
|
||
</ul>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl --header <span style="color:#4e9a06">&#34;Host:</span><span style="color:#4e9a06">${</span><span style="color:#000">SERVICE_HOSTNAME</span><span style="color:#4e9a06">}</span><span style="color:#4e9a06">&#34;</span> http://<span style="color:#4e9a06">${</span><span style="color:#000">INGRESS_IP</span><span style="color:#4e9a06">}</span>
|
||
</code></pre></div><h2 id="traffic-splitting">Traffic Splitting</h2>
|
||
<p>Updating the service to split traffic between the two revisions is done by
|
||
extending our <code>traffic</code> list, and splitting the <code>percent</code> across them.</p>
|
||
<ol>
|
||
<li>Execute the command below to update Service, resulting in a 50/50 traffic
|
||
split.</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl apply --filename docs/serving/samples/traffic-splitting/split_sample.yaml
|
||
</code></pre></div><ol start="2">
|
||
<li>Verify the deployment by checking the service status:</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl get ksvc --output yaml
|
||
</code></pre></div><ol start="3">
|
||
<li>Once updated, <code>curl</code> requests to the base domain should result in responses
|
||
split evenly between <code>Welcome to the share app!</code> and
|
||
<code>Welcome to the stock app!</code>.</li>
|
||
</ol>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">curl --header <span style="color:#4e9a06">&#34;Host:</span><span style="color:#4e9a06">${</span><span style="color:#000">SERVICE_HOSTNAME</span><span style="color:#4e9a06">}</span><span style="color:#4e9a06">&#34;</span> http://<span style="color:#4e9a06">${</span><span style="color:#000">INGRESS_IP</span><span style="color:#4e9a06">}</span>
|
||
</code></pre></div><h2 id="clean-up">Clean Up</h2>
|
||
<p>To clean up the sample service:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">kubectl delete --filename docs/serving/samples/traffic-splitting/split_sample.yaml
|
||
</code></pre></div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>V0.21-Docs: Routing and managing traffic with blue/green deployment</title>
|
||
<link>https://knative.dev/v0.21-docs/serving/samples/blue-green-deployment/</link>
|
||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||
|
||
<guid>https://knative.dev/v0.21-docs/serving/samples/blue-green-deployment/</guid>
|
||
<description>
|
||
|
||
|
||
<p>This sample demonstrates updating an application to a new version using a
|
||
blue/green traffic routing pattern. With Knative, you can safely reroute traffic
|
||
from a live version of an application to a new version by changing the routing
|
||
configuration.</p>
|
||
<h2 id="before-you-begin">Before you begin</h2>
|
||
<p>You need:</p>
|
||
<ul>
|
||
<li>A Kubernetes cluster with <a href="../../../install/index.html">Knative installed</a>.</li>
|
||
<li>(Optional) <a href="../../using-a-custom-domain">A custom domain configured</a> for use
|
||
with Knative.</li>
|
||
</ul>
|
||
<p>Note: The source code for the gcr.io/knative-samples/knative-route-demo image
|
||
that is used in this sample, is located at
|
||
<a href="https://github.com/mchmarny/knative-route-demo">https://github.com/mchmarny/knative-route-demo</a>.</p>
|
||
<h2 id="deploying-revision-1-blue">Deploying Revision 1 (Blue)</h2>
|
||
<p>We&rsquo;ll be deploying an image of a sample application that displays the text &ldquo;App
|
||
v1&rdquo; on a blue background.</p>
|
||
<p>First, create a new file called <code>blue-green-demo-config.yaml</code>and copy this into
|
||
it:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Configuration</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">containers</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">gcr.io/knative-samples/knative-route-demo:blue</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># The URL to the sample app docker image</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">env</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">T_VERSION</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;blue&#34;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div><p>Save the file, then deploy the configuration to your cluster:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl apply --filename blue-green-demo-config.yaml
|
||
|
||
configuration <span style="color:#4e9a06">&#34;blue-green-demo&#34;</span> configured
|
||
</code></pre></div><p>This will deploy the initial revision of the sample application. Before we can
|
||
route traffic to this application we need to know the name of the initial
|
||
revision which was just created. Using <code>kubectl</code> you can get it with the
|
||
following command:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl get configurations blue-green-demo -o<span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">jsonpath</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#39;{.status.latestCreatedRevisionName}&#39;</span>
|
||
</code></pre></div><p>The command above will return the name of the revision, it will be similar to
|
||
<code>blue-green-demo-lcfrd</code>. In the rest of this document we will use this revision
|
||
name, but yours will be different.</p>
|
||
<p>To route inbound traffic to it, we need to define a route. Create a new file
|
||
called <code>blue-green-demo-route.yaml</code> and copy the following YAML manifest into it
|
||
(do not forget to edit the revision name):</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Route</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># The name of our route; appears in the URL to access the app</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># The namespace we&#39;re working in; also appears in the URL to access the app</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">traffic</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">revisionName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo-lcfrd</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">percent</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">100</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># All traffic goes to this revision</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div><p>Save the file, then apply the route to your cluster:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl apply --filename blue-green-demo-route.yaml
|
||
|
||
route <span style="color:#4e9a06">&#34;blue-green-demo&#34;</span> configured
|
||
</code></pre></div><p>You&rsquo;ll now be able to view the sample app at the URL shown by:</p>
|
||
<pre><code>kubectl get route blue-green-demo
|
||
</code></pre><h2 id="deploying-revision-2-green">Deploying Revision 2 (Green)</h2>
|
||
<p>Revision 2 of the sample application will display the text &ldquo;App v2&rdquo; on a green
|
||
background. To create the new revision, we&rsquo;ll edit our existing configuration in
|
||
<code>blue-green-demo-config.yaml</code> with an updated image and environment variables:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Configuration</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Configuration name is unchanged, since we&#39;re updating an existing Configuration</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">containers</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">gcr.io/knative-samples/knative-route-demo:green</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># URL to the new version of the sample app docker image</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">env</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">T_VERSION</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;green&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Updated value for the T_VERSION environment variable</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div><p>Save the file, then apply the updated configuration to your cluster:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl apply --filename blue-green-demo-config.yaml
|
||
|
||
configuration <span style="color:#4e9a06">&#34;blue-green-demo&#34;</span> configured
|
||
</code></pre></div><p>Find the name of the second revision with the following command:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl get configurations blue-green-demo -o<span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">jsonpath</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#39;{.status.latestCreatedRevisionName}&#39;</span>
|
||
</code></pre></div><p>In the rest of this document we will assume that the second revision is called
|
||
<code>blue-green-demo-m9548</code>, however yours will differ. Make sure to use the correct
|
||
name of the second revision in the manifests that follow.</p>
|
||
<p>At this point, the first revision (<code>blue-green-demo-lcfrd</code>) and the second
|
||
revision (<code>blue-green-demo-m9548</code>) will both be deployed and running. We can
|
||
update our existing route to create a new (test) endpoint for the second
|
||
revision while still sending all other traffic to the first revision. Edit
|
||
<code>blue-green-demo-route.yaml</code>:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Route</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Route name is unchanged, since we&#39;re updating an existing Route</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">traffic</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">revisionName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo-lcfrd</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">percent</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">100</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># All traffic still going to the first revision</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">revisionName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo-m9548</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">percent</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># 0% of traffic routed to the second revision</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">tag</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">v2</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># A named route</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div><p>Save the file, then apply the updated route to your cluster:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl apply --filename blue-green-demo-route.yaml
|
||
|
||
route <span style="color:#4e9a06">&#34;blue-green-demo&#34;</span> configured
|
||
</code></pre></div><p>Revision 2 of the app is staged at this point. That means:</p>
|
||
<ul>
|
||
<li>No traffic will be routed to revision 2 at the main URL,
|
||
<code>http://blue-green-demo.default.[YOUR_CUSTOM_DOMAIN].com</code></li>
|
||
<li>Knative creates a new route named v2 for testing the newly deployed version.
|
||
The URL of this can be seen in the status section of your Route.</li>
|
||
</ul>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl get route blue-green-demo --output <span style="color:#000">jsonpath</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;{.status.traffic[*].url}&#34;</span>
|
||
</code></pre></div><p>This allows you to validate that the new version of the app is behaving as
|
||
expected before switching any traffic over to it.</p>
|
||
<h2 id="migrating-traffic-to-the-new-revision">Migrating traffic to the new revision</h2>
|
||
<p>We&rsquo;ll once again update our existing route to begin shifting traffic away from
|
||
the first revision and toward the second. Edit <code>blue-green-demo-route.yaml</code>:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Route</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Updating our existing route</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">traffic</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">revisionName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo-lcfrd</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">percent</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Updating the percentage from 100 to 50</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">revisionName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo-m9548</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">percent</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Updating the percentage from 0 to 50</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">tag</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">v2</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div><p>Save the file, then apply the updated route to your cluster:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl apply --filename blue-green-demo-route.yaml
|
||
|
||
route <span style="color:#4e9a06">&#34;blue-green-demo&#34;</span> configured
|
||
</code></pre></div><p>Refresh the original route
|
||
(<code>http://blue-green-demo.default.[YOUR_CUSTOM_DOMAIN].com</code>) a few times to see that
|
||
some traffic now goes to version 2 of the app.</p>
|
||
<blockquote>
|
||
<p>Note: This sample shows a 50/50 split to assure you don&rsquo;t have to refresh too
|
||
much, but it&rsquo;s recommended to start with 1-2% of traffic in a production
|
||
environment</p>
|
||
</blockquote>
|
||
<h2 id="rerouting-all-traffic-to-the-new-version">Rerouting all traffic to the new version</h2>
|
||
<p>Lastly, we&rsquo;ll update our existing route to finally shift all traffic to the
|
||
second revision. Edit <code>blue-green-demo-route.yaml</code>:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serving.knative.dev/v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Route</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Updating our existing route</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">traffic</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">revisionName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo-lcfrd</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">percent</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">tag</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">v1</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Adding a new named route for v1</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">revisionName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">blue-green-demo-m9548</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">percent</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">100</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Named route for v2 has been removed, since we don&#39;t need it anymore</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></code></pre></div><blockquote>
|
||
<p>Note: You can remove the first revision blue-green-demo-lcfrd instead of 0% of traffic
|
||
when you will not roll back the revision anymore.
|
||
Then the non-routeable revision object will be garbage collected.</p>
|
||
</blockquote>
|
||
<p>Save the file, then apply the updated route to your cluster:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl apply --filename blue-green-demo-route.yaml
|
||
|
||
route <span style="color:#4e9a06">&#34;blue-green-demo&#34;</span> configured
|
||
</code></pre></div><p>Refresh the original route
|
||
(<code>http://blue-green-demo.default.[YOUR_CUSTOM_DOMAIN].com</code>) a few times to verify
|
||
that no traffic is being routed to v1 of the app.</p>
|
||
<p>We added a named route to v1 of the app, so you can now access it at the URL
|
||
listed in the traffic block of the status section. To get the URL, enter the
|
||
following command:</p>
|
||
<div class="highlight"><pre style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">kubectl get route blue-green-demo --output <span style="color:#000">jsonpath</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;{.status.traffic[*].url}&#34;</span>
|
||
</code></pre></div><p>With all inbound traffic being directed to the second revision of the
|
||
application, Knative will soon scale the first revision down to 0 running pods
|
||
and the blue/green deployment can be considered complete. Using the named <code>v1</code>
|
||
route will reactivate a pod to serve any occasional requests intended
|
||
specifically for the initial revision.</p>
|
||
<h2 id="cleaning-up">Cleaning up</h2>
|
||
<p>To delete the sample app, enter the following commands:</p>
|
||
<pre><code>kubectl delete route blue-green-demo
|
||
kubectl delete configuration blue-green-demo
|
||
</code></pre>
|
||
</description>
|
||
</item>
|
||
|
||
</channel>
|
||
</rss>
|