[{"Value":"","Discard":false,"Expires":9999999999}] Uncategorized archivos - CloudArch https://cloudarch.es/category/uncategorized/ Blog sobre arquitectura en la nube Thu, 07 Aug 2025 13:11:17 +0000 en-US hourly 1 https://wordpress.org/?v=7.1.3 https://cloudarch.es/wp-content/uploads/2024/02/cropped-CloudArch-1-32x32.png Uncategorized archivos - CloudArch https://cloudarch.es/category/uncategorized/ 32 32 228797714 🔍 Observability: The Superpower Behind Healthy Servers 🚀 https://cloudarch.es/observability-the-superpower-behind-healthy-servers/ https://cloudarch.es/observability-the-superpower-behind-healthy-servers/#respond Thu, 07 Aug 2025 13:11:16 +0000 https://cloudarch.es/?p=698 Today we’re diving into a topic that can make or break your infrastructure—and your peace of mind: Monitoring, Observability, and […]

La entrada <h1>🔍 Observability: The Superpower Behind Healthy Servers 🚀</h1> se publicó primero en CloudArch.

]]>
Today we’re diving into a topic that can make or break your infrastructure—and your peace of mind: Monitoring, Observability, and Alerting.

You might think it’s “just for DevOps”, but in reality, these practices protect your users, your revenue, and yes… even your weekend sleep 😴


🌈 What Is Observability (and Why Should You Care)?

Let’s break it down:

  • Monitoring tells you something is wrong.
  • Observability helps you understand why it’s wrong.
  • Alerting tells you as soon as it goes wrong.

💡 Imagine your servers are a spaceship.
Monitoring is your dashboard—gauges, lights, speed indicators.
Observability is the system logs, black box, and mission control data that explain why the ship shakes when you press a button.
And alerting is the alarm that yells: “⚠ Engine overheating!”

Without these, you’re flying blind. With them, you’re in control. 🎮


🧠 The 3 Pillars of Observability

Observability is powered by:

  1. Metrics 📊 — Numbers that reflect system performance (CPU, RAM, latency, etc.)
  2. Logs 📄 — Time-stamped records of system events.
  3. Traces 🔗 — Data that follows the path of requests across services (crucial in microservices).

Together, they give you deep visibility into how your system behaves—not just in a single spot, but across your entire stack.


⚡ Why It Matters

Let’s get real.

Without observability:

  • You know something broke, but not what, where, or why.
  • You spend hours digging through logs manually.
  • Customers get frustrated before you even realize there’s a problem.

With observability:

  • ✅ You detect issues earlier
  • ✅ You fix them faster
  • ✅ You prevent them from happening again
  • ✅ You reduce stress for your team and downtime for your users

📈 Real Business Impact (with Data!)

💰 Return on Investment

A 2023 Observability Forecast by New Relic showed that:

  • 41% of organizations gained $1M+ in value per year from observability
  • Teams with mature observability were 2x more likely to resolve issues in under 30 minutes
  • Companies achieved up to 2x ROI on their observability investments

“We were able to go from 12 hours of downtime a month to almost zero.”
— DevOps Manager, financial sector

📉 Outage Cost Reduction

💥 Without observability:
Average outage cost = $9.83M/year
💚 With full-stack observability:
Reduced to $6.17M/year

That’s a savings of $3.66M annually… just by having the right insights! 💸

⚙ Faster Recovery = Happier Users

  • 🎯 William Hill improved MTTR by 80%
  • 📺 Seven Network maintained 100% uptime during peak streaming
  • 💼 BlackLine cut cloud spend by $16M/year

🧑‍💻 Developer Experience

  • DAZN scaled to 5,000 daily deployments
  • Burnout dropped significantly—70% fewer incidents outside working hours

“We spend $80K/month on observability to protect $15M/year in revenue. One missed SLA costs us $250K.”
— Reddit /r/devops user


🔔 The Role of Smart Alerts

Monitoring is great, but alerting is what protects you from waking up to angry clients (or worse, a dead business). 🚨

But not all alerts are created equal.

🛑 Bad alerting = noisy Slack channels and alert fatigue
✅ Good alerting = smart, context-aware signals that only fire when something really needs attention

