DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Evaluating Your Event Streaming Needs the Software Architect Way
Watch Now

Deployment

In the SDLC, deployment is the final lever that must be pulled to make an application or system ready for use. Whether it's a bug fix or new release, the deployment phase is the culminating event to see how something works in production. This Zone covers resources on all developers’ deployment necessities, including configuration management, pull requests, version control, package managers, and more.

icon
Latest Refcards and Trend Reports
Refcard #233
Getting Started With Kubernetes
Getting Started With Kubernetes
Refcard #379
Getting Started With Serverless Application Architecture
Getting Started With Serverless Application Architecture
Trend Report
Kubernetes in the Enterprise
Kubernetes in the Enterprise

DZone's Featured Deployment Resources

Use AWS Controllers for Kubernetes To Deploy a Serverless Data Processing Solution With SQS, Lambda, and DynamoDB

Use AWS Controllers for Kubernetes To Deploy a Serverless Data Processing Solution With SQS, Lambda, and DynamoDB

By Abhishek Gupta CORE
In this blog post, you will be using AWS Controllers for Kubernetes on an Amazon EKS cluster to put together a solution wherein data from an Amazon SQS queue is processed by an AWS Lambda function and persisted to a DynamoDB table. AWS Controllers for Kubernetes (also known as ACK) leverage Kubernetes Custom Resource and Custom Resource Definitions and give you the ability to manage and use AWS services directly from Kubernetes without needing to define resources outside of the cluster. The idea behind ACK is to enable Kubernetes users to describe the desired state of AWS resources using the Kubernetes API and configuration language. ACK will then take care of provisioning and managing the AWS resources to match the desired state. This is achieved by using Service controllers that are responsible for managing the lifecycle of a particular AWS service. Each ACK service controller is packaged into a separate container image that is published in a public repository corresponding to an individual ACK service controller. There is no single ACK container image. Instead, there are container images for each individual ACK service controller that manages resources for a particular AWS API. This blog post will walk you through how to use the SQS, DynamoDB, and Lambda service controllers for ACK. Prerequisites To follow along step-by-step, in addition to an AWS account, you will need to have AWS CLI, kubectl, and Helm installed. There are a variety of ways in which you can create an Amazon EKS cluster. I prefer using eksctl CLI because of the convenience it offers. Creating an EKS cluster using eksctl can be as easy as this: eksctl create cluster --name my-cluster --region region-code For details, refer to Getting started with Amazon EKS – eksctl. Clone this GitHub repository and change it to the right directory: git clone https://github.com/abhirockzz/k8s-ack-sqs-lambda cd k8s-ack-sqs-lambda Ok, let's get started! Setup the ACK Service Controllers for AWS Lambda, SQS, and DynamoDB Install ACK Controllers Log into the Helm registry that stores the ACK charts: aws ecr-public get-login-password --region us-east-1 | helm registry login --username AWS --password-stdin public.ecr.aws Deploy the ACK service controller for Amazon Lambda using the lambda-chart Helm chart: RELEASE_VERSION_LAMBDA_ACK=$(curl -sL "https://api.github.com/repos/aws-controllers-k8s/lambda-controller/releases/latest" | grep '"tag_name":' | cut -d'"' -f4) helm install --create-namespace -n ack-system oci://public.ecr.aws/aws-controllers-k8s/lambda-chart "--version=${RELEASE_VERSION_LAMBDA_ACK}" --generate-name --set=aws.region=us-east-1 Deploy the ACK service controller for SQS using the sqs-chart Helm chart: RELEASE_VERSION_SQS_ACK=$(curl -sL "https://api.github.com/repos/aws-controllers-k8s/sqs-controller/releases/latest" | grep '"tag_name":' | cut -d'"' -f4) helm install --create-namespace -n ack-system oci://public.ecr.aws/aws-controllers-k8s/sqs-chart "--version=${RELEASE_VERSION_SQS_ACK}" --generate-name --set=aws.region=us-east-1 Deploy the ACK service controller for DynamoDB using the dynamodb-chart Helm chart: RELEASE_VERSION_DYNAMODB_ACK=$(curl -sL "https://api.github.com/repos/aws-controllers-k8s/dynamodb-controller/releases/latest" | grep '"tag_name":' | cut -d'"' -f4) helm install --create-namespace -n ack-system oci://public.ecr.aws/aws-controllers-k8s/dynamodb-chart "--version=${RELEASE_VERSION_DYNAMODB_ACK}" --generate-name --set=aws.region=us-east-1 Now, it's time to configure the IAM permissions for the controller to invoke Lambda, DynamoDB, and SQS. Configure IAM Permissions Create an OIDC Identity Provider for Your Cluster For the steps below, replace the EKS_CLUSTER_NAME and AWS_REGION variables with your cluster name and region. export EKS_CLUSTER_NAME=demo-eks-cluster export AWS_REGION=us-east-1 eksctl utils associate-iam-oidc-provider --cluster $EKS_CLUSTER_NAME --region $AWS_REGION --approve OIDC_PROVIDER=$(aws eks describe-cluster --name $EKS_CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f2- | cut -d '/' -f2-) Create IAM Roles for Lambda, SQS, and DynamoDB ACK Service Controllers ACK Lambda Controller Set the following environment variables: ACK_K8S_SERVICE_ACCOUNT_NAME=ack-lambda-controller ACK_K8S_NAMESPACE=ack-system AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) Create the trust policy for the IAM role: read -r -d '' TRUST_RELATIONSHIP <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "${OIDC_PROVIDER}:sub": "system:serviceaccount:${ACK_K8S_NAMESPACE}:${ACK_K8S_SERVICE_ACCOUNT_NAME}" } } } ] } EOF echo "${TRUST_RELATIONSHIP}" > trust_lambda.json Create the IAM role: ACK_CONTROLLER_IAM_ROLE="ack-lambda-controller" ACK_CONTROLLER_IAM_ROLE_DESCRIPTION="IRSA role for ACK lambda controller deployment on EKS cluster using Helm charts" aws iam create-role --role-name "${ACK_CONTROLLER_IAM_ROLE}" --assume-role-policy-document file://trust_lambda.json --description "${ACK_CONTROLLER_IAM_ROLE_DESCRIPTION}" Attach IAM policy to the IAM role: # we are getting the policy directly from the ACK repo INLINE_POLICY="$(curl https://raw.githubusercontent.com/aws-controllers-k8s/lambda-controller/main/config/iam/recommended-inline-policy)" aws iam put-role-policy \ --role-name "${ACK_CONTROLLER_IAM_ROLE}" \ --policy-name "ack-recommended-policy" \ --policy-document "${INLINE_POLICY}" Attach ECR permissions to the controller IAM role. These are required since Lambda functions will be pulling images from ECR. aws iam put-role-policy \ --role-name "${ACK_CONTROLLER_IAM_ROLE}" \ --policy-name "ecr-permissions" \ --policy-document file://ecr-permissions.json Associate the IAM role to a Kubernetes service account: ACK_CONTROLLER_IAM_ROLE_ARN=$(aws iam get-role --role-name=$ACK_CONTROLLER_IAM_ROLE --query Role.Arn --output text) export IRSA_ROLE_ARN=eks.amazonaws.com/role-arn=$ACK_CONTROLLER_IAM_ROLE_ARN kubectl annotate serviceaccount -n $ACK_K8S_NAMESPACE $ACK_K8S_SERVICE_ACCOUNT_NAME $IRSA_ROLE_ARN Repeat the steps for the SQS controller. ACK SQS Controller Set the following environment variables: ACK_K8S_SERVICE_ACCOUNT_NAME=ack-sqs-controller ACK_K8S_NAMESPACE=ack-system AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) Create the trust policy for the IAM role: read -r -d '' TRUST_RELATIONSHIP <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "${OIDC_PROVIDER}:sub": "system:serviceaccount:${ACK_K8S_NAMESPACE}:${ACK_K8S_SERVICE_ACCOUNT_NAME}" } } } ] } EOF echo "${TRUST_RELATIONSHIP}" > trust_sqs.json Create the IAM role: ACK_CONTROLLER_IAM_ROLE="ack-sqs-controller" ACK_CONTROLLER_IAM_ROLE_DESCRIPTION="IRSA role for ACK sqs controller deployment on EKS cluster using Helm charts" aws iam create-role --role-name "${ACK_CONTROLLER_IAM_ROLE}" --assume-role-policy-document file://trust_sqs.json --description "${ACK_CONTROLLER_IAM_ROLE_DESCRIPTION}" Attach IAM policy to the IAM role: # for sqs controller, we use the managed policy ARN instead of the inline policy (unlike the Lambda controller) POLICY_ARN="$(curl https://raw.githubusercontent.com/aws-controllers-k8s/sqs-controller/main/config/iam/recommended-policy-arn)" aws iam attach-role-policy --role-name "${ACK_CONTROLLER_IAM_ROLE}" --policy-arn "${POLICY_ARN}" Associate the IAM role to a Kubernetes service account: ACK_CONTROLLER_IAM_ROLE_ARN=$(aws iam get-role --role-name=$ACK_CONTROLLER_IAM_ROLE --query Role.Arn --output text) export IRSA_ROLE_ARN=eks.amazonaws.com/role-arn=$ACK_CONTROLLER_IAM_ROLE_ARN kubectl annotate serviceaccount -n $ACK_K8S_NAMESPACE $ACK_K8S_SERVICE_ACCOUNT_NAME $IRSA_ROLE_ARN Repeat the steps for the DynamoDB controller. ACK DynamoDB Controller Set the following environment variables: ACK_K8S_SERVICE_ACCOUNT_NAME=ack-dynamodb-controller ACK_K8S_NAMESPACE=ack-system AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) Create the trust policy for the IAM role: read -r -d '' TRUST_RELATIONSHIP <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "${OIDC_PROVIDER}:sub": "system:serviceaccount:${ACK_K8S_NAMESPACE}:${ACK_K8S_SERVICE_ACCOUNT_NAME}" } } } ] } EOF echo "${TRUST_RELATIONSHIP}" > trust_dynamodb.json Create the IAM role: ACK_CONTROLLER_IAM_ROLE="ack-dynamodb-controller" ACK_CONTROLLER_IAM_ROLE_DESCRIPTION="IRSA role for ACK dynamodb controller deployment on EKS cluster using Helm charts" aws iam create-role --role-name "${ACK_CONTROLLER_IAM_ROLE}" --assume-role-policy-document file://trust_dynamodb.json --description "${ACK_CONTROLLER_IAM_ROLE_DESCRIPTION}" Attach IAM policy to the IAM role: # for dynamodb controller, we use the managed policy ARN instead of the inline policy (like we did for Lambda controller) POLICY_ARN="$(curl https://raw.githubusercontent.com/aws-controllers-k8s/dynamodb-controller/main/config/iam/recommended-policy-arn)" aws iam attach-role-policy --role-name "${ACK_CONTROLLER_IAM_ROLE}" --policy-arn "${POLICY_ARN}" Associate the IAM role to a Kubernetes service account: ACK_CONTROLLER_IAM_ROLE_ARN=$(aws iam get-role --role-name=$ACK_CONTROLLER_IAM_ROLE --query Role.Arn --output text) export IRSA_ROLE_ARN=eks.amazonaws.com/role-arn=$ACK_CONTROLLER_IAM_ROLE_ARN kubectl annotate serviceaccount -n $ACK_K8S_NAMESPACE $ACK_K8S_SERVICE_ACCOUNT_NAME $IRSA_ROLE_ARN Restart ACK Controller Deployments and Verify the Setup Restart the ACK service controller Deployment using the following commands. It will update service controller Pods with IRSA environment variables. Get list of ACK service controller deployments: export ACK_K8S_NAMESPACE=ack-system kubectl get deployments -n $ACK_K8S_NAMESPACE Restart Lambda, SQS, and DynamoDB controller Deployments: DEPLOYMENT_NAME_LAMBDA=<enter deployment name for lambda controller> kubectl -n $ACK_K8S_NAMESPACE rollout restart deployment $DEPLOYMENT_NAME_LAMBDA DEPLOYMENT_NAME_SQS=<enter deployment name for sqs controller> kubectl -n $ACK_K8S_NAMESPACE rollout restart deployment $DEPLOYMENT_NAME_SQS DEPLOYMENT_NAME_DYNAMODB=<enter deployment name for dynamodb controller> kubectl -n $ACK_K8S_NAMESPACE rollout restart deployment $DEPLOYMENT_NAME_DYNAMODB List Pods for these Deployments. Verify that the AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN environment variables exist for your Kubernetes Pod using the following commands: kubectl get pods -n $ACK_K8S_NAMESPACE LAMBDA_POD_NAME=<enter Pod name for lambda controller> kubectl describe pod -n $ACK_K8S_NAMESPACE $LAMBDA_POD_NAME | grep "^\s*AWS_" SQS_POD_NAME=<enter Pod name for sqs controller> kubectl describe pod -n $ACK_K8S_NAMESPACE $SQS_POD_NAME | grep "^\s*AWS_" DYNAMODB_POD_NAME=<enter Pod name for dynamodb controller> kubectl describe pod -n $ACK_K8S_NAMESPACE $DYNAMODB_POD_NAME | grep "^\s*AWS_" Now that the ACK service controller has been set up and configured, you can create AWS resources! Create SQS Queue, DynamoDB Table, and Deploy the Lambda Function Create SQS Queue In the file sqs-queue.yaml, replace the us-east-1 region with your preferred region as well as the AWS account ID. This is what the ACK manifest for the SQS queue looks like: apiVersion: sqs.services.k8s.aws/v1alpha1 kind: Queue metadata: name: sqs-queue-demo-ack annotations: services.k8s.aws/region: us-east-1 spec: queueName: sqs-queue-demo-ack policy: | { "Statement": [{ "Sid": "__owner_statement", "Effect": "Allow", "Principal": { "AWS": "AWS_ACCOUNT_ID" }, "Action": "sqs:SendMessage", "Resource": "arn:aws:sqs:us-east-1:AWS_ACCOUNT_ID:sqs-queue-demo-ack" }] } Create the queue using the following command: kubectl apply -f sqs-queue.yaml # list the queue kubectl get queue Create DynamoDB Table This is what the ACK manifest for the DynamoDB table looks like: apiVersion: dynamodb.services.k8s.aws/v1alpha1 kind: Table metadata: name: customer annotations: services.k8s.aws/region: us-east-1 spec: attributeDefinitions: - attributeName: email attributeType: S billingMode: PAY_PER_REQUEST keySchema: - attributeName: email keyType: HASH tableName: customer You can replace the us-east-1 region with your preferred region. Create a table (named customer) using the following command: kubectl apply -f dynamodb-table.yaml # list the tables kubectl get tables Build Function Binary and Create Docker Image GOARCH=amd64 GOOS=linux go build -o main main.go aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws docker build -t demo-sqs-dynamodb-func-ack . Create a private ECR repository, tag and push the Docker image to ECR: AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com aws ecr create-repository --repository-name demo-sqs-dynamodb-func-ack --region us-east-1 docker tag demo-sqs-dynamodb-func-ack:latest $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/demo-sqs-dynamodb-func-ack:latest docker push $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/demo-sqs-dynamodb-func-ack:latest Create an IAM execution Role for the Lambda function and attach the required policies: export ROLE_NAME=demo-sqs-dynamodb-func-ack-role ROLE_ARN=$(aws iam create-role \ --role-name $ROLE_NAME \ --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}' \ --query 'Role.[Arn]' --output text) aws iam attach-role-policy --role-name $ROLE_NAME --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Since the Lambda function needs to write data to DynamoDB and invoke SQS, let's add the following policies to the IAM role: aws iam put-role-policy \ --role-name "${ROLE_NAME}" \ --policy-name "dynamodb-put" \ --policy-document file://dynamodb-put.json aws iam put-role-policy \ --role-name "${ROLE_NAME}" \ --policy-name "sqs-permissions" \ --policy-document file://sqs-permissions.json Create the Lambda Function Update function.yaml file with the following info: imageURI - The URI of the Docker image that you pushed to ECR, e.g., <AWS_ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com/demo-sqs-dynamodb-func-ack:latest role - The ARN of the IAM role that you created for the Lambda function, e.g., arn:aws:iam::<AWS_ACCOUNT_ID>:role/demo-sqs-dynamodb-func-ack-role This is what the ACK manifest for the Lambda function looks like: apiVersion: lambda.services.k8s.aws/v1alpha1 kind: Function metadata: name: demo-sqs-dynamodb-func-ack annotations: services.k8s.aws/region: us-east-1 spec: architectures: - x86_64 name: demo-sqs-dynamodb-func-ack packageType: Image code: imageURI: AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/demo-sqs-dynamodb-func-ack:latest environment: variables: TABLE_NAME: customer role: arn:aws:iam::AWS_ACCOUNT_ID:role/demo-sqs-dynamodb-func-ack-role description: A function created by ACK lambda-controller To create the Lambda function, run the following command: kubectl create -f function.yaml # list the function kubectl get functions Add SQS Trigger Configuration Add SQS trigger which will invoke the Lambda function when an event is sent to the SQS queue. Here is an example using AWS Console: Open the Lambda function in the AWS Console and click on the Add trigger button. Select SQS as the trigger source, select the SQS queue, and click on the Add button. Now you are ready to try out the end-to-end solution! Test the Application Send a few messages to the SQS queue. For the purposes of this demo, you can use the AWS CLI: export SQS_QUEUE_URL=$(kubectl get queues/sqs-queue-demo-ack -o jsonpath='{.status.queueURL}') aws sqs send-message --queue-url $SQS_QUEUE_URL --message-body user1@foo.com --message-attributes 'name={DataType=String, StringValue="user1"}, city={DataType=String,StringValue="seattle"}' aws sqs send-message --queue-url $SQS_QUEUE_URL --message-body user2@foo.com --message-attributes 'name={DataType=String, StringValue="user2"}, city={DataType=String,StringValue="tel aviv"}' aws sqs send-message --queue-url $SQS_QUEUE_URL --message-body user3@foo.com --message-attributes 'name={DataType=String, StringValue="user3"}, city={DataType=String,StringValue="new delhi"}' aws sqs send-message --queue-url $SQS_QUEUE_URL --message-body user4@foo.com --message-attributes 'name={DataType=String, StringValue="user4"}, city={DataType=String,StringValue="new york"}' The Lambda function should be invoked and the data should be written to the DynamoDB table. Check the DynamoDB table using the CLI (or AWS console): aws dynamodb scan --table-name customer Clean Up After you have explored the solution, you can clean up the resources by running the following commands: Delete SQS queue, DynamoDB table and the Lambda function: kubectl delete -f sqs-queue.yaml kubectl delete -f function.yaml kubectl delete -f dynamodb-table.yaml To uninstall the ACK service controllers, run the following commands: export ACK_SYSTEM_NAMESPACE=ack-system helm ls -n $ACK_SYSTEM_NAMESPACE helm uninstall -n $ACK_SYSTEM_NAMESPACE <enter name of the sqs chart> helm uninstall -n $ACK_SYSTEM_NAMESPACE <enter name of the lambda chart> helm uninstall -n $ACK_SYSTEM_NAMESPACE <enter name of the dynamodb chart> Conclusion and Next Steps In this post, we have seen how to use AWS Controllers for Kubernetes to create a Lambda function, SQS, and DynamoDB table and wire them together to deploy a solution. All of this (almost) was done using Kubernetes! I encourage you to try out other AWS services supported by ACK. Here is a complete list. Happy building! More
Fargate vs. Lambda: The Battle of the Future

