kubernetes_helper 1.18.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2dbeb51cb4e066084e681ea3a15c69b56780641bfbf38efa9dc8595b785de68c
4
- data.tar.gz: 11c03302e5c59638b3fb0fa64602be15cfc24ddd41e7818c65afc5ac4df2cf2b
3
+ metadata.gz: c3ddc1acbc8178da9b6974ef51e84d193a819438a1ec47f3307399c4d09ab89e
4
+ data.tar.gz: 82a49cdadb9f156d8e0ba7092de2c30a1f912e5127ec8edfc8bbd51db48a3f93
5
5
  SHA512:
6
- metadata.gz: addb118b0d1d53ccc36843b1ca108d449aba773382ea54dbff665131a8282d9173d57b81a4b95d87a5ffa27f8dbce039fac989a36afd1d579aa48260f823515e
7
- data.tar.gz: 17b845c6b15502d98294a82b33d08ddf6109aa2b0e49685ac1f299722980ae17f1d8fb07dc2f4242e093703a0448f20f4556fc2016bc8afdabf3b5088c7eba7d
6
+ metadata.gz: 683358d87dd5f2d41515512b3d7dd46774dce3f04e57556f515b3238ecec878b7f1a0416afba026ebf1f229b9659cbe02b98c9368cd0bd7cdeddb403ecafc4c7
7
+ data.tar.gz: '0586f4298b889b1d2068f26f2772f492aa170d77e842207c79f18ee34383d20b00dcc48eb087bb7dad3aea1d79c997bf98515ea796578854b844f4c375b39058'
data/README.md CHANGED
@@ -49,11 +49,44 @@ Configuration and customization can be done for multiple environments and at any
49
49
  - `deployment.logs_resources` (Hash, optional): Configure depending on the app requirements. Default: `{ cpu: { max: '200m', min: '50m' }, mem: { max: '200Mi', min: '50Mi' } }`
50
50
 
51
51
  ### Application deployment.yml for jobs or services without internet interaction (Optional)
52
+ Ideal to run sidekiq or similar jobs as a service without interacting via HTTP.
52
53
  - `deployment.job_apps[].name` (String, optional): Job deployment name (Note: Underscores are not accepted). Sample: `my-app-job`. Note: This deployment is created only if this value is present
53
54
  - `deployment.job_apps[].command` (String, optional): Bash command to be used for job container. Sample: `bundle exec sidekiq`
54
55
  - `deployment.job_apps[].sidekiq_alive_gem` (Boolean, default false): If true will add liveness checker settings using `sidekiq_alive_gem` (`sidekiq_alive` gem needs to be present in your Gemfile)
55
56
  - `deployment.job_apps[].services` (Array, Optional): List of linux service names that are required for a healthy job container. Sample: `['sidekiq', 'cron']`. Note: This will be ignored if `sidekiq_alive_gem` was defined.
56
57
  - `deployment.job_apps[].resources` (Hash, optional): Configure depending on the job app requirements. Sample: `{ cpu: { max: '1', min: '500m' }, mem: { max: '1Gi', min: '500Mi' } }`
