Followers

Kubernetes Design Pattern - Side Car, Adapter, Ambassador containers

  Side-Car container A Pod is composed of one or more application containers. A sidecar container is a utility container and its purpose is ...

 


Side-Car container

A Pod is composed of one or more application containers. A sidecar container is a utility container and its purpose is to support the main container.

It is important to note that a standalone sidecar does not serve any purpose, it must be paired with one or more containers.


Generally, a sidecar container is reusable and can be paired with numerous type of main containers.

Example

Create a Pod that defines the main application container that writes the current date to a log file every five seconds.

The sidecar container is nginx serving that logfile. (In practice, your sidecar is likely to be a log collection container that uploads to external storage.

Let's create a file called pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-sidecar
spec:
  # Create a volume called 'shared-logs' that the
  # app and sidecar share.
  volumes:
  - name: shared-logs
    emptyDir: {}

  # In the sidecar pattern, there is a main application
  # container and a sidecar container.
  containers:

  # Main application container
  - name: app-container
    # Simple application: write the current date
    # to the log file every five seconds
    image: alpine # alpine is a simple Linux OS image
    command: ["/bin/sh"]
    args: ["-c", "while true; do date >> /var/log/app.txt; sleep 5;done"]

    # Mount the pod's shared log file into the app
    # container. The app writes logs here.
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log

  # Sidecar container
  - name: sidecar-container
    # Simple sidecar: display log files using nginx.
    # In reality, this sidecar would be a custom image
    # that uploads logs to a third-party or storage service.
    image: nginx:1.7.9
    ports:
      - containerPort: 80

    # Mount the pod's shared log file into the sidecar
    # container. In this case, nginx will serve the files
    # in this directory.
    volumeMounts:
    - name: shared-logs
      mountPath: /usr/share/nginx/html # nginx-specific mount path

Execute the file

   kubectl apply -f pod.yaml

Connect to the sidecar pod

  kubectl exec pod-with-sidecar -c sidecar-container -it bash

Install curl on the sidecar

   apt-get update && apt-get install curl

Access the log file via the sidecar

   curl 'http://localhost:80/app.txt'


Adapter Container

It is a container that transforms main application data in such a way that it should be understood by an end system means it is used for data transformation.

For example, you are running pods with microservices that are to be monitored by a monitoring tool like Prometheus, but microservices are developed in different programming languages and these are generating data in different formats so in this case, we can apply an Adapter pattern to transform data which would be understood by Prometheus



Example


Create a Config Map which overwrites the default website of Nginx, lets call the file name  configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf
data:
  default.conf: |
    server {
      listen       80;
      server_name  localhost;
      location / {
          root   /usr/share/nginx/html;
          index  index.html index.htm;
      }
      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
          root   /usr/share/nginx/html;
      }
      location /nginx_status {
        stub_status;
        allow 127.0.0.1;  #only allow requests from localhost
        deny all;   #deny all other hosts
      }
    }

Create a Pod that implements the Adapter pattern to transform the data so that we can feed it to Prometheus. Let's have filename as adapter.yaml

apiVersion: v1
kind: Pod
metadata:
  name: webserver-1
  labels:
    app: webserver
spec:
  volumes:
    - name: nginx-conf
      configMap:
        name: nginx-conf
        items:
          - key: default.conf
            path: default.conf
  containers:
    - name: webserver
      image: nginx
      ports:
        - containerPort: 80
      volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: nginx-conf
          readOnly: true
    - name: adapter
      image: nginx/nginx-prometheus-exporter:0.4.2
      args: ["-nginx.scrape-uri","http://localhost/nginx_status"]
      ports:
        - containerPort: 9113

To access the application let's have a service.yaml file

apiVersion: v1
kind: Service
metadata:
  name: myapp-nodeport-service
  labels:
    app: myapp-service-httpd
    tier: frontend
spec:
  type: NodePort
  ports:
    - targetPort: 80
      port: 80
      nodePort: 30008
      name: nginx
    - targetPort: 9113
      port: 9113
      nodePort: 30009
      name: adaptor
  selector:
    app: webserver

Execute

    kubectl apply -f .

    kubectl exec -it webserver bash

    apt update && apt install curl -y

    curl localhost/nginx_status

    curl localhost:9113/metrics

 Ambassador Container

The Ambassador container is a special type of sidecar container which simplifies accessing services outside the Pod. When you are running applications on kubernetes it’s a high chance that you should access the data from the external services. The Ambassador container hides the complexity and provides the uniform interface to access these external services.

