Kubernetes manifests examples

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my_app # deployment name
  namespace: kisphp
spec:
  selector:
    matchLabels:
      app: my_app # label for the deployment used by Service to connect
  template:
    metadata:
      labels:
        app: my_app
    spec:
      containers:
        - name: php # container name in pod
          image: my-php-fpm # docker image used for this container
          imagePullPolicy: Always # always get the docker image from registry
          ports:
            - containerPort: 9000 # port to communicate
          # load environment variables from config map
          envFrom:
            - configMapRef:
                name: my_app
          # load encoded secret from Secrets manifest
          env:
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: mysql_password
                  name: my_app
          # set resources
          resources:
            requests:
              memory: "64Mi"
              cpu: "10m"
            limits:
              memory: "512Mi"
              cpu: "100m"
          # (optional)
          lifecycle:
            # used to trigger actions after container starts
            postStart:
              exec:
                command:
                  - "/bin/bash"
                  - "-c"
                  - 'curl -s -X GET --max-time 3000 http://${SERVICE_NAME}.notifications.svc.cluster.local/start/${HOSTNAME}/php >&1; exit 0'
            # used to trigger actions before container stops
            preStop:
              exec:
                command:
                  - "/bin/bash"
                  - "-c"
                  - 'curl -s -X GET --max-time 3000 http://${SERVICE_NAME}.notifications.svc.cluster.local/stop/${HOSTNAME}/php >&1; exit 0'
          # mount volumes for this container
          volumeMounts:
            # thumbnails volume
            - mountPath: /app/web/thumbs
              name: thumbnails
            # files uploads volume
            - mountPath: /uploads
              name: uploads
        # similar to above explanations
        - name: nginx
          image: my-nginx
          imagePullPolicy: Always
          ports:
            - containerPort: 80
          envFrom:
            - configMapRef:
                name: my_app
          resources:
            requests:
              memory: "32Mi"
              cpu: "10m"
            limits:
              memory: "256Mi"
              cpu: "100m"
          lifecycle:
            postStart:
              exec:
                command:
                  - "/bin/bash"
                  - "-c"
                  - 'curl -s -X GET --max-time 3000 http://${SERVICE_NAME}.notifications.svc.cluster.local/start/${HOSTNAME}/php >&1; exit 0'
            preStop:
              exec:
                command:
                  - "/bin/bash"
                  - "-c"
                  - 'curl -s -X GET --max-time 3000 http://${SERVICE_NAME}.notifications.svc.cluster.local/stop/${HOSTNAME}/php >&1; exit 0'
          volumeMounts:
            - mountPath: /app/web/thumbs
              name: thumbnails
      # all init containers will run before the main containers
      initContainers:
        - name: update-database
          image: my-app-nginx
          envFrom:
            - configMapRef:
                name: my-app-config
          command:
            - "bin/console"
            - "setup:install"
      # set volumes per deployment that will be used by containers using volumeMounts
      volumes:
        # define thumbnails directory as empty volume every time
        - name: thumbnails
          emptyDir: {}
        # load uploads directory from PersistentVolumeClaim
        - name: uploads
          persistentVolumeClaim:
            claimName: my-app-uploads
apiVersion: v1
kind: Service
metadata:
  name: my-app        # name of the service
  namespace: kisphp   # namespace for the service (must be the same for all)
spec:
  type: NodePort      # ClusterIP, LoadBalancer
  selector:
    app: my_app       # must match the label from Deployment
  ports:
    - port: 80        # service port to listen
      targetPort: 80  # container port defined in deployment
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-app
  namespace: kisphp
  annotations:
    controller.scope.enabled: "true"
    controller.scope.namespace: "kisphp"
spec:
  # (optional) if you want to listen to 443 port
  tls:
    - hosts:
        - www.example.com
      secretName: example.com-tls # secret defined for SSL certificate
  # rules for the application routes
  rules:
    - host: www.example.com       # host to listen to
      http:
        paths:
          - backend:
              serviceName: my-app # service name for the application
              servicePort: 80     # service port to communicate
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-app-config # config map name, will be used by deployments, cronjobs, etc
  namespace: kisphp
data:
  SYMFONY_ENV: prod

  MYSQL_HOST: "127.0.0.1"
  MYSQL_USER: mysql_username_here

  UPLOAD_DIRECTORY: /data/uploads
apiVersion: v1
kind: Secret
metadata:
  name: my-app-secrets
  namespace: kisphp
data:
  my_db_password: a2lzcGhw # base64 encoded
  redis_password: a2lzcGhw # base64 encoded
apiVersion: v1
kind: PersistentVolume
metadata:
  name: uploaded-files
  # PVs don't have a namespace
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: /mnt/nfs/uploaded_files
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-app-uploads
  namespace: kisphp
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 20Gi
# if you define PVC for AWS EFS, just set the storage to 1Gi, no matter how big the EFS is
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: my-cron-job
  namespace: kisphp
  labels:
    app: my-cron-job
spec:
  schedule: "* * * * *" # run every minute
  concurrencyPolicy: Forbid # do not allow concurent jobs
  successfulJobsHistoryLimit: 0 # delete successful pods
  failedJobsHistoryLimit: 2 # keep last 2 failed pods for debug
  startingDeadlineSeconds: 120
  suspend: false
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: my-cron-job
        spec:
          restartPolicy: Never
          nodeSelector:
            type: cron
          containers:
            # name of the container in pod
            - name: app-cron
              # docker image to load for this container
              image: my-php-container:tag_name
              # always download image from registry
              imagePullPolicy: Always
              # define necessary resources for this container
              resources:
                requests:
                  cpu: "1"
                  memory: "256Mi"
                limits:
                  cpu: "1"
                  memory: "1Gi"
              # load all variables defined in config map
              envFrom:
                - configMapRef:
                    name: my-app-config
              env:
                # set inline variable for container
                - name: CONTAINER_PURPOSE
                  value: cron
                # register a secret (password) to env vars from secrets manifests
                - name: MYSQL_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: my-app-secrets #
                      key: my_db_password # reference to variable name in secrets manifest
              command:
                - vendor/bin/codecept
              args:
                - run
                - "--dry-run"
              volumeMounts:
                - name: project-data
                  mountPath: /stored_data
          volumes:
            # using aws EFS
            - name: project-data
              nfs:
                server: 1a2b3c4d.efs.eu-central-1.amazonaws.com
                path: /
            # using PVC
            - name: uploads
              persistentVolumeClaim:
                claimName: uploaded-files
apiVersion: batch/v1
kind: Job
metadata:
  name: thumb-cleanup
  namespace: kisphp
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: php
          image: my-custom-container
          imagePullPolicy: Always
          envFrom:
            - configMapRef:
                name: my-config
          command:
            - vendor/bin/console
            - cleanup:thumbs
          env:
            - name: CONTAINER_PURPOSE
              value: job
            - name: MY_DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-password
                  key: password