[{"Value":"","Discard":false,"Expires":9999999999}] Automatization archivos - CloudArch https://cloudarch.es/category/automatization/ Blog sobre arquitectura en la nube Mon, 08 Dec 2025 18:24:43 +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 Automatization archivos - CloudArch https://cloudarch.es/category/automatization/ 32 32 228797714 Introduction to KEDA: Event-Driven Autoscaling for Kubernetes https://cloudarch.es/introduction-to-keda/ https://cloudarch.es/introduction-to-keda/#respond Sun, 07 Dec 2025 20:12:58 +0000 https://cloudarch.es/?p=752 When building applications in Kubernetes, one of the most important challenges is efficiently managing workloads. You want your services to […]

La entrada Introduction to KEDA: Event-Driven Autoscaling for Kubernetes se publicó primero en CloudArch.

]]>
When building applications in Kubernetes, one of the most important challenges is efficiently managing workloads. You want your services to scale up when demand spikes, and scale down (even to zero) when idle, to save resources and reduce costs. This is especially critical in production environments where traffic can be unpredictable.

This is where KEDA (Kubernetes Event-Driven Autoscaling) comes in. KEDA is a lightweight, open-source component that integrates with Kubernetes to provide event-driven autoscaling. Unlike traditional Horizontal Pod Autoscalers (HPAs) that only scale based on CPU or memory usage, KEDA can scale your workloads based on external metrics or events, such as:

  • Messages in a queue (Redis, RabbitMQ, Azure Service Bus, etc.)
  • Jobs waiting in Kafka topics
  • Custom metrics from Prometheus
  • Database triggers or cloud events

With KEDA, your applications can react instantly to real-world workloads without over-provisioning resources. It allows you to run microservices cost-effectively while maintaining responsiveness.

What we are building

In this guide, we’ll build a realistic event-driven microservice that processes jobs from a Redis queue. The scenario mirrors what many production systems face:

  • A backend service receives tasks (e.g., image processing, notifications, or data ingestion) and pushes them into a Redis queue.
  • Worker pods consume tasks from the queue.
  • KEDA monitors the queue and scales the number of worker pods up or down depending on the number of pending tasks.

By the end of this guide, you will have:

  • A working Minikube cluster with KEDA installed
  • A Redis-backed job queue
  • A worker deployment that automatically scales according to queue length
  • Complete YAML manifests and a test workflow to simulate real production traffic

This project is valuable because it lets you experience a real-world autoscaling scenario. Most production systems have unpredictable workloads, and learning how KEDA responds to events gives you a deep understanding of:

  • Event-driven design patterns
  • How Kubernetes interacts with external triggers
  • Autoscaling strategies beyond CPU/memory metrics

Even if your real application is more complex (with multiple queues or different event sources), this example provides a solid foundation to implement production-ready, cost-efficient, and resilient services.

What you’ll learn:

  • Start a 3‑node Minikube cluster (if not started)
  • Install Helm (if needed)
  • Install KEDA with Helm
  • Deploy Redis (simple single‑replica) and a worker Deployment that consumes jobs
  • Create a ScaledObject that uses the Redis List scaler
  • Create a producer CronJob that pushes items into the Redis list to simulate load
  • Observe scaling behavior and clean up

Prerequisites

Make sure you have the following locally installed and working on your machine:

  • kubectl (compatible with your Minikube Kubernetes version)
  • minikube (we will use it to run a 3‑node local cluster)
  • helm (Helm 3)
  • docker (or your container runtime used by Minikube driver)

If any of those are missing, install them first. For example on Debian/Ubuntu: sudo snap install kubectl –classic (or use your distro’s package manager). I will not assume any particular OS beyond these tools being available.

Start a 3-node Minikube cluster

# Start minikube with 3 nodes (one control-plane + 2 workers), adjust memory/
CPUs if needed
$ minikube start --nodes=3 --driver=docker --memory=4096 --cpus=2

# Verify nodes come up
$ kubectl get nodes

Notes: –nodes=3 creates 1 control-plane and 2 worker nodes by default. If you already have the cluster running, skip the minikube start step. Make sure kubectl context points to your minikube cluster: kubectl config current-context .

Install Helm

This command will install Helm for you in your local machine. Please, refer to this other post if you wanna learn more about it.

# Add KEDA Helm repo and update
helm repo add kedacore https://kedacore.github.io/charts
helm repo update

# Install KEDA into namespace 'keda'
helm install keda kedacore/keda --namespace keda --create-namespace

# Wait for KEDA pods to become ready
kubectl -n keda get pods

Why Helm? Helm is the easiest official way to install KEDA and its CRDs. KEDA installs CRDs that are required for ScaledObject and ScaledJob resources.

What we’re going to deploy (high level)

  • redis-deployment.yaml — a simple Redis single‑pod deployment + service to be able to access it from other pods
  • worker-deployment.yaml — a small Python worker Deployment that polls job-queue (a Redis list) and processes items, initially it will have 0 replics since it will imitate a job that doesn’t need to be running always
  • producer-cronjob.yaml — a CronJob that pushes messages into Redis periodically to generate load
  • scaledobject-redis.yaml — KEDA ScaledObject definition that scales worker based on Redis list length

I’ll explain each file before showing it. All manifests are designed to run in the default namespace for simplicity. You can change namespace fields if you prefer.

Redis Manifest

# redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  labels:
    app: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7.0-alpine
        ports:
        - containerPort: 6379
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "250m"
            memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  ports:
  - port: 6379
    targetPort: 6379
    protocol: TCP
  selector:
    app: redis
  type: ClusterIP

As we should know already, we are gonna deploy this in our cluster with:

kubectl apply -f redis-deployment.yaml

To be sure the redis service is client, we can test the connectivity with a redis client:

kubectl run -i --tty redis-client --image=redis:7.0-alpine --restart=Never
-- sh
# inside pod shell run: redis-cli -h redis ping
# should reply PONG

Worker code + Deployment

We’ll create a tiny Python worker that continuously polls a Redis list (named job-queue ) with BRPOP and “processes” messages (here, just sleep and echo ). Just to replicate some functionality of reading from Redis. The purpouse of this guide is not the logic of the code itself but it’s realibility on production environments.

In real life your worker would do meaningful job processing.

# worker.py
import time
import os
import redis


REDIS_HOST = os.getenv('REDIS_HOST', 'redis')
REDIS_PORT = int(os.getenv('REDIS_PORT', '6379'))
LIST_NAME = os.getenv('LIST_NAME', 'job-queue')


r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, decode_responses=True)
print('Worker started, connecting to', REDIS_HOST)


while True:
    try:
        # BRPOP blocks until an item is available
        item = r.brpop(LIST_NAME, timeout=5)
        if item:
            # item is (list_name, value)
            value = item[1]
            print('Processing', value)
            # simulate processing
            time.sleep(2)
            print('Done', value)
        else:
            # nothing to do, sleep to avoid tight loop
            time.sleep(1)
    except Exception as e:
        print('Worker error:', e)
        time.sleep(2)