Fargate vs. Lambda: The Battle of the Future

By William Talluri
Fargate vs. Lambda has recently been a trending topic in the serverless space. Fargate and Lambda are two popular serverless computing options available within the AWS ecosystem. While both tools offer serverless computing, they differ regarding use cases, operational boundaries, runtime resource allocations, price, and performance. This blog aims to take a deeper look into the Fargate vs. Lambda battle. What Is AWS Fargate? AWS Fargate is a serverless computing engine offered by Amazon that enables you to efficiently manage containers without the hassles of provisioning servers and the underlying infrastructure. When cluster capacity management, infrastructure management, patching, and provisioning resource tasks are removed, you can finally focus on delivering faster and better quality applications. AWS Fargate works with Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS), supporting a range of container use cases such as machine learning applications, microservices architecture apps, on-premise app migration to the cloud, and batch processing tasks. Without AWS Fargate Developers build container images Define EC2 instances and deploy them Provision memory and compute resources and manage them Create separate VMs to isolate applications Run and manage applications Run and manage the infrastructure Pay EC2 instances usage charges When AWS Fargate Is Implemented Developers build container images Define compute and memory resources Run and manage apps Pay compute resource usage charges In the Fargate vs. Lambda context, Fargate is the serverless compute option in AWS used when you already have containers for your application and simply want to orchestrate them easier and faster. It works with Elastic Kubernetes Service (EKS) as well as Elastic Container Service (ECS). EKS and ECS have two types of computing options: 1. EC2 type: With this option, you need to deal with the complexity of configuring Instances/Servers. This can be a challenge for inexperienced users. You must set up your EC2 instances and put containers inside the servers with some help from the ECS or EKS configurations. 2. Fargate type: This option allows you to reduce the server management burden while easily updating and increasing the configuration limits required to run Fargate. What Is Serverless? Before delving deep into the serverless computing battle of Lambda vs. Fargate or Fargate vs. Lambda, it’s important first to gain a basic understanding of the serverless concept. Serverless computing is a technology that enables developers to run applications without needing to provision server infrastructure. The cloud provider will provide the backend infrastructure on-demand and charge you according to a pay-as-you-go model. The term “serverless” might be misleading for some people. Indeed, it’s important to note that serverless technology doesn’t imply the absence of servers. Rather, the cloud provider will manage the server infrastructure with this technology, allowing developers to concentrate their efforts on an app’s front-end code and logic. Resources are spun when the code executes a function and terminates when the function stops. Billing is based on the duration of the execution time of the resources. Therefore, operational costs are optimized because you don’t pay for idle resources. With serverless technology, you can say goodbye to capacity planning, administrative burdens, and maintenance. Furthermore, you can enjoy high availability and disaster recovery at zero cost. Auto-scaling to zero is also available. Finally, resource utilization is 100%, and billing is done granularly, measuring 100 milliseconds as a unit. What Is AWS Lambda? AWS Lambda is an event-driven serverless computing service. Lambda runs predefined code in response to an event or action, enabling developers to perform serverless computing. This cross-platform was developed by Amazon and first released in 2014. It supports major programming languages such as C#, Python, Java, Ruby, Go, and Node.js. It also supports custom runtime. Some of the popular use cases of Lambda include updating a DynamoDB table, uploading data to S3 buckets, and running events in response to IoT sensor data. The pricing is based on milliseconds of usage, rounding off to the nearest millisecond. Moreover, Lambda allows you to manage Docker containers of sizes up to 50 GB via ECR. When you compare Fargate vs. Lambda, Fargate is for containerized applications running for days, weeks, or years. Lambda is designed specifically to handle small portions of an application, such as a function. For instance, a function that clears the cache every 6 hours and lasts for 30 seconds can be executed using Lambda. A Typical AWS Lambda Architecture AWS Lambda is a Function-as-a-Service (FaaS) that helps developers build event-driven apps. In the app’s compute layer, Lambda triggers AWS events. What are the three core components of Lambda architecture? 1) Function: A function is a piece of code written by developers to perform a task. The code also contains the details of the runtime environment of the function. The runtime environments are based on Amazon Linux AMI and contain all required libraries and packages. Capacity and maintenance are handled by AWS. a. Code Package: The packaged code containing the binaries and assets required for the code to run. The maximum size is 250 MB or 50 MB in a compressed version. b. Handler: The starting point of the invoked function running a task based on parameters provided by event objects. c. Event Object: A parameter provided to the Handler to perform the logic for an operation. d. Context Object: Facilitates interaction between the function code and the execution environment. The data available for Context Objects include: i. AWS Request ID ii. Remaining time for the function to time out iii. Logging statements to CloudWatch 2) Configuration: Rules that specify how a function is executed. a. IAM Roles: Assigns permissions for functions to interact with AWS services. b. Network Configuration: Specifies rules to run functions inside a VPC or outside a VPC. c. Version: Reverts functions to previous versions. d. Memory Dial: Controls resource allocations to functions. e. Environment Variables: Values injected into the code during the runtime. f. Timeout: Time for a function to run. 3) Event Source: The event that triggers the function. a. Push Model: Functions triggered via S3 objects, API Gateway and Amazon Alexa. b. Pull Model: Lambda pulls events from DynamoDB or Kinesis. A Typical AWS Fargate Architecture What are the four core components of the AWS Fargate architecture? 1) Task Definition: A JSON file that describes definitions for at least one of the application containers. 2) Task: Instantiation of a task definition at a cluster level. 3) Cluster: Tasks or services logically grouped in Amazon ECS. 4) Service: A process that runs tasks in Amazon ECS cluster based on task definitions. Fargate vs Lambda: Performance As far as performance is concerned in the AWS Fargate vs. Lambda debate, AWS Fargate is the winner, as it runs on dedicated resources. Lambda has certain limitations when it comes to allocating computing and memory resources. Based on the selected amount of RAM, AWS allocates the corresponding CPU resources meaning that the user cannot customize CPU resources. Moreover, the maximum available memory for Lambda functions is 10 GB, whereas Fargate allows for 120 GB of memory. Furthermore, Fargate allows you to choose up to 16 vCPU resources. Another notable issue is that a Lambda function only has a run time of 15 minutes for every invocation. On the other hand, in the absence of runtime limitations, the Fargate environment is always in a warm state. Fargate functions must be packaged into containers, increasing the load time to around 60 seconds. This is a very long time compared to Lambda functions which can get started within 5 seconds. Fargate allows you to launch 20 tasks per second using ECS RunTask API. Moreover, you can launch 500 tasks per service in 120 seconds with ECS Service Scheduler. That said, scaling the environment during unexpected spike requests and health monitoring tends to cause a bit of a delay in start-up time. Lambda Cold Starts When Lambda receives a request to execute a task, it starts by downloading the code from S3 buckets and creating an execution environment based on the predefined memory and its corresponding compute resources. If there is any initialization code, Lambda runs it outside the environment and then runs the handler code. The time required for downloading the code and preparing the execution environment is counted as the cold start duration. After executing the code, Lambda freezes the environment so that the same function can run quickly if invoked again. If you run the function concurrently, each invocation gets a cold start. There will also be a code start if the code is updated. The typical time for cold starts falls between 100 ms and 1 second. In light of the foregoing, Lambda falls short in the Lambda vs. Fargate race regarding cold starts. However, Provisioned Concurrency is a solution to reduce cold starts. The runtime choice will also have an impact on Lambda cold starts. For instance, Java runtime involves multiple resources to run the JVM environment, which delays the start. On the other hand, C# or Node.js runtime environments offer lower latencies. Fargate Cold Starts Fargate takes time to provision resources and starts a task. Once the environment is up and running, containers get dedicated resources and run the code as defined. Fargate vs. Lambda: Support AWS Fargate works as an operational layer of a serverless computing architecture to manage Docker-based ECS or Kubernetes-based EKS environments. For ECS, you can define container tasks in text files using JSON. There is support for other runtime environments as well. Fargate offers more capacity deployment control than Lambda, as Lambda is limited to 10GB of space and 10GB of package size for container images and 250 MB for deployments to S3 buckets. Lambda supports all major programming languages, such as Python, Go, Ruby, PHP, C#, Node.js, and Java, and code compilation tools, such as Maven and Gradle. That said, Lambda only supports Linux-based container images. With Fargate, you can develop Docker container images locally using Docker Compose and run them in Fargate without worrying about compatibility issues. Since development and architecture is independent of Fargate, it outperforms Lambda in this particular category. When more control over the container environment is the key requirement, AWS Fargate is definitely the right choice. Fargate vs. Lambda: Costs When comparing Fargate vs. Lambda costs, it is important to note that both tools serve different purposes. While Lambda is a Function-as-a-Service, Fargate is a serverless computing tool for container-based workloads. Lambda costs are billed in milliseconds. AWS Lambda charges $0.20 per 1 Million requests with $0.0000166667 for every GB-second duration for the first 6 Billion GB-seconds / month. The duration costs vary based on the allocated memory. For instance, 128 MB memory costs you $0.0000000021 per ms, and 10 GB memory costs you $0.0000001667 per ms. For example, consider 10 GB of memory with 6 vCPU and concurrency, which is always running. The monthly cost for the foregoing would be $432.50. If the concurrency is two, the price is doubled. If the environment runs half the day, the price gets divided by two. If it’s running for 10 minutes per day, the cost would be $9.10 per month. If you consider the same configuration in Fargate, the prices are drastically lower. Fargate charges a flat rate of $0.04048 per vCPU per hour ($29.145 per month) $0.004445 per GB per hour ($3.20 per month) So, a 10 GB memory with 6 vCPUs running continuously for a month with concurrency one would cost $206.87. Moreover, Fargate separates CPUs from memory, allowing you to choose the right-sized configuration. Therefore, you can save costs by reducing the CPUs depending on your needs. When you consider a concurrency of 10, the difference increases exponentially. Another advantage of Fargate is the spot pricing which offers an additional 30% savings. Notice that Lambda costs are lower than Fargate when the idle time is greater. In light of the foregoing, we can conclude that Lambda is more suitable for workloads that are idle for long periods. Lambda is cost-effective if the resources are idle for a quarter or less of the time. Lambda is the best choice to scale fast or isolate security from an app code. Contrastingly, Fargate suits cloud environments with minimally idle workloads. We think the best option is to implement Infrastructure as Code (IaC) and begin with Lambda. When workloads increase, you can seamlessly switch to Fargate. Fargate vs. Lambda: Easy to Work Lambda is easy to set up and operate as there are minimal knobs to adjust compared to Fargate. More abstraction implies less operational burden. However, it also implies limited flexibility. Lambda comes with a rich ecosystem that offers fully automated administration. You can use the management console or the API to call and control functions synchronously or asynchronously, including concurrency. The runtime supports a common set of functionalities and allows you to switch between different frameworks and languages. As far as operational burdens go, Lambda is easier compared to EC2. Fargate stands between Lambda and EC2 in this category, leaning closer towards Lambda. That said, EC2 offers more flexibility in configuring and operating the environment, followed by Fargate and Lambda. Fargate vs Lambda: Community Both AWS Fargate and Lambda are a part of the AWS serverless ecosystem. As such, both tools enjoy the same level of community support. Both services offer adequate support for new and advanced users, from documentation and how-to guides to tutorials and FAQs. Fargate vs Lambda: Cloud Agnostic Each cloud vendor manages serverless environments differently. For instance, C# functions written for AWS will not work on the Google Cloud. In light of the foregoing, developers need to consider cloud-agnostic issues if multi-cloud and hybrid-cloud architectures are involved. Moving between different cloud vendors involves considerable expenses and operational impacts. As such, vendor lock-in is a big challenge for serverless functions. To overcome this, we suggest using an open-source serverless framework offered by Serverless Inc. Moreover, implementing hexagonal architecture is a good idea because it allows you to move code between different serverless cloud environments. Fargate vs Lambda: Scalability In terms of Lambda vs Fargate scalability, Lambda is known as one of the best scaling technologies available in today’s market. Rapid scaling and scaling to zero are the two key strengths of Lambda. The tool instantly scales from zero to thousands and scales down from 1000 to 0, making it a good choice for low workloads, test environments, and workloads with unexpected traffic spikes. As far as Fargate is concerned, container scaling depends on resizing the underlying clusters. Furthermore, it doesn’t natively scale down to zero. Therefore, you’ll have to shut down Fargate tasks outside business hours to save on operational costs. Tasks such as configuring auto-scaling and updating base container images add up when it comes to maintenance. Fargate vs. Lambda: Security Lambda and Fargate are inherently secure as part of the AWS ecosystem. You can secure the environment using the AWS Identity and Access Management (IAM) service. Similarly, both tools abstract away the underlying infrastructure, which means the security of the infrastructure is managed by other services. The difference between the two tools lies in the IAM configuration. Lambda allows you to customize IAM roles for each function or service, while Fargate customizes each container and pod. Fargate tasks run in an isolated computing environment wherein CPU or memory is not shared with other tasks. Similarly, Lambda functions run in a dedicated execution environment. Also, Fargate offers more control over the environment and more secure touchpoints than Lambda. When to Use Fargate or Lambda? AWS Lambda Use Cases: Operating serverless websites Massively scaling operations Real-time processing of high volumes of data Predictive page rendering Scheduled events for every task and data backup Parse user input and cleanup backend data to increase a website’s rapid response time Analyzing log data on-demand Integrating with external services Converting documents into the user-requested format on-demand Real-Life Lambda Use Cases Serverless Websites: Bustle One of the best use cases for Lambda is operating serverless websites. By hosting frontend apps on S3 buckets and using CloudFront content delivery, organizations can manage static websites and take advantage of the Lambda pricing model. Bustle is a news, entertainment, and fashion website for women. The company was having difficulties scaling its application. In addition, server management, monitoring, and automation was becoming an important administrative burden. The company, therefore, decided to move to AWS Lambda with API Gateway and Amazon Kinesis to run serverless websites. Now, the company doesn’t have to worry about scaling, and its developers can deploy code at an extremely low cost. Event-driven Model for Workloads With Idle Times: Thomson Reuters Companies that manage workloads that are idle most of the time can benefit from the Lambda serverless feature. A notable example is Thomson Reuters, one of the world’s most trusted news organizations. The company wanted to build its own analytics engine. The small team working on this project desired a lessened administrative burden. At the same time, the tool needed to scale elastically during breaking news. Reuters chose Lambda. The tool receives data from Amazon Kinesis and automatically loads this data in a master dataset in an S3 bucket. Lambda is triggered with data integrations with Kinesis and S3. As such, Reuters enjoyed high scalability at the lowest cost possible. Highly Scalable Real-time Processing Environment: Realtor.com AWS Lambda enables organizations to scale resources while instantly cost-effectively processing tasks in real-time. Realtor.com is a leader in the real estate market. After the move to the digital world, the company started experiencing exponential traffic growth. Furthermore, the company needed a solution to update ad listings in real-time. Realtor.com chose AWS for its cloud operations. The company uses Amazon Kinesis Data Streams to collect and stream ad impressions. The internal billing system consumes this data using Amazon Kinesis Firehose, and the aggregate data is sent to the Amazon Redshift data warehouse for analysis. The application uses AWS Lambda to read Kinesis Data Streams and process each event. Realtor.com is now able to massively scale operations cost-effectively while making changes to ad listings in real-time. AWS Fargate Use Cases AWS Fargate is the best choice for managing container-based workloads with minimal idle times. Build, run, and manage APIs, microservices, and applications using containers to enjoy speed and immutability Highly scalable container-based data processing workloads Migrate legacy apps running on EC2 instances without refactoring or rearchitecting them Build and manage highly scalable AI and ML development environments Real-Life Use Cases Samsung Samsung is a leader in the electronics category. The company operates an online portal called “Samsung Developers,” which consists of SmartThings Portal for the Internet of Things (IoT), Bixby Portal for voice-based control of mobile services, and Rich Communication Services (RCS) for mobile messaging. The company was using Amazon ECS to manage the online portal. After the re: Invent 2017 event, Samsung was inspired to implement Fargate for operational efficiency. After migrating to AWS Fargate, the company no longer needed dedicated operators and administrators to manage the web services of the portal. Now, geographically distributed teams simply have to create new container images uploaded to ECR and moved to the test environment on Fargate. Developers can therefore focus more on code, and frequent deployments and administrators can focus more on performance and security. Compute costs were downsized by 44.5%. Quola Insurtech Startup Quola is a Jakarta-based insurance technology startup. The company developed software that automates claim processing using AI and ML algorithms to eliminate manual physical reviews. Quola chose AWS cloud and Fargate to run and manage container-based workloads. Amazon Simple Queue Service (SQS) is used for the message-queuing service. With Fargate, Quola is able to scale apps seamlessly. When a new partner joined the network, data transactions increased from 10,000 to 100,000 in a single day. Nevertheless, the app was able to scale instantly without performance being affected. Vanguard Financial Services Vanguard is a leading provider of financial services in the US. The company moved its on-premise operations to the AWS cloud in 2015 and now manages 1000 apps that run on microservices architecture. With security being a key requirement in the financial industry, Vanguard operates in the secure environment of Fargate. With Fargate, the company could offer seamless computing capacity to its containers and reduce costs by 50%. Considerations When Moving to a Serverless Architecture Inspired by the amazing benefits of serverless architecture, many businesses are aggressively embracing the serverless computing model. Here are the steps to migrate monolith and legacy apps to a serverless architecture. a) Monolith to Microservices: Most legacy apps are built using a monolith architecture. When such is the case, the first step is to break the large into smaller and modular microservices, after which each microservice will perform a specific task or function. b) Implement each Microservice as a REST API: The next step is identifying the best fit within these microservices. Implement each microservice as a REST API with API endpoints as resources. Amazon API Gateway is a fully managed service that can help you. c) Implement a Serverless Compute Engine: Implement a serverless compute engine such as Lambda or Fargate and move the business logic to the serverless tool such that AWS provisions resources every time a function is invoked. d) Staggered Deployment Strategy: Migrating microservices to the serverless architecture can be done in a staggered process. Identify the right services and then build, test, and deploy them. Continue this process to smoothly and seamlessly move the entire application to the new architecture. Considerations for Moving to Amazon Lambda Migrating legacy apps to Lambda is not a difficult job. If your application is written in any Lambda-supported languages, you can simply refactor the code and migrate the app to Lambda. You simply need to make some fundamental changes, such as changing the dependency on local storage to S3 or updating authentication modules. When Fargate vs. Lambda security is considered, Lambda has fewer touchpoints to secure than Fargate. If you are using Java runtime, keep in mind that the size of the runtime environment and resources can result in more cold starts than with Node.js or C#. Another key point to consider is memory allocation. Currently, Lambda’s maximum memory allocation is 3 GB. If your application requires more computing and memory resources, Fargate is a better choice. Considerations for Moving to AWS Fargate While AWS manages resource provisioning, customers still need to handle network security tasks. For instance, when a task is created, AWS creates an Elastic Network Interface (ENI) in the VPC and automatically attaches each task ENI to its corresponding subnet. Therefore, managing the connectivity between the ENI and its touch points is the customer’s sole responsibility. More specifically, you need to manage ENI access to AWS EC2, CloudWatch, Apps running on-premise or other regions, Egress, Ingress, etc. Moreover, audit and compliance aspects must be carefully managed, which is why Fargate is not preferred for highly regulated environments. Conclusion The Fargate vs Lambda battle is getting more and more interesting as the gap between container-based and serverless systems is getting smaller with every passing day. There is no silver bullet when deciding which service is the best. With the new ability to deploy Lambda functions as Docker container images, more organizations seem to lean towards Lambda. On the other hand, organizations that need more control over the container runtime environment are sticking with Fargate. More
The Power of Docker Images: A Comprehensive Guide to Building From Scratch
The Power of Docker Images: A Comprehensive Guide to Building From Scratch
By Ruchita Varma
Orchestration Pattern: Managing Distributed Transactions
Orchestration Pattern: Managing Distributed Transactions
By Gaurav Gaur CORE
Stop Using Spring Profiles Per Environment
Stop Using Spring Profiles Per Environment
By Bukaj Sytlos
Unlock the Full Potential of Git
Unlock the Full Potential of Git

