The Longhorn volume for the *invoice-ninja* PVC got into a strange state following an unexpected shutdown this morning. One of its replicas seemed to have disappeared, and it also thought that the size had changed. As such, it got stuck in "expanding" state, but it was not actually being expanded. This issue is described in detail in the Longhorn documentation: [Troubleshooting: Unexpected expansion leads to degradation or attach failure][0]. Unfortunately, there is no way to recover a volume from that state, and it must be deleted and recreated from backup. This changes some of the properties of the PVC, so they need to be updated in the manifest. [0]: https://longhorn.io/kb/troubleshooting-unexpected-expansion-leads-to-degradation-or-attach-failure/
220 lines
5.6 KiB
YAML
220 lines
5.6 KiB
YAML
---
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: invoice-ninja
|
|
labels:
|
|
app.kubernetes.io/name: invoice-ninja
|
|
app.kubernetes.io/component: invoice-ninja
|
|
app.kubernetes.io/part-of: invoice-ninja
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteMany
|
|
resources:
|
|
requests:
|
|
storage: 3816Mi
|
|
storageClassName: longhorn-static
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: invoice-ninja
|
|
labels:
|
|
app.kubernetes.io/name: invoice-ninja
|
|
app.kubernetes.io/component: invoice-ninja
|
|
app.kubernetes.io/part-of: invoice-ninja
|
|
spec:
|
|
ports:
|
|
- port: 8000
|
|
targetPort: http
|
|
selector:
|
|
app.kubernetes.io/name: invoice-ninja
|
|
app.kubernetes.io/component: invoice-ninja
|
|
type: ClusterIP
|
|
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: invoice-ninja
|
|
labels:
|
|
app.kubernetes.io/name: invoice-ninja
|
|
app.kubernetes.io/component: invoice-ninja
|
|
app.kubernetes.io/part-of: invoice-ninja
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: invoice-ninja
|
|
app.kubernetes.io/component: invoice-ninja
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/name: invoice-ninja
|
|
app.kubernetes.io/component: invoice-ninja
|
|
app.kubernetes.io/part-of: invoice-ninja
|
|
spec:
|
|
initContainers:
|
|
- name: init
|
|
image: &image docker.io/invoiceninja/invoiceninja:5.8.16
|
|
command:
|
|
- /init.sh
|
|
securityContext:
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- CHOWN
|
|
readOnlyRootFilesystem: true
|
|
runAsGroup: 0
|
|
runAsNonRoot: false
|
|
runAsUser: 0
|
|
volumeMounts:
|
|
- mountPath: /app
|
|
name: app
|
|
- mountPath: /init.sh
|
|
name: init
|
|
subPath: init.sh
|
|
- mountPath: /storage
|
|
name: data
|
|
subPath: storage
|
|
containers:
|
|
- name: invoice-ninja
|
|
image: *image
|
|
env: &env
|
|
- name: DB_HOST
|
|
value: invoice-ninja-db
|
|
- name: DB_DATABASE
|
|
value: ninja
|
|
- name: DB_USERNAME
|
|
value: ninja
|
|
- name: DB_PASSWORD_FILE
|
|
value: /run/secrets/invoiceninja/db.password
|
|
- name: APP_KEY_FILE
|
|
value: /run/secrets/invoiceninja/app.key
|
|
- name: APP_CIPHER
|
|
value: AES-256-GCM
|
|
- name: TRUSTED_PROXIES
|
|
value: '*'
|
|
envFrom: &envFrom
|
|
- configMapRef:
|
|
name: invoice-ninja
|
|
readinessProbe: &probe
|
|
tcpSocket:
|
|
port: 9000
|
|
periodSeconds: 60
|
|
startupProbe:
|
|
<<: *probe
|
|
periodSeconds: 1
|
|
failureThreshold: 60
|
|
securityContext:
|
|
readOnlyRootFilesystem: true
|
|
volumeMounts: &mounts
|
|
- mountPath: /run/secrets/invoiceninja
|
|
name: secrets
|
|
readOnly: true
|
|
- mountPath: /tmp
|
|
name: tmp
|
|
subPath: tmp
|
|
- mountPath: /var/www/app
|
|
name: app
|
|
- mountPath: /var/www/app/public/storage
|
|
name: data
|
|
subPath: storage-public
|
|
- mountPath: /var/www/app/storage
|
|
name: data
|
|
subPath: storage
|
|
- mountPath: /var/www/app/storage/logs
|
|
name: tmp
|
|
subPath: logs
|
|
- name: nginx
|
|
image: docker.io/library/nginx:1
|
|
ports:
|
|
- containerPort: 8000
|
|
name: http
|
|
readinessProbe: &probe
|
|
httpGet:
|
|
port: 8000
|
|
path: /health
|
|
periodSeconds: 60
|
|
startupProbe:
|
|
<<: *probe
|
|
periodSeconds: 1
|
|
failureThreshold: 30
|
|
securityContext:
|
|
readOnlyRootFilesystem: true
|
|
runAsUser: 101
|
|
runAsGroup: 101
|
|
volumeMounts:
|
|
- mountPath: /etc/nginx/nginx.conf
|
|
name: nginx-conf
|
|
subPath: nginx.conf
|
|
readOnly: true
|
|
- mountPath: /run/nginx
|
|
name: run
|
|
subPath: nginx
|
|
- mountPath: /var/cache/nginx
|
|
name: nginx-cache
|
|
- mountPath: /var/www/app/public
|
|
name: app
|
|
subPath: public
|
|
readOnly: true
|
|
- mountPath: /var/www/app/public/storage
|
|
name: data
|
|
subPath: storage-public
|
|
readOnly: true
|
|
- name: cron
|
|
image: *image
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
cleanup() { kill -TERM $!; exit; }
|
|
trap cleanup TERM
|
|
while sleep 60; do php artisan schedule:run; done
|
|
env: *env
|
|
envFrom: *envFrom
|
|
securityContext:
|
|
readOnlyRootFilesystem: true
|
|
volumeMounts: *mounts
|
|
enableServiceLinks: false
|
|
affinity:
|
|
podAffinity:
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|
- weight: 1
|
|
podAffinityTerm:
|
|
topologyKey: kubernetes.io/hostname
|
|
labelSelector:
|
|
matchExpressions:
|
|
- key: app.kubernetes.io/name
|
|
operator: In
|
|
values:
|
|
- invoice-ninja-db
|
|
securityContext:
|
|
runAsNonRoot: True
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
volumes:
|
|
- name: app
|
|
emptyDir: {}
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: invoice-ninja
|
|
- name: init
|
|
configMap:
|
|
name: invoice-ninja-init
|
|
defaultMode: 0755
|
|
- name: nginx-cache
|
|
emptyDir: {}
|
|
- name: nginx-conf
|
|
configMap:
|
|
name: nginx
|
|
- name: run
|
|
emptyDir:
|
|
medium: Memory
|
|
- name: secrets
|
|
secret:
|
|
secretName: invoice-ninja
|
|
- name: tmp
|
|
emptyDir: {}
|