# Dockerfile.worker
FROM python:3.11-slim
WORKDIR /app
COPY worker.py .
RUN pip install --no-cache-dir redis
CMD ["python","/app/worker.py"]

By default if we create the image, it will be in our local registry and Minikube won’t see it. To solve this problem we can enable an addon called registry which will allow us to create a registry in Minikube.

minikube addons enable registry

We need to do a port-forward to forward the data to the registry:

kubectl port-forward -n kube-system service/registry 5000:80

And now, in other terminal to not terminate our tunnel, we need to build and push the image so it can be used within the cluster:

docker build -t keda-worker:latest -f Dockerfile.worker .
docker tag keda-worker:latest localhost:5000/keda-worker:latest
docker push localhost:5000/keda-worker:latest

And now we need to create the deployment of our service using the brand new image:

# worker-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-worker
  labels:
    app: keda-worker
spec:
  replicas: 0 # start with 0 so we can see KEDA scale up from zero
  selector:
    matchLabels:
      app: keda-worker
  template:
    metadata:
      labels:
        app: keda-worker
    spec:
      containers:
      - name: worker
        image: localhost:5000/keda-worker:latest
        imagePullPolicy: Always
        env:
        - name: REDIS_HOST
          value: "redis"
        - name: REDIS_PORT
          value: "6379"
        - name: LIST_NAME
          value: "job-queue"
        resources:
          requests:
            cpu: "50m"
            memory: "64Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"

Please, pay attention that we stated that we want a total of 0 replicas since the design of this is to only run when Keda allows it, saving us computing time and resources in our cluster.

kubectl apply -f worker-deployment.yaml

Create the KEDA ScaledObject for Redis List

Now that we have Redis ready to have message and our service ready to start reading those messages when it’s needed, we need to create a ScaledObject which will tell our service when it’s time to work, create instances and do its job.

# scaledobject-redis.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: keda-worker-scaledobject
  labels:
    app: keda-worker
spec:
  scaleTargetRef:
    name: keda-worker
  pollingInterval: 5 # how often KEDA checks Redis (seconds)
  cooldownPeriod: 30 # how long to wait after scale down before next check
  minReplicaCount: 0
  maxReplicaCount: 10
  triggers:
  - type: redis
    metadata:
      address: "redis.default.svc:6379"
      listName: "job-queue"
      listLength: "5" # scale target: number of items -> triggers scale
      activationListLength: "1" # minimum backlog to activate scaling

Fields explained:

  • scaleTargetRef.name — the Deployment the ScaledObject controls (kedaworker).
  • pollingInterval — how often KEDA will query Redis.
  • minReplicaCount /maxReplicaCount — limits for scaling.
  • triggers — an array of trigger definitions. Here we use the redis scaler.
  • listLength is the target backlog size that will cause KEDA to adjust replicas (KEDA converts this into HPA metrics internally).
  • activationListLength prevents scaling up until backlog is at least that value.

Please, pay special attention at triggers.type since that value is unique for the kind of job we are doing. Keda provides us with an extensive list of different triggers we can use depending on what we want to observe in order to scale our services. You can have a complete list at their official site.

Keda and Redis are on different namespaces on our cluster, when specifying the address make sure you are pointing correctly to Redis. If you don’t use default namespace as I did, it will be different than redis.default.svc:6379

kubectl apply -f scaledobject-redis.yaml

Producer Cronjon to generate load

Finally, we are going to create a cronjob that will just generate some load to replicate a real user, and will just push a message to redis every minute so we can emulate the whole flow automatically and don’t hit any button neither waiting for an user.

# producer-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: job-producer
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: producer
            image: redis:7.0-alpine
            command: [ "sh", "-c" ]
            args:
            - |
              now=$(date +%s)
              echo "Producing job-$now"
              redis-cli -h redis rpush job-queue job-$now
              sleep 1
kubectl apply -f producer-cronjob.yaml

Observe KEDA scaling in action

For this purpose I have splited my terminal into 3 sections, so I can see everything at one glance. First I have to sections of the same size: right and left.

On the right size I will be running the logs of the Scaled Object to see how it’s being triggered everytime it sees there is 1 or more messages in the queue

kubectl logs -f -n keda keda-operator-f948b6c4-ln9ch

And then the left side I will have it splitted into two parts again. In the upper part I will be checking how many messages do I have on the list

watch 'kubectl exec -it deploy/redis -- redis-cli llen job-queue'

And at the botton I will be watching the number of pods from my deplotments

watch 'kubectl get deploy'

There we will be able to see how every minute the list has a new message, a pod of the worker is being created and the message is deleted. Reading all the logs in the right side.

By this way, we could have a service that only will be running when it’s needed. But also, this can be replicated and configured to just scale up or down services based on some triggers to ensure we are always giving the desired availability and reliability.

Clean up resources

kubectl delete -f producer-cronjob.yaml
kubectl delete -f scaledobject-redis.yaml
kubectl delete -f worker-deployment.yaml
kubectl delete -f redis-deployment.yaml
helm uninstall keda -n keda
kubectl delete namespace keda

You can see and download all the code on GitHub https://github.com/JoaquinJimenezGarcia/LearningKeda

La entrada Introduction to KEDA: Event-Driven Autoscaling for Kubernetes se publicó primero en CloudArch.

]]>
https://cloudarch.es/introduction-to-keda/feed/ 0 752
🧠 Run Your Own LLM Locally with Ollama and Docker https://cloudarch.es/run-your-own-llm-locally-with-ollama-and-docker/ https://cloudarch.es/run-your-own-llm-locally-with-ollama-and-docker/#respond Thu, 06 Nov 2025 22:29:39 +0000 https://cloudarch.es/?p=744 In the last few years, large language models (LLMs) have become the brain behind many modern tools — from ChatGPT […]

La entrada 🧠 Run Your Own LLM Locally with Ollama and Docker se publicó primero en CloudArch.

]]>
In the last few years, large language models (LLMs) have become the brain behind many modern tools — from ChatGPT to Gemini and Claude. They help us code faster, summarize text, and even generate entire articles.
But what if you could run one of these models on your own machine, completely offline, without sending a single byte of your data to the cloud?

That’s exactly what Ollama allows you to do.

In this post, I’ll show you how to deploy your own LLM locally using Ollama on Docker, step by step — from installation to using it via API. We’ll also explore why it can be a game-changer for privacy, experimentation, and control.


🚀 Why Run an LLM Locally?

While cloud-based LLMs like ChatGPT or Gemini are powerful and easy to use, they come with trade-offs:

  • 💾 Data Privacy: Anything you send to those services is processed in the cloud. Running your own model locally ensures that all your prompts, code, and data stay on your machine.
  • ⚙ Customization: You can tweak system prompts, memory, or even fine-tune models without limitations.
  • 🔒 Offline Access: No internet? No problem. You can still use the model.
  • 💸 Cost Control: No API fees or subscriptions — just your local hardware doing the work.

