►
From YouTube: Building Stateful Workloads in Kubernetes
Description
Kubernetes Community Days Bengaluru'21
It's day 2. Kubernetes is running. You have your deployments and services set. Now how do you migrate the data store? Let's journey together on this code-focused tour through ConfigMaps, Secrets, Persistent Volumes, Persistent Volume Claims, and StatefulSets. We'll craft and launch a strategy to care for your users' data in this new container world. You can power your business on Kubernetes: stateless or stateful.
A
A
I've
been
that
person
chasing
the
speaker
and
it
didn't
work
out
for
me
as
well
either.
So
you
can
head
to
robrich.org
right
now
and
click
on
presentations
here
at
the
top
and
here's
building,
stateful
workloads
and
kubernetes.
The
slides
are
online
right
now,
while
you're
here
on
robrich.org.
Let's
click
on
about
me
and
we'll
take
a
look
at
this
page
and
see
some
of
the
things
that
I've
done
recently.
A
I'm
a
microsoft
mvp,
a
friend
of
redgate,
a
cyril
developer
advocate,
and
let
me
tell
you
about
az,
give
cam
a
z
gift
camp
brings
volunteer
developers
together
with
charities
to
build
free
software.
We
start
building
friday
after
work
sunday
afternoon.
We
deliver
the
completed
software
to
the
charity.
Sleep
is
optional.
Caffeine
provided,
if
you're
in
phoenix,
come
join
us
for
the
next
a-z
give
camp
or,
if
you'd,
like
a
gift
camp
in
your
neighborhood,
hit
me
up
on
email
and
or
twitter
and
let's
get
a
gift
camp
in
your
neighborhood
too.
A
A
Let's
first
talk
about
stateless
kubernetes,
that's
the
easy
part,
so
we
have
a
user.
It
goes
into
an
ingress
that
ingress
resolves,
dns
and
forwards
off
to
the
service
that
acts
as
a
load
balancer
in
front
of
all
of
our
pods
that
have
the
containers
yeah.
We
got
this.
This
is
easy.
This
is
what
we
do
all
the
time
we
have
stateless
web
services
and
running
them
inside
of
kubernetes
is
easy,
but
our
application
probably
doesn't
look
like
that.
It
looks
like
this.
A
We've
got
a
user,
we've
got
an
ingress,
we've
got
a
service,
we've
got
the
pods
with
the
containers
in
them,
but
we
also
have
well
stateful
pieces.
We
have
an
ssl
certificate
that
we
need
to
terminate.
We
have
a
database
cluster.
We
have
some
secrets
and
configuration
that
helps
us
discover
that
cluster
and
file
storage.
A
So
how
do
we
add
this
state
to
our
application?
That's
what
we'll
do
today.
So,
first,
let's
talk
about
state.
What
is
state,
not
these
states?
What
is
state
this
state
is
the
things
that
live
beyond
the
current
lifetime.
If
the
current
lifetime
is
the
request,
then
it's
things
that
live
beyond
the
request.
If
the
current
state
is
the
function
call,
then
it's
maybe
class
variables.
If
the
current
state
is
the
machine,
then
maybe
it's
keeping
things
beyond
machine
restart.
A
A
A
Ctl
get
all
is
great
for
being
able
to
get
all
of
these
stateless
resources,
but
it
very
specifically
does
not
affect
stateful
resources,
as
you
grab
these
slides
from
roberts.org
click
into
each
of
these
blue
links,
and
you
can
learn
more
about
issues
that
people
have
filed.
Saying
hey
this
stateful
resource
isn't
available
when
I
say
cube
ctlc
at
all.
A
To
that
end,
this
last
one
is
their
recommendation
of
deprecating
cube
ctl
get
all
because
it
isn't
stateful.
Now,
they've
done
this
on
purpose.
Cubectl
getall
very
specifically
returns
the
things
that
can
be
easily
recreated.
They
specifically
don't
return
secrets
or
config
maps
or
other
data
that
might
get
destroyed.
If
you
stop
and
restart
it.
A
Okay,
that's
the
design
decision
that
they
made,
but
we're
looking
for
stateful
resources.
How
do
we
find
them?
Well,
here's
a
great
github
issue
that
a
github
comment
to
this
that
creates
a
mechanism
for
getting
all
of
the
things
now
in
this
script,
we're
going
to
say,
cubectl,
api
resources
that
api
resources
will
return
the
list
of
all
of
the
resources
in
your
cluster,
including
crds.
A
A
Well,
you
probably
want
to
create
an
alias
for
this
or
maybe
a
command.
Now
the
cool
thing
is:
if
you
create
a
file
called
cube,
ctl
dash,
get
underscore
all
and
put
this
script
in
it.
Then
you
can
do
a
cube.
Ctl
get
all
and
you'll
be
able
to
get
all
of
the
things
so
cube.
Ctl
get
all
does
not
actually
get
all
of
the
things,
and
so
you'll
need
to
specify
the
specific
type
of
thing
that
you
want.
A
Okay,
let's
look
at
each
of
the
stateful
things
that
we
want
to
look
at
first,
let's
look
at
volumes.
Volumes
is
file
storage.
If
we
save
things
into
our
container,
when
the
container
restarts
that
file
is
gone
because
well,
the
container
file
system
is
gone.
So
how
do
we
store
files
beyond
a
container
restart?
A
That's
where
we
use
volumes
now
a
volume
is
a
sim
link.
I
may
have
my
content
off
in
ntfs
drive
or
maybe
in
a
cloud
blob
store,
and
I
just
want
to
sim
link
that
into
a
particular
folder
inside
my
container.
Now.
The
beautiful
thing
here
is
that
the
application
doesn't
know
that
this
is
assembling
off
to
a
more
durable
storage
location.
It's
just
a
local
file.
The
downside
is,
it
is
actually
now
remote
file
access,
so
file
locks,
don't
work.
A
The
local
operating
system
believes
that
it
locked
the
file,
but
it
only
locked
it
local
to
that
container.
So
any
other
containers
reading
this
file
system
may
tend
to
clobber
the
thing
use
different
paths,
maybe
a
path
that
includes
the
hostname
or
the
function
of
this
application
or
the
user
id
something
to
make
it
unique
so
that
we
don't
end
up
clobbering
the
same
paths.
A
Here's
an
example:
yaml
file
that
creates
file
storage,
now
notice
here
in
the
pod
definition.
Now
this
pod
definition
may
be
part
of
a
deployment
or
other
mechanism
here
in
this
pod
definition.
I
have
my
list
of
containers
and
in
this
case
I
have
an
nginx
alpine
container
and
now
I
may
have
other
resources
like
resource
limits
or
other
parameters,
and
here
I
have
a
volume
mount
section
here
in
the
volume
mount
section.
I
have
the
path
in
the
container
to
that
directory.
A
A
A
I
probably
want
to
swap
this
out
with
a
cloud
storage
or
a
network
share,
but
for
the
sake
of
testing,
when
I'm
using
docker
desktop
host
path
is
perfect.
That's
why
I've
included
it
here
as
you're
testing.
Hostpath
is
a
great
way
to
not
have
to
configure
a
whole
bunch
of
other
stuff
in
production
use
something
more
durable.
A
So
we
have
this
file,
that's
yml
file.
That
includes
the
details
of
how
to
spin
up
this
volume,
but
now
we're
stuck
in
a
quandary
who
owns
this.
Does
the
developer
own?
This
does
operations
own
this
now
the
developer
owns
the
rest
of
this
yaml
file,
so
it
might
make
sense
that
the
developer
could
own
this
part,
but
operations
really
wants
to
control
where
the
files
are
stored,
to
ensure
that
it's
backed
up
correctly
to
ensure
that
there's
proper
authentication
to
this
folder
so
who
owns
this
file?
A
A
Now,
let's
grab
one
of
these
persistent
volume
pieces,
we
will
claim
it
and
we
will
use
that
persistent
volume
claim
in
our
container
storage,
persistent
volume,
persistent
volume
claim
container
now.
The
beautiful
thing
here
is
that
ops
can
own
the
storage
in
the
persistent
volume
development
can
own
the
persistent
volume
claim
in
the
container.
A
These
are
four
separate,
yaml
files.
Now
that's
perfect.
We
have
an
elegant
separation
of
dev
and
ops.
Now,
if
we
don't
need
that
separation,
maybe
we're
in
a
really
small
business,
where
all
things
are
the
same,
then
we
can
use
the
simpler
approach,
but
when
we
need
that
separation
of
concerns
built
into
kubernetes
is
this
mechanism
to
do
exactly
that?
A
Here's
a
yaml
file
for
that
persistent
volume.
Now
here
in
the
persistent
volume
we
still
have
that
host
path,
specifying
the
folder
on
the
physical
storage
medium.
Then
we
specify
other
characteristics
about
this.
In
this
case,
my
access
mode
is
read,
write
once
I
could
also
do
read,
write
many
many
containers
can
access
it
at
the
same
time
and
read
only
where
they
can
read
it,
but
they
can't
write.
I'm
also
specifying
a
storage
capacity,
in
this
case
10
gigs
and
a
storage
class
name.
A
A
Now,
I'm
going
to
specify
the
characteristics
of
the
volume
that
I
want
to
claim:
storage
class
manual
access
mode
read:
write
once
and
resources
storage,
three
gigs
now
I'll
be
able
to
claim
that
persistent
volume
that
we
created
previously,
because
I
have
a
match
on
the
storage
class
name,
a
match
on
the
access
mode,
and
this
the
volume
is
at
least
this
big,
that's
perfect.
So
I've
got
this
persistent
volume
claim
notice.
I
don't
need
to
match
it
by
name.
A
I
just
need
to
match
it
by
characteristic,
and
now
I
have
a
name
of
pv
claim
when
we
create
that
pod
definition,
our
container's
definition
is
identical.
We
still
identify
this
as
the
volume
and
the
path
in
the
container
to
the
directory
is
the
same.
But
now,
in
the
volume
section
instead
of
listing
the
hostpath
driver,
I
list
the
persistent
volume
claim
and
I'll
identify
that
claim
name
now.
The
pod
will
own
this
persistent
volume
claim
and
this
persistent
volume
claim
will
claim
this
volume.
A
So,
ultimately,
now
we
get
that
really
elegant
separation
concerns
where
operations
can
own
the
storage
and
the
persistent
volumes
ensuring
it's
backed
up
carefully,
ensuring
that
access
modifiers
are
as
expected
as
a
developer.
I
can
claim
one
of
those
persistent
volumes
and
attach
it
into
my
container
in
a
really
elegant
way:
file
storage.
A
A
So
here's
an
example
configuration
yaml
file.
I
have
my
pod
definition.
Maybe
this
is
part
of
a
deployment
or
maybe
it's
a
separate
pod
definition
in
my
containers
list.
I
specify
my
things.
Maybe
I'm
specifying
other
details
like
a
volume
and
now
I
have
an
end
section
for
the
environment
variables
I'll
give
it
a
name
and
a
value
name
and
a
value.
A
A
A
A
We
have
a
key
of
secure
database
and
we're
using
cyril
to
do
so.
Our
logging
is
enabled
and
here's
our
api
url.
We
have
a
config
map
now
in
our
pod
definition.
Maybe
in
the
case
of
a
deployment
or
a
separate
pod,
we
can
specify
a
bunch
of
other
details
and
then
we
will
specify
end
from
this
config
map
reference.
I'm
naming
my
config
map,
and
so
all
of
the
keys
from
that
config
map
are
now
exposed
as
environment
variables
inside
my
container.
A
I
can
also
mount
it
as
files
now,
in
this
case
I
have
a
volume
mount
section
and
I
have
a
folder
inside
my
container
and
I
have
a
volume
section
instead
of
using
host
path
or
another
driver
here,
I'm
specifying
the
config
map,
I'm
naming
that
config
map.
So
inside
this
directory,
I
will
have
those
three
files,
one
for
the
secure
database,
one
for
logging
and
one
for
the
environment,
the
api
url.
A
I
can
open
each
of
those
three
files
and
I
can
get
at
the
contents
in
that
up
in
those
files
to
be
able
to
read
those
variables.
Now,
that's
perfect!
I
have
that
great
separation
of
concerns.
If
I
need
it,
if
I
don't
need
it,
I
can
use
the
simpler
approach.
Now.
Some
of
these
configuration
details
might
be
secret.
So,
let's
see,
how
will
you
store
secrets
now?
Secrets
are
built
into
kubernetes
and
they
have
been
for
quite
some
time,
but
they
were
always
stored
as
base64
encoded.
A
A
Now
these
are
encrypted
at
rest
as
base64
encoded,
and
they
are
copied
to
every
node
on
the
off
chance
that
I
start
a
container
on
that
node
and
need
to
read
these
secrets.
So
if
you
lose
any
nodes
in
your
cluster,
you
can
probably
assume
that
you've
lost
the
secrets
and
you
should
go
roll
those
keys.
A
So
here's
how
we
can
create
a
secret.
Now
we
have
this
yaml
file,
defining
the
secret,
here's,
the
name,
the
keys
and
the
values
for
each
of
the
keys
and
values
that
I
want
in
this
secret
now
here
I'm
specifying
them
as
string
data.
If
I
chose
to
specify
it
as
data,
then
it
would
need
to
be
base64
encoded,
which
is
a
great
way
to
include
other
content
like
json
objects.
A
Now
the
cool
part
is
I've,
got
a
yaml
file.
The
downside
is
it's
really
easy
to
check
this
in
the
source
control?
Let's
not.
Instead,
let's
create
this
secret
on
the
command
line,
where
we
know
that
this
content
won't
get
checked
into
source
control,
so
we'll
create
this
secret.
Here's,
the
secret
name,
db
connection
and
then
the
keys
and
values
for
all
of
the
keys
and
values
that
I
want
in
this
secret.
A
A
A
I
could
also
do
it
as
environment
variables.
Last
time
we
just
specified
that
all
of
the
environment
should
come
from
a
particular
config
map,
in
this
case
we'll
enumerate
them.
Here's
the
name
of
the
environment,
variable
that
I
want
to
create
and
I'm
going
to
get
that
value
from
the
secret:
here's,
the
secret
name
and
the
secret
key.
A
We
were
able
to
do
configuration
and
volumes,
which
is
great
now,
if
I
have
configuration
or
secrets,
or
I
need
to
store
data
more
durably
in
files,
I
can
do
so
with
kubernetes
native
details,
but
what
if
I
need
lots
of
pods
running
together?
Maybe
I
have
a
cluster.
Maybe
this
is
a
database
cluster.
A
A
Here's
a
stateful
set
and
it's
pretty
much
a
deployment.
We
can
see
that
we
have
a
template
that
has
all
of
the
container
details
and
those
are,
as
we
would
expect.
The
only
difference
from
a
deployment
is
that
it
is
a
stateful
set
and
that
we're
specifying
this
headless
service
name
now
that
headless
service.
Then
here
is
pretty
much
a
regular
service.
A
A
A
Now
I
may
choose
in
my
headless
service,
to
accept
inbound
traffic
to
load
balance
across
all
these
machines,
but
maybe
in
my
stateful
set,
I
want
only
a
subset
of
those
machines
or
a
subset
of
those
ports
available.
So
I'll,
probably
not
reuse,
this
headless
service
for
inbound
traffic,
but
rather
create
a
second
service
that
accepts
traffic.
Only
for
those
particular
details
that
I
need.
A
A
We
had
the
ingress
and
the
service
and
the
pods
with
containers
inside
them.
That
was
our
stateless
environment
and
yeah.
That
was
easy.
We
have
a
domain
name.
Perhaps
that's
a
config
map
in
our
ingress
that
identifies
this
domain
name,
so
it
can
be
environment
specific
we
have
our
https
certificate.
Perhaps
this
is
a
secret.
Now,
the
beauty
of
it
being
a
secret
is
that
well
it's
secret.
A
We
have
our
containers
that
have
configuration
details
to
be
able
to
discover
the
database
cluster.
Perhaps
these
are
environment,
variables
or
files
stored
in
config
maps
or
maybe
secrets
our
database
cluster.
Now
we
need
multiple
machines
to
be
able
to
pull
this
off
so
we'll
use
a
stateful
set
so
that
each
of
these
pods
can
be
able
to
discover
the
other
pods
to
be
able
to
replicate
data
between
them.
A
A
These
are
all
tools
that
are
built
into
kubernetes
to
help
us
get
to
that
next
level
of
being
able
to
use
stateful
resources
inside
of
kubernetes.
Now
all
of
these
things
are
built
in
what's
great
is
we
can
replace
some
of
them
with
advanced
details?
Maybe
we
need
a
specific
driver
to
get
to
our
sin,
or
maybe
we
need
very
specific
encryption
details.