Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
August 11, 2022 04:16 am GMT

Write your Kubernetes Infrastructure as Go code - Extend cdk8s with custom Constructs

Build a Wordpress deployment as a cdk8s construct

Constructs are the fundamental building block of cdk8s (Cloud Development Kit for Kubernetes) - an open-source framework (part of CNCF) with which you can define your Kubernetes applications using regular programming languages (instead of yaml). In Getting started with cdk8s, you saw how to use the core cdk8s library.

You can also use the cdk8s-plus library (also covered this a previous blog) to reduce the amount of boilerplate code you need to write. With cdk8s-plus, creating a Kubernetes Deployment, specifying it's container (and other properties) and exposing it via a Service is three function calls away.

For example, to setup and access Nginx, you simply need this:

//...deployment := cdk8splus22.NewDeployment(chart, jsii.String("deployment"), &cdk8splus22.DeploymentProps{Metadata: &cdk8s.ApiObjectMetadata{Name: jsii.String("nginx-deployment-cdk8s-plus")}})deployment.AddContainer(&cdk8splus22.ContainerProps{        Name:  jsii.String("nginx-container"),        Image: jsii.String("nginx"),        Port:  jsii.Number(80)})deployment.ExposeViaService(&cdk8splus22.DeploymentExposeViaServiceOptions{        Name:        jsii.String("nginx-container-service"),        ServiceType: cdk8splus22.ServiceType_LOAD_BALANCER,        Ports:       &[]*cdk8splus22.ServicePort{{Port: jsii.Number(9090), TargetPort: jsii.Number(80)}}})//...

But things can get even better!

Instead of writing the same logic over and over, you can package it in the form of a reusable component that can be invoked just like other built-in cdk8s functions (e.g. NewDeployment, NewService etc.). Although it might not sound as useful for the simple application(s), this approach is invaluable for a large project, team or organisation who want to scale their engineering efforts. In fact, there is already a pool of ready-to-use components available at constructs.dev. These include constructs contributed by the community, AWS and others as well, across multiple programming languages.

To better understand how this might look in practice

... let's look at the code. I will continue to use Wordpress as an example, like I did in the previous blog post. Here is a code snippet that shows how everything is wired together (with implementation walk-through in the next section):

You can refer to the complete code on Github

//...func NewMyChart(scope constructs.Construct, id string, props *MyChartProps) cdk8s.Chart {    //....    NewWordpressStack(chart, jsii.String("wordpress-stack"), &WordpressProps{//....)    return chart}func main() {    app := cdk8s.NewApp(nil)    NewMyChart(app, "wordpress-custom-stack", nil)    app.Synth()}
  • NewWordpressStack gives us a construct that represents an entire Wordpress installation (single line of code!)
  • We simply configure it as per our requirements (with WordpressProps)
  • Include this as part of a cdk8s.Chart which is then included in the cdk8s.App (as with any other cdk8s application)

There is lot of flexibility in terms of how you want to build a custom construct, depending on your requirements. But, at its very core, the basic concept is to define a way to create a new construct.Construct. You would want to provide a way to add metadata to further configure/refine your Construct - typically, thats done through properties (cdk8s.ChartProps).

First we define WordpressProps - this encapsulates/externalises the attributes of the Wordpress installation. Since this is just an example, I have provided limited attributes such as MySQL/Wordpress Docker images, MySQL password, and required storage.

type WordpressProps struct {    MySQLImage    *string    MySQLPassword *string    MySQLStorage  *float64    WordpressImage   *string    WordpressStorage *float64}

Then we have a function that will allow other charts/constructs to instantiate Wordpress. This is where the entire implementation resides.

func NewWordpressStack(scope constructs.Construct, id *string, props *WordpressProps) constructs.Construct {    ...}

The props *WordpressProps parameter allows other constructs to influence the Wordpress stack creation e.g. you can define how much storage you need, maybe use a different Docker image for Wordpress/MySQL. The actual code for this function is similar to the one you saw here (with required adjustments), so there is no point repeating it here. I will simply highlight the important bits - specifically the ones that use the props to configure the required components.

This sample construct used cdk8splus22 library. The reason for this naming convention is because each cdk8s-plus library is separately vended to target a specific Kubernetes version - the 22 at the end signifies that this dependency will work with Kubernetes 1.22. You can use the library corresponding to your Kubernetes version and refer to the FAQs for more info.