This approach is perfect for developers, researchers, and hobbyists who want to experiment safely with AI on their own terms.


🧩 What Is Ollama?

Ollama is a lightweight runtime that lets you run open-source LLMs (like Llama 3, Mistral, Phi, or Gemma) with a single command.
It exposes a REST API compatible with the OpenAI format, meaning you can integrate it easily with existing tools or scripts.

Think of it as “Docker for models” — you pull, run, and interact with them locally.


⚙ Requirements

Before starting, make sure you have:

  • Docker installed (docker --version)
  • At least 8 GB of RAM (16 GB recommended)
  • Disk space: models range from 2 GB to 15 GB
  • Optional: NVIDIA GPU (for better performance)

🧱 Step 1: Run Ollama in Docker

Open a terminal and pull the official Ollama image:

docker pull ollama/ollama

Then start the container:

docker run -d \
  --name ollama \
  -v ollama:/root/.ollama \
  -p 11434:11434 \
  ollama/ollama
  • The volume ollama:/root/.ollama stores your downloaded models.
  • The port 11434 exposes Ollama’s REST API locally.

If you have an NVIDIA GPU, add --gpus=all to use hardware acceleration.


🧠 Step 2: Pull a Model

Once the container is up, let’s download a model.
For this example, we’ll use Mistral, a solid open-source model known for good reasoning and small size (~4 GB):

docker exec -it ollama ollama pull mistral

You can also try Llama 3 or Gemma later.

Check your installed models:

docker exec -it ollama ollama list

💬 Step 3: Chat in the CLI

Start a local chat session:

docker exec -it ollama ollama run mistral

Example:

>>> Hello, what can you do?
I can summarize text, answer questions, or help you write code — all locally on your machine!

To exit, press Ctrl + C.


🌐 Step 4: Use the API

Ollama exposes an endpoint compatible with OpenAI’s API at http://localhost:11434/api/generate.

Let’s test it with curl:

curl http://localhost:11434/api/generate -d '{
  "model": "mistral",
  "prompt": "Write a haiku about Docker."
}'

You’ll get a JSON response similar to:

{"response":"Containers afloat / Isolation in motion / Cloud in a small box"}

🧩 Step 5: Connect from Python

You can even use the OpenAI client library — just point it to Ollama’s local endpoint:

pip install openai

Then create a small Python script:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")

response = client.chat.completions.create(
    model="mistral",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain what Docker is in one sentence."}
    ]
)

print(response.choices[0].message.content)

Run it, and you’ll see the response generated locally — no external API involved.


🧭 Best Practices

  • 💾 Keep models on a dedicated volume: This avoids re-downloading large files every time you restart Docker.
  • 🧹 Clean unused models: docker exec -it ollama ollama rm <model>
  • ⚡ Optimize with GPU: Ollama automatically uses GPU if available (CUDA or Metal).
  • 🔐 Stay offline: If you want full privacy, disable internet access for the container. The model works entirely locally.
  • 📊 Monitor resources: Some models can use several GBs of RAM — use docker stats to watch usage.

🔒 Which Model Is 100% Private?

If privacy is your top priority, I recommend Mistral 7B:

  • ✅ Open-source and licensed for local use
  • ✅ Excellent performance on general tasks
  • ✅ Does not send data anywhere
  • ✅ Works well even without GPU
  • ⚖ Around 4 GB on disk

You can pull it with:

docker exec -it ollama ollama pull mistral

This model runs entirely on your machine — no telemetry, no cloud, no data collection.


🧩 Bonus: Expose Ollama on Your Local Network

If you want to connect from another device on your LAN (e.g. from a laptop or tablet), run:

docker run -d \
  --name ollama \
  -v ollama:/root/.ollama \
  -p 0.0.0.0:11434:11434 \
  ollama/ollama

Then access it from another device using your local IP, e.g.:

http://192.168.1.100:11434/api/generate

✅ Conclusion

Running an LLM locally gives you control, privacy, and freedom.
With Ollama on Docker, you can deploy models like Mistral or Llama 3 in minutes, use them offline, and even integrate them into your own tools or scripts.

No subscriptions, no data leaks — just you, your machine, and your AI.

La entrada 🧠 Run Your Own LLM Locally with Ollama and Docker se publicó primero en CloudArch.

]]>
https://cloudarch.es/run-your-own-llm-locally-with-ollama-and-docker/feed/ 0 744
🩺 Docker HEALTHCHECK: Is Your App Really Alive Inside the Container? https://cloudarch.es/docker-healthcheck-guide/ https://cloudarch.es/docker-healthcheck-guide/#respond Thu, 05 Jun 2025 17:29:30 +0000 https://cloudarch.es/?p=674 Running a container doesn’t mean your app is running fine. It might look like everything’s green from the outside… but […]

La entrada 🩺 Docker HEALTHCHECK: Is Your App Really Alive Inside the Container? se publicó primero en CloudArch.

]]>
Running a container doesn’t mean your app is running fine. It might look like everything’s green from the outside… but inside? Your app could be frozen, stuck, or completely dead 🧊💀

Welcome to the world of Docker HEALTHCHECK — a super underrated feature that can make or break your reliability game. Today we’ll dive into:

✅ Why HEALTHCHECK is essential
⚠ Real risks of skipping it
⚙ How Docker HEALTHCHECK Works
🛠 How to add it to your Dockerfiles
👀 Two practical test cases (healthy vs unhealthy)

❗ Why You Should Care

Let’s be honest. We often celebrate when our container is “up and running” — but that just means the process inside hasn’t crashed. It doesn’t tell us if:

  • The web server is responding 🕸
  • The database is reachable 📉
  • Your app logic is frozen in a loop 🔁

Without a healthcheck, Docker assumes everything is okay. That’s dangerous in production, but also in dev: it gives you a false sense of security.

Healthchecks add real visibility — if your app doesn’t behave as expected, Docker will mark it as unhealthy, and tools like Docker Swarm or Kubernetes can act accordingly (restarts, scaling, etc.).

⚙ How Docker HEALTHCHECK Works — Under the Hood

When you add a HEALTHCHECK instruction in your Dockerfile, you’re telling the Docker engine to periodically run a command inside the container to determine its health status. Here’s how it works step by step:


🧱 1. The HEALTHCHECK Instruction

Example:

HEALTHCHECK --interval=10s --timeout=3s --retries=3 \
CMD curl -f http://localhost:5000/health || exit 1

You’re defining:

OptionMeaning
CMDThe actual command to run inside the container. It must exit with 0 for healthy, non-zero for unhealthy.
--intervalHow often to run the health check (default: 30s).
--timeoutHow long to wait before the command is considered failed (default: 30s).
--retriesNumber of consecutive failures before the container is marked unhealthy (default: 3).

🧠 2. Docker Monitors Using a Background Healthcheck Manager