Git is one of the most popular version control systems used by developers worldwide. As a software developer, you must be well-versed in Git and its commands to manage code efficiently, collaborate with other team members, and keep track of changes. While there are many Git commands available, not all are equally important. In this article, I’ll cover the top Git commands that every senior-level developer should know. “A Git pull a day keeps the conflicts away” Git Init The git init command initializes a new Git repository. This command is used to start tracking changes in your project. As soon as you run this command, Git creates a new .git directory, which contains all the necessary files to start using Git for version control. Once initialized, Git tracks all changes made to your code and creates a history of your commits. Shell $ git init Initialized empty Git repository in /path/to/repository/.git/ Git Clone The git clone command creates a copy of a remote Git repository on your local machine. This is a great way to start working on a new project or to collaborate with others on existing projects. When you run this command, Git downloads the entire repository, including all branches and history, to your local machine. Shell $ git clone https://github.com/username/repository.git Git Add The git add command adds new or modified files to the staging area, which prepares them to be committed. The staging area is a temporary storage area where you can prepare your changes before committing them. You can specify individual files or directories with this command. Git tracks changes in three stages — modified, staged, and committed. The add command moves changes from the modified stage to the staged stage. To add all changes in the current directory to the staging area, run: Shell $ git add file.txt Shell git add . Git Commit The git commit command creates a new commit with the changes you've added to the staging area. A commit is a snapshot of your repository at a specific point in time, and each commit has a unique identifier. The git commit command records changes to the repository. A commit includes a commit message that describes the changes made. To commit changes to the repository, run the following command: Shell $ git commit -m "Added new feature" Git Status The git status command shows you the current state of your repository, including any changes that have been made and which files are currently staged for commit. It tells you which files are modified, which files are staged, and which files are untracked. Shell $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: file.txt Git Log The git log command shows you the history of all the commits that have been made to your repository. You can use this command to see who made changes to the repository and when those changes were made along with their author, date, and commit message. Shell $ git log commit 5d5b5e5dce7d1e09da978c8706fb3566796e2f22 Author: John Doe <john.doe@example.com> Date: Tue Mar 23 14:39:51 2023 -0400 Added new feature git log --graph: Displays the commit history in a graph format. git log --oneline: Shows the commit history in a condensed format. git log --follow: Follows the history of a file beyond renames. Git Diff The git diff command shows you the differences between the current version of a file and the previous version. This command is useful when you want to see what changes were made to a file. When you run this command, Git shows you the changes that were made between two commits or between a commit and your current working directory. This will show you the differences between the current branch and the “feature_branch” branch. Shell $ git diff feature_branch Git Branch The git branch command shows you a list of all the branches in the Git repository. You can use this command to see which branch you are currently on and to create new branches. This command is used to create, list, or delete branches. Shell $ git branch feature-1 Git Checkout The git checkout command is used to switch between branches. You can use this command to switch to a different branch or to create a new branch. Shell $ git checkout feature-1 Git Merge The git merge command is used to merge changes from one branch into another. This command is useful when you want to combine changes from different branches. When you run this command, Git combines the changes from two branches and creates a new commit. Shell $ git merge feature-1 Git Pull The git pull command is used to update your local repository with changes from a remote repository. This command is used to download changes from a remote repository and merge them into your current branch. When you run this command, Git combines the changes from the remote repository with your local changes and creates a new commit. Shell $ git pull origin master Git Push The git push command is used to push your changes to a remote repository. This command is useful when you want to share your changes with others. When you run this command, Git sends your commits to the remote repository and updates the remote branch. Shell $ git push origin master Git Remote This command is used to manage the remote repositories that your Git repository is connected to. It allows you to add, rename, or remove remote repositories. git remote rm: Removes a remote repository. git remote show: Shows information about a specific remote repository. git remote rename: Renames a remote repository. Git Fetch This command is used to download changes from a remote repository to your local repository. When you run this command, Git updates your local repository with the latest changes from the remote repository but does not merge them into your current branch. Shell $ git fetch origin Git Reset This command is used to unstaged changes in the staging area or undo commits. When you run this command, Git removes the changes from the staging area or rewinds the repository to a previous commit. Shell $ git reset file.txt Git Stash This command is used to temporarily save changes that are not yet ready to be committed. When you run this command, Git saves your changes in a temporary storage area and restores the repository to its previous state. Shell $ git stash save "Work in progress" “Why did the Git user become a magician? Because they liked to git stash and make their code disappear” Git Cherry-Pick This command is used to apply a specific commit to a different branch. When you run this command, Git copies the changes from the specified commit and applies them to your current branch. Shell $ git cherry-pick 5d5b5e5dce7d1e09da978c8706fb3566796e2f22 Git Rebase This command is used to combine changes from two branches into a single branch. When you run this command, Git replays the changes from one branch onto another branch and creates a new commit. Shell $ git rebase feature-1 Git Tag This command is used to create a tag for a specific commit. A tag is a label that marks a specific point in your Git history. Shell $ git tag v1.0.0 Git Blame This command is used to view the commit history for a specific file or line of code. When you run this command, Git shows you the author and date for each line of code in the file. Shell $ git blame file.txt “Git: making it easier to blame others since 2005” Git Show This command is used to view the changes made in a specific commit. When you run this command, Git shows you the files that were changed and the differences between the old and new versions. Shell $ git show 5d5b5e5dce7d1e09da978c8706fb3566796e2f22 Git Bisect This command is used to find the commit that introduced a bug in your code. When you run this command, Git helps you narrow down the range of commits to search through to find the culprit. Shell $ git bisect start $ git bisect bad HEAD $ git bisect good 5d5b5e5dce7d1e09da978c8706fb3566796e2f22 Git Submodule This command is used to manage submodules in your Git repository. A submodule is a separate Git repository included as a subdirectory of your main Git repository. Shell $ git submodule add https://github.com/example/submodule.git Git Archive This command is used to create a tar or zip archive of a Git repository. When you run this command, Git creates an archive of the repository that you can save or send to others. Shell $ git archive master --format=zip --output=archive.zip Git Clean This command is used to remove untracked files from your working directory. When you run this command, Git removes all files and directories that are not tracked by Git. Shell $ git clean -f Git Reflog This command is used to view the history of all Git references in your repository, including branches, tags, and HEAD. When you run this command, Git shows you a list of all the actions that have been performed in your repository. Git Config This command is used in Git to configure various aspects of the Git system. It is used to set or get configuration variables that control various Git behaviors. Here are some examples of how to use git config: Set user information: Shell git config --global user.name "Your Name" git config --global user.email "your.email@example.com" The above commands will set your name and email address globally so that they will be used in all your Git commits. Show configuration variables: Shell git config --list The above command will display all the configuration variables and their values that are currently set for the Git system. Set the default branch name: Shell git config --global init.defaultBranch main The above command will set the default branch name to “main”. This is the branch name that Git will use when you create a new repository. Git Grep This command in Git searches the contents of a Git repository for a specific text string or regular expression. It works similarly to the Unix grep command but is optimized for searching through Git repositories. Here's an example of how to use git grep: Let’s say you want to search for the word “example” in all the files in your Git repository. You can use the following command: Shell git grep example This will search for the word “example” in all the files in the current directory and its subdirectories. If the word “example” is found, git grep will print the name of the file, the line number, and the line containing the matched text. Here's an example output: Shell README.md:5:This is an example file. index.html:10:<h1>Example Website</h1> In this example, the word “example” was found in two files: README.md and index.html. The first line of the output shows the file name, followed by the line number and the line containing the matched text. You can also use regular expressions with git grep. For example, if you want to search for all instances of the word "example" that occur at the beginning of a line, you can use the following command: Shell git grep '^example' This will search for all instances of the word “example” that occur at the beginning of a line in all files in the repository. Note that the regular expression ^ represents the beginning of a line. Git Revert This command is used to undo a previous commit. Unlike git reset, which removes the commit from the repository, git revert creates a new commit that undoes the changes made by the previous commit. Here's an example of how to use git revert. Let’s say you have a Git repository with three commits: Plain Text commit 1: Add new feature commit 2: Update documentation commit 3: Fix bug introduced in commit 1 You realize that the new feature you added in commit 1 is causing issues and you want to undo that commit. You can use the following command to revert commit 1: Shell git revert <commit-1> This will create a new commit that undoes the changes made by commit 1. If you run git log after running git revert, you'll see that the repository now has four commits: Plain Text commit 1: Add new feature commit 2: Update documentation commit 3: Fix bug introduced in commit 1 commit 4: Revert "Add new feature" The fourth commit is the one created by git revert. It contains the changes necessary to undo the changes made by commit 1. Git RM This command is used to remove files from a Git repository. It can be used to delete files that were added to the repository, as well as to remove files that were previously tracked by Git. Here's an example of how to use git rm- Remove a file that was added to the repository but not yet committed: Shell git rm filename.txt This will remove filename.txt from the repository and stage the deletion for the next commit. Remove a file that was previously committed: Shell git rm filename.txt git commit -m "Remove filename.txt" The first command will remove filename.txt from the repository and stage the deletion for the next commit. The second command will commit the deletion. Remove a file from the repository but keep it in the working directory: Shell git rm --cached filename.txt This will remove filename.txt from the repository but keep it in the working directory. The file will no longer be tracked by Git, but it will still exist on your local machine. Remove a directory and its contents from the repository: Shell git rm -r directoryname This will remove directoryname and its contents from the repository and stage the deletion for the next commit. In conclusion, these frequently used Git commands are essential for every software professional who works with Git repositories regularly. Knowing how to use these commands effectively can help you streamline your workflow, collaborate with your team more effectively, and troubleshoot issues that may arise in your Git repository. In conclusion, these 25 Git commands are essential for every software engineer who work with Git repositories regularly. Knowing how to use these commands effectively can help you streamline your workflow, collaborate with your team more effectively, and troubleshoot issues that may arise in your Git repository. If you enjoyed this story, please share it to help others find it! Feel free to leave a comment below. Thanks for your interest. Connect with me on LinkedIn.