We use the MySQL password from props and use that to create the Secret.

    //...    password := props.MySQLPassword    mysqlSecret := cdk8splus22.NewSecret(wordpressConstruct, jsii.String("mysql-secret"),        &cdk8splus22.SecretProps{            Metadata: &cdk8s.ApiObjectMetadata{Name: jsii.String(secretName)}})     secretKey := "password"    mysqlSecret.AddStringData(jsii.String(secretKey), password)    //...

The container images for MySQL and Wordpress are referenced via their respective Deployments:

//...    containerImage := props.MySQLImage    mysqlContainer := dep.AddContainer(&cdk8splus22.ContainerProps{        Name:  jsii.String("mysql-container"),        Image: containerImage,        Port:  jsii.Number(3306),    })//...    wordpressContainer := wordPressDeployment.AddContainer(&cdk8splus22.ContainerProps{        Name:  jsii.String("wordpress-container"),        Image: props.WordpressImage,        Port:  jsii.Number(80),    })

We also use the passed in storage as well - this is used to configure the PersistentVolumeClaim request.

...    mysqlPVC := cdk8splus22.NewPersistentVolumeClaim(wordpressConstruct, jsii.String("mysql-pvc"), &cdk8splus22.PersistentVolumeClaimProps{        AccessModes: &[]cdk8splus22.PersistentVolumeAccessMode{cdk8splus22.PersistentVolumeAccessMode_READ_WRITE_ONCE},        Storage:     cdk8s.Size_Gibibytes(props.MySQLStorage)})...    wordpressPVC := cdk8splus22.NewPersistentVolumeClaim(wordpressConstruct, jsii.String("wordpress-pvc"), &cdk8splus22.PersistentVolumeClaimProps{        AccessModes: &[]cdk8splus22.PersistentVolumeAccessMode{cdk8splus22.PersistentVolumeAccessMode_READ_WRITE_ONCE},        Storage:     cdk8s.Size_Gibibytes(props.WordpressStorage)})

Finally, we call NewWordpressStack from another cdk8s.Chart and pass in the attributes we want to configure.

func NewMyChart(scope constructs.Construct, id string, props *MyChartProps) cdk8s.Chart {    var cprops cdk8s.ChartProps    if props != nil {        cprops = props.ChartProps    }    chart := cdk8s.NewChart(scope, jsii.String(id), &cprops)    NewWordpressStack(chart, jsii.String("wordpress-stack"), &WordpressProps{        MySQLImage:       jsii.String("mysql"),        MySQLPassword:    jsii.String("Password123"),        MySQLStorage:     jsii.Number(3),        WordpressImage:   jsii.String("wordpress:4.8-apache"),        WordpressStorage: jsii.Number(2)})    return chart}

Use this to install Wordpress

To test it locally...

... you can use minikube, kind, etc.

# make sure cluster is runningminikube startgit clone https://github.com/abhirockzz/cdk8s-for-go-developerscd part4-custom-construct

Create manifest and inspect all the resources (see dist directory):

cdk8s synth

To deploy them:

kubectl apply -f dist/# output (might differ in your case)secret/mysql-pass createddeployment.apps/mysql-mysql-deployment-cdk8splus-c83762d9 createdpersistentvolumeclaim/mysql-mysql-pvc-c8799bba createdservice/mysql-service createddeployment.apps/wordpress-wordpress-deployment-cdk8splus-c8252da7 createdservice/wordpress-service createdpersistentvolumeclaim/wordpress-wordpress-pvc-c8334a29 created

Check the Kubernetes Service (called wordpress-service) which exposes the wordpress Deployment.

kubectl get svc wordpress-service

If you're using minikube, in a different terminal run (if not already running):

minikube tunnel

Use your browser to navigate to http://localhost:80. You should see the familiar Wordpress installation screen.

Image description

Go ahead, finish the installation and log into your Wordpress instance. Feel free to experiment with it.

Conclusion

cdk8s is a powerful tool itself but it also provides you the ability to extend and build other abstraction on top of it. You saw how to write a custom construct in Go and used it deploy Wordpress on Kubernetes. This can be further used as a foundation for other re-usable components.

Happy coding!


Original Link: https://dev.to/abhirockzz/write-your-kubernetes-infrastructure-as-go-code-extend-cdk8s-with-custom-constructs-5eb4

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To