When you start a container that has a HEALTHCHECK, Docker spawns a lightweight internal timer per container. This timer schedules and executes the CMD at the interval you define.

It’s all handled by the Docker daemon, which adds a health state entry to the container’s metadata.

🧪 3. Exit Codes Determine Health

Docker executes the healthcheck command inside the container, and uses its exit code to decide the result:

Exit CodeMeaning
0Healthy ✅
1Unhealthy ❌
>1Unhealthy ❌

CMD not found or fails to run? Still counts as unhealthy.

Docker tracks the consecutive failures, and once the retry limit is reached, the container is marked as unhealthy.

🔄 4. Status Stored in Container Metadata

You can view this with:

docker inspect --format='{{json .State.Health}}' [container_name] | jq

It shows:

  • Status: starting, healthy, or unhealthy
  • FailingStreak: how many times it failed consecutively
  • Log: recent healthcheck attempts with timestamps and outputs

Docker updates this metadata in real-time, and you can consume it via:

  • CLI (docker ps, docker inspect)
  • Docker Remote API (/containers/id/json)
  • Orchestration tools (like Swarm or Kubernetes)

🪄 5. No Magic, Just Smart Logic

Docker doesn’t inject anything magical into your container. It simply:

  • Executes the given command using the container’s existing binaries (like curl, wget, etc.)
  • Waits for the result
  • Updates internal health state

But this tiny mechanism becomes powerful when combined with:

  • Restart policies (--restart=on-failure)
  • Health-based load balancers (Swarm, K8s, Traefik)
  • Alerting systems (via Docker events or logs)

💡 A Note About “Starting”

After the container boots, healthchecks begin after a default grace period of 0s (can be configured). During this period, the container status shows as:

"Status": "starting"

Once the first successful check is done, status becomes healthy. If it fails N times, it becomes unhealthy.

🚫 What Healthchecks DON’T Do

  • ❌ They do not stop or restart containers by themselves
  • ❌ They don’t directly affect container networking or DNS
  • ❌ They don’t send alerts unless you wire them to an external system

🔧 Adding a HEALTHCHECK to Your Dockerfile

It’s simple! Here’s the syntax:

HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD curl -f http://localhost:5000/health || exit 1

This checks every 10 seconds if the /health endpoint returns a success. If it fails 3 times in a row, the container becomes unhealthy.

🧪 Let’s Test It in Action

We’ll create two test containers:

✅ Healthy App

This one includes a proper /health endpoint that always returns 200 OK.

Dockerfile:

FROM python:3.11-slim
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /app
COPY app.py .
# Install curl
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN pip install flask
EXPOSE 5000
HEALTHCHECK --interval=10s CMD curl -f http://127.0.0.1:5000/health || exit 1
CMD ["python", "app.py"]

app.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
return "All good!"

@app.route('/health')
def health():
return "OK", 200

app.run(host="0.0.0.0", port=5000)

👉 Build and run:

docker build -t healthy-app .
docker run -d --name
healthtest healthy-app
docker inspect --format='{{.State.Health.Status}}'
healthtest
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55e9b6f148a9 healthcheck_test "python app.py" 18 seconds ago Up 18 seconds (healthy) 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp healthtest

🎉 You’ll get: healthy

❌ Unhealthy App

Now let’s break the /health endpoint.

Modified app.py:

@app.route('/health')
def health():
return "Error", 500

Build and run again:

docker build -t unhealthy-app .
docker run -d --name broken unhealthy-app
docker inspect --format='{{.State.Health.Status}}' broken

💥 Result: unhealthy

You’ll also see the logs showing failed healthcheck attempts:

$ docker inspect broken | jq '.[].State.Health.Log'
[
{
"Start": "2025-06-05T19:26:07.323262742+02:00",
"End": "2025-06-05T19:26:07.367595028+02:00",
"ExitCode": 1,
"Output": " % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r 0 5 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\ncurl: (22) The requested URL returned error: 500\n"
},
{
"Start": "2025-06-05T19:26:17.369661511+02:00",
"End": "2025-06-05T19:26:17.408770486+02:00",
"ExitCode": 1,
"Output": " % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r 0 5 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\ncurl: (22) The requested URL returned error: 500\n"
},
{
"Start": "2025-06-05T19:26:27.409488914+02:00",
"End": "2025-06-05T19:26:27.450101106+02:00",
"ExitCode": 1,
"Output": " % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r 0 5 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\ncurl: (22) The requested URL returned error: 500\n"
},
{
"Start": "2025-06-05T19:26:37.450803223+02:00",
"End": "2025-06-05T19:26:37.492805511+02:00",
"ExitCode": 1,
"Output": " % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r 0 5 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\ncurl: (22) The requested URL returned error: 500\n"
}
]

👁 What’s the Impact?

ScenarioBehavior
No HEALTHCHECKDocker marks container as healthy by default
HEALTHCHECK passesContainer state = healthy ✅
HEALTHCHECK failsContainer state = unhealthy 🚨

Why it matters:

  • Your orchestration tools (Swarm, Kubernetes, etc.) rely on this signal
  • You can detect failing containers early during development
  • It helps your CI/CD pipeline make smart decisions

🧠 Final Thoughts

A HEALTHCHECK is like a pulse check for your app ❤️‍🩹
Just because a container runs doesn’t mean your service is okay.

Whether you’re in local development or scaling in production, a tiny HEALTHCHECK line in your Dockerfile can save you hours of debugging and nights of firefighting.

So go ahead — make your containers honest.

Docker HEALTHCHECK is:

  • A built-in mechanism that runs periodic commands inside containers
  • Based entirely on the exit status of your script or command
  • Tracked by the Docker daemon, with results exposed via CLI & API
  • Powerful when combined with orchestration, restarts, and alerts

📚 Bonus tip: Want to auto-restart unhealthy containers?
Add this when running your container:

docker run --restart=on-failure ...

La entrada 🩺 Docker HEALTHCHECK: Is Your App Really Alive Inside the Container? se publicó primero en CloudArch.

]]>
https://cloudarch.es/docker-healthcheck-guide/feed/ 0 674
Helm Repositories: Your Gateway to Kubernetes Apps 🗂️⛵ https://cloudarch.es/helm-repositories-your-gateway-to-kubernetes-apps/ https://cloudarch.es/helm-repositories-your-gateway-to-kubernetes-apps/#respond Tue, 08 Apr 2025 20:46:25 +0000 https://cloudarch.es/?p=656 So you’ve installed Helm, taken your first breath in this world of Kubernetes package management, and you’re wondering… Now what? […]

La entrada Helm Repositories: Your Gateway to Kubernetes Apps 🗂️⛵ se publicó primero en CloudArch.

]]>
So you’ve installed Helm, taken your first breath in this world of Kubernetes package management, and you’re wondering… Now what? What makes Helm truly magical isn’t just that it simplifies your deployments — it’s where it gets its powers from: the Helm repository.