Imagine that you have the pod with one container running successfully but, you need to access external services. But, these external services are dynamic in nature or difficult to access. Sometimes there is a different format that external service returns. There are some other reasons as well and you don’t want to handle this complexity in the main container. So, we use the Ambassador containers to handle these kinds of scenarios


Example

Microservice for this example:-Fake API

Ambassador Container

Let’s look at the Ambassador container which is a simple NGINX server that acts as a reverse proxy. Here is the simple nginx.conf file.

worker_processes 4;

events { worker_connections 1024; }

http {
    server {
        listen 3000;
        location / {
            proxy_pass https://fakestoreapi.com/products;
        }
    }
}

Create a Docker file

FROM nginx:alpine

#!/bin/sh

COPY ./.nginx/nginx.conf /etc/nginx/nginx.conf

## Remove default nginx index page
RUN rm -rf /usr/share/nginx/html/*

EXPOSE 3000

ENTRYPOINT ["nginx", "-g", "daemon off;"]

Create a Docker image and push it to docker hub

    docker build -t nginx-server-proxy .

    docker tag nginx-server-proxy ramansharma95/nginx-server-proxy

    docker push ramansharma95/nginx-server-proxy

Main Container

The main container is the nodejs express server that serves on the port 9000. This server calls the reverse proxy and this proxy intern calls the actual API. Here is the server.js file.

Let's create files which are required for nodejs app

package.json

{
  "name": "main-container",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "request": "^2.88.2",
    "request-promise": "^4.2.6"
  }
}

package-lock.json

server.js

const express = require("express");
const app = express();
const port = 9000;
var rp = require('request-promise');

var options = {
    method: 'GET',
    uri: 'http://localhost:3000'
}

app.get("/", (req, res) => {
    rp(options).then(function (body) {
        res.json(JSON.parse(body))
    }).catch(function (err) {
        console.log(err);
    });
})

app.listen(port, () => {
    console.log('Server listening on port ', port);
})

Docker file

FROM node:slim

COPY ./package.json .

RUN npm install

COPY ./server.js .

CMD ["node", "server.js"]

Execute below commands

docker build -t main-container .

docker tag main-container ramansharma95/main-container

docker push ramansharma95/main-container

Create Pod(pod.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: ambassador-container
spec:
  containers:
  - image: ramansharma95/main-container
    name: main-container
    imagePullPolicy: Always
    resources: {}
    ports:
      - containerPort: 9000
  - image: ramansharma/nginx-server-proxy
    name: ambassador-container
    imagePullPolicy: Always
    resources: {}
    ports:
      - containerPort: 3000

Execute 



COMMENTS

Name

Ansible,6,AWS,1,Azure DevOps,1,Containerization with docker,2,DevOps,2,Docker Quiz,1,Docker Swarm,1,DockerCompose,1,ELK,2,git,2,Jira,1,Kubernetes,1,Kubernetes Quiz,5,SAST DAST Security Testing,1,SonarQube,3,Splunk,2,vagrant kubernetes,1,YAML Basics,1,
ltr
item
DevOpsWorld: Kubernetes Design Pattern - Side Car, Adapter, Ambassador containers
Kubernetes Design Pattern - Side Car, Adapter, Ambassador containers
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAXBVcqy6s6j0IUGNBp-ad3FjPVA_oR1AAiu9ES6JsOO3shDE3sLtRHKPV5FiUz8oOdruBLeKbCtQ1q43A1dL01MunXTAt1Yb28JX-KDQCUmPgNVdwS8j1AQ0gFvQ4tvMM5CP3-1ypW7t0jmFhJpXAOixy_R7Sf1Ubt0sxfiu1SxTAalkXqvpSuJaY/w530-h293/Kubernetes%20Patterns.jpg
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAXBVcqy6s6j0IUGNBp-ad3FjPVA_oR1AAiu9ES6JsOO3shDE3sLtRHKPV5FiUz8oOdruBLeKbCtQ1q43A1dL01MunXTAt1Yb28JX-KDQCUmPgNVdwS8j1AQ0gFvQ4tvMM5CP3-1ypW7t0jmFhJpXAOixy_R7Sf1Ubt0sxfiu1SxTAalkXqvpSuJaY/s72-w530-c-h293/Kubernetes%20Patterns.jpg
DevOpsWorld
https://www.devopsworld.co.in/2022/05/kubernetes-design-pattern-side-car.html
https://www.devopsworld.co.in/
https://www.devopsworld.co.in/
https://www.devopsworld.co.in/2022/05/kubernetes-design-pattern-side-car.html
true
5997357714110665304
UTF-8
Loaded All Posts Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS PREMIUM CONTENT IS LOCKED STEP 1: Share to a social network STEP 2: Click the link on your social network Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy Table of Content