-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mrc-4908 k8s setup #1
Changes from 9 commits
eb5618b
69d5f98
4fc22d8
6e4e6c7
7badd77
1078b51
55e8329
37c5cfd
472a689
31b18a4
a6f2fa5
16ad36d
8b19073
d5fd1c4
bc066f3
9a9c8f0
526208e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
apache/ssl | ||
k8s/ssl |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -33,7 +33,7 @@ Some applications (copied over from the original deployment are in `apps`). Thes | |||||
|
||||||
## Bringing the bits up | ||||||
|
||||||
``` | ||||||
```bash | ||||||
docker network create twinkle 2> /dev/null || /bin/true | ||||||
docker volume create shiny_logs | ||||||
docker run -d --name haproxy --network twinkle mrcide/haproxy:dev | ||||||
|
@@ -55,7 +55,26 @@ docker exec haproxy update_shiny_servers shiny 1 | |||||
|
||||||
Teardown | ||||||
|
||||||
``` | ||||||
```bash | ||||||
docker rm -f haproxy apache shiny-1 | ||||||
docker network rm twinkle | ||||||
``` | ||||||
|
||||||
## Running in Kubernetes | ||||||
|
||||||
The following is guide to run the shiny server in kubernetes. They are based on running a Kind cluster. The configuration may | ||||||
nee to be adjusted for other k8s clusters. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
### Prerequisites | ||||||
|
||||||
A production kubernetes cluster using k3s is needed to be setup first. To setup a k8s cluster follow the guide [here](https://mrc-ide.myjetbrains.com/youtrack/articles/RESIDE-A-31/Setting-up-Kubernetes-k8s-Cluster). Note: If using dev cluster (KIND), the storageClassName: local-path & longhorn is unavailable and you will need to provision own storage class and persistant volume. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does the recommended setup look like for developing this locally? or on a staging machine (separate from the shiny staging, which is really for the users)? Do we need a second cluster somewhere that we use? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the link shows the dev and prod setup and they both can be used locally... for staging, we can use the same cluster and just do another deployment and rename the deployment to something else... But if you wanted a seperate machine for just staging spinning up another cluster might be easiest There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sorry, don't really understand this. Why aren't these available? You talk about using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. have updated to avoid confusion |
||||||
|
||||||
Run `start-k8s-shiny <env>` to run the shint server in k8s. | ||||||
|
||||||
|
||||||
#### Teardown | ||||||
|
||||||
Run the following: | ||||||
|
||||||
1. `kubectl delete -k k8s/overlays/<env>`. Replace <env> with staging or production. | ||||||
2. `kubectl delete ns twinkle` to remove namespace. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: shiny-deploy | ||
labels: | ||
app: shiny | ||
spec: | ||
replicas: 2 | ||
selector: | ||
matchLabels: | ||
app: shiny | ||
template: | ||
metadata: | ||
labels: | ||
app: shiny | ||
spec: | ||
initContainers: | ||
- name: init-shiny | ||
image: busybox:1.28 | ||
command: ["sh", "-c", "mkdir -p /shiny/logs /shiny/apps"] | ||
volumeMounts: | ||
- name: shiny-data | ||
mountPath: /shiny | ||
containers: | ||
- name: shiny | ||
image: absternator/shiny-server:dev # todo: change to actual one!!! mrcide- | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What changes did you make here? Can we get the image build script/Dockerfile here and building on BK? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just changed the image so it has an image to pull from the docker hub... i can add the docker build & push step to the startup script? is that you want? ps.. sorry whats BK? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BK=BuildKite, where we have some non-gha CI builds running, |
||
volumeMounts: | ||
- name: shiny-data | ||
mountPath: /shiny | ||
# todo: create appropriate resource requests and limits | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the consequence of these limits? Are they speculative (affecting scheduling) or caps (meaning the scheduler kills processes that exceed them)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have updated comments but i think usually requests are set or nothing is fine most of the time ... the most common is to set up requests so that each pod has allocated specific resources before being scheduled... |
||
# resources: | ||
# requests: | ||
# memory: "128Mi" | ||
# cpu: "250m" | ||
volumes: | ||
- name: shiny-data | ||
persistentVolumeClaim: | ||
claimName: shiny-pvc |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
apiVersion: networking.k8s.io/v1 | ||
kind: Ingress | ||
metadata: | ||
name: ingress-shiny | ||
annotations: | ||
nginx.ingress.kubernetes.io/affinity: "cookie" | ||
nginx.ingress.kubernetes.io/session-cookie-name: "shinycookie" | ||
nginx.ingress.kubernetes.io/session-cookie-expires: "172800" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this in seconds? 48 hours? Seems reasonable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yup in seconds... 48 hours |
||
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800" | ||
spec: | ||
ingressClassName: nginx | ||
tls: | ||
- hosts: | ||
- shiny-dev.dide.ic.ac.uk | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we'll need to update this setting for prod, and for running locally? |
||
secretName: tls-secret | ||
rules: | ||
- host: shiny-dev.dide.ic.ac.uk | ||
http: | ||
paths: | ||
- path: / | ||
pathType: Prefix | ||
backend: | ||
service: | ||
name: shiny-svc | ||
port: | ||
number: 3838 |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,12 @@ | ||||||
apiVersion: kustomize.config.k8s.io/v1beta1 | ||||||
kind: Kustomization | ||||||
metadata: | ||||||
name: shiny | ||||||
|
||||||
namespace: twinkle # assume this namespace exists | ||||||
|
||||||
resources: | ||||||
- persistance.yaml | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
- deployment.yaml | ||||||
- service.yaml | ||||||
- ingress.yaml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# todo: storage capacity as per requirements | ||
# can use local-path if single node or dont need distributed & replicated | ||
apiVersion: v1 | ||
kind: PersistentVolumeClaim | ||
metadata: | ||
name: shiny-pvc | ||
spec: | ||
storageClassName: longhorn | ||
accessModes: | ||
- ReadWriteMany | ||
resources: | ||
requests: | ||
storage: 15Gi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: shiny-svc | ||
spec: | ||
type: ClusterIP | ||
selector: | ||
app: shiny | ||
ports: | ||
- protocol: TCP | ||
port: 3838 | ||
targetPort: 3838 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/usr/bin/env bash | ||
|
||
export VAULT_ADDR=https://vault.dide.ic.ac.uk:8200 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a k8s/vault adaptor to make this easier? Not necessarily for this PR, but feels like something we might do a bunch of we do more with this style. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. il have a look into that... in the past when we stored secerts in azure key vault we would run and get the secrets in CI and create the secret that way so kubernetes could use it... but il see if there is other ways |
||
export VAULT_TOKEN=$(vault login -method=github -token-only) | ||
|
||
DEST=${PWD}/k8s/ssl | ||
mkdir -p $DEST | ||
|
||
vault read -field=value /secret/shiny.dide/dev/ssl/cert > \ | ||
${DEST}/certificate.pem | ||
vault read -field=value /secret/shiny.dide/dev/ssl/key > \ | ||
${DEST}/key.pem | ||
|
||
kubectl -n twinkle create secret tls tls-secret --cert ${DEST}/certificate.pem --key ${DEST}/key.pem |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env bash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this script do? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pretty much coppies files from host machine into a kubernetes pod using rsync |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest some hardening of your bash scripts (basically any time you write one). In general we end up with:
which will cause the script to fail if any line errors or if you reference an undefined variable. |
||
# https://serverfault.com/questions/741670/rsync-files-to-a-kubernetes-pod | ||
# example usage: | ||
# ./krsync -av --progress --stats <hostdir> podName@namespace:<poddir> | ||
|
||
if [ -z "$KRSYNC_STARTED" ]; then | ||
export KRSYNC_STARTED=true | ||
exec rsync -a --delete --blocking-io --rsh "$0" $@ | ||
fi | ||
|
||
# Running as --rsh | ||
namespace='' | ||
pod=$1 | ||
shift | ||
|
||
# If user uses pod@namespace, rsync passes args as: {us} -l pod namespace ... | ||
if [ "X$pod" = "X-l" ]; then | ||
pod=$1 | ||
shift | ||
namespace="-n $1" | ||
shift | ||
fi | ||
|
||
# customise this to cluster needs!! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What sort of customisation is expected here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. loose comment when i first did have now removed |
||
exec kubectl $namespace exec -i $pod -- "$@" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
apiVersion: kustomize.config.k8s.io/v1beta1 | ||
kind: Kustomization | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤨 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😕 ? |
||
|
||
resources: | ||
- ../../base | ||
|
||
commonLabels: | ||
env: production | ||
|
||
replicas: | ||
- name: shiny-deploy | ||
count: 9 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
apiVersion: kustomize.config.k8s.io/v1beta1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably will need a name for what the users think of staging that won't confuse us - preview or testing perhaps? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. have changed naming to testing... because you are right we dont have a specific staging k8s cluster |
||
kind: Kustomization | ||
|
||
resources: | ||
- ../../base | ||
|
||
commonLabels: | ||
env: staging | ||
|
||
replicas: | ||
- name: shiny-deploy | ||
count: 3 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/usr/bin/env bash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is just a temporary thing until we have the management bit working? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yup temporary until we sort the management side |
||
|
||
# uses krysnc to sync files to a kubernetes pod and thus into k8s cluster (via persistant volume) | ||
# RUN this from repository root to ensure correct paths to app files | ||
NAMESPACE=twinkle | ||
SYNC_DIR=/shiny/apps | ||
|
||
|
||
FIRST_SHINY_POD=$(kubectl get pods -l app=shiny -n $NAMESPACE -o jsonpath='{.items[0].metadata.name}') | ||
echo "pod name: $FIRST_SHINY_POD" | ||
$PWD/k8s/krsync -av --progress --stats $PWD/apps/* $FIRST_SHINY_POD@$NAMESPACE:$SYNC_DIR |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/usr/bin/env bash | ||
|
||
# example use case: ./start-k8s-shiny production | ||
|
||
# Set the environment variable to the first command-line argument or default to 'staging' | ||
ENV=${1:-staging} | ||
if [[ "$ENV" != "staging" && "$ENV" != "production" ]]; then | ||
echo "Error: env must be either 'staging' or 'production'" | ||
exit 1 | ||
fi | ||
# Make the script itself executable | ||
chmod +x "$0" | ||
|
||
# Make the k8s directory and its contents executable | ||
chmod +x k8s/ | ||
|
||
# Create a Kubernetes namespace named 'twinkle' | ||
kubectl create ns twinkle | ||
|
||
# Run the script to configure SSL (assuming it's in the k8s directory) | ||
k8s/configure_ssl || { echo "Error: Failed to configure SSL"; exit 1; } | ||
|
||
# Apply Kubernetes manifests from overlays based on the specified or default environment | ||
kubectl apply -k "k8s/overlays/$ENV" | ||
|
||
# Wait for the 'shiny-deploy' deployment to be in the 'available' condition within the 'twinkle' namespace | ||
echo 'Waiting for pods to be ready...' | ||
kubectl wait -n twinkle --for=condition=available --timeout=300s deployment/shiny-deploy | ||
|
||
# Run the script for 'shiny-sync' (assuming it's in the k8s directory) | ||
k8s/shiny-sync |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest you remove the docker instructions and the haproxy/httpd bits entirely