If Helm is the Kubernetes version of a package manager, then Helm repos are its treasure chests. And just like any good explorer, you’re going to need to know where to find the maps.


So… what is a Helm repo, really? 🤔

Let’s imagine you’re building a house in Kubernetes. Instead of crafting each brick by hand (writing all those YAMLs), you can order a ready-to-assemble kit. That kit? It’s called a Helm chart. And where do you get it from? A Helm repository.

A Helm repo is basically a collection of Helm charts — pre-packaged Kubernetes applications that are ready for deployment. These charts are stored in an online repository, which you can connect to and browse from your terminal.

Think of it like a Play Store or App Store, but for Kubernetes.


The Default Chart Repo: Bitnami & Friends

The Helm team maintains a default, stable repo full of widely-used applications: NGINX, MySQL, Prometheus, Grafana, WordPress… you name it. One of the most popular ones is from Bitnami, which packages and maintains a huge collection of up-to-date and secure charts.

But the real beauty is this: you can add any Helm repo to your local setup — official, third-party, or even your own private one.


Let’s get our hands dirty 🧤💻

Adding a Helm repo is as simple as a single command. For example, to add Bitnami’s public repository:

helm repo add bitnami https://charts.bitnami.com/bitnami

That’s it. You’ve just connected your Helm CLI to a vast world of applications.

Want to make sure everything’s in sync?

helm repo update

This command refreshes the list of available charts and their latest versions from all the repos you’ve added.

To check which repos you currently have on your machine:

helm repo list

It’ll show you a tidy little table with all your configured repositories. Nice and clean.


Exploring the Chart Library with helm search 🔍

Once you’ve added a repository — say Bitnami — and updated it, you’re probably thinking: “Cool… but what can I actually install?”

That’s where the magic of searching comes in.

You can use:

helm search repo wordpress

And Helm will scan through all your added repositories and list any charts that match the name “wordpress”. It’ll even show you the latest version and a short description — kind of like browsing a menu at a restaurant, but for apps in your Kubernetes cluster 🍽.

Want to see everything available from Bitnami? Just do:

helm search repo bitnami

And boom — a full buffet of deployable goodness.

This command is especially useful when you’re not quite sure what you’re looking for, or when you’re exploring new tools to add to your stack.


Installing Charts from Repos 🧙‍♂️✨

Now comes the fun part. Let’s say you want to install WordPress in your Kubernetes cluster (because why not launch a blog while you’re launching containers? 😄).

Installing any chart is as easy as using the helm install command following with some parameters:

helm install <name for your app, you choose it> <reponame_chart>

Once you’ve added Bitnami’s repo, you can run:

helm install my-wordpress bitnami/wordpress

Boom. Helm fetches the chart from the Bitnami repo, installs it into your cluster, and gives you all the necessary info to access it.

You don’t even need to download the chart locally unless you want to customize it (more on that in a future post 😉).


Behind the Scenes 🕵

When you install a chart from a repo, Helm does a few things:

  1. It looks up the chart metadata in the repo index.
  2. It pulls down a .tgz (tar.gz) package that contains all the YAML templates, values, and configuration.
  3. It renders those templates with your values and sends the final manifests to Kubernetes.

The best part? You didn’t touch a single YAML file.


Final Thoughts 🧠

Getting familiar with Helm repos is a crucial step in mastering Helm — and honestly, it’s where the fun begins. You now have access to hundreds of production-grade Kubernetes apps, just a command away.

But don’t stop here.

Next, we’re going to explore how to customize these charts to suit your environment, your values, and your style (yes, Kubernetes can have style 👨‍🎨).

Until then, try playing with a few different charts. Install Redis, launch a full monitoring stack with Prometheus + Grafana, or spin up your own Jenkins CI system — all in just a few keystrokes.

Your cluster will thank you. 😌


👉 Enjoying the series?
Make sure to follow, subscribe, or share this post with someone who still thinks Helm is just something you wear on a boat. 😄
#Helm #Kubernetes #DevOps #CloudNative #K8s #InfrastructureAsCode #HelmCharts

La entrada Helm Repositories: Your Gateway to Kubernetes Apps 🗂️⛵ se publicó primero en CloudArch.

]]>
https://cloudarch.es/helm-repositories-your-gateway-to-kubernetes-apps/feed/ 0 656
What is Helm? The Kubernetes Package Manager Explained for Beginners 🚀 https://cloudarch.es/what-is-helm-the-kubernetes-package-manager/ https://cloudarch.es/what-is-helm-the-kubernetes-package-manager/#respond Tue, 08 Apr 2025 10:30:27 +0000 https://cloudarch.es/?p=650 Welcome to the first post in our Helm series! Whether you’re a DevOps engineer, cloud enthusiast, or just getting started […]

La entrada What is Helm? The Kubernetes Package Manager Explained for Beginners 🚀 se publicó primero en CloudArch.

]]>

Welcome to the first post in our Helm series! Whether you’re a DevOps engineer, cloud enthusiast, or just getting started with Kubernetes, you’re about to discover a powerful tool that can make your life way easier: Helm.

In this post, we’ll dive into:

  • What is Helm?
  • What problems does it solve?
  • Key benefits of using Helm
  • How to install Helm (in just a few steps!)

Let’s jump right in!


What is Helm? 🧭

Imagine managing a complex application in Kubernetes — dozens of YAML files, multiple services, deployments, secrets, configs, and everything in between. It’s like assembling IKEA furniture without the manual.

Helm is here to be your manual.

It’s the package manager for Kubernetes — just like apt is for Ubuntu or yum is for CentOS, but made for the cloud-native world.

With Helm, you can:

  • Package your Kubernetes YAMLs into reusable templates (called Charts)
  • Deploy complex applications with a single command
  • Easily manage upgrades, rollbacks, and configurations

In short: Helm makes deploying to Kubernetes faster, simpler, and less error-prone.


What Problems Does Helm Solve? ⚠

Kubernetes is powerful, but managing it manually is like juggling flaming swords. Here are some real headaches Helm helps with:

1. Too many YAML files

Applications often require multiple resources: Deployments, Services, ConfigMaps, Ingresses, etc. Helm bundles them into one chart.

2. Hard-coded values

Editing the same YAML files over and over to change values (like image tags or environment settings)? Helm allows dynamic values with templates and variables.

3. No easy way to upgrade or rollback

With Helm, you can upgrade an app version and roll back instantly if something goes wrong.

4. App reuse across environments

Want the same app in dev, staging, and prod with just different configs? Helm makes it effortless.


Benefits of Using Helm ✨

Helm isn’t just a nice-to-have — it’s a must-have for scalable, maintainable Kubernetes environments.

Here’s why:

• Saves Time ⏱

Automate and simplify deployments with one-liners.

• Improves Consistency

Avoid human error and deploy the same app across environments with confidence.

• Version Control Friendly

Helm charts can live in Git, making your infrastructure-as-code even more powerful.

