Loading video player...
Today we're going to be taking a look at
a Kubernetes capability that is quite
new, but it's also been around for a
while and it's called Gateway API. It
has only started getting traction over
the last couple of weeks. What is
Gateway API? Why does it even exist?
What are the features? So, what can we
achieve using Gateway API? How to deploy
it and how to use it? This video is a
first video that is part of a minieries
on gateway API. So in this video, we'll
take a look at the features and
capabilities, but at the end of this
video, I'll provide you some links to
material to other gateway API
controllers that I want to cover in the
series. So this is why you should
subscribe. So if you like the video, be
sure to like, subscribe, hit the bell so
you know when the next episode drops.
Let's get straight to the point. So
without further ado, let's go.
So looking at the Kubernetes
documentation, gateway API is basically
just a family of APIs. Similar to how
ingress is an API that ingress
controllers use, gateway API is a set of
APIs that gateway API controllers can
use. So it's a set of APIs that make
network services available and it does
so by using extensible role oriented
protocol-aware configuration mechanisms.
Basically what that allows us to do is
to achieve advanced traffic routing.
Gateway API solves a bunch of challenges
that ingress had. So think of gateway
API as a more advanced ingress. Instead
of defining absolutely everything in one
ingress rule, we can now build routing
rules in modular fashions. So if you're
familiar with ingress, ingress is one
rule that defines how does traffic come
in, what to do with the traffic all in
one object. Gateway API is similar but
it's role oriented. So it allows us to
model our traffic after organizational
roles that are responsible for managing
Kubernetes and service networking. So
think about a large enterprise company.
You have infrastructure people, you have
cluster operators, people who are in
charge of Kubernetes and then you have
application developers. So different
people interfacing with the platforms in
different ways. Then you have
application developers and all their
concern is about running applications in
the cluster pretty much writing code and
having their applications run in the
cluster. So firstly, gateway API allows
for a portable specification. This means
we can move gateway API between
different controllers. So we don't get
vendor locked. It's also quite
expressive. That way we can expressively
specify what to do with the traffic
similar to what we could have done at
ingress but more modularly. And gateway
API is also very much extensible. For
example, application developers should
only be concerned with how their
application receives traffic. So
developers more like I want this domain
and this path to come to my service.
They shouldn't be concerned with what
TLS certificates are being used, how
it's rotated, what networking ports are
used, and how the operating system load
balances the traffic. That's more for
the cluster operators. The same way
cluster operators shouldn't have to be
concerned about how the cloud
infrastructure provides the traffic to
the cluster. Their concern is more about
the network traffic, the security, the
policies, what ports are used, how it's
load balanced. Same way the cloud
providers or the infrastructure folks
shouldn't be concerned what network
policies are used within the cluster.
They're more likely to take care of
things like what AWS load balancing
capability do we provide to the
platform. Do we use a API gateway in
AWS? Do we use an ALB, an NLB, an Azure
load balancer or an API gateway? Gateway
API achieves this separation by having a
resource model that is modeled around
this. So these are the main concepts you
should understand when looking at
gateway API. First of all, the gateway
class. What is a gateway class? So
gateway class defines a set of gateways
with a common configuration that's
managed by a controller. Think about in
the ingress world, you might have an
haroxy ingress controller. You might
have an enginex ingress controller and
you use an ingress class that
distinguish which ingress controller
takes care of which ingresses. The same
way gateway API has a gateway class that
defines that. So we could have a gateway
class that says these gateways are used
by ISTTO or traffic or envoy. This is
the highest level API and it's defined
globally within the cluster. It doesn't
sit in a namespace. The next object
lives in a namespace and that is the
gateway. The gateway defines an instance
of traffic handling infrastructure such
as a cloud load balancer. So the gateway
could point to something like an API
gateway controller like envoy pselium
and more. It also helps define things
like a cloud load balancer. So if you're
running an Azure, how do we want to
manage that Azure load balancer? The
gateway lives at a namespace level. This
is the power of this whole thing. It's
all modular. So I can say a specific
department uses a specific gateway.
Another department might use a different
gateway. This way we can split things
up. Then we have our routes. Now the
popular ones are HTTP route and gRPC
route. This is kind of like the rules we
have within an ingress where you define
HTTP specific rules for mapping traffic
from a gateway listener to a back-end
endpoint like a Kubernetes service. So
developers would be concerned with HTTP
routes because they can say I want this
domain and this path to come to my
service A. So this is how I like to
visualize this modularity in action. So
you have a Kubernetes cluster and at the
top here, this is your public domain.
Traffic comes in from a client and it
goes to what's called the gateway. Now
cluster operators look at this gateway.
The gateway will define what ports are
exposed at or 443. It also points to
things like TLS certificates. You can
see over here and these TLS certificates
can live in different namespaces. So
they're decoupled from the actual
gateway. This is great for security. And
then we have the gateway class managed
by infrastructure operators. And this
defines the implementation. What
implementation is available to our
cluster. So this will define things like
do we use a traffic gateway API, an SD1
or whichever product it uses under the
hood that is implemented by the gateway
itself. Gateways can live in any
namespace and they basically forward the
traffic based on HTTP routes. We have
HTTP, gRPC, TCP and UDP. And there are
more routes to come. Then over here we
have application developers and they
basically define the routes. This
defines HTTP like specific rules that
map the traffic from the gateway to the
upstream service which then goes to
pods. We can also see this model
explained on the gateway API special
interest group documentation where they
explain all of this in detail. So you
have infra providers taking care of
gateway classes, cluster operators
looking after gateways, application
developers managing their routes. So to
take gateway API for a spin, we'll need
a Kubernetes cluster. And for that, I
like to use a utility called kind, which
allows me to create lightweight
Kubernetes clusters that I can use for
testing. In this video, I'm going to be
using Kubernetes 1.34. After that is
done, I check my cluster and we're good
to go. To start working with Gateway
API, we have to install the gateway API
CRDs. At the time of this recording, the
CRDs are not part of the native
Kubernetes installation. So unlike
things like ingress and config maps and
services, gateway API has to be
installed in the cluster and we can grab
this off the gateway API special
interest group documentation. There is a
standard channel which you can just
apply using cubectl or the experimental
channel which you can apply using
cubectl. Now given this is an
informative video, I want to show you
all the possible features. So in this
video I'm going to be using the
experimental channel. something you want
to keep in mind before going to
production. So I simply cubectl apply
the experimental channel release and in
this video I'm using 1.4. I go ahead and
install that on my cluster and you'll
see that this applies a bunch of new
objects to the cluster. So there's
gateway class, there's gateway, HTTP
routes and some other routes and
features. Important to know that this
list will constantly evolve and change
as gateway API is evolving and changing
rapidly. And as you can see here at the
time of this recording, the stable
channel gives you gateway class, a
gateway and HTTP route. You can retrieve
these using cubectl. The experimental
channel has things like TLS route, TCP
route, and UDP route and more. Important
to note that the gateway API is
extremely new. So a lot of the stuff I
say in this video might be irrelevant in
a few weeks time. Things like cores and
oorthth and external authentication,
these are all coming into the
experimental channel. Now that we have a
Kubernetes cluster and we have the
gateway API CRDs, we can go ahead and
install a gateway class and a gateway.
We can set these up and we can then
decide what gateway API implementation
we want to use. Now this video is all
about gateway API and does not concern
the implementation. So whether you
decide to use ISTTO, Envoy, Traffic,
Psyllium, it doesn't really matter.
Everything you see in this video should
technically be supported by all the
controllers as it's a default standard.
We will then deep dive each of the
specific controllers in future videos.
So in this video, I just randomly pick
the popular gateway API controller
that's easy to install. In this example,
it'll be traffic. So I just give the
chart a version. I say Helmreo add. I
add the traffic Helmreo. I can then also
search for other versions if I want to.
And after running that in my terminal, I
simply say helm install and I go ahead
and install a basic traffic API gateway
controller. I paste that to my terminal
and we get our controller deployed. I
can then go ahead and check my
installation by running cubectl get
pods. Go ahead and run that and that's
all looking good. I can use the cubectl
logs command to check the output if my
controller is happy. We can see that
it's there. It's all good to go. And
since we don't have a load balancer,
we're running kind. We're just going to
use port forward to create a endpoint
that we can start to use. So cubectl
port forward is great for that. I go to
my terminal and I set that up. And I can
leave this terminal running in the
background somewhere. For testing and
evaluation purposes, load balances
should not concern us. Port forwarding
is great for this. You don't need some
open- source load balancer to test and
trial out things. Same way, we're going
to need a DNS endpoint or a domain. And
for that and local testing, I just like
to use a host file. We can use a simple
host file entry to set up some example
domains. So I'm going to have one domain
called exampleapp.com, another one
specific to a service like a Go service
or some kind of functionality you want
to expose, and another one for another
API like exampleappython.com.
Windows and Linux both have this
feature. In Windows, you can find it in
system 32 drivers EDC directory. In
Linux, it's an etc hosts. Once you've
saved that, you'll now have a domain or
a DNS entry that you can test with
locally. And we point this to local host
because that's where we're running our
port forward from. So all the traffic
here will go to our gateway API
controller. Next up, to fully evaluate
these features, we're going to need some
example applications. So we'll need
something like a Go micros service that
we can run and maybe a Python one to
simulate different technologies. And in
the real world, you also want a front
end, something written in HTML that
perhaps makes an Ajax post call to one
of the backend services. To do this,
it's really straightforward. I have a
bunch of example apps that I use
throughout my videos. So, in my Git
repo, I have a Python folder with a
deployment YAML. I have a Golang folder
with a deployment YAML. So, this will
deploy a Go and a Python microser. And
then I have a web app.yaml, YAML which
is a simple web HTML which makes a post
call to the backend API the Go
application very easy to get this
running I just copy paste this jump into
my terminal and paste it with that
deployed I can now say cubectl get pods
and we have two instances of our go
service two instances of our Python
service and our web front end also
important to notice all of these
services have endpoints that are not
exposed they're all cluster IP so
they're all just running locally and
privately and securely within our
cluster. Gateway API is all about making
these applications publicly accessible
similar to an ingress. Now, how do we
send traffic to these example
applications? Firstly, we need to take a
look at a gateway class. Now, the
gateway class is a Kubernetes object
we'll define in YAML that the
infrastructure providers look at. The
first point of call of traffic into our
cluster will be via some sort of load
balancer. If you're running an EKS or
AKS or GKE, you'll have a public
endpoint. That public endpoint is
provided by some sort of hardware or
infrastructure. So, infrastructure
people should provide you this
capability and that is what a gateway
class defines. It basically says what
implementation are we going to use to
accept this traffic. So, we'll go ahead
and install a gateway class. Now, a
gateway class is a cluster scoped
resource. So it doesn't live in a
namespace and it's provided by the
infrastructure guys. This resource
presents a class of gateways that can be
instantiated and used. So installing a
gateway class is as simple as applying a
small YAML file. Now because in this
example I'll be using traffic. My
gateway class specifies that my
implementation of my gateways will be
traffic. And this is what a typical
gateway class looks like. You give it a
name. You can call it anything you like.
It lives at a cluster level and it
points to a controller which is the
implementation that will be implementing
this gateway class. You can have a few
of these running in your cluster. So
it's as easy as grabbing this YAML file
and applying it to your cluster with
cubectl. Then just like any other
Kubernetes resource, we need to test to
make sure it's working. We say get
gateway class. You can see it's there.
And like any other Kubernetes object,
you want to describe it to make sure
it's functional. And what you're looking
for here is the status. make sure that
it has been handled and it is accepted
and that there are no errors here. This
actually means that my controller behind
the scene that we deployed with Helm has
actually gone ahead and handled this and
accepted it. If there's any problems
here, your traffic will not work and
will not be accepted to your pods. So
cubectl describe always check whether
your class is successfully implemented
and accepted. Now we have a gateway
class deployed to our cluster. So our
infrastructure team has given us load
balancing capabilities and now our
cluster operators can define how we want
to accept traffic into the cluster. What
ports do we want to expose? What TLS
certificates do we want to use? This is
all done using a gateway. We can have a
gateway that attaches to the traffic
gateway class. We could have another
gateway that attaches itself to an STO
gateway class. So it gives us this
flexibility. Now typically the gateway
lives in the same name space as the
routes and applications but it does not
need to. This gives you even more
flexibility as you can have a gateway
per namespace. You can have a central
gateway which allows all routes to
attach to it. That's a lot of power and
flexibility and you can protect all of
these resources using general Kubernetes
arbback. Same way I applied a gateway
class I can apply a gateway using a
simple YAML file. And this is what a
gateway YAML looks like. You can give it
a name. So I can either call it
something like traffic so people know
it's a traffic gateway API or I can give
it a generic name. So I hide the
implementation from developers. This is
all up to you. I'm just going to deploy
it in the default name space. So this is
my gateway that will manage all the
traffic coming into my cluster. And I
bind this to my class by using this
gateway class field. This gateway will
then implement this gateway class. Next
up, we want to define how is traffic
coming into the cluster and we do this
setting up listeners. You can have
multiple listeners. This is an array.
So, we can have a rule for HTTP and
HTTPS. I like to expose HTTP because I
can use this for health probes, health
probes for the load balancer, health
probes for specific endpoints, and I can
set up a rule and we can always redirect
non-HTTP traffic to HTTPS. So here you
can see what I've done is I have an
entry for HTTP. This is the protocol and
the port. And then this is the next
modular capability that I like is that
you can say what routes are allowed to
attach to this listener. So I can say
only routes from the same namespace as
this gateway. So in this case because I
deploy this gateway to the default
namespace only applications in the
default namespace can use this gateway.
I can also change this to say all
basically then I can move this gateway
to a more like a platform engineering
specific namespace or something like
cube system or wherever you're centrally
managing things and that means that all
HTTP routes and general routes can be
attached to this gateway or you could
use something like a label selector
that's also really useful. This allows
you to totally customize what routes can
be used on this gateway and the HTTPS
one is pretty much the same. The only
difference is that I can do things like
say TLS and I can say turn on TLS and
the mode is terminate. So this allows me
to terminate TLS at the gateway level
and then route to different ports on
upstream services. And this is also the
magic that I like is you can give a
certificate reference and the
certificate reference takes in a
namespace as well. So this is a secret
in the default namespace for TLS. This
means I can put my TLS certificate
anywhere in my cluster I like and the
gateway will be able to read it. This
also means that I don't need a TLS
certificate in every name. I can
centrally move it to one place. I can
use arbback to protect it and only allow
cluster operators to rotate it. and they
don't have to rotate many certificates.
You could also use something like search
manager to rotate it. And again, it also
has the same settings like allowed
routes. So this is how we set up a
simple two listeners, one for HTTP and
one for HTTPS. And keep in mind that
this is a standard implementation. So it
doesn't matter what gateway API
controller you choose. This should be
implemented and working across all of
them. Then I jump to my terminal and I
go ahead and apply that gateway. Then I
can do cubectl get gateway. We can see
it's there in our default namespace.
Remember gateways are namespaced. I can
then say cubectl describe gateway and we
can look at the status and it is
accepted and valid. But notice that I do
have an error on one of my routes. So
the first one doesn't have an error. But
if we scroll down, we can see there's an
error because our TLS certificate is not
found. I have not gone ahead and
installed a TLS certificate just yet. In
this video, I'll be using a self-signed
local certificate once we take a look at
TLS, but our gateway is good to go for
now. Next up, we're going to take a look
at some real world traffic examples. Now
that we have our infrastructure in
place, we can go ahead and use gateway
APIs from a development standpoint.
Let's take a look at some real world
functionality. The most important one I
want to cover from an introduction
standpoint is the traffic management
features, which features HTTP routes.
And there are some important fields on
HTTP routes that we'll cover such as
parent ref, section name, host names,
rules, matches, and filters. We can use
this to construct rules for what to do
with the traffic coming in via our
gateway. Now, the first most basic
simplest example is routing traffic by
host name. If you have an application
like example app go and you want to send
that to a go service you have multiple
departments all have their own DNS or
domain names and you want to route based
on host. We do this with ingress
controllers and any kind of reverse
proxy by inspecting the traffic and
looking at the host header and this
allows us to route based on host header.
So what we can do is we can set up
something like example app.python.com
python.com go to python service on a
different port and we can have another
domain like example appgo.com route to a
go service. So this is basically an HTTP
route routing to an upstream Kubernetes
service. So that is the Kubernetes
service port that we're mapping there.
And because we're running a local domain
using our host file, we'll be able to
access these on our browser. So let's
look at our first rule which is an HTTP
route by host name. And this is how you
define an HTTP route. You give it a name
and a name space. This is our Python
route. I'm going to be showing you two
routes within the same file. The first
field we want is parent refs. This helps
us define what gateway to bind to. And
here we are pointing to the gateway API
gateway that we created earlier. gateway
API also allows us to bind to a specific
listener in the gateway. So remember our
gateway had an HTTP and an HTTPS
listener. So in this example, I'm
showing you how to bind to a specific
listener using the section name. And
this is the type of object we want to
bind to. In our case, it's called a
gateway. And then I specify what host
name do we expect for this traffic. So
this is example app-pon.com.
And then we can specify what we want to
do with this traffic using what's called
rules. Rules is an array. So you can
have multiple rules. And we'll look at
more complicated ones as we go along.
Here we don't really have much rules
other than the fact that we want all
traffic to go to the Python service. So
we create this thing called a backend
reference. And this points to a
Kubernetes service. The Kubernetes
service name is Python SVC. It's running
on port 5000. And we can give it a
weight. So this means we could have
multiple rules sending maybe 50% of
traffic to one and it's 50% of traffic
to another. And then I've got the same
one here but this time for a go service.
So HTTP route. We give it a name and a
namespace. We bind to the gateway API
over here. This is our host name. This
time it's example app-go.com and a
backend reference. This time pointing to
the go service on port 5000. I can hop
into my terminal cubectl. I'll apply
that and immediately these routes will
be created. They'll be consumed by our
gateway API controller and they should
be accessible. So using these links we
can go ahead and access our Python and
our Go service. Here you can see we have
hello from Python and we have hello from
Go. So this is how you route traffic
based on domain. Next up you can route
traffic based on path and you can do
this in a number of different ways. You
can configure the path that's coming in
to your platform as well as the path
that is passed through to the upstream
service. So to do routing by path, we
can do so using different strategies
depending on what we want to achieve as
the outcome. We can do exact match of
the path. This means anything with just
slash goes as it is to the upstream. In
many cases, using exact is not really
useful because if we define an exact
path as slash, that means the upstream
will not be able to accept any other
paths or files behind it. We can do path
prefix. So we can say anything /star
goes to upstream/star. And this is very
much a more common approach. And to
achieve pathing by route, let's take a
look at an HTTP route that does so.
We're going to override the route we had
before. also use the same name, bind to
the same gateway, have the same host
name, but this time our rule is a little
bit more complex. This time we're adding
a match section by path. And here we say
exact. So technically this will only
allow us to visit the path slash and
then whatever matches this path will be
sent to the upstream service. Whatever
doesn't match this path will hit the 404
default page of the gateway API
controller. It's important to understand
when debugging this, make sure you know
what 404 you're hitting. Sometimes
developers can get confused because
their path gets a 404, but it may be the
404 of the upstream instead of 404 of
the gateway. So just be mindful of that.
Then we're going to do the same for the
go service. So HTTP route the name and
namespace. We bind to the same gateway.
We use the same host name and here we
also use an exact path. So let's see how
that behaves. Go ahead and update that.
Head over to our URLs. Press enter. We
see no difference. On the go side also
we see no difference. But notice I have
a status endpoint on my go service. And
if I hit that I get page not found. But
I do know that my go service does have a
status endpoint. But this is because we
used exact match. We're only matching
exactly the path slash and sending that
to the upstream go service. In this
case, slash status doesn't match. It
doesn't match the exact rule. So, it's
not going to go to the upstream. It's
going to get a 404 directly from the
gateway API. If we wanted all of the
paths to be servable from the upstream,
we can change the type to path prefix.
This will pretty much match and allow us
to visit slashstar. So anything behind
the slash and pass the entire URL to the
upstream. So if I go ahead and apply
that again, go to my path and refresh,
you can see it immediately returns.
Okay, so now anything I pass as a URL
will go to my go service. This is useful
if you have services that have their own
dedicated domain. There are however
scenarios where services are sharing a
domain like you might have a central
API. example.com domain which routes
paths to different upstream
microservices depending on the path. We
can do this type of routing using URL
rewrite. For example, we can rewrite
host names or URLs using the URL rewrite
feature. So we can merge our APIs under
one domain. So I can use exampleapp.com
and I can say /api/python
go to the Python service. Note here that
my Python service does not see the URL
portion API/Python.
So anything behind the Python syntax
here will go to the Python service but
nothing in front. The same way for the
Go service. Everything after API/go goes
to the Go micro service. This means we
can do / API/go/stus
and status will be passed to the
upstream service like so. So we are
rewriting the prefix here and this is
fairly straightforward to do with an
HTTP route. So let's go ahead and update
our routes for our Python and our Go
service. This time I'm going to change
things slightly. So we still have the
same name and namespace, still binding
to the same gateway API. This time I'm
changing the host name. I want to run my
Go and Python microser behind a
centralapp.com
domain. And here I'm going to specify a
rule. This is a slightly more complex
rule, but it's still very simple. So
this time we match on a specific path
API/Python.
But the keyword here is that we want the
type of match to be a path prefix. This
means that technically we could have
anything behind this path. Then what we
do is we're going to apply a filter. And
this is where the type is URL rewrite.
This is the module we want to use
provided by the gateway API
specification. And each of these types
generally have different settings
underneath. So you can have types like
dealing with cores, dealing with
upstream authentication and other types
that are still coming in the
experimental channel, some that are GA
and more to be implemented in the
future. So this is a rapidly changing
ecosystem. And what we're going to do
here is we're going to pass some
parameters to the URL rewrite module. It
needs a path. So it needs to know what
do we want to send it to. In our case,
we want to replace the prefix match. So
here we have a path prefix API/python.
We want to replace it with slash. That
means that the upstream service, in our
case, the Python service will not see
API/Python as part of the URL. It'll
only see what's after this prefix. So
this is really useful. You can see it in
action when we start taking a look at
the Go service because the Go service
also looks the same the same gateway API
but also the same domain. So it now
shares the domain of the Python service
and it has its own different match rule
to say / API/go as a path prefix and URL
rewrite that and change that prefix to
slash. So don't pass API/go to the
upstream go service that we have over
here. So let's go ahead and apply that
and see what it looks like. Now this
time I can open up API Python or API go.
If I do so you can see API Python goes
to the root page of the Python
application. Notice if I do /st status
on this one I get a not found. And this
time this is the not found of the Python
application. So here our gateway API is
passing everything after API/Python
to the upstream service and the Python
application doesn't have a status page.
So this is a classic example of
understanding where your 404s is coming
from. So here our gateway API is working
as expected. We can do the same with the
go service. See / API/go goes to the go
microser but our go service does have a
status page. So I can go slashstatus and
we can see that goes to our go
application successfully. So this allows
us to have multiple APIs under a single
domain and our gateway API can now act
as a true API gateway. A slightly more
advanced feature of the gateway API is
the ability to modify request and
response headers. This is using a
special field called the request header
modifier and response header modifier.
What we can do with this is we can
update request and response header
fields. We can inject new headers or
drop certain headers. This is exactly
what something like corores does when
the browser tries to protect the user
from cross origin API calls or
crossdomain calls. As DevOps engineers,
we often have to deal with cores. Now,
it's important to know at the time of
this recording, we can manipulate
request and response headers using
gateway API, but corores is not part of
the stable gateway API implementation
yet. Therefore, we can cover it in
upcoming videos, but I can show you how
to manipulate headers to bypass and work
around cores and show you the feature of
manipulating headers. To show you the
problem of cores, what I've done is I've
got a small web app that I'm going to
port forward to quickly. So this simple
web API is the example app we've
deployed the front-end one which makes
an API call to example app.com to the go
micros service. When I click this button
this will attempt to make a javascript
ajax call and you can see that it gets a
cause error. You can see this in the
browser here we're getting a coor
specific error. This is because
localhost is not allowed to make an API
call to exampleapp.com. The browser is
blocking it. Now generally to deal with
cores you would use a corores module of
whatever software you're using and that
should handle it. You generally never
need to resort to custom scripting. But
if you wanted to modify headers in HTTP
requests, you can do so using the HTTP
route. So here we're going to do it for
the go service just so I can demonstrate
to you what that looks like. We use the
same route we had before. This time we
still bind to the same gateway, same
host name. We're going to keep the rules
as we had it before. So, we're going to
keep our path matching. API/go go to the
Go service upstream. This time, we're
going to add an extra filter. This is
the response header modifier. And what
you can do here is you can tweak
response headers. You can either add or
remove headers. So, here we add headers.
And you can provide any headers you'd
like to add. This is just an array of
names and values. So, here I add the
access control allow origin headers. I'm
allowing localhost 8000 to make that
call. I pass the methods we're allowed
to execute. And that's pretty much it.
That is how you modify response headers.
And then I have my existing rule that I
like to keep here, the URL rewrite to
pass any path to our go service. So I
jump to my terminal and I apply that
rule. And notice now on my web app, I
can click the button and now it's
allowing it. And if we take a look at
that network request in the browser
inspection tool, we can see that it's
injected these response headers. So
that's how you manipulate HTTP request
and response headers using the gateway
API. Now gateway API can also handle
HTTPS. So think about things like TLS
and SSL connectivity. So we can specify
a TLS certificate in one specific area
or wherever we like and we can have
HTTPS enabled and all traffic coming
into HTTPS. We can either pass it
through as is, but that would mean every
micros service would need HTTPS support
as well and would probably need the
certificate reference. A lot of
companies will terminate TLS at the
gateway level. That means we don't need
to pass the complexity and overhead of
managing TLS at every service. Gateway
API allows us to do this. In this video,
I generated a test TLS certificate using
a utility called makesert. You can find
this utility on GitHub. It's useful for
testing local environments. You can
create a locally trusted development
certificate that works in the browser
that the browser trusts. It allows you
to install root certificates, create a
certificate, and then have it
automatically accepted and trusted by
the browser. Great for local testing. So
I ran a few commands locally using curl
to get the latest version of makes it
add it to user local bin and give it
execution permissions. Then I set this
environment variable of where I want my
CA root to live. So I just put that in a
specific folder. You can do this for
Linux or Windows. I go ahead and run
makes it and generate some certificates.
And then I run makes it install which
allows me to install the root
certificate in my local browser and
trust it. With the TLS certificates
generated locally, I can then deploy my
secret to Kubernetes. So I can say
cubectl create secret TLS just like a
real certificate. I'm going to call it
secret TLS. I'm going to put it in the
default name space and I will just give
it my cert and key. Go ahead and punch
that into the terminal. And now I've got
a TLS secret created. Now to enable TLS,
we need to do two things. Firstly, we
need to adjust the gateway to enable TLS
as a listener. Listener allows us to
bind to specific ports such as 443. We
then need to update our HTTP route to
tell it to bind to the HTTPS listener,
the new one that we'll be adding to the
gateway. So on the gateway, I've already
done this. I do have this endpoint
called HTTPS. This is my new listener.
Here I specify the port to listen on. So
this is the port that the traffic will
come in on for HTTPS. I'll specify mode
as terminate. That means I will
terminate TLS at the gateway level. And
here is the certificate reference. I've
now created that certificate as a secret
in the default namespace. So the warning
on the cubectl describe on this gateway
should disappear. So that's the gateway.
You go ahead and update your gateway
after making these changes. And then you
go to your HTTP route and update the
reference to say you now want to listen
to the HTTPS listener on the gateway. We
keep the host name the same and
everything else such as the rules all
remains the same. So two things to keep
in mind. First adjust the gateway to
enable the TLS listener first. Enable
443. Then apply the TLS listener in your
HTTP route. Then we can go ahead and
update our HTTP route. And one thing
we'll need to do also is now port
forward to our gateway API using 443
instead. So I'll just switch out the
port forward in the terminal to 443 from
80. And the result of this is now we can
go to HTTPS on the same URL and this
will route internally to HTTP on the go
service. Remember the go service does
not have TLS enabled. So we're
offloading at the gateway level. So I
click that endpoint and you can see now
my site is secure. So I have a locally
browser trusted certificate here and
this is coming now over TLS. Another
point of interest I wanted to make is a
new feature called infrastructure
labels. This is a useful feature because
it gives us the ability to customize
infrastructure under the hood for
gateways. Think of cloud load balances
like AWS ALBs and Azure load balances.
You can use infrastructure labels to
make changes to these. This is
equivalent of an ingress where you set
annotations or labels on infrastructure
like services and the cloud will go
ahead and make changes to the load
balances under the hood. So this is all
possible using gateway API. Now so it's
important to know that everything we've
done so far should be supported by any
gateway API controller. So from this
guide you'll have the knowledge to go
ahead and look at something like or
envoy or contour or Kong or traffic and
then you should know how to implement
gateway API features from a basic
standpoint. At the bottom of this guide
I have a reference to gateway API
controller guides which I'm working on
which includes things like trafficto
envoy and it can include more. But I
need you guys to let me know down in the
comments what you'd like to see and what
is it about that gateway API that you're
interested in. And some are subject to
change. So that is the introduction to
gateway API. Let me know down in the
comments below what sort of gateway API
controller and implementation you're
interested in. And if you've been using
Gateway API, what is your feedback so
far? And more importantly, why are you
interested in a specific controller?
What are the things that help? And what
are some of the challenges? Let me know
in the comments down below. And if you
like this video, be sure to like,
subscribe, hit the bell so you know when
the next episode drops. And also
remember to check out the development of
the ultimate DevOps road map in the link
down below and follow on Instagram for
more updates on the road map. And as
always, thanks for watching and until
next time, peace.
Follow the DevOps roadmapππ½ https://www.instagram.com/marceldempers My DevOps Roadmap ππ½ https://marceldempers.dev Patreon ππ½https://patreon.com/marceldempers Checkout the source code below ππ½ and follow along π€ Also if you want to support the channel further, become a member π https://marceldempers.dev/join Checkout "That DevOps Community" too https://marceldempers.dev/community Source Code π§ -------------------------------------------------------------- https://github.com/marcel-dempers/docker-development-youtube-series Like and Subscribe for more :) Follow me on socials! Instagram | https://www.instagram.com/marceldempers X | https://x.com/marceldempers GitHub | https://github.com/marcel-dempers LinkedIn | https://www.linkedin.com/in/marceldempers Music: Track: Reckoner - lofi hip hop chill beats for study~game~sleep | is licensed under a Creative Commons Attribution licence (https://creativecommons.org/licenses/by/3.0/) Listen: https://soundcloud.com/reckonero/reckoner-lofi-hip-hop-chill-beats-for-studygamesleep Track: souKo - souKo - Parallel | is licensed under a Creative Commons Attribution licence (https://creativecommons.org/licenses/by/3.0/) Listen: https://soundcloud.com/soukomusic/parallel