ingress-nginx/examples/grpc/index.html

1381 lines
35 KiB
HTML

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-3.0.6">
<title>gRPC - NGINX Ingress Controller</title>
<link rel="stylesheet" href="../../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#009688">
<script src="../../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../../extra.css">
</head>
<body dir="ltr" data-md-color-primary="teal" data-md-color-accent="green">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#grpc" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="../.." title="NGINX Ingress Controller" class="md-header-nav__button md-logo">
<i class="md-icon">public</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
NGINX Ingress Controller
</span>
<span class="md-header-nav__topic">
gRPC
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://github.com/kubernetes/ingress-nginx/" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#__github" width="24" height="24"></use>
</svg>
</div>
<div class="md-source__repository">
kubernetes/ingress-nginx
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<nav class="md-tabs md-tabs--active" data-md-component="tabs">
<div class="md-tabs__inner md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../.." title="Welcome" class="md-tabs__link">
Welcome
</a>
</li>
<li class="md-tabs__item">
<a href="../../deploy/" title="Deployment" class="md-tabs__link">
Deployment
</a>
</li>
<li class="md-tabs__item">
<a href="../../user-guide/nginx-configuration/" title="User guide" class="md-tabs__link">
User guide
</a>
</li>
<li class="md-tabs__item">
<a href="../" title="Examples" class="md-tabs__link md-tabs__link--active">
Examples
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="../.." title="NGINX Ingress Controller" class="md-nav__button md-logo">
<i class="md-icon">public</i>
</a>
NGINX Ingress Controller
</label>
<div class="md-nav__source">
<a href="https://github.com/kubernetes/ingress-nginx/" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#__github" width="24" height="24"></use>
</svg>
</div>
<div class="md-source__repository">
kubernetes/ingress-nginx
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-1" type="checkbox" id="nav-1">
<label class="md-nav__link" for="nav-1">
Welcome
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-1">
Welcome
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." title="Welcome" class="md-nav__link">
Welcome
</a>
</li>
<li class="md-nav__item">
<a href="../../how-it-works/" title="How it works" class="md-nav__link">
How it works
</a>
</li>
<li class="md-nav__item">
<a href="../../troubleshooting/" title="Troubleshooting" class="md-nav__link">
Troubleshooting
</a>
</li>
<li class="md-nav__item">
<a href="../../development/" title="Development" class="md-nav__link">
Development
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-2" type="checkbox" id="nav-2">
<label class="md-nav__link" for="nav-2">
Deployment
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-2">
Deployment
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../deploy/" title="Installation Guide" class="md-nav__link">
Installation Guide
</a>
</li>
<li class="md-nav__item">
<a href="../../deploy/baremetal/" title="Bare-metal considerations" class="md-nav__link">
Bare-metal considerations
</a>
</li>
<li class="md-nav__item">
<a href="../../deploy/rbac/" title="Role Based Access Control (RBAC)" class="md-nav__link">
Role Based Access Control (RBAC)
</a>
</li>
<li class="md-nav__item">
<a href="../../deploy/upgrade/" title="Upgrade" class="md-nav__link">
Upgrade
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3" type="checkbox" id="nav-3">
<label class="md-nav__link" for="nav-3">
User guide
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-3">
User guide
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3-1" type="checkbox" id="nav-3-1">
<label class="md-nav__link" for="nav-3-1">
NGINX Configuration
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="2">
<label class="md-nav__title" for="nav-3-1">
NGINX Configuration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../user-guide/nginx-configuration/" title="Introduction" class="md-nav__link">
Introduction
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/nginx-configuration/annotations/" title="Annotations" class="md-nav__link">
Annotations
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/nginx-configuration/configmap/" title="ConfigMap" class="md-nav__link">
ConfigMap
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/nginx-configuration/custom-template/" title="Custom NGINX template" class="md-nav__link">
Custom NGINX template
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/nginx-configuration/log-format/" title="Log format" class="md-nav__link">
Log format
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../user-guide/cli-arguments/" title="Command line arguments" class="md-nav__link">
Command line arguments
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/custom-errors/" title="Custom errors" class="md-nav__link">
Custom errors
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/default-backend/" title="Default backend" class="md-nav__link">
Default backend
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/exposing-tcp-udp-services/" title="Exposing TCP and UDP services" class="md-nav__link">
Exposing TCP and UDP services
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/ingress-path-matching/" title="Regular expressions in paths" class="md-nav__link">
Regular expressions in paths
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/external-articles/" title="External Articles" class="md-nav__link">
External Articles
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/miscellaneous/" title="Miscellaneous" class="md-nav__link">
Miscellaneous
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/monitoring/" title="Prometheus and Grafana installation" class="md-nav__link">
Prometheus and Grafana installation
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/multiple-ingress/" title="Multiple Ingress controllers" class="md-nav__link">
Multiple Ingress controllers
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/tls/" title="TLS/HTTPS" class="md-nav__link">
TLS/HTTPS
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3-12" type="checkbox" id="nav-3-12">
<label class="md-nav__link" for="nav-3-12">
Third party addons
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="2">
<label class="md-nav__title" for="nav-3-12">
Third party addons
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../user-guide/third-party-addons/modsecurity/" title="ModSecurity Web Application Firewall" class="md-nav__link">
ModSecurity Web Application Firewall
</a>
</li>
<li class="md-nav__item">
<a href="../../user-guide/third-party-addons/opentracing/" title="OpenTracing" class="md-nav__link">
OpenTracing
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-4" type="checkbox" id="nav-4" checked>
<label class="md-nav__link" for="nav-4">
Examples
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-4">
Examples
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../" title="Introduction" class="md-nav__link">
Introduction
</a>
</li>
<li class="md-nav__item">
<a href="../PREREQUISITES/" title="Prerequisites" class="md-nav__link">
Prerequisites
</a>
</li>
<li class="md-nav__item">
<a href="../affinity/cookie/" title="Sticky Sessions" class="md-nav__link">
Sticky Sessions
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-4-4" type="checkbox" id="nav-4-4">
<label class="md-nav__link" for="nav-4-4">
Auth
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="2">
<label class="md-nav__title" for="nav-4-4">
Auth
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../auth/basic/" title="Basic Authentication" class="md-nav__link">
Basic Authentication
</a>
</li>
<li class="md-nav__item">
<a href="../auth/client-certs/" title="Client Certificate Authentication" class="md-nav__link">
Client Certificate Authentication
</a>
</li>
<li class="md-nav__item">
<a href="../auth/external-auth/" title="External Basic Authentication" class="md-nav__link">
External Basic Authentication
</a>
</li>
<li class="md-nav__item">
<a href="../auth/oauth-external-auth/" title="External OAUTH Authentication" class="md-nav__link">
External OAUTH Authentication
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-4-5" type="checkbox" id="nav-4-5">
<label class="md-nav__link" for="nav-4-5">
Customization
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="2">
<label class="md-nav__title" for="nav-4-5">
Customization
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../customization/configuration-snippets/" title="Configuration Snippets" class="md-nav__link">
Configuration Snippets
</a>
</li>
<li class="md-nav__item">
<a href="../customization/custom-configuration/" title="Custom Configuration" class="md-nav__link">
Custom Configuration
</a>
</li>
<li class="md-nav__item">
<a href="../customization/custom-errors/" title="Custom Errors" class="md-nav__link">
Custom Errors
</a>
</li>
<li class="md-nav__item">
<a href="../customization/custom-headers/" title="Custom Headers" class="md-nav__link">
Custom Headers
</a>
</li>
<li class="md-nav__item">
<a href="../customization/external-auth-headers/" title="External authentication" class="md-nav__link">
External authentication
</a>
</li>
<li class="md-nav__item">
<a href="../customization/ssl-dh-param/" title="Custom DH parameters for perfect forward secrecy" class="md-nav__link">
Custom DH parameters for perfect forward secrecy
</a>
</li>
<li class="md-nav__item">
<a href="../customization/sysctl/" title="Sysctl tuning" class="md-nav__link">
Sysctl tuning
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../docker-registry/" title="Docker registry" class="md-nav__link">
Docker registry
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
gRPC
</label>
<a href="./" title="gRPC" class="md-nav__link md-nav__link--active">
gRPC
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#prerequisites" title="Prerequisites" class="md-nav__link">
Prerequisites
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#step-1-kubernetes-deployment" title="Step 1: kubernetes Deployment" class="md-nav__link">
Step 1: kubernetes Deployment
</a>
</li>
<li class="md-nav__item">
<a href="#step-2-the-kubernetes-service" title="Step 2: the kubernetes Service" class="md-nav__link">
Step 2: the kubernetes Service
</a>
</li>
<li class="md-nav__item">
<a href="#step-3-the-kubernetes-ingress" title="Step 3: the kubernetes Ingress" class="md-nav__link">
Step 3: the kubernetes Ingress
</a>
</li>
<li class="md-nav__item">
<a href="#step-4-test-the-connection" title="Step 4: test the connection" class="md-nav__link">
Step 4: test the connection
</a>
</li>
<li class="md-nav__item">
<a href="#debugging-hints" title="Debugging Hints" class="md-nav__link">
Debugging Hints
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../multi-tls/" title="Multi TLS certificate termination" class="md-nav__link">
Multi TLS certificate termination
</a>
</li>
<li class="md-nav__item">
<a href="../rewrite/" title="Rewrite" class="md-nav__link">
Rewrite
</a>
</li>
<li class="md-nav__item">
<a href="../static-ip/" title="Static IPs" class="md-nav__link">
Static IPs
</a>
</li>
<li class="md-nav__item">
<a href="../tls-termination/" title="TLS termination" class="md-nav__link">
TLS termination
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#prerequisites" title="Prerequisites" class="md-nav__link">
Prerequisites
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#step-1-kubernetes-deployment" title="Step 1: kubernetes Deployment" class="md-nav__link">
Step 1: kubernetes Deployment
</a>
</li>
<li class="md-nav__item">
<a href="#step-2-the-kubernetes-service" title="Step 2: the kubernetes Service" class="md-nav__link">
Step 2: the kubernetes Service
</a>
</li>
<li class="md-nav__item">
<a href="#step-3-the-kubernetes-ingress" title="Step 3: the kubernetes Ingress" class="md-nav__link">
Step 3: the kubernetes Ingress
</a>
</li>
<li class="md-nav__item">
<a href="#step-4-test-the-connection" title="Step 4: test the connection" class="md-nav__link">
Step 4: test the connection
</a>
</li>
<li class="md-nav__item">
<a href="#debugging-hints" title="Debugging Hints" class="md-nav__link">
Debugging Hints
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/kubernetes/ingress-nginx/edit/master/docs/examples/grpc/README.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1 id="grpc">gRPC<a class="headerlink" href="#grpc" title="Permanent link">&para;</a></h1>
<p>This example demonstrates how to route traffic to a gRPC service through the
nginx controller.</p>
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">&para;</a></h2>
<ol>
<li>You have a kubernetes cluster running.</li>
<li>You have a domain name such as <code class="codehilite">example.com</code> that is configured to route
traffic to the ingress controller. Replace references to
<code class="codehilite">fortune-teller.stack.build</code> (the domain name used in this example) to your
own domain name (you're also responsible for provisioning an SSL certificate
for the ingress).</li>
<li>You have the nginx-ingress controller installed in typical fashion (must be
at least
<a href="https://quay.io/kubernetes-ingress-controller/nginx-ingress-controller">quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.13.0</a>
for grpc support.</li>
<li>You have a backend application running a gRPC server and listening for TCP
traffic. If you prefer, you can use the
<a href="https://github.com/kubernetes/ingress-nginx/images/grpc-fortune-teller">fortune-teller</a>
application provided here as an example. </li>
</ol>
<h3 id="step-1-kubernetes-deployment">Step 1: kubernetes <code class="codehilite">Deployment</code><a class="headerlink" href="#step-1-kubernetes-deployment" title="Permanent link">&para;</a></h3>
<div class="codehilite"><pre><span></span>$ kubectl create -f app.yaml
</pre></div>
<p>This is a standard kubernetes deployment object. It is running a grpc service
listening on port <code class="codehilite">50051</code>.</p>
<p>The sample application
<a href="https://github.com/kubernetes/ingress-nginx/images/grpc-fortune-teller">fortune-teller-app</a>
is a grpc server implemented in go. Here's the stripped-down implementation:</p>
<div class="codehilite"><pre><span></span><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">grpcServer</span> <span class="o">:=</span> <span class="nx">grpc</span><span class="p">.</span><span class="nx">NewServer</span><span class="p">()</span>
<span class="nx">fortune</span><span class="p">.</span><span class="nx">RegisterFortuneTellerServer</span><span class="p">(</span><span class="nx">grpcServer</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">FortuneTeller</span><span class="p">{})</span>
<span class="nx">lis</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">net</span><span class="p">.</span><span class="nx">Listen</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;:50051&quot;</span><span class="p">)</span>
<span class="nx">grpcServer</span><span class="p">.</span><span class="nx">Serve</span><span class="p">(</span><span class="nx">lis</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
<p>The takeaway is that we are not doing any TLS configuration on the server (as we
are terminating TLS at the ingress level, grpc traffic will travel unencrypted
inside the cluster and arrive "insecure").</p>
<p>For your own application you may or may not want to do this. If you prefer to
forward encrypted traffic to your POD and terminate TLS at the gRPC server
itself, add the ingress annotation <code class="codehilite">nginx.ingress.kubernetes.io/backend-protocol: &quot;GRPCS&quot;</code>.</p>
<h3 id="step-2-the-kubernetes-service">Step 2: the kubernetes <code class="codehilite">Service</code><a class="headerlink" href="#step-2-the-kubernetes-service" title="Permanent link">&para;</a></h3>
<div class="codehilite"><pre><span></span>$ kubectl create -f svc.yaml
</pre></div>
<p>Here we have a typical service. Nothing special, just routing traffic to the
backend application on port <code class="codehilite">50051</code>.</p>
<h3 id="step-3-the-kubernetes-ingress">Step 3: the kubernetes <code class="codehilite">Ingress</code><a class="headerlink" href="#step-3-the-kubernetes-ingress" title="Permanent link">&para;</a></h3>
<div class="codehilite"><pre><span></span>$ kubectl create -f ingress.yaml
</pre></div>
<p>A few things to note:</p>
<ol>
<li>We've tagged the ingress with the annotation
<code class="codehilite">nginx.ingress.kubernetes.io/backend-protocol: &quot;GRPC&quot;</code>. This is the magic
ingredient that sets up the appropriate nginx configuration to route http/2
traffic to our service.</li>
<li>We're terminating TLS at the ingress and have configured an SSL certificate
<code class="codehilite">fortune-teller.stack.build</code>. The ingress matches traffic arriving as
<code class="codehilite">https://fortune-teller.stack.build:443</code> and routes unencrypted messages to
our kubernetes service.</li>
</ol>
<h3 id="step-4-test-the-connection">Step 4: test the connection<a class="headerlink" href="#step-4-test-the-connection" title="Permanent link">&para;</a></h3>
<p>Once we've applied our configuration to kubernetes, it's time to test that we
can actually talk to the backend. To do this, we'll use the
<a href="https://github.com/fullstorydev/grpcurl">grpcurl</a> utility:</p>
<div class="codehilite"><pre><span></span>$ grpcurl fortune-teller.stack.build:443 build.stack.fortune.FortuneTeller/Predict
<span class="o">{</span>
<span class="s2">&quot;message&quot;</span>: <span class="s2">&quot;Let us endeavor so to live that when we come to die even the undertaker will be sorry.\n\t\t-- Mark Twain, \&quot;Pudd&#39;nhead Wilson&#39;s Calendar\&quot;&quot;</span>
<span class="o">}</span>
</pre></div>
<h3 id="debugging-hints">Debugging Hints<a class="headerlink" href="#debugging-hints" title="Permanent link">&para;</a></h3>
<ol>
<li>Obviously, watch the logs on your app.</li>
<li>Watch the logs for the nginx-ingress-controller (increasing verbosity as
needed).</li>
<li>Double-check your address and ports.</li>
<li>Set the <code class="codehilite">GODEBUG=http2debug=2</code> environment variable to get detailed http/2
logging on the client and/or server.</li>
<li>Study RFC 7540 (http/2) <a href="https://tools.ietf.org/html/rfc7540">https://tools.ietf.org/html/rfc7540</a>.</li>
</ol>
<blockquote>
<p>If you are developing public gRPC endpoints, check out
https://proto.stack.build, a protocol buffer / gRPC build service that can use
to help make it easier for your users to consume your API.</p>
</blockquote>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../docker-registry/" title="Docker registry" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Docker registry
</span>
</div>
</a>
<a href="../multi-tls/" title="Multi TLS certificate termination" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Multi TLS certificate termination
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../../assets/javascripts/application.5e60981f.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:"../.."}})</script>
<script>!function(e,a,t,n,o,c,i){e.GoogleAnalyticsObject=o,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(t),i=a.getElementsByTagName(t)[0],c.async=1,c.src="https://www.google-analytics.com/analytics.js",i.parentNode.insertBefore(c,i)}(window,document,"script",0,"ga"),ga("create","UA-118407822-1","kubernetes.github.io"),ga("set","anonymizeIp",!0),ga("send","pageview");var links=document.getElementsByTagName("a");if(Array.prototype.map.call(links,function(e){e.host!=document.location.host&&e.addEventListener("click",function(){var a=e.getAttribute("data-md-action")||"follow";ga("send","event","outbound",a,e.href)})}),document.forms.search){var query=document.forms.search.query;query.addEventListener("blur",function(){if(this.value){var e=document.location.pathname;ga("send","pageview",e+"?q="+this.value)}})}</script>
</body>
</html>