By Shivam Bharadwaj
Tackling the Top 5 Kubernetes Debugging Challenges
Tackling the Top 5 Kubernetes Debugging Challenges

Cloud-native technologies like Kubernetes enable companies to build software quickly and scale effortlessly. However, debugging these Kubernetes-based applications can be quite challenging due to the added complexity of building service-oriented architectures (microservices) and operating the underlying Kubernetes infrastructure. Bugs are inevitable and typically occur as a result of an error or oversight made during the software development process. So, in order for a business to keep pace with app delivery and keep their end users happy, developers need an efficient and effective way to debug. This involves finding, analyzing, and fixing these bugs. This article highlights five Kubernetes debugging challenges and how to tackle them. #1. Slow Dev Loop Due To Building and Re-Deploying Containers When a development team adopts a cloud-native technology like Kubernetes, their developer experience is significantly altered as they’ll now be expected to carry out extra steps in the inner dev loop. Instead of coding and seeing the result of their code changes immediately, as they used to when working with monolithic environments, they now have to manage external dependencies, build containers, and implement orchestration configuration (e.g., Kubernetes YAML) before they can see the impact of their code changes. There are several ways to tackle this Kubernetes debugging challenge: The first one is for you to develop services locally and focus on unit tests over end-to-end tests but this was painful when a service/web application has authentication requirements and dependencies on databases. Another way to solve this is to use a tool called DevSpace which will automate your build and deployment steps, thereby making it faster. And finally, you can also utilize a CNCF tool called Telepresence to connect your local development environment to a remote Kubernetes cluster, thereby making it possible to access these external dependencies in the remote Kubernetes cluster and test them against the service being developed locally for an instant feedback loop. #2. Lack of Visibility in the End-to-End Flow of a Distributed Application Another debugging challenge when working with Kubernetes is having full visibility of the end-to-end flow of your application because there are often just too many services. And without full visibility, it’s difficult to identify and fix a bug. Ideally, you should be able to get cross-service visibility into what is calling what, what is timing out, etc. To tackle this, you need to utilize tools that make observability and tracing more seamless. For example, tools OpenTelemetry, Jaeger, and Grafana Tempo can help you get the necessary information to reproduce errors. The goal here is to get as much information as possible, and when you do, you’d be able to fix bugs in real-time and ultimately improve the overall performance of your application. #3. Inability To Attach a Debugger to the Code One of the most important things a developer needs is the ability to attach a debugger to their code, and working with Kubernetes doesn’t make this easy. Yes, things like print/log statements work, but they are nowhere near as good as being able to put a debugger on something and step through the code, especially if it’s a new code base that a user isn’t familiar with. Two possible ways to tackle this Kubernetes debugging issue are to: Develop locally and find ways to mock or spin up local instances of dependencies. Ensure code is unit testable and focus on those because they are easier to write tests for and easy to throw a debugger on. #4. Complicated Setup for Performing Integration Testing With a Local Change Cloud-native applications are often composed of various microservices. More often than not, these microservices work interdependently and communicate with each other to process larger business requests. As an example, a timeline service for a social media application may need to talk to a user profile service to determine a user's followers and, at the same time, may need to talk to an authentication service to determine the authentication state of a user. Because of this multi-directional, service-to-service communication that happens between microservices, it is crucial to perform integration testing on microservices before deploying any changes because unit testing alone doesn't always provide guarantees about the behavior of the application in the target environment. Performing integration testing in this context naturally involves running multiple services and connecting to (potentially remote) middleware and data stores. This requires techniques and tooling that present multiple challenges. These challenges include having limited resources and inconsistent data between production and non-production environments; managing distinct configurations for separate environments; and difficulties associated with managing service versioning, releases, and deployment cycles. #5. Reproducing an Issue That Only Happens in Prod/Staging Sometimes, it can be very complex to reproduce a bug that happened in production or staging locally. At this point, your mocks or existing values will not be sufficient. You’d think to yourself, how can I actually reproduce this issue? How can I get to the root of the problem faster? Well, an open-source tool called Telepresence is usually my go-to when facing the K8s debugging challenge — The tool allows you to access remote dependencies as if they were running locally and reroute traffic from remote to local services. This means you’d get to debug them in real-time, reproduce these issues, and push a fix to your preferred version control and CI/CD pipeline faster. Conclusion Most organizations insist that any important delivery of software goes through multiple iterations of testing, but it’s important to remember that bugs are inevitable. Having the ability to debug applications effectively is one of the best techniques for identifying, understanding, and fixing bugs. Container technology, such as Kubernetes, provides many benefits for software developers but also introduces app debugging challenges. Fortunately, there are multiple ways to address these challenges easily. If there are other Kubernetes debugging techniques that you’d like to share, please mention them in the comment section.

By Edidiong Asikpo
Steel Threads Are a Technique That Will Make You a Better Engineer
Steel Threads Are a Technique That Will Make You a Better Engineer

Steel Threads are a powerful but obscure software design approach. Learning about Steel Threads will make you a better engineer. You can use them to avoid common problems like integration pain, and you can use them to cut through the complexity of system design. So Obscure It Was Deleted From Wikipedia in 2013 How unknown are Steel Threads? The concept was deleted from Wikipedia in 2013 because “the idea is not notable within Software Engineering, and hasn’t received significant coverage from notable sources.” Let’s add to the coverage, and also talk through why it is such a useful approach. What Are Steel Threads? A Steel Thread is a very thin slice of functionality that threads through a software system. They are called “threads” because they weave through the various parts of the software system and implement an important use case. They are called “steel” because the thread becomes a solid foundation for later improvements. With a Steel Thread approach, you build the thinnest possible version that crosses the boundaries of the system and covers an important use case. Example of Conventional, Problematic Approach Let’s say you’re building a new service to replace a part of your monolithic codebase. The most common way to do this would be to: Look at the old code, and figure out the needs of the new system. Design and build out the APIs that provide the capabilities you need. Go into the old code, and update references to use the new APIs. Do it behind a feature flag. Cut over using the feature flag. Fix any issues that come up until it’s working, turning off the feature flag if necessary to go back to the old code path. When it’s stable, remove the old code paths. Sounds reasonable, right? Well, this is the most common way software engineers operate, but this approach has a lot of landmines. What problems would I expect in this project? It may be appealing to build the new service in a way disconnected from the old system. After all, the design might feel purer. But you’re also introducing significantly more structural change and you’re making these changes without any integration into the old system. This increases integration pain significantly. My expectation would be that all the estimates for the project are unrealistic. And I’d expect the project to be considered a failure after it is completed, even if the resulting service has a generally good design. I would expect the switchover to the new system to be problematic. There will be a series of problems uncovered as you switch over, that will require switching back to the old code paths or working intensely to fix problems in the final stages of the project. Both of these things are avoidable, by not having a huge cutover. Note that even cutting over one percent of traffic to the new service with a feature flag is a cutover approach. Why? You’re cutting over all that one percent of traffic to all the changes at the same time. I still would not expect it to go well. You are taking steps that are too large. Example Using a Steel Thread Contrast that approach with the Steel Thread way of doing it. Think about the new system you’re building. Come up with some narrow use cases that represent Steel Threads of the system – they cover useful functionality into the system, but don’t handle all use cases, or are constrained in some ways. Choose a starting use case that is as narrow as possible, that provides some value. For example, you might choose one API that you think would be part of the new service. Build out the new API in a new service. Make it work for just that narrow use case. For any other use case, use the old code path. Get it out to production, and into full use. (Tip: you could even do both the new AND old code path, and compare!) Then you gradually add the additional use cases, until you’ve moved all of the functionality you need to, to the new service. Each use case is in production. Once you’re done, you rip out the old code and feature flags. This isn’t risky at all, since you’re already running on the new system. Steel Threads Avoid Integration Pain, and Give You Higher Confidence Integration pain is one of the bigger causes of last-minute problems in projects. When you cut over to a new system, you always find problems you don’t expect. You should be suspicious of anything that involves a cut-over. Do things in small increments. Steel Threads integrate from the beginning, so you never have a lot of integration pain to wade through. Instead, you have small integration pain, all along the way. Also, your service never needs to be tested before it goes live, because you’ve tested it incrementally, along the way. You know it can handle production loads. You’ve already added network latency, so you know the implications of that. All the surprises are moved forward, and handled incrementally, as just part of the way you gradually roll out the service. The important thing is that you have a working, integrated system, and as you work on it, you keep it working. And you flesh it out over time. Steel Threads Can Help Cut Through Complexity When you’re designing a system, you have a LOT of complexity. Building a set of requirements for the new system can be a challenging endeavor. When using a Steel Thread approach, you choose some of the core requirements and phrase them in a way that cuts through the layers of the system, and exercises your design. It provides a sort of skeletal structure for the whole system. The implementation of that Steel Thread then becomes the bones upon which further requirements can be built. Thus, Steel Threads are a subset of the requirements of a system. For example, let’s say you’re implementing a clone of Slack. Your initial Steel Thread might be something like: “Any unauthenticated person can post a message in a hardcoded #general room in a hardcoded account. Messages persist through page refreshes.” Note how limited this initial Steel Thread is. It doesn’t handle authentication, users, or accounts. It does handle writing messages, and persisting them. Your second Steel Thread can move the system towards being more useful. You could, for example, have a Steel Thread that allows the message poster to choose the name they post under. This second Steel Thread hasn’t actually done much. You still don’t have authentication, accounts, or even a concept of a user. But you have made a chat room that works enough that you can start using it. Steel Threads Provide Early Feedback Note that in this Slack clone example, you can get early feedback on the system you’re building, even though you haven’t built that much yet. This is another powerful reason for using Steel Threads. After just those two Steel Threads, your team could start using the chat room full-time. Think about how much your team will learn from using your system. It’s a working system. Compare that to what you would have learned building out the User and Account systems, hooking everything up, and finally building out a chat room. Start With Steel Threads Steel Threads are often a good place to start when designing your projects. They create a skeleton for the rest of the work to come. They nail down the core parts of the system so that there are natural places to flesh out. I encourage you to try a Steel Threaded approach. I think you’ll find it can transform your projects. Let me know your experiences with it! Steel Threads Are Closely Related To Vertical Slices You may have heard of the term “vertical slicing." I describe the concept in my post on Milestones. Steel Threads are a software design technique that results in delivering your software in vertical slices. The term tends to be used to describe the initial vertical slices of a system. They’re closely related concepts, but not completely the same. I’ve also heard of Steel Threads being referred to as “tracer bullets."