Combine alerts with automation (like restarting services or scaling infrastructure) and you’re moving toward self-healing systems 🤖


📚 A Real Example

Imagine your WordPress site is sluggish on mobile. 🐌
Monitoring says all systems are “green”.
But using traces, you discover that a mobile-specific JS file fails to load, causing timeouts.

Without observability? You’d be in the dark.
With it? You fix it in 5 minutes—before users even notice.


🧭 In Conclusion: Why Observability Is Essential

It’s not just about logs and dashboards.
It’s about trust, speed, resilience, and business success.

  • ✅ Catch problems early
  • ✅ Troubleshoot faster
  • ✅ Optimize cost and performance
  • ✅ Keep your team and customers happy
  • ✅ Innovate without fear

Observability is your infrastructure’s early warning system, diagnosis tool, and performance coach—all in one. 🛠💡


🧪 Want to See It in Action?

Check out our live Grafana Demo Dashboard where we simulate a WordPress-based Linux server running real-time fake data. Perfect for learning, showing clients, or testing dashboards. 🎛🔥


💬 Final Words

In the world of cloud-native infrastructure, ignorance is never bliss.

Investing in monitoring, observability, and alerting isn’t a nice-to-have…
…it’s the foundation of a stable, scalable, and successful system. 🚦

Until next time—stay observable, stay reliable, and may your error budgets be low! 😉

La entrada <h1>🔍 Observability: The Superpower Behind Healthy Servers 🚀</h1> se publicó primero en CloudArch.

]]>
https://cloudarch.es/observability-the-superpower-behind-healthy-servers/feed/ 0 698
How to mount Secrets in our Deployments https://cloudarch.es/how-to-mount-secrets-in-our-deployments/ https://cloudarch.es/how-to-mount-secrets-in-our-deployments/#respond Mon, 24 Jun 2024 09:46:48 +0000 https://cloudarch.es/?p=547 Frequently we would need to use passwords and sensitive data in our pods for them to work, like for example […]

La entrada How to mount Secrets in our Deployments se publicó primero en CloudArch.

]]>
Frequently we would need to use passwords and sensitive data in our pods for them to work, like for example passwords to the databases or keys for our APIs. However, what is the best way to implement those? Adding the values is never a good idea, since it will allow other people to see that sensitive data that maybe they shouldn’t see.

For this reason, Kubernetes introduces Secrets which are defined as the following:

A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. Such information might otherwise be put in a Pod specification or in a container image. Using a Secret means that you don’t need to include confidential data in your application code.

Because Secrets can be created independently of the Pods that use them, there is less risk of the Secret (and its data) being exposed during the workflow of creating, viewing, and editing Pods. Kubernetes, and applications that run in your cluster, can also take additional precautions with Secrets, such as avoiding writing sensitive data to nonvolatile storage.

Secrets are similar to ConfigMaps but are specifically intended to hold confidential data.

https://kubernetes.io/docs/concepts/configuration/secret/

Now, in order to learn how to create them and mount them, let’s image the next case scenario:

Currently, the webapp-deployment is running with sensitive database environment variables directly embedded in the deployment YAML. To enhance security and protect the sensitive data, perform the following steps:

  • Create a Kubernetes Secret named db-secret with the below sensitive database environment variable values:
    • Key: DB_Host , Value: mysql-host
    • Key: DB_User , Value: root
    • Key: DB_Password , Value: dbpassword
  • Update the webapp-deployment to load the sensitive database environment variables from the newly created db-secret Secret.

Creating the Secret with it’s values

First of all, let’s start by creating the Secret. A secret is basically an object with a name that contains one or multiple keys with values. So we can have for this example a secret for the database data with three keys for the needed details with its values. We can create it using the kubectl create secret command. This allows to create secrets from string passed as arguments or even passed as files.

controlplane $ kubectl create secret generic db-secret / 
--from-literal=DB_Host=mysql-host / 
--from-literal=DB_User=root / 
--from-literal=DB_Password=dbpassword
secret/db-secret created

Once we have created it we can check the content.

controlplane $ k get secret
NAME        TYPE     DATA   AGE
db-secret   Opaque   3      10s
controlplane $ k describe secret db-secret
Name:         db-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
DB_Host:      10 bytes
DB_Password:  10 bytes
DB_User:      4 bytes

