chore: adjustments for k8s deployment (#7531)
* chore: handle TERM in datatracker-start.sh * chore: delay celery start if migration needed * chore: skip-checks when migrating * chore: label beat/celery as deleteBeforeUpgrade Used by the infra-k8s deployment process to flag these as needing to be shut down before a new release rolls out. * chore: increase termination grace periods
This commit is contained in:
parent
bdc4b618bb
commit
c1941df7e7
|
@ -5,6 +5,14 @@
|
||||||
echo "Running Datatracker checks..."
|
echo "Running Datatracker checks..."
|
||||||
./ietf/manage.py check
|
./ietf/manage.py check
|
||||||
|
|
||||||
|
if ! ietf/manage.py migrate --skip-checks --check ; then
|
||||||
|
echo "Unapplied migrations found, waiting to start..."
|
||||||
|
sleep 5
|
||||||
|
while ! ietf/manage.py migrate --skip-checks --check ; do
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
cleanup () {
|
cleanup () {
|
||||||
# Cleanly terminate the celery app by sending it a TERM, then waiting for it to exit.
|
# Cleanly terminate the celery app by sending it a TERM, then waiting for it to exit.
|
||||||
if [[ -n "${celery_pid}" ]]; then
|
if [[ -n "${celery_pid}" ]]; then
|
||||||
|
|
|
@ -4,14 +4,29 @@ echo "Running Datatracker checks..."
|
||||||
./ietf/manage.py check
|
./ietf/manage.py check
|
||||||
|
|
||||||
echo "Running Datatracker migrations..."
|
echo "Running Datatracker migrations..."
|
||||||
./ietf/manage.py migrate --settings=settings_local
|
./ietf/manage.py migrate --skip-checks --settings=settings_local
|
||||||
|
|
||||||
echo "Starting Datatracker..."
|
echo "Starting Datatracker..."
|
||||||
|
|
||||||
|
# trap TERM and shut down gunicorn
|
||||||
|
cleanup () {
|
||||||
|
if [[ -n "${gunicorn_pid}" ]]; then
|
||||||
|
echo "Terminating gunicorn..."
|
||||||
|
kill -TERM "${gunicorn_pid}"
|
||||||
|
wait "${gunicorn_pid}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
trap 'trap "" TERM; cleanup' TERM
|
||||||
|
|
||||||
|
# start gunicorn in the background so we can trap the TERM signal
|
||||||
gunicorn \
|
gunicorn \
|
||||||
--workers "${DATATRACKER_GUNICORN_WORKERS:-9}" \
|
--workers "${DATATRACKER_GUNICORN_WORKERS:-9}" \
|
||||||
--max-requests "${DATATRACKER_GUNICORN_MAX_REQUESTS:-32768}" \
|
--max-requests "${DATATRACKER_GUNICORN_MAX_REQUESTS:-32768}" \
|
||||||
--timeout "${DATATRACKER_GUNICORN_TIMEOUT:-180}" \
|
--timeout "${DATATRACKER_GUNICORN_TIMEOUT:-180}" \
|
||||||
--bind :8000 \
|
--bind :8000 \
|
||||||
--log-level "${DATATRACKER_GUNICORN_LOG_LEVEL:-info}" \
|
--log-level "${DATATRACKER_GUNICORN_LOG_LEVEL:-info}" \
|
||||||
ietf.wsgi:application
|
${DATATRACKER_GUNICORN_EXTRA_ARGS} \
|
||||||
|
ietf.wsgi:application &
|
||||||
|
gunicorn_pid=$!
|
||||||
|
wait "${gunicorn_pid}"
|
||||||
|
|
124
k8s/beat.yaml
124
k8s/beat.yaml
|
@ -1,61 +1,63 @@
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: beat
|
name: beat
|
||||||
spec:
|
labels:
|
||||||
replicas: 1
|
deleteBeforeUpgrade: yes
|
||||||
revisionHistoryLimit: 2
|
spec:
|
||||||
selector:
|
replicas: 1
|
||||||
matchLabels:
|
revisionHistoryLimit: 2
|
||||||
app: beat
|
selector:
|
||||||
strategy:
|
matchLabels:
|
||||||
type: Recreate
|
app: beat
|
||||||
template:
|
strategy:
|
||||||
metadata:
|
type: Recreate
|
||||||
labels:
|
template:
|
||||||
app: beat
|
metadata:
|
||||||
spec:
|
labels:
|
||||||
securityContext:
|
app: beat
|
||||||
runAsNonRoot: true
|
spec:
|
||||||
containers:
|
securityContext:
|
||||||
- name: beat
|
runAsNonRoot: true
|
||||||
image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG"
|
containers:
|
||||||
imagePullPolicy: Always
|
- name: beat
|
||||||
ports:
|
image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG"
|
||||||
- containerPort: 8000
|
imagePullPolicy: Always
|
||||||
name: http
|
ports:
|
||||||
protocol: TCP
|
- containerPort: 8000
|
||||||
volumeMounts:
|
name: http
|
||||||
- name: dt-vol
|
protocol: TCP
|
||||||
mountPath: /a
|
volumeMounts:
|
||||||
- name: dt-tmp
|
- name: dt-vol
|
||||||
mountPath: /tmp
|
mountPath: /a
|
||||||
- name: dt-cfg
|
- name: dt-tmp
|
||||||
mountPath: /workspace/ietf/settings_local.py
|
mountPath: /tmp
|
||||||
subPath: settings_local.py
|
- name: dt-cfg
|
||||||
env:
|
mountPath: /workspace/ietf/settings_local.py
|
||||||
- name: "CONTAINER_ROLE"
|
subPath: settings_local.py
|
||||||
value: "beat"
|
env:
|
||||||
envFrom:
|
- name: "CONTAINER_ROLE"
|
||||||
- configMapRef:
|
value: "beat"
|
||||||
name: django-config
|
envFrom:
|
||||||
securityContext:
|
- configMapRef:
|
||||||
allowPrivilegeEscalation: false
|
name: django-config
|
||||||
capabilities:
|
securityContext:
|
||||||
drop:
|
allowPrivilegeEscalation: false
|
||||||
- ALL
|
capabilities:
|
||||||
readOnlyRootFilesystem: true
|
drop:
|
||||||
runAsUser: 1000
|
- ALL
|
||||||
runAsGroup: 1000
|
readOnlyRootFilesystem: true
|
||||||
volumes:
|
runAsUser: 1000
|
||||||
# To be overriden with the actual shared volume
|
runAsGroup: 1000
|
||||||
- name: dt-vol
|
volumes:
|
||||||
- name: dt-tmp
|
# To be overriden with the actual shared volume
|
||||||
emptyDir:
|
- name: dt-vol
|
||||||
sizeLimit: "2Gi"
|
- name: dt-tmp
|
||||||
- name: dt-cfg
|
emptyDir:
|
||||||
configMap:
|
sizeLimit: "2Gi"
|
||||||
name: files-cfgmap
|
- name: dt-cfg
|
||||||
dnsPolicy: ClusterFirst
|
configMap:
|
||||||
restartPolicy: Always
|
name: files-cfgmap
|
||||||
terminationGracePeriodSeconds: 30
|
dnsPolicy: ClusterFirst
|
||||||
|
restartPolicy: Always
|
||||||
|
terminationGracePeriodSeconds: 600
|
||||||
|
|
162
k8s/celery.yaml
162
k8s/celery.yaml
|
@ -1,80 +1,82 @@
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: celery
|
name: celery
|
||||||
spec:
|
labels:
|
||||||
replicas: 1
|
deleteBeforeUpgrade: yes
|
||||||
revisionHistoryLimit: 2
|
spec:
|
||||||
selector:
|
replicas: 1
|
||||||
matchLabels:
|
revisionHistoryLimit: 2
|
||||||
app: celery
|
selector:
|
||||||
strategy:
|
matchLabels:
|
||||||
type: Recreate
|
app: celery
|
||||||
template:
|
strategy:
|
||||||
metadata:
|
type: Recreate
|
||||||
labels:
|
template:
|
||||||
app: celery
|
metadata:
|
||||||
spec:
|
labels:
|
||||||
securityContext:
|
app: celery
|
||||||
runAsNonRoot: true
|
spec:
|
||||||
containers:
|
securityContext:
|
||||||
# -----------------------------------------------------
|
runAsNonRoot: true
|
||||||
# ScoutAPM Container
|
containers:
|
||||||
# -----------------------------------------------------
|
# -----------------------------------------------------
|
||||||
- name: scoutapm
|
# ScoutAPM Container
|
||||||
image: "scoutapp/scoutapm:version-1.4.0"
|
# -----------------------------------------------------
|
||||||
imagePullPolicy: IfNotPresent
|
- name: scoutapm
|
||||||
livenessProbe:
|
image: "scoutapp/scoutapm:version-1.4.0"
|
||||||
exec:
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
livenessProbe:
|
||||||
- "sh"
|
exec:
|
||||||
- "-c"
|
command:
|
||||||
- "./core-agent probe --tcp 0.0.0.0:6590 | grep -q 'Agent found'"
|
- "sh"
|
||||||
securityContext:
|
- "-c"
|
||||||
readOnlyRootFilesystem: true
|
- "./core-agent probe --tcp 0.0.0.0:6590 | grep -q 'Agent found'"
|
||||||
runAsUser: 65534 # "nobody" user by default
|
securityContext:
|
||||||
runAsGroup: 65534 # "nogroup" group by default
|
readOnlyRootFilesystem: true
|
||||||
# -----------------------------------------------------
|
runAsUser: 65534 # "nobody" user by default
|
||||||
# Celery Container
|
runAsGroup: 65534 # "nogroup" group by default
|
||||||
# -----------------------------------------------------
|
# -----------------------------------------------------
|
||||||
- name: celery
|
# Celery Container
|
||||||
image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG"
|
# -----------------------------------------------------
|
||||||
imagePullPolicy: Always
|
- name: celery
|
||||||
ports:
|
image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG"
|
||||||
- containerPort: 8000
|
imagePullPolicy: Always
|
||||||
name: http
|
ports:
|
||||||
protocol: TCP
|
- containerPort: 8000
|
||||||
volumeMounts:
|
name: http
|
||||||
- name: dt-vol
|
protocol: TCP
|
||||||
mountPath: /a
|
volumeMounts:
|
||||||
- name: dt-tmp
|
- name: dt-vol
|
||||||
mountPath: /tmp
|
mountPath: /a
|
||||||
- name: dt-cfg
|
- name: dt-tmp
|
||||||
mountPath: /workspace/ietf/settings_local.py
|
mountPath: /tmp
|
||||||
subPath: settings_local.py
|
- name: dt-cfg
|
||||||
env:
|
mountPath: /workspace/ietf/settings_local.py
|
||||||
- name: "CONTAINER_ROLE"
|
subPath: settings_local.py
|
||||||
value: "celery"
|
env:
|
||||||
envFrom:
|
- name: "CONTAINER_ROLE"
|
||||||
- configMapRef:
|
value: "celery"
|
||||||
name: django-config
|
envFrom:
|
||||||
securityContext:
|
- configMapRef:
|
||||||
allowPrivilegeEscalation: false
|
name: django-config
|
||||||
capabilities:
|
securityContext:
|
||||||
drop:
|
allowPrivilegeEscalation: false
|
||||||
- ALL
|
capabilities:
|
||||||
readOnlyRootFilesystem: true
|
drop:
|
||||||
runAsUser: 1000
|
- ALL
|
||||||
runAsGroup: 1000
|
readOnlyRootFilesystem: true
|
||||||
volumes:
|
runAsUser: 1000
|
||||||
# To be overriden with the actual shared volume
|
runAsGroup: 1000
|
||||||
- name: dt-vol
|
volumes:
|
||||||
- name: dt-tmp
|
# To be overriden with the actual shared volume
|
||||||
emptyDir:
|
- name: dt-vol
|
||||||
sizeLimit: "2Gi"
|
- name: dt-tmp
|
||||||
- name: dt-cfg
|
emptyDir:
|
||||||
configMap:
|
sizeLimit: "2Gi"
|
||||||
name: files-cfgmap
|
- name: dt-cfg
|
||||||
dnsPolicy: ClusterFirst
|
configMap:
|
||||||
restartPolicy: Always
|
name: files-cfgmap
|
||||||
terminationGracePeriodSeconds: 30
|
dnsPolicy: ClusterFirst
|
||||||
|
restartPolicy: Always
|
||||||
|
terminationGracePeriodSeconds: 600
|
||||||
|
|
|
@ -77,7 +77,7 @@ spec:
|
||||||
name: files-cfgmap
|
name: files-cfgmap
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
terminationGracePeriodSeconds: 30
|
terminationGracePeriodSeconds: 60
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
|
Loading…
Reference in a new issue