By Jade Rubick CORE
Reliability Is Slowing You Down
Reliability Is Slowing You Down

Three Hard Facts First, the complexity of your software systems is through the roof, and you have more external dependencies than ever before. 51% of IT professionals surveyed by SolarWinds in 2021 selected IT complexity as the top issue facing their organization. Second, you must deliver faster than the competition, which is increasingly difficult as more open-source and reusable tools let small teams move extremely fast. Of the 950 IT professionals surveyed by RedHat, only 1% indicated that open-source software was “not at all important.” And third, reliability is slowing you down. The Reliability/Speed Tradeoff In the olden days of software, we could just test the software before a release to ensure it was good. We ran unit tests, made sure the QA team took a look, and then we’d carefully push a software update during a planned maintenance window, test it again, and hopefully get back to enjoying our weekend. By 2023 standards, this is a lazy pace! We expect teams to constantly push new updates (even on Fridays) with minimal dedicated manual testing. They must keep up with security patches, release the latest features, and ensure that bug fixes flow to production. The challenge is that pushing software faster increases the risk of something going wrong. If you took the old software delivery approach and sped it up, you’d undoubtedly have always broken releases. To solve this, modern tooling and cloud-native infrastructure make delivering software more reliable and safer, all while reducing the manual toil of releases. According to the 2021 State of DevOps report, more than 74% of organizations surveyed have Change Failure Rate (CFR) greater than 16%. For organizations seeking to speed up software changes (see DORA metrics), many of these updates caused issues requiring additional remediation like a hotfix or rollback. If your team hasn’t invested in improving the reliability of software delivery tooling, you won’t be able to achieve reliable releases at speed. In today’s world, all your infrastructure, including dev/test infrastructure, is part of the production environment. To go fast, you also have to go safely. More minor incremental changes, automated release and rollback procedures, high-quality metrics, and clearly defined reliability goals make fast and reliable software releases possible. Defining Reliability With clearly defined goals, you will know if your system is reliable enough to meet expectations. What does it mean to be up or down? You have hundreds of thousands of services deployed in clouds worldwide in constant flux. The developers no longer coordinate releases and push software. Dependencies break for unexpected reasons. Security fixes force teams to rush updates to production to avoid costly data breaches and cybersecurity threats. You need a structured, interpreted language to encode your expectations and limits of your systems and automated corrective actions. Today, definitions are in code. Anything less is undefined. The alternative is manual intervention, which will slow you down. You can’t work on delivering new features if you’re constantly trying to figure out what’s broken and fix releases that have already gone out the door. The most precious resource in your organization is attention, and the only way to create more is to reduce distractions. Speeding Up Reliably Service level objectives (SLOs) are reliability targets that are precisely defined. SLOs include a pointer to a data source, usually a query against a monitoring or observability system. They also have a defined threshold and targets that clearly define pass or fail at any given time. SLOs include a time window (either rolling or calendar aligned) to count errors against a budget. OpenSLO is the modern de facto standard for declaring your reliability targets. Once you have SLOs to describe your reliability targets across services, something changes. While SLOs don’t improve reliability directly, they shine a light on the disconnect between expectations and reality. There is a lot of power in simply clarifying and publishing your goals. What was once a rough shared understanding becomes explicitly defined. We can debate the SLO and decide to raise, lower, redefine, split, combine, and modify it with a paper trail in the commit history. We can learn from failures as well as successes. Whatever other investments you’re making, SLOs help you measure and improve your service. Reliability is engineered; you can’t engineer a system without understanding its requirements and limitations. SLOs-as-code defines consistent reliability across teams, companies, implementations, clouds, languages, etc.

By Kit Merker
Distributed Tracing: A Full Guide
Distributed Tracing: A Full Guide

What Is Distributed Tracing? The rise of microservices has enabled users to create distributed applications that consist of modular services rather than a single functional unit. This modularity makes testing and deployment easier while preventing a single point of failure with the application. While applications begin to scale and distribute their resources amongst multiple cloud-native services, tracing a single transaction becomes tedious and nearly impossible. Hence, developers need to apply distributed tracing techniques. Distributed tracing allows a single transaction to be tracked across the front end to the backend services while providing visibility into the systems’ behavior. How Distributed Tracing Works The distributed tracing process operates on a fundamental concept of being able to trace every transaction through multiple distributed components of the application. To achieve this visibility, distributed tracing technology uses unique identifiers, namely the Trace ID, to tag each transaction. The system then puts together each trace from the various components of the application by using this unique identifier, thus building a timeline of the transaction. Each trace consists of one or more spans that represent a single operation within a single trace. It is essential to understand that a span can be referred to as a parent span for another span, indicating that the parent span triggers the child span. Implementing Distributed Tracing Setting up a distributed tracing depends on the selected solution. However, every solution will consist of these common steps. These three steps ensure developers have a solid base to start their distributed tracing journey: Setting up a distributed tracing system. Instrumenting code for tracing. Collecting and storing trace data. 1. Setting Up a Distributed System Selecting the right distributed tracing solution is crucial. Key aspects, such as compatibility, scale, and other important factors must be addressed. Many distributed tracing tools support various programming languages, including Node.js, Python, Go, .NET, Java, etc. These tools allow developers to use a single solution for distributed tracing across multiple services. 2. Instrumenting Code for Tracing Depending on the solution, the method of integration may change. The most common approach many solutions provide is using an SDK that collects the data during runtime. For example, developers using Helios with Node.js require installing the latest Helios OpenTelemetry SDK by running the following command: npm install --save helios-opentelemetry-sdk Afterward, the solution requires defining the following environment variables. Finally, it enables the SDK to collect the necessary data from the service: export NODE_OPTIONS="--require helios-opentelemetry-sdk" export HS_TOKEN="{{HELIOS_API_TOKEN}" export HS_SERVICE_NAME="<Lambda01>" export HS_ENVIRONMENT="<ServiceEnvironment01>" 3. Collecting and Storing Trace Data In most distributed tracing systems, trace data collection occurs automatically during the runtime. Then, this data makes its way to the distributed tracing solution, where the analysis and visualization occur. The collection and storage of the trace data depend on the solution in use. For example, if the solution is SaaS-based, the solution provider will take care of all trace data collecting and storage aspects. However, if the tracing solution is self-hosted, the responsibility of taking care of these aspects falls on the administrators of the solution. Analyzing Trace Data Analyzing trace data can be tedious. However, visualizing the trace data makes it easier for developers to understand the actual transaction flow and identify anomalies or bottlenecks. The following demonstrates the flow of the transaction through the various services and components of the application. An advanced distributed tracing system may highlight errors and bottlenecks that each transaction runs through. Since the trace data contains the time it takes for each service to process the transaction, developers can analyze the latencies and identify abnormalities that may impact the application’s performance. Identifying an issue using the distributed tracing solution can provide insight into the problem that has taken place. However, to gain further details regarding the issue, developers may need to use additional tools that provide added insight with observability or the capability to correlate traces with the logs to identify the cause. Distributed tracing solutions, such as Helios, offer insight into the error’s details, which eases the developer’s burden. Best Practices for Distributed Tracing A comprehensive distributed tracing solution empowers developers to respond to crucial issues swiftly. The following best practices set the fundamentals for a successful distributed tracing solution. 1. Ensuring Trace Data Accuracy and Completeness Collecting trace data from services enable developers to identify the performance and latency of all the services each transaction flows through. However, when the trace data does not contain information from a specific service, it reduces the accuracy of the entire trace and its overall completeness. To ensure developers obtain the most out of distributed tracing, it is vital that the system collects accurate trace information from all services to reflect the original data. 2. Balancing Trace Overhead and Detail Collecting all trace information from all the services will provide the most comprehensive trace. However, collecting most trace information comes at the cost of the overhead to the overall application or the individual service. The tradeoff between the amount of data collected and the acceptable overhead is crucial. Planning for this tradeoff ensures distributed tracing does not harm the overall solution, thus outweighing the benefits the solution brings. Another take on balancing these aspects is filtering and sampling the trace information to collect what is required. However, this would require additional planning and a thorough understanding of the requirement to collect valuable trace information. 3. Protecting Sensitive Data in Trace Data Collecting trace information from transactions includes collecting payloads of the actual transaction. This information is usually considered sensitive since it may contain personally identifiable information of customers, such as driver’s license numbers or banking information. Regulations worldwide clearly define what information to store during business operations and how to handle this information. Therefore, it is of unparalleled importance that the information collected must undergo data obfuscation. Helios enables its users to easily obfuscate sensitive data from the payloads collected, thereby enabling compliance with regulations. In addition to obfuscation, Helios provides other techniques to enhance and filter out the data sent to the Helios platform. Distributed Tracing Tools Today, numerous distributed tracing tools are available for developers to easily leverage their capabilities in resolving issues quicker. 1. Lightstep Lightstep is a cloud-agnostic distributed tracing tool that provides full-context distributed tracing across multi-cloud environments or microservices. It enables developers to integrate the solution with complex systems with little extra effort. It also provides a free plan with the features required for developers to get started on their distributed tracing journey. In addition, the free plan offers many helpful features, including data ingestion, analysis, and monitoring. Source: LightStep UI 2. Zipkin Zipkin is an open-source solution that provides distributed tracing with easy-to-use steps to get started. It enhances its distributed tracing efforts by enabling the integration with Elasticsearch for efficient log searching. Source: Zipkin UI It was developed at Twitter to gather crucial timing data needed to troubleshoot latency issues in service architectures, and it is straightforward to set up with a simple Docker command: docker run -d -p 9411:9411 openzipkin/zipkin 3. Jaeger Tracing Jaeger Tracing is yet another open-source solution that provides end-to-end distributed tracing and the ability to perform root cause analysis to identify performance issues or bottlenecks across each trace. It also supports Elasticsearch for data persistence and exposes Prometheus metrics by default to help developers derive meaningful insights. In addition, it allows filtering traces based on duration, service, and tags using the pre-built Jaeger UI. Source: Jaeger Tracing 4. SigNoz SigNoz is an open-source tool that enables developers to perform distributed tracing across microservices-based systems while capturing logs, traces, and metrics and later visualizing them within its unified UI. It also provides insightful performance metrics such as the p50, p95, and p99 latency. Some key benefits of using SigNoz include the consolidated UI that showcases logs, metrics, and traces while supporting OpenTelemetry. Source: SigNoz UI 5. New Relic New Relic is a distributed tracing solution that can observe 100% of an application’s traces. It provides compatibility with a vast technology stack and support for industry-standard frameworks such as OpenTelemetry. It also supports alerts to diagnose errors before they become major issues. New Relic has the advantage of being a fully managed cloud-native with support for on-demand scalability. In addition, developers can use a single agent to automatically instrument the entire application code. Source: New Relic UI 6. Datadog Datadog is a well-recognized solution that offers cloud monitoring as a service. It provides distributed tracing capabilities with Datadog APM, including additional features to correlate distributed tracing, browser sessions, logs, profiles, network, processes, and infrastructure metrics. In addition, Datadog APM allows developers to easily integrate the solution with the application. Developers can also use the solution’s capabilities to seamlessly instrument application code to monitor cloud infrastructure. Source: DataDog UI 7. Splunk Splunk offers a distributed tracing tool capable of ingesting all application data while enabling an AI-driven service to identify error-prone microservices. It also adds the advantage of correlating between application and infrastructure metrics to better understand the fault at hand. You can start with a free tier that brings in essential features. However, it is crucial to understand that this solution will store data in the cloud; this may cause compliance issues in some industries. Source: Splunk UI 8. Honeycomb Honeycomb brings in distributed tracing capabilities in addition to its native observability functionalities. One of its standout features is that it uses anomaly detection to pinpoint which spans are tied to bad user experiences. It supports OpenTelemetry to enable developers to instrument code without being stuck to a single vendor while offering a pay-as-you-go pricing model to only pay for what you use. Source: HoneyComb UI 9. Helios Helios brings advanced distributed tracing techniques that enhance the developer’s ability to get actionable insight into the end-to-end application flow by adapting OpenTelemetry’s context propagation framework. The solution provides visibility into your system across microservices, serverless functions, databases, and third-party APIs, thus enabling you to quickly identify, reproduce, and resolve issues. Source: Helios Sandbox Furthermore, Helios provides a free trace visualization tool based on OpenTelemetry that allows developers to visualize and analyze a trace file by simply uploading it. Conclusion Distributed tracing has seen many iterations and feature enhancements that allow developers to easily identify issues within the application. It reduces the time taken to detect and respond to performance issues and helps understand the relationships between individual microservices. The future of distributed tracing would incorporate multi-cloud tracing, enabling developers to troubleshoot issues across various cloud platforms. Also, these platforms consolidate the trace, thus cutting off the requirement for developers to trace these transactions across each cloud platform manually, which is time-consuming and nearly impossible to achieve. I hope you have found this helpful. Thank you for reading!