• Easily Shareable

Share your charts with teammates or open source them for the community.

• Built-in Rollbacks

One bad deployment? Roll it back like it never happened.


How to Install Helm 🛠

Ready to get started? Installing Helm is quick and painless.

Step 1: Download the Helm Binary

For macOS:

brew install helm

For Linux:

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

For Windows:

Use Chocolatey or Scoop:

choco install kubernetes-helm

Step 2: Verify the Installation

helm version

You should see something like:

version.BuildInfo{Version:"v3.x.x", GitCommit:"...", ...}

Boom — you’re ready to helm your ship! ⛵


What’s Next?

In the next post, we’ll break down what a Helm Chart really is, how it’s structured, and how to create your very first one.

If you’re enjoying this series, don’t forget to:

  • Subscribe to the blog
  • Share this post with your DevOps squad
  • Leave a comment if you have questions or want a topic covered!

Until next time — keep it cloud-native! ☁


La entrada What is Helm? The Kubernetes Package Manager Explained for Beginners 🚀 se publicó primero en CloudArch.

]]>
https://cloudarch.es/what-is-helm-the-kubernetes-package-manager/feed/ 0 650
Concurrency vs. Parallelism in GoLang https://cloudarch.es/concurrency-vs-parallelism-in-golang/ https://cloudarch.es/concurrency-vs-parallelism-in-golang/#respond Mon, 13 Jan 2025 11:34:10 +0000 https://cloudarch.es/?p=634 Concurrency vs. Parallelism in GoLang Do goroutines run one by one or in parallel? The short answer is: it depends. […]

La entrada Concurrency vs. Parallelism in GoLang se publicó primero en CloudArch.

]]>
Concurrency vs. Parallelism in GoLang

  • Concurrency: GoLang allows you to execute multiple tasks apparently simultaneously. This is achieved through goroutines, which are lightweight functions that execute concurrently. The Go runtime is responsible for scheduling these goroutines on the available system threads, giving the illusion of parallelism.
  • Parallelism: Parallelism involves executing multiple tasks truly simultaneously, utilizing multiple processor cores. If you have a task that can be divided into independent subtasks, Go can leverage parallelism to accelerate execution.

Do goroutines run one by one or in parallel?

The short answer is: it depends.

  • One by one: If there are not enough resources (CPU cores, memory) or if the tasks are tightly coupled, goroutines will execute sequentially, one after another.
  • In parallel: If you have multiple cores available and the tasks are independent, the Go runtime will attempt to execute the goroutines in parallel, taking advantage of all available cores.

Is it possible to apply parallelism to save execution time?

Absolutely! GoLang is designed to facilitate concurrent and parallel programming. Here are some ways to take advantage of parallelism:

  • Goroutines: Create multiple goroutines to execute independent tasks.
  • Channels: Use channels to communicate and synchronize between goroutines.
  • WaitGroups: Use sync.WaitGroup to wait for all goroutines to finish before proceeding.
  • Parallel data processing: Divide large datasets into smaller chunks and process each chunk in a different goroutine.
  • Use parallelism libraries: Explore libraries like parallel that offer high-level functions for performing operations in parallel.

Simple example:

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	// Code block for sequencial execution
	t1 := time.Now()
	sequencial()
	t1f := time.Now()
	t1t := t1f.Sub(t1)
	fmt.Println("Sequencial took", t1t)

	// Code block for routines. It cna apply parallelism due to free CPU
	t2 := time.Now()
	parallelism()
	t2f := time.Now()
	t2t := t2f.Sub(t2)
	fmt.Println("Parallelism took", t2t)
}

func sequencial() {
	for i := 0; i < 5; i++ {
		fmt.Println("Execution", i)

		waitTime()
	}
}

func parallelism() {
	var wg sync.WaitGroup

	for i := 0; i < 5; i++ {
		wg.Add(1)
		fmt.Println("Execution", i)

		go waitTimeParallel(&wg)
	}
	wg.Wait()
}

func waitTime() {
	time.Sleep(5 * time.Second)
}

func waitTimeParallel(wg *sync.WaitGroup) {
	time.Sleep(5 * time.Second)
	wg.Done()
}

In this example, 5 goroutines are created that simulate independent tasks. By using sync.WaitGroup, it is ensured that the main program waits for all goroutines to finish before terminating.

If we take a close look to the execution of the output, we might see how we can take advantage of parallelism and run each task in a different CPU core, so the total execution time will be drastically lower. Since the task is just a 5-seconds counter, it will run everything at the same time, counting only 5 seconds. In the sequencial example we see how it runs each task one after one, counting 5 seconds per each task.

Important considerations:

  • Communication between goroutines: Channels are essential for coordinating work between goroutines.
  • Synchronization: Use sync.WaitGroup, mutexes, or semaphores to synchronize access to shared resources.
  • Deadlocks: Beware of deadlocks, which can occur when two or more goroutines are waiting for another to perform an action.
  • Overhead: Creating and managing many goroutines has a cost. Evaluate whether the benefit of parallelism justifies the overhead.

In summary:

GoLang provides you with powerful tools for leveraging concurrency and parallelism. By understanding the basic concepts and applying them correctly, you can write more efficient and scalable programs.

La entrada Concurrency vs. Parallelism in GoLang se publicó primero en CloudArch.

]]>
https://cloudarch.es/concurrency-vs-parallelism-in-golang/feed/ 0 634
Mastering Prometheus and Alertmanager for Monitoring and Alerting https://cloudarch.es/prometheus-alertmanage/ https://cloudarch.es/prometheus-alertmanage/#respond Mon, 09 Dec 2024 10:10:30 +0000 https://cloudarch.es/?p=628 Monitoring systems are critical in modern IT environments to ensure reliability and uptime. Prometheus and Alertmanager are open-source tools that […]

La entrada Mastering Prometheus and Alertmanager for Monitoring and Alerting se publicó primero en CloudArch.

]]>
Monitoring systems are critical in modern IT environments to ensure reliability and uptime. Prometheus and Alertmanager are open-source tools that simplify monitoring, metric collection, and alerting.

This guide will cover everything you need to start using Prometheus and Alertmanager, even if you are a complete beginner.


What is Prometheus?

Prometheus is a robust monitoring tool designed for cloud-native environments. It collects metrics from configured targets at given intervals, evaluates rule expressions, and triggers alerts when thresholds are breached.

Key Features:

  • Multi-dimensional data model: Uses key-value pairs to identify metrics.
  • Powerful query language (PromQL).
  • Efficient storage: Time-series data storage.
  • Visualization: Integrates well with Grafana.

What is Alertmanager?

Alertmanager handles alerts generated by Prometheus, deduplicates them, groups them, and routes them to various receivers like email, Slack, or PagerDuty.

Key Features:

  • Alert grouping.
  • Silencing alerts.
  • Integration with multiple receivers.

Installing Prometheus

Prerequisites:

  • A Linux server with root access.
  • Docker or direct installation via binaries.