58
+ Sample:
59
+ ```ruby
60
+ {
61
+ job_apps: [
62
+ {
63
+ name: "my-app-sidekiq",
64
+ command: 'bundle exec sidekiq',
65
+ services: %w[sidekiq],
66
+ resources: { mem: { max: '10Gi', min: '5Gi' } }
67
+ }
68
+ ]
69
+ }
70
+
71
+ ```
72
+
73
+ ### Required settings for Cronjob apps (Note: Cronjobs do not support `sidekiq_alive_gem` and `services`)
74
+ Ideal to process periodic tasks
75
+ - `deployment.job_apps[].schedule` (String): Cron schedule. Sample: `*/5 * * * *`
76
+ - `deployment.job_apps[].kind` (String, default `Deployment`): Kind of job application [`Deployment` or `CronJob`]
77
+ - `deployment.job_apps[].concurrency_policy` (String, default `Forbid`): [Documentation](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#concurrency-policy)
78
+ - `deployment.job_apps[].suspend` (String, default `false`): If `true` then marks as finished the job application (stops creating new pods).
79
+ Sample:
80
+ ```ruby
81
+ {
82
+ job_apps: [{
83
+ name: "my-promotions-cronjob",
84
+ command: 'bundle exec rake promotions:process > ./log/promotions.log 2>&1',
85
+ schedule: '0 22 * * *',
86
+ kind: 'CronJob'
87
+ }]
88
+ }
89
+ ```
57
90
 
58
91
  ### Applications secrets.yml (Optional)
59
92
  - `secrets.name` (String): K8s secrets name where env vars will be saved and fetched from. Sample: `my-app-secrets`
@@ -78,6 +78,7 @@ module KubernetesHelper
78
78
  def render_template(template_name, locals = {})
79
79
  path = KubernetesHelper.settings_path(template_name, use_template: true)
80
80
  text = "\n#{File.read(path)}"
81
+ text = text.gsub("\n", "\n#{' ' * locals[:tab]}") if locals[:tab]
81
82
  replace_config_variables(text, locals)
82
83
  end
83
84
 
@@ -94,12 +95,13 @@ module KubernetesHelper
94
95
 
95
96
  # parse secrets auto importer
96
97
  def parse_import_secrets(document) # rubocop:disable Metrics/AbcSize
97
- containers = document.dig('spec', 'template', 'spec', 'containers') || []
98
+ cronjob_containers = document.dig('spec', 'jobTemplate', 'spec', 'template', 'spec', 'containers')
99
+ containers = document.dig('spec', 'template', 'spec', 'containers') || cronjob_containers || []
98
100
  containers.each do |container|
99
101
  container['env'] = (container['env'] || [])
100
- container['env'] = container['env'] + static_env_vars if container.delete('static_env')
102
+ container['env'] = (container['env'] + static_env_vars).uniq if container.delete('static_env')
101
103
  if container['import_secrets']
102
- container['env'] = container['env'] + import_secrets(*container['import_secrets'])
104
+ container['env'] = (container['env'] + import_secrets(*container['import_secrets'])).uniq
103
105
  container.delete('import_secrets')
104
106
  end
105
107
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KubernetesHelper
4
- VERSION = '1.18.0'
4
+ VERSION = '1.20.0'
5
5
  end
@@ -84,50 +84,10 @@ This gem comes with continuous deployment script out of the box which can be exe
84
84
  PROD_CLOUD_TOKEN=<secret content here>
85
85
  ```
86
86
 
87
- * Add github workflow to automatically run deployment when merged into master or staging, something like:
88
- ```yml
89
- name: "Continuous Deployment"
90
- on:
91
- push:
92
- branches:
93
- - master
94
- - staging
95
-
96
- deployment:
97
- runs-on: ubuntu-latest
98
- jobs:
99
- steps:
100
- - uses: actions/checkout@v2
101
- with:
102
- ref: ${{ env.DEPLOY_BRANCH }}
103
- - name: Cancel previous Workflow Actions
104
- uses: styfle/cancel-workflow-action@0.6.0
105
- with:
106
- access_token: ${{ github.token }}
107
-
108
- - name: Set up Cloud SDK
109
- uses: google-github-actions/setup-gcloud@master
110
- - uses: satackey/action-docker-layer-caching@v0.0.11
111
- continue-on-error: true
112
- with:
113
- key: CD-docker-cache-${{ hashFiles('Dockerfile', 'Gemfile.lock') }}
114
-
115
- #### App deployment
116
- - run: sudo gem install kubernetes_helper
117
- - name: App deployment
118
- env:
119
- KB_AUTH_TOKEN: ${{ github.ref_name == 'master' && secrets.PROD_CLOUD_TOKEN || secrets.BETA_CLOUD_TOKEN }}
120
- DEPLOY_ENV: ${{ github.ref_name == 'master' && 'production' || 'beta' }}
121
- run: kubernetes_helper run_deployment 'cd.sh'
122
- ```
87
+ * Add github workflow to automatically run deployment when merged into master or staging: [See here](https://github.com/owen2345/reusable-ci-cd-actions#continuous-deployment)
123
88
 
124
- ## Apply any k8s setting changes
125
- - Secrets
126
- Open kubernetes secrets and add/edit/remove values and then save it
127
- `kubectl edit secret ...`
128
- Once secrets were updated, then restart all related pods, see: https://medium.com/devops-dudes/how-to-propagate-a-change-in-kubernetes-secrets-by-restarting-dependent-pods-b71231827656
129
-
130
- - Other settings
89
+ ## Apply deployment changes manually
90
+ Note: it can be enable for auto update with (`settings.rb`): `update_deployment: true`
131
91
  ```bash
132
92
  DEPLOY_ENV=beta kubernetes_helper run_yml 'deployment.yml' 'kubectl apply'
133
- ```
93
+ ```
@@ -12,11 +12,7 @@ fi
12
12
 
13
13
  ## Build and push containers
14
14
  echo "****** building image..."
15
- <% if continuous_deployment.docker_cmd %>
16
- <%= continuous_deployment.docker_cmd %>
17
- <% else %>
18
- docker <%=continuous_deployment.docker_build_cmd || 'build -f Dockerfile'%> -t $DEPLOY_NAME .
19
- <% end %>
15
+ eval $DOCKER_BUILD_CMD
20
16
  docker push $DEPLOY_NAME
21
17
 
22
18
  echo "****** tagging image $DEPLOY_NAME as $LATEST_NAME"
@@ -23,11 +23,7 @@ if [ -z $ALREADY_DEPLOYED ]
23
23
  then
24
24
  ## Build and push containers
25
25
  echo "****** image not created yet, building image..."
26
- <% if continuous_deployment.docker_cmd %>
27
- <%= continuous_deployment.docker_cmd %>
28
- <% else %>
29
- docker <%=continuous_deployment.docker_build_cmd || 'build -f Dockerfile'%> -t $DEPLOY_NAME .
30
- <% end %>
26
+ eval $DOCKER_BUILD_CMD
31
27
  docker push $DEPLOY_NAME
32
28
  else
33
29
  echo "****** image was already created: $ALREADY_DEPLOYED"
@@ -0,0 +1,41 @@
1
+ - apiVersion: batch/v1
2
+ kind: CronJob
3
+ metadata:
4
+ name: &cronjob_name <%= locals[:job_app][:name] %>
5
+ spec:
6
+ schedule: "<%= locals[:job_app][:schedule] %>"
7
+ concurrencyPolicy: "<%= locals[:job_app][:concurrency_policy] || 'Forbid' %>"
8
+ suspend: <%= locals[:job_app][:suspend] || false %>
9
+ # startingDeadlineSeconds: 200
10
+ jobTemplate:
11
+ spec:
12
+ template:
13
+ spec:
14
+ <<: *template_spec
15
+ restartPolicy: OnFailure
16
+ containers:
17
+ - <<: *app_container
18
+ name: *cronjob_name
19
+ <% if locals[:job_app][:command] %>
20
+ command: [ "/bin/bash", "-c", "<%= locals[:job_app][:command] %>" ]
21
+ <% end %>
22
+ <% if locals[:job_app][:resources] %>
23
+ <%= include_template "_resources.yml", locals[:job_app][:resources].merge(tab: 2) %>
24
+ <% end %>
25
+ ports: [ ]
26
+ livenessProbe: null
27
+ readinessProbe: null
28
+ <%= include_template "_container_extra_settings.yml", { pod: 'job', pod_name: locals[:job_app][:name], tab: 2 } %>
29
+
30
+ <% if deployment.cloud_secret_name %>
31
+ - *cloudsql_container
32
+ <% end %>
33
+
34
+ <% if deployment.log_container %>
35
+ - <<: *logs_container
36
+ <% end %>
37
+
38
+ <%= include_template "_custom_containers.yml", { pod: 'job', pod_name: locals[:job_app][:name], tab: 2 } %>
39
+
40
+ volumes:
41
+ <%= include_template "_volumes.yml", { pod: 'job', pod_name: locals[:job_app][:name], tab: 2 } %>
@@ -1,12 +1,15 @@
1
1
  ports: [ ]
2
- <% if (deployment.job_services || []).any? %>
2
+ <% if (locals[:services] || []).any? %>
3
3
  livenessProbe: &liveness_probe
4
4
  exec:
5
5
  command: [ /bin/sh, -c,
6
- 'if [ $(ps -ef | grep "<%= deployment.job_services.join("\\|") %>" | grep -v "grep" | wc -l) -lt <%= deployment.job_services.count %> ]; then
6
+ 'if [ $(ps -ef | grep "<%= locals[:services].join("\\|") %>" | grep -v "grep" | wc -l) -lt <%= locals[:services].count %> ]; then
7
7
  echo "Some required services are not running"; exit 1;
8
8
  fi' ]
9
9
  initialDelaySeconds: 120
10
10
  periodSeconds: 30
11
11
  readinessProbe: *liveness_probe
12
+ <% else %>
13
+ livenessProbe: null
14
+ readinessProbe: null
12
15
  <% end %>
@@ -0,0 +1,47 @@
1
+ - apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: &job_app_name <%= locals[:job_app][:name] %>
5
+ spec:
6
+ replicas: 1
7
+ selector:
8
+ matchLabels:
9
+ name: *job_app_name
10
+ strategy:
11
+ type: Recreate
12
+ minReadySeconds: 10
13
+ template:
14
+ metadata:
15
+ labels:
16
+ name: *job_app_name
17
+ spec:
18
+ <<: *template_spec
19
+ containers:
20
+ - <<: *app_container
21
+ name: *job_app_name
22
+ <% if locals[:job_app][:command] %>
23
+ command: [ "/bin/bash", "-c", "<%= locals[:job_app][:command] %>" ]
24
+ <% end %>
25
+ <% if locals[:job_app][:resources] %>
26
+ <%= include_template "_resources.yml", locals[:job_app][:resources] %>
27
+ <% end %>
28
+ <%= include_template "_container_extra_settings.yml", { pod: 'job', pod_name: locals[:job_app][:name] } %>
29
+
30
+ <% if locals[:job_app][:sidekiq_alive_gem] %>
31
+ <%= include_template "_sidekiq_alive_gem.yml" %>
32
+ <% else %>
33
+ <%= include_template "_job_liveness.yml", { services: locals[:job_app][:services] } %>
34
+ <% end %>
35
+
36
+ <% if deployment.cloud_secret_name %>
37
+ - *cloudsql_container
38
+ <% end %>
39
+
40
+ <% if deployment.log_container %>
41
+ - <<: *logs_container
42
+ <% end %>
43
+
44
+ <%= include_template "_custom_containers.yml", { pod: 'job', pod_name: locals[:job_app][:name] } %>
45
+
46
+ volumes:
47
+ <%= include_template "_volumes.yml", { pod: 'job', pod_name: locals[:job_app][:name] } %>
@@ -18,4 +18,4 @@
18
18
  <% end %>
19
19
  <% end %>
20
20
 
21
- <%= include_template "_custom_volumes.yml", { pod: locals[:pod] } %>
21
+ <%= include_template "_custom_volumes.yml", { pod: locals[:pod], tab: locals[:tab] } %>
data/lib/templates/cd.sh CHANGED
@@ -16,6 +16,12 @@ CI_COMMIT_SHA=${CI_COMMIT_SHA:-$(date +%s) }
16
16
  DEPLOY_NAME="${IMAGE_NAME}:${CI_COMMIT_SHA}"
17
17
  LATEST_NAME="${IMAGE_NAME}:<%= continuous_deployment.image_tag || 'latest' %>"
18
18
 
19
+ <% if continuous_deployment.docker_cmd %>
20
+ DOCKER_BUILD_CMD="<%= continuous_deployment.docker_cmd %>"
21
+ <% else %>
22
+ DOCKER_BUILD_CMD="docker <%=continuous_deployment.docker_build_cmd || 'build -f Dockerfile'%> -t $DEPLOY_NAME --build-arg DEPLOY_VERSION=${DEPLOY_VERSION} ."
23
+ <% end %>
24
+
19
25
  <%= include_template "_cd_google.sh" if continuous_deployment.image_name.include?('gcr.io/') %>
20
26
  <%= include_template "_cd_digital.sh" if continuous_deployment.image_name.include?('digitalocean.com/') %>
21
27
 
@@ -3,7 +3,7 @@ documents:
3
3
  kind: Deployment
4
4
  metadata:
5
5
  name: &app_name <%=deployment.name%>
6
- spec: &default_spec
6
+ spec:
7
7
  replicas: <%=deployment.replicas%>
8
8
  selector:
9
9
  matchLabels:
@@ -107,53 +107,8 @@ documents:
107
107
  <%= include_template "_volumes.yml", { pod: 'web' } %>
108
108
 
109
109
  <% deployment.job_apps.each do |job_app| %>
110
- - apiVersion: apps/v1
111
- kind: Deployment
112
- metadata:
113
- name: &job_app_name <%= job_app[:name] %>
114
- spec:
115
- <<: *default_spec
116
- replicas: 1
117
- selector:
118
- matchLabels:
119
- name: *job_app_name
120
- strategy:
121
- type: Recreate
122
- template:
123
- metadata:
124
- labels:
125
- name: *job_app_name
126
- spec:
127
- <<: *template_spec
128
- containers:
129
- - <<: *app_container
130
- name: *job_app_name
131
- <% if job_app[:command] %>
132
- command: [ "/bin/bash", "-c", "<%= job_app[:command] %>" ]
133
- <% end %>
134
- <% if job_app[:resources] %>
135
- <%= include_template "_resources.yml", job_app[:resources] %>
136
- <% end %>
137
- <%= include_template "_container_extra_settings.yml", { pod: 'job', pod_name: job_app[:name] } %>
138
-
139
- <% if job_app[:sidekiq_alive_gem] %>
140
- <%= include_template "_sidekiq_alive_gem.yml" %>
141
- <% else %>
142
- <%= include_template "_job_liveness.yml" %>
143
- <% end %>
144
-
145
- <% if deployment.cloud_secret_name %>
146
- - *cloudsql_container
147
- <% end %>
148
-
149
- <% if deployment.log_container %>
150
- - <<: *logs_container
151
- <% end %>
152
-
153
- <%= include_template "_custom_containers.yml", { pod: 'job', pod_name: job_app[:name] } %>
154
-
155
- volumes:
156
- <%= include_template "_volumes.yml", { pod: 'job', pod_name: job_app[:name] } %>
110
+ <%= include_template '_jobs_pod.yml', job_app: job_app if job_app[:kind] != 'CronJob' %>
111
+ <%= include_template '_cronjobs_pod.yml', job_app: job_app if job_app[:kind] == 'CronJob' %>
157
112
  <% end %>
158
113
 
159
114
  <% if deployment.replicas_range %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kubernetes_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.0
4
+ version: 1.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - owen2345
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-12 00:00:00.000000000 Z
11
+ date: 2022-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erb
@@ -44,9 +44,11 @@ files:
44
44
  - lib/templates/_cd_digital.sh
45
45
  - lib/templates/_cd_google.sh
46
46
  - lib/templates/_container_extra_settings.yml
47
+ - lib/templates/_cronjobs_pod.yml
47
48
  - lib/templates/_custom_containers.yml
48
49
  - lib/templates/_custom_volumes.yml
49
50
  - lib/templates/_job_liveness.yml
51
+ - lib/templates/_jobs_pod.yml
50
52
  - lib/templates/_replicas.yml
51
53
  - lib/templates/_resources.yml
52
54
  - lib/templates/_sidekiq_alive_gem.yml