By Lahiru Hewawasam
Deploying Go Applications to AWS App Runner: A Step-By-Step Guide
Deploying Go Applications to AWS App Runner: A Step-By-Step Guide

In this blog post, you will learn how to run a Go application to AWS App Runner using the Go platform runtime. You will start with an existing Go application on GitHub and deploy it to AWS App Runner. The application is based on the URL shortener application (with some changes) that persists data in DynamoDB. Introduction AWS App Runner is a robust and user-friendly service that simplifies the deployment process of web applications in the AWS Cloud. It offers developers an effortless and efficient way to deploy their source code or container image directly to a scalable and secure web application without requiring them to learn new technologies or choose the appropriate compute service. One of the significant benefits of using AWS App Runner is that it connects directly to the code or image repository, enabling an automatic integration and delivery pipeline. This eliminates the need for developers to go through the tedious process of manually integrating their code with AWS resources. For developers, AWS App Runner simplifies the process of deploying new versions of their code or image repository. They can easily push their code to the repository, and App Runner will automatically take care of the deployment process. On the other hand, for operations teams, App Runner allows for automatic deployments every time a new commit is pushed to the code repository or a new container image version is added to the image repository. App Runner: Service Sources With AWS App Runner, you can create and manage services based on two types of service sources: Source code (covered in this blog post) Source image Source code is nothing but your application code that App Runner will build and deploy. All you need to do is point App Runner to a source code repository and choose a suitable runtime that corresponds to a programming platform version. App Runner provides platform-specific managed runtimes (for Python, Node.js, Java, Go, etc.). The AWS App Runner Go platform runtime makes it easy to build and run containers with web applications based on a Go version. You don’t need to provide container configuration and build instructions such as a Dockerfile. When you use a Go runtime, App Runner starts with a managed Go runtime image which is based on the Amazon Linux Docker image and contains the runtime package for a version of Go and some tools. App Runner uses this managed runtime image as a base image and adds your application code to build a Docker image. It then deploys this image to run your web service in a container. Let’s Get Started Make sure you have an AWS account and install AWS CLI. 1. Create a GitHub Repo for the URL Shortener Application Clone this GitHub repo and then upload it to a GitHub repository in your account (keep the same repo name i.e. apprunner-go-runtime-app): git clone https://github.com/abhirockzz/apprunner-go-runtime-app 2. Create a DynamoDB Table To Store URL Information Create a table named urls. Choose the following: Partition key named shortcode (data type String) On-Demand capacity mode 3. Create an IAM Role With DynamoSB-Specific Permissions export IAM_ROLE_NAME=apprunner-dynamodb-role aws iam create-role --role-name $IAM_ROLE_NAME --assume-role-policy-document file://apprunner-trust-policy.json Before creating the policy, update the dynamodb-access-policy.json file to reflect the DynamoDB table ARN name. aws iam put-role-policy --role-name $IAM_ROLE_NAME --policy-name dynamodb-crud-policy --policy-document file://dynamodb-access-policy.json Deploy the Application to AWS App Runner If you have an existing AWS App Runner GitHub connection and want to use that, skip to the Repository selection step. 1. Create an AWS App Runner GitHub Connection Open the App Runner console and choose Create service. Create AWS App Runner Service On the Source and deployment page, in the Source section, for Repository type, choose Source code repository. Under Connect to GitHub, choose Add new, and then, if prompted, provide your GitHub credentials. Add GitHub connection In the Install AWS Connector for GitHub dialog box, if prompted, choose your GitHub account name. If prompted to authorize the AWS Connector for GitHub, choose Authorize AWS Connections. Choose Install. Your account name appears as the selected GitHub account/organization. You can now choose a repository in your account. 2. Repository Selection For Repository, choose the repository you created: apprunner-go-runtime-app. For Branch, choose the default branch name of your repository (for example, main). Configure your deployment: In the Deployment settings section, choose Automatic, and then choose Next. Choose GitHub repo 3. Configure Application Build On the Configure build page, for the Configuration file, choose Configure all settings here. Provide the following build settings: Runtime: Choose Go 1 Build command: Enter go build main.go Start command: Enter ./main Port: Enter 8080 Choose Next. Configure runtime info 4. Configure Your Service Under Environment variables, add an environment variable. For Key, enter TABLE_NAME, and for Value, enter the name of the DynamoDB table (urls) that you created before. Add environment variables Under Security > Permissions, choose the IAM role that you had created earlier (apprunner-dynamodb-role). Add IAM role for App Runner Choose Next. On the Review and create page, verify all the details you’ve entered, and then choose Create and deploy. If the service is successfully created, the console shows the service dashboard, with a Service overview of the application. Verify URL Shortener Functionality The application exposes two endpoints: To create a short link for a URL Access the original URL via the short link First, export the App Runner service endpoint as an environment variable: export APP_URL=<enter App Runner service URL> # example export APP_URL=https://jt6jjprtyi.us-east-1.awsapprunner.com 1. Invoke It With a URL That You Want to Access via a Short Link curl -i -X POST -d 'https://abhirockzz.github.io/' $APP_URL # output HTTP/1.1 200 OK Date: Thu, 21 Jul 2022 11:03:40 GMT Content-Length: 25 Content-Type: text/plain; charset=utf-8 {"ShortCode":"ae1e31a6"} You should get a JSON response with a short code and see an item in the DynamoDB table as well. You can continue to test the application with other URLs that you want to shorten! 2. Access the URL Associated With the Short Code Enter the following in your browser http://<enter APP_URL>/<shortcode>. For example, when you enter https://jt6jjprtyi.us-east-1.awsapprunner.com/ae1e31a6, you will be redirected to the original URL. You can also use curl. Here is an example: export APP_URL=https://jt6jjprtyi.us-east-1.awsapprunner.com curl -i $APP_URL/ae1e31a6 # output HTTP/1.1 302 Found Location: https://abhirockzz.github.io/ Date: Thu, 21 Jul 2022 11:07:58 GMT Content-Length: 0 Clean up Once you complete this tutorial, don’t forget to delete the following resources: DynamoDB table App Runner service Conclusion In this blog post, you learned how to go from a Go application in your GitHub repository to a complete URL shortener service deployed to AWS App Runner!

By Abhishek Gupta CORE
How To Run a Docker Container on the Cloud: Top 5 CaaS Solutions
How To Run a Docker Container on the Cloud: Top 5 CaaS Solutions

In the past few years, there has been a growing number of organizations and developers joining the Docker journey. Containerization simplifies the software development process because it eliminates dealing with dependencies and working with specific hardware. Nonetheless, the biggest advantage of using containers is down to the portability they offer. But, it can be quite confusing how to run a container on the cloud. You could certainly deploy these containers to servers on your cloud provider using Infrastructure as a Service (IaaS). However, this approach will only take you back to the issue we mentioned previously, which is, you’d have to maintain these servers when there’s a better way to do that. Table of Contents How To Run a Docker Container on the Cloud Using a Container Registry Using Container-as-a-Service Why Should I Use CaaS? What Are the Best CaaS Solutions? AWS ECS AWS Lambda AWS App Runner Azure Container Instances Google Cloud Run Conclusion How To Run a Docker Container on the Cloud Using a Container Registry You are probably reading this if your container runs locally but are wondering how to run it on the cloud. In this case, the next step to take to bring it to the cloud is to select a container registry that will act as a centralized location to store your containers. Essentially, you will need to push your container to this registry, whether public or private, so your image can be distributed from there. Using Container-as-a-Service Containers-as-a-Service (CaaS) is a concept that allows companies to directly run their container on the cloud using any given provider of choice. With CaaS, the infrastructure required to run containers such as orchestration tools, e.g, Docker Swarm, Kubernetes, OpenStack, etc., as well as cluster management software are non-existent for the user. As a side note, CaaS joins the already established cloud service models such as Infrastructure-as-a-Service (IaaS), Platform-as-a-Service (PaaS), and Software-as-a-Service (SaaS). Why Should I Use CaaS? Some of the advantages of using Container-as-a-Service are: Cost reduction: it eliminates the time, effort, and money spent on maintaining secure infrastructure to run your container. Flexibility: you can easily move from cloud to cloud or even back to your on-prem infrastructure, freeing you from vendor lock-in. Speed: Since the underlying infrastructure abstracts from it, you can deploy your container quicker. Overall, CaaS will not only simplify the running process of a software application but also improve overall security around it as most CaaS solutions offer vulnerability scans. Furthermore, you don’t have to worry about managing the hardware that will run your container. What Are the Best CaaS Solutions? When choosing a CaaS solution, some of the key considerations include: Can it operate multi-container applications? What networks and storage functions are available? Which file format does it support? How is storage achieved? Which billing model does it use? Amazon Elastic Container Service (Amazon ECS) Amazon ECS is a scalable container orchestration platform by AWS designed to run, stop, and manage containers in a cluster environment by using task definition. Essentially, task definition is where you define: The container to use. How many containers to run. How your containers are linked. What resources your containers use. Note: AWS ECS also supports mounting EFS volumes. With that in mind, you have two ways of using ECS: By using EC2 Instances. By using Fargate. ECS With EC2 In this case, containers will be deployed to EC2 Instances (VMs) created for the cluster. The merits include: Full control over the type of EC2 instance used. Your container is used for machine learning and is GPU-oriented, meaning you can choose to run on an EC2 instance that is optimized for this usage. Reduce your cost by using Spot instances, which can reduce your cost by up to 90%. On the other hand, the only demerit is that: You are responsible for patching, managing network security, and the scalability associated with these instances. Pricing: When it comes to cost, you are charged for the EC2 instances run within your ECS cluster and VPC networking. ECS With Fargate AWS Fargate was launched in 2017, and with this model, you don’t have to be worried about managing EC2 Instances. AWS Fargate directly manages the underlying servers required to run your container by pre-configuring a cluster for you. You will just need to add your workload to it. The advantages include: No infrastructure to manage. AWS deals with availability and scalability of your container application. Fargate Spot, based on similar principles as the Spot instances, AWS mentions a cost reduction of up to 70%. In contrast, the downside is: Only one networking mode is currently supported (awsvpc), which might limit you with the network layers in some specific scenarios you might try to achieve. A recent report by Datadog, mentions that, in 2021, 32% of AWS container environments were using AWS Fargate. This trend confirms that companies are switching gradually to serverless environments. Pricing: Fargate’s pricing is based on a “pay as you go” model. There are no upfront costs and you only pay for the compute and memory resources consumed. Here’s a pricing example for the region US West (Oregon): $0.04048 per vCPU per hour. $0.004445 per gigabyte per hour. The table below will help you better understand the terminology used with ECS/Fargate and Kubernetes: Infrastructure Layer Component ECS Fargate Kubernetes Workload Deployment UnitDesired StateAccess Endpoint TaskServiceALB PodDeploymentIngress Control Plane API EndpointSchedulerControllerState Management Frontend ServiceCapacity ManagerCluster ManagerState DB Kube-apiserverKube-schedulerKube-controlleretcd Data Plane Guest OSAgentContainer RuntimeNetwork Amazon Linux 2Fargate AgentDockerENI/VPC Linux/WindowsKubeletContainerdCN/Kubeproxy AWS Lambda A serverless service by AWS whereby you bring your code, whether it is Java, Go, C#, Python, Powershell, Node.js or Ruby, and Amazon will run it into a callable function that complies with their language’s Lambda interface. Lambda functions are mostly called by connecting them to AWS API Gateway, which exposes the functions as REST API calls. You might be wondering why we are even mentioning AWS Lambda at this point as there’s no link with Docker or container images. According to AWS, in December 2020, AWS Lambda began supporting running container images up to 10GB in size. Using Lambda to run a Docker container on the cloud gives you: Scalability: Lambda will automatically create new instances of your function to meet demand as it can scale up to 500 new instances every minute. However, you may have to contend with: Reduced portability: Since Lambda is AWS’ proprietary serverless tech, you will need to significantly adjust your function to move to another cloud provider. Slow scalability: When we mentioned how Lambda can spin up new instances, we weren’t talking about its speed. A cold start for your function will require time and has a hard impact on Java and .NET applications. Can’t run long-running tasks: Lambda functions can only run up to 15 minutes. Pricing: You are charged by the number of requests for their functions and by the duration (time spent to execute the function). Pricing will also vary depending on the amount of memory you allocate to your function. Nonetheless, Lambda offers a free tier that works even if you use your annual AWS Free Tier term, which offers 400,000 GB-seconds of compute time every month. AWS App Runner Launched in May 2021, AWS App Runner facilitates bringing a web application to the cloud without worrying about scaling or the infrastructure associated with it. Essentially, it simply runs Amazon ECS with Fargate to execute your container but you don’t need to set up or configure anything related to Fargate to get going. It can run in build mode, which pulls code from your GitHub repository and builds the application at any commits you might push to your main branch. Alternatively, it can run in container mode, where you will connect your container registry (only AWS ECR is supported) and point to your image. If you want to see what AWS has planned for App Runner, they outline everything you need to know with their detailed roadmap. The core advantage of AWS App Runner when it comes to running a Docker container on the cloud is that: It is easy to configure and provides a simple way to get a web application to run in the cloud. On the other hand, the disadvantages include: Build mode only supports Python and Node.js runtimes. Can’t scale down to 0, you need to pay for at least one instance. Build mode has no integration with AWS CodeCommit or other Source Control Management, meaning you will be forced to use GitHub. App cannot communicate with private VPC: More details here. Pricing: You are billed for what you use. For example, a minimal instance (1vCPU, 2GB) will cost $0.078 per hour or around $56.00 per month, plus a little extra for automatic build and deployment, if it is always running: $0.064 per vCPU per hour. $0.007 per gigabyte per hour. Automatic deployment: $1 per application per month. Build Fee: $0.005/build-minute. Detailed pricing information is available on their website. Azure Container Instances (ACI) Microsoft was a late entrant in the CaaS market since Azure Container Instances was announced in July 2017. It offers: Support for persistent storage by mounting Azure file share to the container. Co-scheduled groups, Azure supports the scheduling of multi-container groups that share a host machine, local network, or storage. Container is in your virtual network and can communicate with other resources in that network. Full control over the instance that runs your container. Adding GPU compute power is not a problem with ACI. The only downside associated with it is that it: Only supports calling Docker containers from a registry. Pricing: Billing is per hour of vCPU, Memory, GPU, and OS used. Using a container that requires a GPU or Windows will be more expensive. $0.04660 per vCPU per hour. $0.0051 per gigabyte per hour. Google Cloud Run Google Cloud Run, GCP’s CaaS solution, became available in November 2019. Similar to the other options of running Docker containers in the cloud listed above, this service is built on the Knative platform based on Kubernetes. Similar to AWS App Runner, you can choose to point to a container registry or repository that contains your application code. Benefits: Use of secrets from Google Secret Manager. Deployment from source code supports Go, Python, Java, Node.js, Ruby, and more. Support traffic splitting between revisions. Disadvantage: Not directly related to Cloud Run but the only disadvantage is connected to GCP as a whole, whereby there is a limited number of regions compared to Azure or AWS, for instance. Pricing: Anyone could try Cloud Run for free with the $300 credit that GCP offers to their new customers. After that, you’ll be billed once you go over the free tier. The free monthly quotas for Google Cloud Run are as follows: CPU: The first 180,000 vCPU-seconds. Memory: The first 360,000 GB-seconds. Requests: The first 2 million requests. Networking: The first 1 GB egress traffic (platform-wide). Once you bypass these limits; however, you’ll need to pay for your usage. The costs for the paid tier of Google Cloud Run are: CPU: $0.00144 per vCPU per minute. Memory: $0.00015 per GB per minute. Requests: $0.40 per 1 million requests. Networking: $0.085 per GB delivered. Conclusion Cloud providers are always innovating to fulfill the needs of customers by continually bringing new services. A minor concern is that the delivery of more services and features makes it even more confusing for developers and organizations. Although there may be slight differences in AWS, Azure, and Google Cloud offerings, it is evident that they all share a common goal. They are all seeking to simplify running Docker containers on the cloud orchestration while maintaining the flexibility required to support a wide range of developer use cases.

