Skip to main content
Kubernetes

Two or more replicas behind a ClusterIP Service, reachable only from your back-end.

Markdown

Prerequisites​

  • A Kubernetes cluster and kubectl access to it.
  • A PostgreSQL database dedicated to Human Plugin, reachable from the cluster. See Prerequisites and access.
  • The registry credentials and the access key from Unico.

Everything below goes in a namespace of its own:

kubectl create namespace human-plugin

1. Registry pull secret​

kubectl -n human-plugin create secret docker-registry unico-registry \
--docker-server=pkg.unico.run \
--docker-username="<username>" \
--docker-password="<token>"

2. Settings Secret​

kubectl -n human-plugin create secret generic human-plugin \
--from-literal=HUMAN_API_ACCESS_KEY='<your access key>' \
--from-literal=POSTGRES_ADDRESS_HOST='<database host>' \
--from-literal=POSTGRES_USER='human_plugin' \
--from-literal=POSTGRES_PASSWORD='<database password>'

Add POSTGRES_ADDRESS_PORT, POSTGRES_DATABASE or POSTGRES_SSL_MODE only if your database differs from the defaults in Configuration. If you manage secrets with another tool (External Secrets, Sealed Secrets, a vault), create the same keys with it. Never commit a Secret manifest with values.

3. Deployment and Service​

human-plugin.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: human-plugin
namespace: human-plugin
spec:
replicas: 2
selector:
matchLabels: { app: human-plugin }
template:
metadata:
labels: { app: human-plugin }
spec:
terminationGracePeriodSeconds: 60
imagePullSecrets:
- name: unico-registry
containers:
- name: human-plugin
image: pkg.unico.run/human-plugin-api:latest
imagePullPolicy: Always
ports:
- { name: http, containerPort: 8080 }
envFrom:
- secretRef: { name: human-plugin }
resources:
requests: { cpu: "1", memory: 1Gi }
limits: { cpu: "1", memory: 1Gi }
readinessProbe:
httpGet: { path: /health/ready, port: http }
timeoutSeconds: 5
livenessProbe:
httpGet: { path: /health/live, port: http }
periodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: human-plugin
namespace: human-plugin
spec:
selector: { app: human-plugin }
ports:
- { name: http, port: 8080, targetPort: http }
kubectl apply -f human-plugin.yaml
kubectl -n human-plugin rollout status deployment/human-plugin
  • replicas: 2: replicas share the database, so you can run as many as you need. Two keep Human Plugin available while one restarts.
  • terminationGracePeriodSeconds: 60: Human Plugin waits up to 55 seconds for requests in flight when it stops. The Kubernetes default, 30 seconds, can cut a create short.
  • imagePullPolicy: Always: with the latest tag, each new Pod pulls the most recent release.
  • Probes: readiness keeps traffic away from a replica until its database answers, and timeoutSeconds: 5 makes it fail when the database stops answering. See Health and monitoring.
  • Resources: the values above are the minimum for each replica. See Hardware requirements.

4. Restrict access​

Your back-end reaches Human Plugin at http://human-plugin.human-plugin.svc:8080. Human Plugin has no authentication of its own, so:

  • do not expose the Service through an Ingress, a LoadBalancer or a NodePort;
  • allow only your back-end's namespace with a NetworkPolicy.
network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: human-plugin-allow-backend
namespace: human-plugin
spec:
podSelector:
matchLabels: { app: human-plugin }
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels: { kubernetes.io/metadata.name: <your back-end namespace> }
ports:
- { port: 8080 }

Human Plugin itself needs outbound HTTPS to Unico and access to your database. See Networking and security.

5. Validate​

kubectl -n human-plugin port-forward svc/human-plugin 8080:8080

In another terminal, check readiness and run the Quickstart create request against http://127.0.0.1:8080:

curl --fail http://127.0.0.1:8080/health/ready

Logs​

kubectl -n human-plugin logs deploy/human-plugin --since=10m

Update​

kubectl -n human-plugin rollout restart deployment/human-plugin

The new Pods pull the latest image and replace the old ones one at a time, once they are ready. See Operations.