Steps for Docker Installation:

  1. Create a prometheus.yml configuration file:
global:
scrape_interval: 15s # Default scrape interval

scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
  1. Start Prometheus:
docker run -d --name=prometheus \
-p 9090:9090 \
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
  1. Access the Prometheus web UI:

Installing Alertmanager

  1. Create an alertmanager.yml configuration file:
global:
resolve_timeout: 5m

route:
receiver: 'email-alert'

receivers:
- name: 'email-alert'
email_configs:
- to: 'your-email@example.com'
from: 'alertmanager@example.com'
smarthost: 'smtp.example.com:587'
auth_username: 'your-username'
auth_password: 'your-password'
  1. Start Alertmanager:
docker run -d --name=alertmanager \
-p 9093:9093 \
-v $(pwd)/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
prom/alertmanager
  1. Access Alertmanager’s web UI:

Configuring Prometheus to Use Alertmanager

Modify prometheus.yml:

alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']

rule_files:
- 'alert_rules.yml'

scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

Create an alert_rules.yml file:

groups:
- name: example-alert
rules:
- alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} is down"
description: "No response from {{ $labels.instance }} for over 1 minute."

Reload Prometheus:

curl -X POST http://localhost:9090/-/reload

Best Practices for Prometheus

  1. Use Node Exporter for OS Metrics:
    • Install Node Exporter:bashCopy codedocker run -d -p 9100:9100 prom/node-exporter
    • Add it to prometheus.yml:yamlCopy codescrape_configs: - job_name: 'node' static_configs: - targets: ['localhost:9100']
  2. Label Your Metrics Wisely:
    • Avoid high cardinality (e.g., too many unique labels).
  3. Set Retention Period:
    • Limit storage to save resources:bashCopy code--storage.tsdb.retention.time=15d
  4. Scale with Prometheus Federation:
    • Use hierarchical setups for large environments.

Creating Custom Metrics

Prometheus allows custom metrics via client libraries:

Example (Python):

Install the library:

pip install prometheus_client

Create a simple exporter:

from prometheus_client import start_http_server, Gauge
import random
import time

# Define a gauge metric
my_gauge = Gauge('random_number', 'A random number generator')

if __name__ == "__main__":
start_http_server(8000)
while True:
my_gauge.set(random.randint(0, 100))
time.sleep(5)

Add it to prometheus.yml:

scrape_configs:
- job_name: 'custom-metrics'
static_configs:
- targets: ['localhost:8000']

Monitoring a Linux System

Use the Node Exporter to monitor Linux system metrics such as CPU, memory, disk usage, and network.

  1. Start Node Exporter:
docker run -d -p 9100:9100 prom/node-exporter
  1. Add it to Prometheus:
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
  1. Access metrics in Prometheus:
    • Query examples:
      • node_cpu_seconds_total
      • node_memory_Active_bytes

Sending Alerts with Alertmanager

  1. Create an alert rule in alert_rules.yml:
groups:
- name: high_cpu_usage
rules:
- alert: HighCPUUsage
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 2m
labels:
severity: warning
annotations:
summary: "High CPU usage detected on {{ $labels.instance }}"
description: "CPU usage is above 80% for more than 2 minutes."
  1. Reload Prometheus:
curl -X POST http://localhost:9090/-/reload
  1. Configure email or Slack integration in Alertmanager.

Conclusion

By following this guide, you can set up a powerful monitoring and alerting system with Prometheus and Alertmanager. Start small, experiment with metrics and alerts, and refine as you scale.

Feel free to share your questions or experiences in the comments below!

La entrada Mastering Prometheus and Alertmanager for Monitoring and Alerting se publicó primero en CloudArch.

]]>
https://cloudarch.es/prometheus-alertmanage/feed/ 0 628
How to deploy your Kubernetes app – Part II https://cloudarch.es/how-to-deploy-your-kubernetes-app-part-ii/ https://cloudarch.es/how-to-deploy-your-kubernetes-app-part-ii/#comments Sun, 04 Aug 2024 22:42:02 +0000 https://cloudarch.es/?p=569 In a previous post we were learning how to install and configure ArgoCD to learn how to deploy your Kubernetes […]

La entrada How to deploy your Kubernetes app – Part II se publicó primero en CloudArch.

]]>
In a previous post we were learning how to install and configure ArgoCD to learn how to deploy your Kubernetes app.

In this new post we will be seeing how to integrate our first Kubernetes deployment by default and learn the basics to start automating our services and workloads.

Before starting we must have something to deploy. For this lab I have prepared a default deployment that will create 3 pods with a Nginx container in each. You can take a look or using it by this link: https://github.com/JoaquinJimenezGarcia/argocd-deploy-test but in case you want to create your own repo basically it looks like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Now that we have our ArgoCD up and running, we will see that it’s empty. However in the upper left corner we would see a button labeled “New App”. We must click there and a new window will pop up with some info we must complete.

However these are the most important fields we need to fill:

  • Application Name: this is the name that will return our ArgoCD to refeer to our resources. We can assign here the value that we want, but following the name of the deployment I gave it the same one: argocd-deploy-test
  • Project Name: the project we are going to use in ArgoCD, since we only have “default” this is the value it must have, but we can create multiple projects with multiple resources
  • Sync Policy: if we want to sync manually or automatically, we would mark “automatically” since we want to be updated if we update the YAML files on Github
  • Repository URL: where the YAML files live, if you are using directly the one I have created, it’s https://github.com/JoaquinJimenezGarcia/argocd-deploy-test
  • Path: the path to deploy our pods, by default I left it as “.”
  • Cluster URL: in which cluster we want to deploy, since we only have the cluster where ArgoCD is installed, we can leave it as https://kubernetes.default.svc
  • Namespace: the namespace where the pods would be deployed, as a good practice we should have multiple namespaces, but as per this lab we are going to be uing only “default” namespace

Now we have all these fields ready, we need to click on create app and ArgoCD autimatically will go to our repo, read the yaml files and execute them.

Because this is only a small YAML file, we should see just a few seconds later our app completeley deployed

If we want to double check, we can go to our cluster and examine the pods looking to see if the pod names match with the ones are deployed there:

And as we can see, the results matches, so our app is perfectly deployed.

So as we marked the auto sync, now it will be reading our Git each 3 minutes to detect changes and apply them. So if for example we push a PR changing the replicas from 3 to 5, it would be updated automatically without more human interaction.

La entrada How to deploy your Kubernetes app – Part II se publicó primero en CloudArch.

]]>
https://cloudarch.es/how-to-deploy-your-kubernetes-app-part-ii/feed/ 2 569
Run security tests on your webapps https://cloudarch.es/run-security-tests-on-your-webapps/ https://cloudarch.es/run-security-tests-on-your-webapps/#respond Mon, 29 Jul 2024 09:27:29 +0000 https://cloudarch.es/?p=560 Day after day we receive more news about another company or website being hacked and millions of users’ data being […]