By Chase Bolt
Kubernetes-Native Development With Quarkus and Eclipse JKube
Kubernetes-Native Development With Quarkus and Eclipse JKube

This article explains what Eclipse JKube Remote Development is and how it helps developers build Kubernetes-native applications with Quarkus. Introduction As mentioned in my previous article, microservices don’t exist in a vacuum. They typically communicate with other services, such as databases, message brokers, or other microservices. Because of this distributed nature, developers often struggle to develop (and test) individual microservices that are part of a larger system. The previous article examines some common inner-loop development cycle challenges and shows how Quarkus, combined with other technologies, can help solve some of the challenges. Eclipse JKube Remote Development was not one of the technologies mentioned because it did not exist when the article was written. Now that it does exist, it certainly deserves to be mentioned. What Is Eclipse JKube Remote Development? Eclipse JKube provides tools that help bring Java applications to Kubernetes and OpenShift. It is a collection of plugins and libraries for building container images and generating and deploying Kubernetes or OpenShift manifests. Eclipse JKube Remote Development is a preview feature first released as part of Eclipse JKube 1.10. This new feature is centered around Kubernetes, allowing developers the ability to run and debug Java applications from a local machine while connected to a Kubernetes cluster. It is logically similar to placing a local development machine inside a Kubernetes cluster. Requests from the cluster can flow into a local development machine, while outgoing requests can flow back onto the cluster. Remember this diagram from the first article using the Quarkus Superheroes? Figure 1: Local development environment logically inserted into a Kubernetes cluster. We previously used Skupper as a proxy to connect a Kubernetes cluster to a local machine. As part of the 1.10 release, Eclipse JKube removes the need to use Skupper or install any of its components on the Kubernetes cluster or your local machine. Eclipse JKube handles all the underlying communication to and from the Kubernetes cluster by mapping Kubernetes Service ports to and from the local machine. Eclipse JKube Remote Development and Quarkus The new Eclipse JKube Remote Development feature can make the Quarkus superheroes example very interesting. If we wanted to reproduce the scenario shown in Figure 1, all we’d have to do is re-configure the rest-fights application locally a little bit and then run it in Quarkus dev mode. First, deploy the Quarkus Superheroes to Kubernetes. Then, add the Eclipse JKube configuration into the <plugins> section in the rest-fights/pom.xml file: XML <plugin> <groupId>org.eclipse.jkube</groupId> <artifactId>openshift-maven-plugin</artifactId> <version>1.11.0</version> <configuration> <remoteDevelopment> <localServices> <localService> <serviceName>rest-fights</serviceName> <port>8082</port> </localService> </localServices> <remoteServices> <remoteService> <hostname>rest-heroes</hostname> <port>80</port> <localPort>8083</localPort> </remoteService> <remoteService> <hostname>rest-villains</hostname> <port>80</port> <localPort>8084</localPort> </remoteService> <remoteService> <hostname>apicurio</hostname> <port>8080</port> <localPort>8086</localPort> </remoteService> <remoteService> <hostname>fights-kafka</hostname> <port>9092</port> </remoteService> <remoteService> <hostname>otel-collector</hostname> <port>4317</port> </remoteService> </remoteServices> </remoteDevelopment> </configuration> </plugin> Version 1.11.0 of the openshift-maven-plugin was the latest version as of the writing of this article. You may want to check if there is a newer version available. This configuration tells OpenShift (or Kubernetes) to proxy requests going to the OpenShift Service named rest-fights on port 8082 to the local machine on the same port. Additionally, it forwards the local machine ports 8083, 8084, 8086, 9092, and 4317 back to the OpenShift cluster and binds them to various OpenShift Services. The code listing above uses the JKube OpenShift Maven Plugin. If you are using other Kubernetes variants, you could use the JKube Kubernetes Maven Plugin with the same configuration. If you are using Gradle, there is also a JKube OpenShift Gradle Plugin and JKube Kubernetes Gradle Plugin available. Now that the configuration is in place, you need to open two terminals in the rest-fights directory. In the first terminal, run ./mvnw oc:remote-dev to start the remote dev proxy service. Once that starts, move to the second terminal and run: Shell ./mvnw quarkus:dev \ -Dkafka.bootstrap.servers=PLAINTEXT://localhost:9092 \ -Dmp.messaging.connector.smallrye-kafka.apicurio.registry.url=http://localhost:8086 This command starts up a local instance of the rest-fights application in Quarkus dev mode. Requests from the cluster will come into your local machine. The local application will connect to other services back on the cluster, such as the rest-villains and rest-heroes applications, the Kafka broker, the Apicurio Registry instance, and the OpenTelemetry collector. With this configuration, Quarkus Dev Services will spin up a local MongoDB instance for the locally-running application, illustrating how you could combine local services with other services available on the remote cluster. You can do live code changes to the local application while requests flow through the Kubernetes cluster, down to your local machine, and back to the cluster. You could even enable continuous testing while you make local changes to ensure your changes do not break anything. The main difference between Quarkus Remote Development and Eclipse JKube Remote Development is that, with Quarkus Remote Development, the application is running in the remote Kubernetes cluster. Local changes are synchronized between the local machine and the remote environment. With JKube Remote Development, the application runs on the local machine, and traffic flows from the cluster into the local machine and back out to the cluster. Wrap-Up As you can see, Eclipse JKube Remote Development compliments the Quarkus Developer Joy story quite well. It allows you to easily combine the power of Quarkus with Kubernetes to help create a better developer experience, whether local, distributed, or somewhere in between.

By Eric Deandrea
Configure Kubernetes Health Checks
Configure Kubernetes Health Checks

Kubernetes is an open-source container orchestration platform that helps manage and deploy applications in a cloud environment. It is used to automate the deployment, scaling, and management of containerized applications. It is an efficient way to manage application health with Kubernetes probes. This article will discuss Kubernetes probes, the different types available, and how to implement them in your Kubernetes environment. What Are Kubernetes Probes? Kubernetes probes are health checks that are used to monitor the health of applications and services in a Kubernetes cluster. They are used to detect any potential problems with applications or services and identify potential resource bottlenecks. Probes are configured to run at regular intervals and send a signal to the Kubernetes control plane if they detect any issues with the application or service. Kubernetes probes are typically implemented using the Kubernetes API, which allows them to query the application or service for information. This information can then be used to determine the application’s or service’s health. Kubernetes probes can also be used to detect changes in the application or service and send a notification to the Kubernetes control plane, which can then take corrective action. Kubernetes probes are an important part of the Kubernetes platform, as they help ensure applications and services run smoothly. They can be used to detect potential problems before they become serious, allowing you to take corrective action quickly. A successful message for a readiness probe indicates the container is ready to receive traffic. If a readiness probe is successful, the container is considered ready and can begin receiving requests from other containers, services, or external clients. A successful message for a liveness probe indicates the container is still running and functioning properly. If a liveness probe succeeds, the container is considered alive and healthy. If a liveness probe fails, the container is considered to be in a failed state, and Kubernetes will attempt to restart the container to restore its functionality. Both readiness and liveness probes return a successful message with an HTTP response code of 200-399 or a TCP socket connection is successful. If the probe fails, it will return a non-2xx HTTP response code or a failed TCP connection, indicating that the container is not ready or alive. A successful message for a Kubernetes probe indicates the container is ready to receive traffic or is still running and functioning properly, depending on the probe type. Types of Kubernetes Probes There are three types of probes: Startup probes Readiness probes Liveness probes 1. Startup Probes A startup probe is used to determine if a container has started successfully. This type of probe is typically used for applications that take longer to start up, or for containers that perform initialization tasks before they become ready to receive traffic. The startup probe is run only once, after the container has been created, and it will delay the start of the readiness and liveness probes until it succeeds. If the startup probe fails, the container is considered to have failed to start and Kubernetes will attempt to restart the container. 2. Readiness Probes A readiness probe is used to determine if a container is ready to receive traffic. This type of probe is used to ensure a container is fully up and running and can accept incoming connections before it is added to the service load balancer. A readiness probe can be used to check the availability of an application’s dependencies or perform any other check that indicates the container is ready to serve traffic. If the readiness probe fails, the container is removed from the service load balancer until the probe succeeds again. 3. Liveness Probes A liveness probe is used to determine if a container is still running and functioning properly. This type of probe is used to detect and recover from container crashes or hang-ups. A liveness probe can be used to check the responsiveness of an application or perform any other check that indicates the container is still alive and healthy. If the liveness probe fails, Kubernetes will attempt to restart the container to restore its functionality. Each type of probe has its own configuration options, such as the endpoint to check, the probe interval, and the success and failure thresholds. By using these probes, Kubernetes can ensure containers are running and healthy and can take appropriate action if a container fails to respond. How To Implement Kubernetes Probes Kubernetes probes can be implemented in a few different ways: The first way is to use the Kubernetes API to query the application or service for information. This information can then be used to determine the application’s or service’s health. The second way is to use the HTTP protocol to send a request to the application or service. This request can be used to detect if an application or service is responsive, or if it is taking too long to respond. The third way is to use custom probes to detect specific conditions in an application or service. Custom probes can be used to detect things such as resource usage, slow responses, or changes in the application or service. Once you have decided which type of probe you will be using, you can then configure the probe using the Kubernetes API. You can specify the frequency of the probe, the type of probe, and the parameters of the probe. Once the probe is configured, you can deploy it to the Kubernetes cluster. Today, I’ll show how to configure health checks to your application deployed on Kubernetes with HTTP protocol to check whether the application is ready, live, and starting as per our requirements. Prerequisites A Kubernetes cluster from any cloud provider. You can even use Minikube or Kind to create a single-node cluster. Docker Desktop to containerize the application. Docker Hub to push the container image to the Docker registry. Node.js installed, as we will use a sample Node.js application. Tutorial Fork the sample application here. Get into the main application folder with the command: cd Kubernetes-Probes-Tutorial Install the dependencies with the command: npm install Run the application locally using the command: node app.js You should see the application running on port 3000. In the application folder, you should see the Dockerfile with the following code content: # Use an existing node image as base image FROM node:14-alpine # Set the working directory in the container WORKDIR /app # Copy package.json and package-lock.json to the container COPY package*.json ./ # Install required packages RUN npm install # Copy all files to the container COPY . . # Expose port 3000 EXPOSE 3000 # Start the application CMD [ "npm", "start" ] This Dockerfile is to create a container image of our application and push it to the Docker Hub. Next, build and push your image to the Docker Hub using the following command: docker buildx build --platform=linux/arm64 --platform=linux/amd64 -t docker.io/Docker Hub username/image name:tag --push -f ./Dockerfile . You can see the pushed image on your Docker Hub account under repositories. Next, deploy the manifest files. In the application folder, you will notice a deployment.yaml file with health checks/probes included, such as readiness and liveness probes. Note: we have used our pushed image name in the YAML file: apiVersion: apps/v1 kind: Deployment metadata: name: notes-app-deployment labels: app: note-sample-app spec: replicas: 2 selector: matchLabels: app: note-sample-app template: metadata: labels: app: note-sample-app spec: containers: - name: note-sample-app-container image: pavansa/note-sample-app resources: requests: cpu: "100m" imagePullPolicy: IfNotPresent ports: - containerPort: 3000 readinessProbe: httpGet: path: / port: 3000 livenessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 You can see the image used and the health checks configured in the above YAML file. We are all set with our YAML file. Assuming you have a running cluster ready, let’s deploy the above mentioned manifest file with the command: kubectl apply -f deployment.yaml You should see the successful deployment of the file: “deployment.apps/notes-app-deployment created.” Let’s check the pod status with the following command to make sure the pods are running: kubectl get pods Let’s describe a pod using the following command: kubectl describe pod notes-app-deployment-7fb6f5d74b-hw5fn You can see the “Liveness and Readiness” status when you describe the pods. Next, let’s check the events section. You can see the different events, such as “scheduled,” “pulled,” “created,” and “started.” All the pod events were successful. Conclusion Kubernetes probes are an important part of the Kubernetes platform, as they help ensure applications and services run smoothly. They can be used to detect potential problems before they become serious, allowing you to take corrective action quickly. Kubernetes probes come in two types: Liveness probes Readiness probes Along with custom probes that can be used to detect specific conditions in an application or service. Implementing Kubernetes probes is a straightforward process that can be done using the Kubernetes API. If you are looking for a way to ensure the health of your applications and services, Kubernetes probes are the way to go. So, make sure to implement Kubernetes probes in your Kubernetes environment today!

