Skip to content

Commit 7632dbb

Browse files
Evgeny ShvarovEvgeny Shvarov
authored andcommitted
deploy to k8s
1 parent 8fc0894 commit 7632dbb

7 files changed

Lines changed: 296 additions & 1 deletion

File tree

.github/workflows/workflow.yaml

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
name: Build DC-analytics image, deploy it to GCR. Run GKE. Run DC-analytics in GKE
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
9+
# Environment variables.
10+
# ${{ secrets }} are taken from GitHub -> Settings -> Secrets
11+
# ${{ github.sha }} is the commit hash
12+
env:
13+
PROJECT_ID: iris-community-demos
14+
SERVICE_ACCOUNT_KEY: ${{ secrets.SERVICE_ACCOUNT_KEY }}
15+
GOOGLE_CREDENTIALS: ${{ secrets.TF_SERVICE_ACCOUNT_KEY }}
16+
GITHUB_SHA: ${{ github.sha }}
17+
GCR_LOCATION: eu.gcr.io
18+
IMAGE_NAME: dc-analytics-image
19+
GKE_CLUSTER: dc-analytics-cluster
20+
GKE_ZONE: europe-west1-b
21+
K8S_NAMESPACE: iris
22+
STATEFULSET_NAME: dc-analytics
23+
24+
jobs:
25+
gcloud-setup-and-build-and-publish-to-GCR:
26+
name: Setup gcloud utility, Build DC-ANALYTICS image and Publish it to Container Registry
27+
runs-on: ubuntu-18.04
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@v2
31+
32+
- name: Setup gcloud cli
33+
uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
34+
with:
35+
version: '275.0.0'
36+
service_account_key: ${{ secrets.SERVICE_ACCOUNT_KEY }}
37+
38+
- name: Configure docker to use the gcloud as a credential helper
39+
run: |
40+
gcloud auth configure-docker
41+
42+
- name: Build DC-ANALYTICS image
43+
run: |
44+
docker build -t ${GCR_LOCATION}/${PROJECT_ID}/${IMAGE_NAME}:${GITHUB_SHA} .
45+
46+
- name: Publish DC-ANALYTICS image to Google Container Registry
47+
run: |
48+
docker push ${GCR_LOCATION}/${PROJECT_ID}/${IMAGE_NAME}:${GITHUB_SHA}
49+
50+
gke-provisioner:
51+
# Inspired by:
52+
## https://www.terraform.io/docs/github-actions/getting-started.html
53+
## https://github.com/hashicorp/terraform-github-actions
54+
name: Provision GKE cluster
55+
runs-on: ubuntu-18.04
56+
steps:
57+
- name: Checkout
58+
uses: actions/checkout@v2
59+
60+
- name: Terraform init
61+
uses: hashicorp/terraform-github-actions@master
62+
with:
63+
tf_actions_version: 0.12.17
64+
tf_actions_subcommand: 'init'
65+
tf_actions_working_dir: 'terraform'
66+
67+
- name: Terraform validate
68+
uses: hashicorp/terraform-github-actions@master
69+
with:
70+
tf_actions_version: 0.12.17
71+
tf_actions_subcommand: 'validate'
72+
tf_actions_working_dir: 'terraform'
73+
74+
- name: Terraform plan
75+
uses: hashicorp/terraform-github-actions@master
76+
with:
77+
tf_actions_version: 0.12.17
78+
tf_actions_subcommand: 'plan'
79+
tf_actions_working_dir: 'terraform'
80+
81+
- name: Terraform apply
82+
uses: hashicorp/terraform-github-actions@master
83+
with:
84+
tf_actions_version: 0.12.17
85+
tf_actions_subcommand: 'apply'
86+
tf_actions_working_dir: 'terraform'
87+
88+
kubernetes-deploy:
89+
name: Deploy Kubernetes manifests to GKE cluster
90+
needs:
91+
- gcloud-setup-and-build-and-publish-to-GCR
92+
- gke-provisioner
93+
runs-on: ubuntu-18.04
94+
steps:
95+
- name: Checkout
96+
uses: actions/checkout@v2
97+
98+
- name: Replace placeholders with values in statefulset template
99+
working-directory: ./k8s/
100+
run: |
101+
cat statefulset.tpl |\
102+
sed "s|DOCKER_REPO_NAME|${GCR_LOCATION}/${PROJECT_ID}/${IMAGE_NAME}|" |\
103+
sed "s|DOCKER_IMAGE_TAG|${GITHUB_SHA}|" > statefulset.yaml
104+
cat statefulset.yaml
105+
106+
- name: Setup gcloud cli
107+
uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
108+
with:
109+
version: '275.0.0'
110+
service_account_key: ${{ secrets.SERVICE_ACCOUNT_KEY }}
111+
112+
- name: Apply Kubernetes manifests
113+
working-directory: ./k8s/
114+
run: |
115+
gcloud container clusters get-credentials ${GKE_CLUSTER} --zone ${GKE_ZONE} --project ${PROJECT_ID}
116+
kubectl apply -f namespace.yaml
117+
kubectl apply -f service.yaml
118+
kubectl apply -f statefulset.yaml
119+
kubectl -n ${K8S_NAMESPACE} rollout status statefulset/${STATEFULSET_NAME}