La entrada Run security tests on your webapps se publicó primero en CloudArch.

]]>
Day after day we receive more news about another company or website being hacked and millions of users’ data being stolen. That’s why in this post we are going to learn how to run security tests on your webapps.

Security is not a matter only a department in IT should be take care of, it’s really important that our apps are security aware since their design to their implementation to avoid huge problems in the future.

In this example, we will be running tests using OWASP ZAP over a vulnerable site called Juice Shop which OWASP offers to do test and learn about this tool.

What is OWASP ZAP

OWASP ZAP (Zed Attack Proxy) is a web app scanner. It’s free and open source and it’s actively maintaned by volunteers in Github. You can learn more about this tool in their official website.

Deploying Juice Shop

As mentioned in the introduction, we will be using a web site designed for security testing called Juice Shop. This site has multiple vulnerabilities we may be able to detect using OWASP ZAP to learn how to use the tool properly.

OWASP provides us a docker image totally ready to just pull and run, so we can have the site up in just two very simple steps

# Pulling the image from the repository
docker pull bkimminich/juice-shop

# Running a container with the previous image maping the ports in our local machine to access it later
docker run --rm -p 3000:3000 bkimminich/juice-shop

Once we saw the previous output, we will be able to access the page from our localhost at port 3000: http://localhost:3000/#/

Installing OWASP ZAP

OWASP also provides us a docker image to run in our environment to execute our tests, and even automate it.

This tool also offers a GUI with plenty of information, however we will be covering only the command-line tool in this post.

Also, we will be setting the network as host, so we can reach the site running from our localhost. That step is not needed in case the Juice Shop is deployed somewhere else or it’s facing the public internet.

# Getting the image
docker pull softwaresecurityproject/zap-stable

# Running an interactive console in a container with the previous image
docker run -it --network=host softwaresecurityproject/zap-stable bash

Executing our first test

Before starting running the scans, we are going to update ZAP and installing two addons:

  • Wappalyzer = this is a technology detection add-on. It detects what the app is actually using.
  • Passive Scan Rules = this is the add-on that would help us to scan the web sites.

Once we have installed those add-ons, we will be ready to scan our Juice Shop site previously deployed.

# Installing the add-ons and updating ZAP
./zap.sh -cmd -addonupdate -addoninstall wappalyzer -addoninstall pscanrulesBeta

# Executing the test on our Juice Shop site
./zap.sh -cmd -zapit http://localhost:3000

After running the test we would be able to see some output with some useful information such as which technology the site is using and some problems sorted by level of criticality.

Farewell

If you want to learn how to perform deeper tests or even integrate these tests with your CI/CD pipelines, stay tune for future posts where we were digging more into this topic.

Also, if you want to know more about automation, read other related posts in the blog.

La entrada Run security tests on your webapps se publicó primero en CloudArch.

]]>
https://cloudarch.es/run-security-tests-on-your-webapps/feed/ 0 560
How to deploy your Kubernetes app – Part I https://cloudarch.es/how-to-deploy-your-kubernetes-app-part-i/ https://cloudarch.es/how-to-deploy-your-kubernetes-app-part-i/#respond Sun, 28 Jul 2024 18:52:00 +0000 https://cloudarch.es/?p=554 Learn how to deploy your Kubernetes app! When we are working with Kubernetes, we might face multiple yaml files for […]

La entrada How to deploy your Kubernetes app – Part I se publicó primero en CloudArch.

]]>
Learn how to deploy your Kubernetes app! When we are working with Kubernetes, we might face multiple yaml files for a single application: deployment file, secrets files, service account files, etc. It may be overwhelming in some cases to maintain all those files and keep the last versions on our infrastructure. That’s why here we are gonna learn how to deploy your Kubernetes app using Github and ArgoCD.

In this first part we will be covering the ArgoCD installation using minikube. However, the exactly same steps can be followed in another Kubernetes environment. In the cloud or on-premises.

What is ArgoCD

Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. Argo CD follows the GitOps pattern of using Git repositories as the source of truth for defining the desired application state.

You can read more info in their official website

Installing ArgoCD

Taking into consideration we already have minikube installed and running with kubectl correctly configured, we just need to create a namespace and deploy a Kubernetes yaml file from the official ArgoCD repository.

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

It’s important to keep the namespace as the one in the examnple because the manifest we are downloading includes references to it such as some for Service Accounts. If we want or we need to change it, we would need to download the repository before applying the manifest and change the references to the namespace.

Since we are gonna be working in the namespace we just created, a good practice would be setting up the defualt namespace to that one to avoid confusion.

kubectl config set-context --current --namespace=argocd

Right after that we would be ready to install the argo command line tool to interact with our ArgoCD via the console. We can just download it from https://github.com/argoproj/argo-cd/releases/latest but if you are using Mac, it can be easier to install it using brew.

brew install argocd

We are able to check that ArgoCD is sucessfully deployed by checking the containers in the current namespace.

k get po
NAME                                               READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                    1/1     Running   0          30m
argocd-applicationset-controller-65bb5ff89-wrfw9   1/1     Running   0          30m
argocd-dex-server-6f898cbd9-4f52l                  1/1     Running   0          30m
argocd-notifications-controller-64bc7c9f7-rpfxk    1/1     Running   0          30m
argocd-redis-5df55f45b7-x8snc                      1/1     Running   0          30m
argocd-repo-server-74d5f58dc5-96zmf                1/1     Running   0          30m
argocd-server-5b86767ddb-lxjl5                     1/1     Running   0          30m

Making our Argo accesible

By default ArgoCD is not exposed to an external IP, so if we need to acces it from outside for example to add new apps or to check the status or our current apps, we must create a Load Balancer, an Ingress or do a port-fordwarding.

Since we are working on minikube, with the port-forwarding would be more than enough. But for cloud environments Ingress may be the right fit. We would be covering now only port-forwarding, but in a later part of this serie we would be working on customizating our ArgoCD by adding other clusters to deploy our apps and exposing it under other kind of network Services.

kubectl port-forward svc/argocd-server -n argocd 8080:443

After forwarding we would be able to see our Argo in our localhost.

Retrieving your ArgoCD credentials

Your credentials were stored in a Secret in your Kubernetes cluster when you were deploying it, but also you can use the argo command-line tool to retrieve the password. The user by default is “admin”.

argocd admin initial-password -n argocd

However a good practice is always changing the default password of your service, you can do it also using the argocd command-line tool

argocd account update-password

Once we have logged in using our credentials, we should see a site like the following.

Farewell

If you enjoyed reading this first part, stay tune to get to know in the next one how to configure the deployment on ArgoCD of our apps.

Also, if you need to know more about Kubernetes, visit our latest posts.

La entrada How to deploy your Kubernetes app – Part I se publicó primero en CloudArch.

]]>
https://cloudarch.es/how-to-deploy-your-kubernetes-app-part-i/feed/ 0 554