(p)retired

Posts

May 29, 2024

Using Rust to generate Kubernetes CRD

For the first time, I chose Rust to solve a problem. Until this, I’ve been trying to use Rust to learn the language and to rewrite existing code. But, this problem led me to Rust because my other tools wouldn’t cut it.

The question was how to represent oneof fields in Kubernetes Custom Resource Definitions (CRDs).

CRDs use OpenAPI schema and the YAML that results can be challenging to grok.

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: deploymentconfigs.example.com
spec:
  group: example.com
  names:
    categories: []
    kind: DeploymentConfig
    plural: deploymentconfigs
    shortNames: []
    singular: deploymentconfig
  scope: Namespaced
  versions:
  - additionalPrinterColumns: []
    name: v1alpha1
    schema:
      openAPIV3Schema:
        description: An example schema
        properties:
          spec:
            properties:
              deployment_strategy:
                oneOf:
                - required:
                  - rolling_update
                - required:
                  - recreate
                properties:
                  recreate:
                    properties:
                      something:
                        format: uint16
                        minimum: 0.0
                        type: integer
                    required:
                    - something
                    type: object
                  rolling_update:
                    properties:
                      max_surge:
                        format: uint16
                        minimum: 0.0
                        type: integer
                      max_unavailable:
                        format: uint16
                        minimum: 0.0
                        type: integer
                    required:
                    - max_surge
                    - max_unavailable
                    type: object
                type: object
            required:
            - deployment_strategy
            type: object
        required:
        - spec
        title: DeploymentConfig
        type: object
    served: true
    storage: true
    subresources: {}

I’ve developed several Kubernetes Operators using the Operator SDK in Go (which builds upon Kubebuilder).

read more
May 28, 2024

Using Delve to debug Go containers on Kubernetes

An interesting question on Stack overflow prompted me to understand how to use Visual Studio Code and Delve to remotely debug a Golang app running on Kubernetes (MicroK8s).

The OP is using Gin which was also new to me so the question gave me an opportunity to try out several things.

Sources

A simple healthz handler:

package main

import (
	"flag"
	"log/slog"
	"net/http"

	"github.com/gin-gonic/gin"
)

var (
	addr = flag.String("addr", "0.0.0.0:8080", "HTTP server endpoint")
)

func healthz(c *gin.Context) {
	c.String(http.StatusOK, "ok")
}
func main() {
	flag.Parse()

	router := gin.Default()
	router.GET("/fib", handler())
	router.GET("healthz", healthz)

	slog.Info("Server starting")
	slog.Info("Server error",
		"err", router.Run(*addr),
	)
}

Containerfile:

read more
April 30, 2024

Securing gRPC services using Tailscale

This is so useful that it’s worth its own post.

I write many gRPC services. As these generally run securely, it’s best to test them that way too but, even with e.g. Let’s Encrypt, it can be challenging to generate appropriate TLS certs.

Tailscale makes this trivial.

Assuming there’s a gRPC service running on localhost:50051, we want to avoid -plaintext:

PORT="50051"

grpcurl \
-plaintext 0.0.0.0:${PORT} \
list

NOTE I’m using list and assuming your service has reflection enabled but you can, of course, use relevant methods.

read more
April 9, 2024

Google Cloud Translation w/ gRPC 3 ways

General

You’ll need a Google Cloud project with Cloud Translation (translate.googleapis.com) enabled and a Service Account (and key) with suitable permissions in order to run the following.

BILLING="..." # Your Billing ID (gcloud billing accounts list)
PROJECT="..." # Your Project ID
ACCOUNT="tester"

EMAIL="${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com"

ROLES=(
    "roles/cloudtranslate.user"
    "roles/serviceusage.serviceUsageConsumer"
)

# Create Project
gcloud projects create ${PROJECT}

# Associate Project with your Billing Account
gcloud billing accounts link ${PROJECT} \
--billing-account=${BILLING}

# Enable Cloud Translation
gcloud services enable translate.googleapis.com \
--project=${PROJECT}

# Create Service Account
gcloud iam service-accounts create ${ACCOUNT} \
--project=${PROJECT}

# Create Service Account Key
gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json \
--iam-account=${EMAIL} \
--project=${PROJECT}