We can see now the secret, but it doesn’t display the content. As it’s stored in base64 we would need to retrieve first the values and then decode to make sure everything is right.

controlplane $ kubectl get secret db-secret -o jsonpath='{.data}'
{"DB_Host":"bXlzcWwtaG9zdA==","DB_Password":"ZGJwYXNzd29yZA==","DB_User":"cm9vdA=="}

controlplane $ echo 'ZGJwYXNzd29yZA==' | base64 --decode
dbpassword

After decoding it, we can see that the value for DB_Password matches with what we specified.

Now we can see it because we have permissions to get Secrets, but other entities using Service Accounts which doesn’t have permissions to get the Secrets won’t be able to see the content.

How to mount Secrets in our Deployments

As mentioned in the case scenario, we have already a working deployment but this one has the data hardcoded in the yaml file. For security reasons, it’s much a better choice to mount and use the Secret we just created instead of writing the values there since someone who hasn’t have permissions to see Secrets will be able to see our sensitive data.

controlplane $ k get deploy
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
webapp-deployment   1/1     1            1           14m
controlplane $ k describe deploy
Name:                   webapp-deployment
Namespace:              default
CreationTimestamp:      Mon, 24 Jun 2024 09:03:46 +0000
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=webapp
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=webapp
  Containers:
   webapp-container:
    Image:      nginx:latest
    Port:       80/TCP
    Host Port:  0/TCP
    Environment:
      DB_Host:      mysql-host
      DB_User:      root
      DB_Password:  dbpassword
    Mounts:         <none>
  Volumes:          <none>
  Node-Selectors:   <none>
  Tolerations:      <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   webapp-deployment-b4ddb5755 (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  15m   deployment-controller  Scaled up replica set webapp-deployment-b4ddb5755 to 1

Inside of the YAML we would see:

controlplane $ k edit deploy webapp-deployment
....
containers:
      - env:
        - name: DB_Host
          value: mysql-host
        - name: DB_User
          value: root
        - name: DB_Password
          value: dbpassword

To change it, instead of value we would need to use valueFrom: and secretKeyRef as following

containers:
      - env:
        - name: DB_Host
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_Host
        - name: DB_User
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_User
        - name: DB_Password
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_Password

Now if we apply these changes we will see how our deployment starts using the new references instead of the hardcoded values, making our deployment much cleaner and safer.

controlplane $ k describe deploy
Name:                   webapp-deployment
Namespace:              default
CreationTimestamp:      Mon, 24 Jun 2024 09:03:46 +0000
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 2
Selector:               app=webapp
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=webapp
  Containers:
   webapp-container:
    Image:      nginx:latest
    Port:       80/TCP
    Host Port:  0/TCP
    Environment:
      DB_Host:      <set to the key 'DB_Host' in secret 'db-secret'>      Optional: false
      DB_User:      <set to the key 'DB_User' in secret 'db-secret'>      Optional: false
      DB_Password:  <set to the key 'DB_Password' in secret 'db-secret'>  Optional: false
    Mounts:         <none>
  Volumes:          <none>
  Node-Selectors:   <none>
  Tolerations:      <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  webapp-deployment-b4ddb5755 (0/0 replicas created)
NewReplicaSet:   webapp-deployment-6ff644ffb8 (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  23m   deployment-controller  Scaled up replica set webapp-deployment-b4ddb5755 to 1
  Normal  ScalingReplicaSet  89s   deployment-controller  Scaled up replica set webapp-deployment-6ff644ffb8 to 1
  Normal  ScalingReplicaSet  87s   deployment-controller  Scaled down replica set webapp-deployment-b4ddb5755 to 0 from 1

If you want to know more about Kubernetes, check all our posts in Kubernetes

La entrada How to mount Secrets in our Deployments se publicó primero en CloudArch.

]]>
https://cloudarch.es/how-to-mount-secrets-in-our-deployments/feed/ 0 547
How to expose a Pod internally in Kubernetes https://cloudarch.es/how-to-expose-pod/ https://cloudarch.es/how-to-expose-pod/#respond Wed, 08 May 2024 10:41:31 +0000 https://cloudarch.es/?p=541 When we create a Pod in Kubernetes, it has assigned a cluster-wide private IP address, which will be accessible by […]

