kubernetes_helper 1.18.0 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
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