# Update Project IAM permissions
for ROLE in "${ROLES[@]}"
do
  gcloud projects add-iam-policy-binding ${PROJECT} \
  --member=serviceAccount:${EMAIL} \
  --role=${ROLE}
done

For the code, you’ll need to install protoc and preferably have it in your path.

read more
April 5, 2024

Google Cloud Events protobufs and SDKs

I’ve written before about Ackal’s use of Firestore and subscribing to Firestore document CRUD events:

  • Routing Firestore events to GKE with Eventarc
  • Cloud Firestore Triggers in Golang using Firestore triggers

I find Google’s Eventarc documentation to be confusing and, in typical Google fashion, even though open-sourced, you often need to do some legwork to find relevant sources, viz:

  • Google’s Protobufs for Eventarc (using cloudevents) google-cloudevents1
  • Convenience (since you can generate these using protoc) language-specific types generated from the above e.g. google-cloudevents-go; google-cloudevents-python etc.

1 – IIUC EventArc is the Google service. It carries Google Events that are CloudEvents. These are defined by protocol buffers schemas.

read more
March 25, 2024

Prost! Tonic w/ a dash of JSON

I naively (!) began exploring JSON marshaling of Protobufs in rust. Other protobuf language SDKs include JSON marshaling making the process straightforward. I was to learn that, in rust, it’s not so simple. Unfortunately, for me, this continues to discourage my further use of rust (rust is just hard).

My goal was to marshal an arbitrary protocol buffer message that included a oneof feature. I was unable to JSON marshal the rust generated by tonic for such a message.

read more
March 12, 2024

Fly Kubernetes

Interested to explore Fly Kubernetes after being accepted into the closed beta.

The folks at Fly are innovative in their technology uses and, having been a long-time Kubernetes user, I was intrigued to learn that Fly.io has implemented Kubernetes atop Fly.

My first Deployment failed:

Authentication required to access image "ghcr.io/{image}"

It was confirmed to me that FKS does not support pulling from private registries. The solution is pull-tag-push images to registry.fly.io but, Fly’s repository is app-specific and so, you need to do some querying to grab the Fly app created by FKS (for your namespace):

read more
March 7, 2024

Prometheus Protobufs and Native Histograms

I responded to a question Prometheus metric protocol buffer in gRPC on Stackoverflow and it piqued my curiosity and got me yak shaving.

Prometheus used to support two exposition formats including Protocol Buffers, then dropped Protocol Buffer and has since re-added it (see Protobuf format). The Protobuf format has returned to support the experimental Native Histograms feature.

I’m interested in adding Native Histogram support to Ackal so thought I’d learn more about this metric.

read more
February 16, 2024

MicroK8s operability add-on

Spent time today yak-shaving which resulted in an unplanned migration from MicroK8s ‘prometheus’ add-on to the new and not fully-documented ‘observability’ add-on:

sudo microk8s.enable prometheus
Infer repository core for addon prometheus
DEPRECATION WARNING: 'prometheus' is deprecated and will soon be removed. Please use 'observability' instead.
...

The reason for the name change is unclear.

It’s unclear whether there’s a difference in the primary components that are installed too (I’d thought Grafana wasn’t included in ‘prometheus’), (Grafana) Loki and (Grafana) Tempo definitely weren’t included and I don’t want them either.

read more
January 30, 2024

Navigating Koyeb's API with Rust

I wrote about Navigating Koyeb’s Golang SDK. That client is generated using the OpenAPI Generator project using Koyeb’s Swagger (now OpenAPI) REST API spec.

This post shows how to generate a Rust SDK using the Generator and provides a very basic example of using the SDK.

The Generator will create a Rust library project:

VERS="v7.2.0"

PACKAGE_NAME="koyeb-api-client-rs"
PACKAGE_VERS="1.0.0"

podman run \
--interactive --tty --rm \
--volume=${PWD}:/local \
docker.io/openapitools/openapi-generator-cli:${VERS} \
generate \
-g=rust \
-i=https://developer.koyeb.com/public.swagger.json \
-o=/local/${PACKAGE_NAME} \
--additional-properties=\
packageName=${PACKAGE_NAME},\
packageVersion=${PACKAGE_VERS}

This will create the project in ${PWD}/${PACKAGE_NAME} including the documentation at:

read more
  • ««
  • «
  • 1
  • 2
  • 3
  • 4
  • 5
  • »
  • »»
© (p)retired 2025