La entrada How to expose a Pod internally in Kubernetes se publicó primero en CloudArch.

]]>
When we create a Pod in Kubernetes, it has assigned a cluster-wide private IP address, which will be accessible by any other pod in the cluster. No matter in which node or host it is deployed while is within the same cluster. But when the pod dies, it will get a new IP assigned which may drive to problems in the network when other resources are connecting to that pod. That’s why Kubernetes introduced how to expose a pod internally in Kubernetes regardless its private IP.

What’s a Service

A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality. When created, each Service is assigned a unique IP address (also called clusterIP). This address is tied to the lifespan of the Service, and will not change while the Service is alive. Pods can be configured to talk to the Service, and know that communication to the Service will be automatically load-balanced out to some pod that is a member of the Service.

How a Pod is added to a Service

Pods are exposed through EndpointSlices. The Service’s selector will be evaluated continuously and the results will be POSTed to an EndpointSlice that is connected to the Service using a labels. When a Pod dies, it is automatically removed from the EndpointSlices that contain it as an endpoint. New Pods that match the Service’s selector will automatically get added to an EndpointSlice for that Service.

How to create a Service to expose a Pod.

We can use the expose option within kubectl command to create it. My personal favourite option is to export that yaml as a file, modify it to satisfy my needs and then apply that file.

In this example we already have a pod called nginx-pod which is running a Nginx service on port 80. We are gonna create a new service called nginx-service which will expose that pod on port 80.

controlplane $ k get po
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          3m52s

controlplane $ k expose pod nginx-pod --port=80 --target-port=80 --dry-run=client -oyaml > service.yaml

controlplane $ cat service.yaml 
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx-pod
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
status:
  loadBalancer: {}
controlplane 

As we can see, we created the service giving the pod name; however it’s not using it. The Service just take the pod to retrieve its selector app: nginx to use it in the service. Thanks to this, every pod that is created with that label, will be added as an endpoint to the Service taking its private IP.

As we want to give it another name. We are gonna edit the file and change the name to nginx-service in the metadata.name section. Then we will apply that file.

controlplane $ vim service.yaml 

controlplane $ k apply -f service.yaml 
service/nginx-service created

controlplane $ k get service
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP   26d
nginx-service   ClusterIP   10.99.122.67   <none>        80/TCP    6s

controlplane $ k describe service nginx-service
Name:              nginx-service
Namespace:         default
Labels:            app=nginx
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.99.122.67
IPs:               10.99.122.67
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         192.168.1.4:80
Session Affinity:  None
Events:            <none>
controlplane $

As we can see, we already have the service created and the endpoint has been automatically added. Now if our pod dies and a new one comes to life, it will be automatically added to the service and we won’t need to change the endpoint in the applications that are using it. If we look at the Pod description we will see how the IPs are the same

controlplane $ k describe po nginx-pod
Name:             nginx-pod
Namespace:        default
Priority:         0
Service Account:  default
Node:             node01/172.30.2.2
Start Time:       Wed, 08 May 2024 10:08:43 +0000
Labels:           app=nginx
Annotations:      cni.projectcalico.org/containerID: 15c844a02dfd1a5b293f640bfa552fe0c4b30a0bc677d780847b7d75d4b658af
                  cni.projectcalico.org/podIP: 192.168.1.4/32
                  cni.projectcalico.org/podIPs: 192.168.1.4/32
Status:           Running
IP:               192.168.1.4
IPs:
  IP:  192.168.1.4

Also if we get more pods with that label, they will be automatically load-balanced by the service.

We can check if the service is working by using a curl command to the Service IP and the assigned port.

controlplane $ curl http://10.99.122.67:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

Note that if we change the label in the pod, it will be removed from the service and won’t be available anymore.

If you want to know more about Kubernetes, read our articles and visit the official documentation.

La entrada How to expose a Pod internally in Kubernetes se publicó primero en CloudArch.

]]>
https://cloudarch.es/how-to-expose-pod/feed/ 0 541