Kubernetes : Launch a single container inside existing cluster, for running cron jobs

1/30/2020

I am working on Kubernetes cluster, where I want to run a single container which runs cron jobs. In the same cluster, I am deploying 3 other containers, which run app-code. What are the changes required just to add a different type of container in the same cluster?

service.yaml :

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: supplier-service
    app.kubernetes.io/instance: supplier-service-instance
    app.kubernetes.io/version: "1.0.0"
    app.kubernetes.io/component: backend
    app.kubernetes.io/managed-by: kubectl
  annotations:
      # Note that the backend talks over HTTP.
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
       # TODO: Fill in with the ARN of your certificate.
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: OUR_ARN
       # Only run SSL on the port named "https" below.
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https
    service.beta.kubernetes.io/do-loadbalancer-redirect-http-to-https: "true"
    service.beta.kubernetes.io/do-loadbalancer-tls-ports: "443"
  name: supplier-service

spec:
  selector:
    app: supplier-service
  type: LoadBalancer
  ports:
  - name: http
    port: 80
    targetPort: 80
  - name: https
    port: 443
    targetPort: 443

deployment.yaml -- this Yaml file runs app-code

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: supplier-service
    app.kubernetes.io/instance: supplier-service-instance
    app.kubernetes.io/version: '1.0.0'
    app.kubernetes.io/managed-by: kubectl
  name: supplier-service-deployment
spec:
  replicas: 3
  strategy:
     type: RollingUpdate
     rollingUpdate:
        maxUnavailable: 25%
        maxSurge: 1
  selector:
    matchLabels: 
      app: supplier-service
  template: 
    metadata:
      labels: 
        app: supplier-service
    spec:
      containers:
        - image: IMAGE-FROM-ECR/supplier-service:latest
          imagePullPolicy: Always
          name: supplier-service
          ports: 
            - containerPort: 80
            - containerPort: 443
            - containerPort: 6379

I have a new DockerFile ready which installs cron jobs inside the container.

deployment-cron.yaml :

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: supplier-service
    app.kubernetes.io/instance: supplier-service-instance
    app.kubernetes.io/version: '1.0.0'
    app.kubernetes.io/managed-by: kubectl
  name: supplier-service-deployment
spec:
  replicas: 1
  strategy:
     type: RollingUpdate
     rollingUpdate:
        maxUnavailable: 25%
        maxSurge: 1
  selector:
    matchLabels: 
      app: supplier-service
  template: 
    metadata:
      labels: 
        app: supplier-service
    spec:
      containers:
        - image: AWS-ECR/supplier-service-cron:latest
          imagePullPolicy: Always
          name: supplier-service
          ports: 
            - containerPort: 80
            - containerPort: 443
            - containerPort: 6379

Is this the correct way to run a single container inside existing cluster, or are there any other changes required? Thank you. :-)

-- We are Borg
cron
docker
kubernetes

2 Answers

1/30/2020

The naming and labels need to be changed from the original deployment yaml.

If you leave metadata.name the same, you would modify the existing deployment on a kubectl apply -f rather than creating a new deployment.

I don't think you need the ports if all your running is cron, unless it's running a full instance of the supplier-service

The existing Service selector would get confused if you leave the label app: supplier-service on your cron container.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: supplier-service
    app.kubernetes.io/instance: supplier-service-instance
    app.kubernetes.io/version: '1.0.0'
    app.kubernetes.io/managed-by: kubectl
  name: supplier-service-cron-deployment
spec:
  replicas: 1
  selector:
    matchLabels: 
      app: supplier-service-cron
  template: 
    metadata:
      labels: 
        app: supplier-service-cron
    spec:
      containers:
        - image: AWS-ECR/supplier-service-cron:latest
          imagePullPolicy: Always
          name: supplier-service-cron

Also kubernetes provides a standalone cronjob functionality in case you weren't aware.

-- Matt
Source: StackOverflow

1/30/2020

Above approach will throw an error to you when you try to deploy two deployments with same name in same namespace.

Example of what you are trying to do is as below

$ cat deploy1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    deployment1: One
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      deployment1: One
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        deployment1: One
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

$ cat deploy2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    deployment2: Two
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      deployment2: Two
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        deployment2: Two
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

Create first deployment.

$ kubectl create -f deploy1.yaml
deployment.apps/nginx created

Create second in same namespace and you should see this error.

$ kubectl create -f deploy2.yaml
Error from server (AlreadyExists): error when creating "deploy2.yaml": deployments.apps "nginx" already exists
-- DT.
Source: StackOverflow