By Pavan Belagatti CORE
Kubernetes Deployment Strategies
Kubernetes Deployment Strategies

Deploying applications with Kubernetes has become increasingly popular due to its numerous benefits. Kubernetes enables easy management of containerized applications, providing a platform for application deployment, scaling, and management. With Kubernetes, applications can be deployed quickly and consistently across different environments, including on-premises and cloud platforms. While deploying applications with Kubernetes, many of us will have questions about what deployment type to use — rolling, blue-green, canary, etc. In this article, we will discuss these deployment types (canary, rolling, and blue-green), how they work, and which one you should choose. Canary Deployment Kubernetes canary deployment is a technique for rolling out new features or changes to a small subset of users or servers before releasing the update to the entire system. This is done by creating a new replica set with the updated version of the software while keeping the original replica set running. A small percentage of traffic is then routed to the new replica set, while the majority of the traffic continues to be served by the original replica set. This allows for the new version to be tested in a live environment while minimizing the risk of issues affecting the entire system. If issues are detected during the canary deployment, it can be quickly rolled back to the original replica set. Canary deployments are a valuable tool for minimizing risk and ensuring high availability in complex distributed systems, by allowing for controlled testing of changes before they are released to the entire system. Here is an example of a canary deployment YAML file in Kubernetes. apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deployment spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp-container image: myapp:v1 ports: - containerPort: 8080 readinessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 5 periodSeconds: 5 livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 10 periodSeconds: 10 In this example, we are deploying a Kubernetes deployment that will create three replicas of our application. The deployment uses a selector to find the appropriate pods to manage based on the label app: myapp. The template section specifies the configuration for the pods created by the deployment. In this case, we're running a single container in each pod, which is specified with the containers field. The container image used is myapp:v1, which is the first version of our application. We've also added two probes to the container to check its health. The readinessProbe checks whether the container is ready to receive traffic, and the livenessProbe checks whether the container is still running. If either of these probes fails, the pod will be restarted. To perform a canary deployment, we would create a second deployment YAML file that specifies the new version of the application, for example, myapp:v2. We would then update the original deployment to set up a canary test by scaling up the replicas of the new version to 1 while keeping the replicas of the old version at 2. Once the new version is running, we can test it to ensure it's functioning correctly. If everything looks good, we can update the original deployment to scale up the replicas of the new version and gradually scale down the replicas of the old version. This will cause a small percentage of traffic to gradually shift from the old version to the new version until all traffic goes to the new version. If any issues arise with the new version, we can quickly roll back to the old version by reversing the process. Rolling Deployment Kubernetes rolling deployment is a strategy for updating and deploying new versions of software in a controlled and gradual manner. Instead of deploying updates all at once, Kubernetes rolls out changes incrementally, reducing the risk of downtime and allowing for easy rollbacks in case of errors. Rolling deployment involves creating a new replica set with the updated version of the software while gradually scaling down the old replica set. This allows for the new version to be deployed while the old version is still running, ensuring that there is no interruption to service. Once the new version is fully deployed, the old replica set is deleted, and the deployment is complete. Kubernetes rolling deployment is essential for ensuring high availability and reliability in complex distributed systems. Here is an example of a rolling deployment YAML file in Kubernetes. apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deployment spec: replicas: 3 selector: matchLabels: app: myapp strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 1 template: metadata: labels: app: myapp spec: containers: - name: myapp-container image: myapp:v1 ports: - containerPort: 8080 In this example, we are deploying a Kubernetes deployment that will create three replicas of our application. The deployment uses a selector to find the appropriate pods to manage based on the label app: myapp. The strategy section specifies the strategy that Kubernetes should use to update the deployment. In this case, we are using a RollingUpdate strategy. This means that Kubernetes will gradually update the deployment by replacing old replicas with new replicas. The maxSurge and maxUnavailable fields control the rolling update process. maxSurge determines the maximum number of replicas that can be created above the desired number of replicas, and maxUnavailable determines the maximum number of replicas that can be unavailable during the update. The template section specifies the configuration for the pods created by the deployment. In this case, we're running a single container in each pod, which is specified with the containers field. The container image used is myapp:v1, which is the first version of our application. To update the deployment, we would create a new deployment YAML file that specifies the new version of the application, for example, myapp:v2. We would then update the original deployment to point to the new YAML file. Once the update is started, Kubernetes will gradually replace old replicas with new ones until all replicas run the new version. The rolling update process allows for updates to be performed with minimal disruption to users, as it always ensures that at least one replica of the old version is running while the new version is being rolled out. Blue-Green Deployment Strategy The blue-green Kubernetes deployment strategy is a technique for releasing new versions of an application to minimize downtime and risk. It involves running two identical environments, one serving as the active production environment (blue) and the other as a new release candidate (green). The new release candidate is thoroughly tested before being switched with the production environment, allowing for a smooth transition without any downtime or errors. Here is an example YAML file for a blue-green deployment on Kubernetes: apiVersion: apps/v1 kind: Deployment metadata: name: my-app labels: app: my-app spec: replicas: 2 selector: matchLabels: app: my-app template: metadata: labels: app: my-app version: blue spec: containers: - name: my-app image: myregistry/my-app:blue ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: my-app-service spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 8080 In this example, we define a deployment for an application called "my-app" with two replicas. The deployment has a label selector of "app: my-app", which will match the corresponding service that routes traffic to the deployment. The first template defines the "blue" version of the application. It is defined with the label "version: blue", which allows for easy identification of the version currently in production. The container image for this version is pulled from the Docker registry at "myregistry/my-app:blue".When a new version is ready, a new template is added with the label "version: green". This new template will have an updated container image with the new version of the application. Once this new template has been created and is ready to be released, the Kubernetes service can be updated to route traffic to the new "green" deployment. This blue-green deployment strategy ensures that the new version of the application can be fully tested before it is released, with no downtime or errors. Which One Should You Choose? The choice of Kubernetes deployment strategy depends on the specific needs and requirements of the application or service being deployed. A canary deployment strategy is typically used when deploying new features or updates to a subset of users or servers to test them in a live environment and is often used for applications that require frequent updates. This strategy allows for the testing of new features with minimal impact on the production environment and can help to identify issues before they affect the entire system. A rolling deployment strategy is ideal for applications that require zero downtime during deployment. It involves incrementally rolling out new versions of an application while ensuring that the old version is still running, reducing the risk of downtime and allowing for easy rollbacks in case of issues. A blue-green deployment strategy is useful for applications where downtime is acceptable but must be minimized. It involves running two identical environments, one serving as the active production environment and the other as a new release candidate. The new release candidate is tested before being switched with the production environment, allowing for a smooth transition without any downtime or errors. In summary, the choice of deployment strategy depends on the specific needs and requirements of the application or service being deployed. Canary deployments are ideal for frequent updates and testing, rolling deployments are ideal for zero-downtime deployments, and blue-green deployments are ideal for minimizing downtime during deployments.

By Pavan Belagatti CORE

Top Deployment Experts

expert thumbnail

John Vester

Lead Software Engineer,
Marqeta @JohnJVester

Information Technology professional with 30+ years expertise in application design and architecture, feature development, project management, system administration and team supervision. Currently focusing on enterprise architecture/application design utilizing object-oriented programming languages and frameworks. Prior expertise building (Spring Boot) Java-based APIs against React and Angular client frameworks. CRM design, customization and integration with Salesforce. Additional experience using both C# (.NET Framework) and J2EE (including Spring MVC, JBoss Seam, Struts Tiles, JBoss Hibernate, Spring JDBC).
expert thumbnail

Marija Naumovska

Product Manager,
Microtica

‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎
expert thumbnail

Vishnu Vasudevan

Head of Product Engineering & Management,
Opsera

Vishnu is an experienced DevSecOps leader and a SAFe Agilist with a track record of building SaaS/PaaS containerized products and improving operational and financial results via Agile/DevSecOps and digital transformations. He has over 16+ years of experience working in Infrastructure, Cloud engineering and automations. Currently, he works as Director - Product engineering at Opsera, responsible for delivering SaaS products under Opsera and services for their customers by using advanced analytics, standing up DevSecOps products, creating and maintaining models, and onboarding new products. Previously, Vishnu worked in leading financial enterprises as a product manager and delivery leader, where he built enterprise PaaS and SaaS products for internal application engineering teams. He enjoys spending free time driving, mountaineering, travel, soccer, playing cricket & cooking.
expert thumbnail

Seun Matt

Engineering Manager,
Cellulant

Tech Entrepreneur | Full Stack Software Developer. I write to let out my views, pass on my knowledge and remain creative.

The Latest Deployment Topics

article thumbnail
Fearless Distroless
With the rise of Docker came a new focus for engineers: optimizing the build to reach the smallest image size possible. This post explores available options.
April 20, 2023
by Nicolas Fränkel CORE
· 1,661 Views · 2 Likes
article thumbnail
AWS: Pushing Jakarta EE Full Platform Applications to the Cloud
In this article, readers will learn how to deploy more complex Jakarta EE applications as serverless services with AWS Fargate.
April 20, 2023
by Nicolas Duminil CORE
· 2,827 Views · 4 Likes
article thumbnail
GitStream vs. Code Owners vs. GitHub Actions
Looking to streamline your GitHub pipeline but unsure where to start? Find out when to use gitStream vs. code owners vs. GitHub Actions.
April 19, 2023
by Dan Lines CORE
· 1,179 Views · 2 Likes
article thumbnail
Introduction to Elasticsearch
Elasticsearch is a highly scalable and distributed search and analytics engine designed to handle large volumes of structured, semi-structured, and unstructured data.
April 19, 2023
by Rama Krishna Panguluri
· 2,327 Views · 2 Likes
article thumbnail
Diving Into Cloud Infrastructure: An Exploration of Its Different Components
In this blog, we’ll explore the building blocks of cloud infrastructure, including virtualization, containers, microservices, and serverless computing.
April 19, 2023
by Ruchita Varma
· 1,747 Views · 1 Like
article thumbnail
5 Noteworthy Reasons to Integrate Uber API Into Your App
This article provides five reasons why developers should integrate Uber API into their apps because it helps to generate many benefits.
April 19, 2023
by Prakash Saini
· 11,219 Views · 1 Like
article thumbnail
Stream File Uploads to S3 Object Storage and Save Money
Learn how to upload files directly to S3-compatible Object Storage from your Node application to improve availability and reduce costs.
April 19, 2023
by Austin Gil CORE
· 2,141 Views · 1 Like
article thumbnail
Breaking the Wall Between Dev, Sec, and Ops
The steps that serve as a roadmap to enable organizations to successfully implement DevSecOps and create secure software right from the outset.
April 18, 2023
by Akanksha Gupta
· 2,484 Views · 1 Like
article thumbnail
Unlock the Mysteries of AWS Lambda Invocation: Asynchronous vs. Synchronous
Unlock the full potential of your AWS Lambda functions with this deep dive into the differences between asynchronous and synchronous invocations for maximum efficiency.
April 18, 2023
by Satrajit Basu CORE
· 2,540 Views · 1 Like
article thumbnail
OpenShift vs. Kubernetes: The Unfair Battle
In this article, we are going to be comparing OpenShift and Kubernetes, and let me tell you, the comparison is far from fair.
April 18, 2023
by Rahul Shivalkar
· 3,018 Views · 2 Likes
article thumbnail
Guide to Creating and Containerizing Native Images
In this article, we will learn how to turn Java applications into native images and then containerize them for further deployment in the cloud.
April 18, 2023
by Dmitry Chuyko
· 3,198 Views · 1 Like
article thumbnail
Scaling IBM App Connect Enterprise Integrations That Use MQ Request/Reply
Use a back-end with multiple client containers to ensure that reply messages return to the correct server when all the containers have identical starting configurations.
April 18, 2023
by Trevor Dolby
· 2,420 Views · 1 Like
article thumbnail
Python Stack Data Structure: A Versatile Tool for Real-time Applications
In this article, we will explore the Python stack data structure, its implementation, and real-time use cases.
April 17, 2023
by Amlan Patnaik
· 2,099 Views · 1 Like
article thumbnail
How to Query Your AWS S3 Bucket With Presto SQL
In this tutorial, the reader will learn how to query an S3-based data lake with Presto, the open-source SQL query engine.
April 17, 2023
by Rohan Pednekar
· 2,482 Views · 1 Like
article thumbnail
GitHub Exposed a Private SSH Key: What You Need to Know
Everyone has secrets leakage incidents from time to time, even massive players like GitHub. This is a good reminder we all need to stay vigilant.
April 15, 2023
by Dwayne McDaniel
· 4,229 Views · 1 Like
article thumbnail
Create a CustomCalendarView Library In Android
This tutorial demonstrates how to create a customizable calendar in Android using the CustomCalendarView feature.
April 14, 2023
by Nilanchala Panigrahy
· 35,567 Views · 2 Likes
article thumbnail
How To Create a Bitmap Blur Effect In Android Using RenderScript
Learn how to achieve the popular blur effect on your Android apps
April 14, 2023
by Nilanchala Panigrahy
· 12,926 Views · 3 Likes
article thumbnail
Xamarin Mobile Application Development for Android - Second Edition Announced
Book titled “Xamarin Mobile Application Development for Android” – Second Edition is announced available to pre-order to be published in September 2015.
April 14, 2023
by Nilanchala Panigrahy
· 7,155 Views · 3 Likes
article thumbnail
Improve AWS Security and Compliance With CDK-nag?
AWS Cloud Development Kit (AWS CDK) is a powerful tool that allows developers to define cloud infrastructure in code using familiar programming languages.
April 14, 2023
by Jeroen Reijn CORE
· 3,431 Views · 2 Likes
article thumbnail
Optimizing Cloud Performance: An In-Depth Guide to Cloud Performance Testing and its Benefits
This article explains cloud performance testing and the types, different forms, benefits, benefits, and commonly used tools.
April 13, 2023
by Waris Husain
· 5,804 Views · 2 Likes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • ...
  • Next

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: