Getting started
Prerequisites
This tutorial assumes you have already installed K8S Bundle. The entire Dealroadshow K8S Framework docummentation also assumes that you are already familiar with basic Kubernetes concepts and have at least some experience with the Kubernetes itself. If not - please learn Kubernetes before using this framework.
Create an App
App is a basic concept in K8S Framework, similar to chart in Helm or, well, app in cdk8s. Put simply - app is a collection of manifests. Basically you will create app to define manifests for one of your services in SOA architecture - in order to distinguish this manifests from other service's manifests. If you have a "good old" monolith, your manifests may be split into apps using some other criteria, such as domain contexts in DDD ideology.
To create an app - simply open terminal and generate app class using Symfony command, shipped with K8S Bundle:
bin/console k8s:generate:app hello
K8S/Hello
in your sources dir (by default src
in Symfony projects), app class HelloApp
and basic dirs that you might want to have in an app:
Tip
To understand app's directory structure better, please read dedicated article for apps.
If you open HelloApp.php
file in IDE of your choice - you will see pretty basic class:
class HelloApp extends AbstractApp
{
public static function name(): string
{
return 'hello';
}
public function manifestConfig(string $shortName): array
{
return [];
}
}
Method HappyApp::name()
is self-explanatory, and other methods are explained in dedicated article.
Define your first Deployment
Now that we have HelloApp
, let's define our first Deployment. Defining deployment using K8S Framework is as simple as defining it's corresponding PHP class for it. We could create deployment class by ourselves, but it would be simpler to generate it using console command:
bin/console k8s:generate:manifest world
world
in command above is simply a short name for manifest. Command will ask you about type of your new manifest and an app, where to generate your new manifest:
Let's look at our new deployment class in src/K8S/Hello/Manifest/WorldDeployment.php
:
class WorldDeployment extends AbstractContainerDeployment
{
public function image(): Image
{
return Image::fromName('my-cool/image');
}
public function selector(SelectorConfigurator $selector): void
{
$selector
->addLabel('app', $this->app->alias())
->addLabel('name', static::shortName())
;
}
public static function shortName(): string
{
return 'world';
}
}
This class is pretty basic too, but it's already a valid Kubernetes deployment!
Dump manifests
Let's dump your first manifest to standard Kubernetes YAML and look at it:
bin/console k8s:dump:all
After running this command we can see our new deployment dumped to file src/Resources/k8s-manifests/hello/world.deployment.yaml
:
Let's look at this file:
hello/world.deployment.yaml | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Few things to note here.
First, look how deployment name is formed in line 7: as you may already guessed, name hello-world
is a concatenation of app name, returned from HelloApp::name()
method, and manifest short name, returned from WorldDeployment::shortName()
. Good news is you will not have to work with full manifest names in your code, but more on
that later.
Second, look at lines 17-18. This annotations guarantee that your pods will be recreated whenever any ConfigMaps or Secrets, used in your deployment, changed. You are welcome!
Modifying deployment
For now we have defined our first deployment. It uses a dummy image name my-cool/image
. Let's replace it for a real image name. For demonstration purposes let it be nginx
:
// ...
public function image(): Image
{
return Image::fromName('nginx');
}
Nginx is an open source web-server, so now that we use it, we know that we should expose some ports to the outside world. In Kubernetes manifests it is done by ports
section. Dealroadshow K8S Framework follows simple rule: all method names in manifest classes are the same as names in corresponding sections in Kubernetes manifest. It means we should just try to define a method ports()
in our deployment. In order to better understand all conventions and best practices for K8S framework, please read Understanding manifests
If you are using a good IDE, for example PhpStorm, just write down first letters por
and IDE will create this method for you:
//...
public function ports(PortsConfigurator $ports): void
{
}
Signature of argument $ports
is pretty straightforward and simply following your IDE hints you could lead you to the something like this:
//...
public function ports(PortsConfigurator $ports): void
{
$ports
->add(80)
->setName('http');
$ports
->add(443)
->setName('https');
}
Define a service
Now we need to define a Kubernetes service in order to expose our deployment. As you may have already guessed - we will generate PHP class for service:
bin/console k8s:generate:manifest world
After chosing service
as a kind of manifest you will get pretty basic service class WorldService
.You can intuitively (and with help of IDE) define service ports in ports()
method, but we should also add a selector()
method in order for service to point properly to our pods. After this simple modifications our service class should look like follows:
class WorldService extends AbstractService
{
public function ports(ServicePortsConfigurator $ports): void
{
$ports
->add(80, 80)
->setName('http');
$ports
->add(443, 443)
->setName('https');
}
public function selector(StringMap $selector): void
{
$selector
->add('app', $this->app->alias())
->add('name', static::shortName())
;
}
public static function shortName(): string
{
return WorldDeployment::shortName();
}
}
Good to know
Please note how we defined short name for a service by reusing short name of deployment.It is a good practice to use deployment name in service, and service name in ingress - in further articles we will learn techniques of how to automatically define selectors and ports for our services based on it's names.
If you dump your manifests now by console command k8s:dump:all
, you'll get your deployment and a service pointing to deployment's pods. In other articles we dive deeper into defining manifests and internals of K8S Framework.