dev.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,11 @@ docker-compose exec iris iris session iris -U IRISAPP
1717
```
1818

1919
## global export
20+
```
2021
$System.OBJ.Export("GlobalName.GBL","/irisdev/app/src/gbl/globalname.xml")
22+
```
23+
24+
## service account key base64 command
25+
```
26+
$ base64 iris-community-demos-09899421cfc4.json | tr -d '\n'
2127
```

k8s/namespace.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: iris

k8s/service.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: dc-analytics
5+
namespace: iris
6+
spec:
7+
selector:
8+
app: dc-analytics
9+
ports:
10+
- name: web
11+
protocol: TCP
12+
port: 52773
13+
targetPort: 52773
14+
- name: super
15+
protocol: TCP
16+
port: 51773
17+
targetPort: 51773
18+
type: LoadBalancer

k8s/statefulset.tpl

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
apiVersion: apps/v1beta1
2+
kind: StatefulSet
3+
metadata:
4+
name: dc-analytics
5+
namespace: iris
6+
spec:
7+
serviceName: dc-analytics
8+
replicas: 1
9+
updateStrategy:
10+
type: RollingUpdate
11+
selector:
12+
matchLabels:
13+
app: dc-analytics
14+
template:
15+
metadata:
16+
labels:
17+
app: dc-analytics
18+
spec:
19+
20+
initContainers:
21+
- name: dc-volume-change-owner-hack
22+
image: busybox
23+
command:
24+
- sh
25+
- -c
26+
- |
27+
chown -R 51773:52773 /opt/dcanalytics/DCANALYTICS-DATA
28+
chmod g+w /opt/dcanalytics/DCANALYTICS-DATA
29+
echo -e "zn \"%sys\"\nif (##class(SYS.Database).%ExistsId(\"/opt/dcanalytics/DCANALYTICS-DATA\")) { halt }\nset db=##class(SYS.Database).%New()\nset db.Directory=\"/opt/dcanalytics/DCANALYTICS-DATA\"\nset db.ResourceName=\"%DB_DCANALYTICS\"\nwrite db.%Save()\nhalt" > /mount-helper/mount_dcanalytics_data
30+
volumeMounts:
31+
- mountPath: /opt/dcanalytics/DCANALYTICS-DATA
32+
name: dc-volume
33+
- mountPath: /mount-helper
34+
name: mount-helper
35+
volumes:
36+
- emptyDir: {}
37+
name: mount-helper
38+
containers:
39+
- image: DOCKER_REPO_NAME:DOCKER_IMAGE_TAG
40+
name: dc-analytics
41+
lifecycle:
42+
postStart:
43+
exec:
44+
command:
45+
- /bin/bash
46+
- -c
47+
- |
48+
sleep 30
49+
iris session iris < /mount-helper/mount_dcanalytics_data
50+
ports:
51+
- containerPort: 52773
52+
name: web
53+
volumeMounts:
54+
- mountPath: /opt/dcanalytics/DCANALYTICS-DATA
55+
name: dc-volume
56+
- mountPath: /mount-helper
57+
name: mount-helper
58+
volumeClaimTemplates:
59+
- metadata:
60+
name: dc-volume
61+
namespace: iris
62+
spec:
63+
accessModes:
64+
- ReadWriteOnce
65+
resources:
66+
requests:
67+
storage: 10Gi

src/cls/Community/Utils.cls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ ClassMethod UpdateCubes(verbose = 1) As %Status
7575
#; if (cube="POST") continue
7676
quit:cube=""
7777

78-
Set st1 = ##class(%DeepSee.Utils).%BuildCube(cube, $$$YES, verbose)
78+
Set st1 = ##class(%DeepSee.Utils).%BuildCube(cube, $$$YES, verbose,,10000)
7979

8080
set st = $$$ADDSC(st, st1)
8181
}

terraform/main.tf

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
It's a Terraform file from article https://community.intersystems.com/post/automating-gke-creation-circleci-builds
3+
Several placeholders are used here. See below their meaning:
4+
5+
---------------------------------------------------------------------------------------------------
6+
Placeholder | Meaning | Example
7+
---------------------------------------------------------------------------------------------------
8+
<PROJECT_ID> | GCP project ID | possible-symbol-254507
9+
<BUCKET_NAME> | Storage for Terraform state/lock—should be unique | circleci-gke-terraform-demo
10+
<REGION> | Region where resources will be created | europe-west1
11+
<LOCATION> | Zone where resources will be created | europe-west1-b
12+
<CLUSTER_NAME> | GKE cluster name | dev-cluster
13+
<NODES_POOL_NAME> | GKE worker nodes pool name | dev-cluster-node-pool
14+
---------------------------------------------------------------------------------------------------
15+
*/
16+
17+
/*
18+
Also, please note that Terraform uses remote bucket. This bucket should be initially created
19+
The following commands could be useful for that:
20+
21+
Check <BUCKET_NAME> availability:
22+
$ gsutil acl get gs://<BUCKET_NAME>
23+
24+
Good answer:
25+
BucketNotFoundException: 404 gs://<BUCKET_NAME> bucket does not exist
26+
27+
"Busy" answer:
28+
AccessDeniedException: 403 <YOUR_ACCOUNT> does not have storage.buckets.get access to <BUCKET_NAME>
29+
30+
Create bucket with versioning:
31+
$ gsutil mb -l EU gs://<BUCKET_NAME>
32+
33+
$ gsutil versioning get gs://<BUCKET_NAME>
34+
gs://<BUCKET_NAME>: Suspended
35+
36+
$ gsutil versioning set on gs://<BUCKET_NAME>
37+
38+
$ gsutil versioning get gs://<BUCKET_NAME>
39+
gs://<BUCKET_NAME>: Enabled
40+
41+
*/
42+
43+
terraform {
44+
required_version = "~> 0.12"
45+
backend "gcs" {
46+
bucket = "dc-analytics"
47+
prefix = "terraform/state"
48+
}
49+
}
50+
51+
provider "google" {
52+
project = "iris-community-demos"
53+
region = "europe-west1"
54+
}
55+
56+
resource "google_container_cluster" "gke-cluster" {
57+
name = "dc-analytics-cluster"
58+
location = "europe-west1-b"
59+
remove_default_node_pool = true
60+
# In regional cluster (location is region, not zone) this is a number of nodes per zone
61+
initial_node_count = 1
62+
}
63+
64+
resource "google_container_node_pool" "preemptible_node_pool" {
65+
name = "dc-analytics-node-pool"
66+
location = "europe-west1-b"
67+
cluster = google_container_cluster.gke-cluster.name
68+
# In regional cluster (location is region, not zone) this is a number of nodes per zone
69+
node_count = 1
70+
71+
node_config {
72+
preemptible = true
73+
machine_type = "n1-standard-1"
74+
oauth_scopes = [
75+
"storage-ro",
76+
"logging-write",
77+
"monitoring"
78+
]
79+
}
80+
}
81+

0 commit comments

Comments
 (0)