kubernetes_helper 1.6.1 → 1.10.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: 59945c95287cd19d19577b1e96f5f6b9853ce4e40a82b022de362ba676ad5bf9
4
- data.tar.gz: 0b5360c14ea7b0f14300b87112225e9421090299ae099f60cf07b48a22ecebde
3
+ metadata.gz: ad11b73ac23d45b86c9b5789ae815af2ee565d6360462368e96c4b15dfcc3301
4
+ data.tar.gz: 61df31315a5b137c9e1c4575002b875f87175d72d5319cf0e1439d8c01afaee6
5
5
  SHA512:
6
- metadata.gz: 8057efca5943cccfa92bc1a8a3a696f5ca2f3b3b21415da3923794c4674848ba7797098e5d718f2b7da376c9d05634182185ea45572500cc9af9481b1246f107
7
- data.tar.gz: 2dd11b252b27be829f8d1de244409c37eda5104f479dda45839b555e9f92423fc0142122e536c3824add5c73e91eba79ca0a5779f26dc9f78ba6bc95441ad942
6
+ metadata.gz: f1a177f81e8bf2a9337d233369c39dd7cc42e2baf0c7dca7fdba25984d86014837db2207bcab10a1b9f8b8bc2060b55dee8c0dc0054074ac4846592856c8d778
7
+ data.tar.gz: 8be87c0b86cc7e4a7711d20d6360e96d5b99d7655ea3a3bed0a8291dec59cc552a9a326911355d2427f0e5548c0976045d7d28204af1c9dcee2c5fd1bc2af1f9
data/README.md CHANGED
@@ -9,7 +9,15 @@ cd my_app/
9
9
  gem install kubernetes_helper -v '~> 1.0'
10
10
  kubernetes_helper generate_templates
11
11
  ```
12
- Note: Requires ruby 1.7+
12
+ Note: Requires ruby 1.7+
13
+
14
+ ## Configuration
15
+ - Edit `.kubernetes/settings.rb` and enter or replace all settings with the valid ones
16
+ - For special applications where default configurations are not enough, you can do the following:
17
+ - Download the corresponding template from [lib/templates](lib/templates)
18
+ - Put it inside `.kubernetes` folder
19
+ - Customize based on your needs (You can add or use your custom variables from `settings.rb`)
20
+ Note: The local template will be used instead of the default.
13
21
 
14
22
  ## Deployment
15
23
  Once you generated the basic templates, it comes with the corresponding [readme.md](/lib/templates/README.md) which includes all the steps to deploy your application.
@@ -21,7 +29,7 @@ Once you generated the basic templates, it comes with the corresponding [readme.
21
29
  - Supports for `- documents` to include multiple documents in a file and share yml variables between them (Sample: `lib/templates/deployment.yml#1`)
22
30
  - Replaces all setting values based on `DEPLOY_ENV`
23
31
  - Supports for secrets auto importer using `import_secrets: ['secrets.yml', '<%=secrets.name%>']` (Sample: `lib/templates/deployment.yml#29`)
24
- - Supports for template including by `include_template 'template_name.yml.erb'`
32
+ - Supports for sub templates by `include_template 'template_name.yml.erb', { my_local_var: 10 }`
25
33
  Sample: `DEPLOY_ENV=beta kubernetes_helper run_deployment "deployment.yml" "kubectl create"`
26
34
 
27
35
  - Run kubernetes commands
@@ -44,6 +52,67 @@ Once you generated the basic templates, it comes with the corresponding [readme.
44
52
  When performing a script it looks first for file inside .kubernetes folder, if not exist,
45
53
  it looks for the file inside kubernetes_helper template folder.
46
54
 
55
+ ## Settings API
56
+ Below settings are used when running Continuous Deployment
57
+ - `continuous_deployment.image_name` (String, Optional): Partial docker image url where `:latest` will be automatically added. Sample: `gcr.io/my-account/my_app_name`
58
+ - `continuous_deployment.image` (String, Optional, is mandatory if `image_name` is empty): Full docker image url. Sample: `gcr.io/my-account/my_app_name:latest`
59
+ - `continuous_deployment.project_name`: Cloud project name. Sample: `my-project-name`
60
+ - `continuous_deployment.cluster_name`: Cluster cluster name. Sample: `my-cluster-name`
61
+ - `continuous_deployment.cluster_region`: Cluster region name. Sample: `europe-west4-a`
62
+ - `continuous_deployment.docker_build_cmd`: Docker command to build the corresponding image. Sample: `build --target production -f Dockerfile `
63
+ - `continuous_deployment.update_deployment` (Boolean, default: false): If true permits to re-generate and update the k8s deployment(s) before applying the new version (new docker image)
64
+
65
+ Below settings are used when configuring the application in the k8s environment
66
+ - `deployment.name` (String): Web deployment name (Note: Underscores are not accepted). Sample: `my-app`
67
+ - `deployment.replicas` (Integer): Quantity of replicas. Sample: `1`
68
+ - `deployment.replicas_range` (Array<min, max, cpu_percentage>, Optional): Defines the minimum and the maximum number of pods that could automatically be created when `CPUUtilizationPercentage` is above than defined. Sample: `[1, 3, 50]`
69
+ - `deployment.cloud_secret_name` (String, Optional): K8s credentials name where cloud secrets will be saved (includes permission like DB). Sample: `my-app-cloud-secret`
70
+ - `deployment.cloud_sql_instance` (String, Optional): Cloud sql instance name. Sample: `my-project:europe-west1:my-instance-name=tcp:5432` (5432 => postgres, 3306 => mysql)
71
+ - `deployment.env_vars` (Hash, optional): List of static env variables (Note: Not recommended for sensitive values). Sample: `{ 'RAILS_ENV' => 'production' }`
72
+ - `deployment.command` (String, Optional): Bash command to be used for web containers. Sample: `rails s -b 0.0.0.0`
73
+ - `deployment.liveness_path` (String, Optional): Relative path to be used for readiness and liveness checker of the web app. Sample: `/check_liveness`
74
+ - `deployment.custom_volumes` (Hash<name: path>, Optional): Custom volumes to be mounted. Sample: `{ my_volume: { kind: 'hostPath', mount_path: '/', settings: { path: '..', type: 'Directory' } } }`
75
+
76
+ - `deployment.job_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
77
+ - `deployment.job_command` (String, optional): Bash command to be used for job container. Sample: `bundle exec sidekiq`
78
+ - `deployment.job_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)
79
+ - `deployment.job_services` (Array, Optional, only `job_sidekiq_alive_gem` or `job_services` is allowed): List of linux service names that are required for a healthy job container. Sample: `['sidekiq', 'cron']`
80
+
81
+
82
+ - `secrets.name` (String): K8s secrets name where env vars will be saved and fetched from. Sample: `my-app-secrets`
83
+
84
+ - `service.name`: K8s service name. Sample: `my-app-service`
85
+ - `service.port_name`: Http port name to connect between k8s ingress and service. Sample: `http-port`. Note: max 15 characters
86
+ - `service.backend_port_name` (String): Web backend port name to be connected between k8s service and web deployments. Sample: `b-port`. Note: max 15 characters
87
+
88
+ - `ingress.name`: Name of k8s ingress for the app: Sample: `my-app-ingress`
89
+ - `ingress.ip_name` (Optional): Static ip address is not created nor assigned if empty value. Sample: `my-app-static-ip`
90
+ - `ingress.certificate_name` (Optional): Ssl certificate is not created nor assigned if empty value. Sample: `my-app-lets-encrypt`. Note: requires `certificate_domain`
91
+ - `ingress.certificate_domain` (Optional): Domain name for the certificate. Sample: `myapp.com`. Note: does not support for willcard domains
92
+
93
+ ### Partials
94
+ - `_container_extra_settings.yml` Partial template to add custom container settings. Receives `pod` as local variable (`web` | `job` | `cloudsql` | `logs`). Sample:
95
+ ```yaml
96
+ <% if locals[:pod] == 'job' %>
97
+ resources:
98
+ requests:
99
+ cpu: 50m
100
+ memory: 256Mi
101
+ limits:
102
+ cpu: 500m
103
+ memory: 1Gi
104
+ <% end %>
105
+ ```
106
+ - `_custom_containers.yml` Partial template to add extra containers (Receives `pod` as local variable: `web` | `job`). Sample:
107
+ ```yaml
108
+ <% if locals[:pod] == 'job' %>
109
+ - name: scraper
110
+ image: owencio/easy_scraper
111
+ ...
112
+ <% end %>
113
+ ```
114
+ - `_cd_apply_images.sh` Partial template to customize the process to apply the new version (new docker image)
115
+
47
116
  ## Templating
48
117
  When performing a command or script, the setting variables are replaced based on `DEPLOY_ENV`.
49
118
  All these setting variable values are configured in `.kubernetes/settings.rb` which defines the values based on `DEPLOY_ENV`.
@@ -11,8 +11,8 @@ module KubernetesHelper
11
11
  binding
12
12
  end
13
13
 
14
- def include_template(name)
15
- render_template.call(name)
14
+ def include_template(name, locals = {})
15
+ render_template.call(name, locals)
16
16
  end
17
17
  end
18
18
 
@@ -36,8 +36,8 @@ module KubernetesHelper
36
36
 
37
37
  # @param text (String)
38
38
  # Sample: replicas: '#{deployment.replicas}'
39
- def replace_config_variables(text)
40
- values = config_values.map do |key, value| # rubocop:disable Style/HashTransformValues
39
+ def replace_config_variables(text, locals = {})
40
+ values = config_values.merge(locals: locals).map do |key, value| # rubocop:disable Style/HashTransformValues
41
41
  [key, value.is_a?(Hash) ? OpenStruct.new(value) : value]
42
42
  end.to_h
43
43
  values[:render_template] = method(:render_template)
@@ -75,10 +75,10 @@ module KubernetesHelper
75
75
  end
76
76
  end
77
77
 
78
- def render_template(template_name)
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
- replace_config_variables(text)
81
+ replace_config_variables(text, locals)
82
82
  end
83
83
 
84
84
  def static_env_vars
@@ -91,10 +91,11 @@ module KubernetesHelper
91
91
  end
92
92
 
93
93
  # parse secrets auto importer
94
- def parse_import_secrets(document)
94
+ def parse_import_secrets(document) # rubocop:disable Metrics/AbcSize
95
95
  containers = document.dig('spec', 'template', 'spec', 'containers') || []
96
96
  containers.each do |container|
97
- container['env'] = (container['env'] || []) + static_env_vars
97
+ container['env'] = (container['env'] || [])
98
+ container['env'] = container['env'] + static_env_vars if container.delete('static_env')
98
99
  if container['import_secrets']
99
100
  container['env'] = container['env'] + import_secrets(*container['import_secrets'])
100
101
  container.delete('import_secrets')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KubernetesHelper
4
- VERSION = '1.6.1'
4
+ VERSION = '1.10.0'
5
5
  end
@@ -0,0 +1,9 @@
1
+ # <% if locals[:pod] == 'job' %>
2
+ # resources:
3
+ # requests:
4
+ # cpu: 50m
5
+ # memory: 256Mi
6
+ # limits:
7
+ # cpu: 500m
8
+ # memory: 1Gi
9
+ # <% end %>
@@ -0,0 +1,5 @@
1
+ # <% if locals[:pod] == 'job' %>
2
+ # - name: scraper
3
+ # image: owencio/easy_scraper
4
+ # ...
5
+ # <% end %>
@@ -0,0 +1,3 @@
1
+ # - name: dshm
2
+ # emptyDir:
3
+ # medium: Memory
@@ -0,0 +1,12 @@
1
+ ports: [ ]
2
+ <% if (deployment.job_services || []).any? %>
3
+ livenessProbe: &liveness_probe
4
+ exec:
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
7
+ echo "Some required services are not running"; exit 1;
8
+ fi' ]
9
+ initialDelaySeconds: 120
10
+ periodSeconds: 30
11
+ readinessProbe: *liveness_probe
12
+ <% end %>
@@ -9,4 +9,4 @@
9
9
  name: <%= deployment.name %>
10
10
  minReplicas: <%= deployment.replicas_range[0] %>
11
11
  maxReplicas: <%= deployment.replicas_range[1] %>
12
- targetCPUUtilizationPercentage: 50
12
+ targetCPUUtilizationPercentage: <%= deployment.replicas_range[2] || 50 %>
@@ -0,0 +1,20 @@
1
+ <% if deployment.cloud_secret_name %>
2
+ - name: gcloud-creds
3
+ secret:
4
+ secretName: '<%=deployment.cloud_secret_name%>'
5
+ <% end %>
6
+
7
+ - name: applog
8
+ emptyDir: {}
9
+
10
+ # Custom volumes
11
+ # { my_volume: { kind: 'hostPath', mount_path: '/', settings: { path: '..', type: 'Directory' } } }
12
+ <% (deployment.custom_volumes || {}).each do |name, vol| %>
13
+ - name: <%= name %>
14
+ <%= vol[:kind] %>:
15
+ <% vol[:settings].each do |k, v| %>
16
+ <%= k %>: <%= v %>
17
+ <% end %>
18
+ <% end %>
19
+
20
+ <%= include_template "_custom_volumes.yml", { pod: locals[:pod] } %>
data/lib/templates/cd.sh CHANGED
@@ -43,14 +43,16 @@ docker tag $DEPLOY_NAME $LATEST_NAME
43
43
  docker push $DEPLOY_NAME
44
44
  docker push $LATEST_NAME
45
45
 
46
+ ## Update new secrets defined in secrets.yml as ENV vars for deployments
47
+ <% if continuous_deployment.update_deployment %>
48
+ kubernetes_helper run_yml 'deployment.yml' 'kubectl apply'
49
+ <% end %>
50
+
46
51
  ## Apply deployments
47
52
  IFS=',' read -r -a deployments <<< "$DEPLOYMENTS"
48
53
  for deployment in "${deployments[@]}"; do
49
54
  [ -z "$deployment" ] && continue # if empty value
50
55
 
51
56
  <%= include_template "_cd_apply_images.sh" %>
52
-
53
- <% if continuous_deployment.update_deployment %>
54
- kubernetes_helper run_yml 'deployment.yml' 'kubectl apply'
55
- <% end %>
56
57
  done
58
+
@@ -4,4 +4,4 @@ metadata:
4
4
  name: '<%=ingress.certificate_name%>'
5
5
  spec:
6
6
  domains: # does not support for willcard domains
7
- - '<%=ingress.domain_name%>'
7
+ - '<%= ingress.domain_name || ingress.certificate_domain %>'
@@ -21,11 +21,17 @@ documents:
21
21
  spec: &template_spec
22
22
  containers:
23
23
  - &app_container
24
- image: '<%=continuous_deployment.image_name%>:latest'
24
+ <% if continuous_deployment.image_name %>
25
+ image: '<%= continuous_deployment.image_name %>:latest'
26
+ <% else %>
27
+ image: '<%= continuous_deployment.image %>'
28
+ <% end %>
29
+
25
30
  <% if deployment.command %>
26
31
  command: ["/bin/bash", "-c", "<%= deployment.command %>"]
27
32
  <% end %>
28
33
  name: *app_name
34
+ static_env: true
29
35
  import_secrets: ['secrets.yml', '<%=secrets.name%>']
30
36
  ports:
31
37
  - containerPort: &port 3000
@@ -41,6 +47,7 @@ documents:
41
47
  periodSeconds: 15
42
48
  readinessProbe: *liveness_probe
43
49
  <% end %>
50
+ <%= include_template "_container_extra_settings.yml", { pod: 'web' } %>
44
51
 
45
52
  volumeMounts:
46
53
  - &log_volume
@@ -69,6 +76,7 @@ documents:
69
76
  env: []
70
77
  volumeMounts:
71
78
  - *cloud_credentials_volume
79
+ <%= include_template "_container_extra_settings.yml", { pod: 'cloudsql' } %>
72
80
  <% end %>
73
81
 
74
82
  - &logs_container # print to stdout all log files
@@ -78,27 +86,13 @@ documents:
78
86
  env: []
79
87
  volumeMounts:
80
88
  - *log_volume
89
+ <%= include_template "_container_extra_settings.yml", { pod: 'logs' } %>
90
+
91
+ <%= include_template "_custom_containers.yml", { pod: 'web' } %>
81
92
 
82
93
  terminationGracePeriodSeconds: 120
83
94
  volumes:
84
- <% if deployment.cloud_secret_name %>
85
- - name: gcloud-creds
86
- secret:
87
- secretName: '<%=deployment.cloud_secret_name%>'
88
- <% end %>
89
-
90
- - name: applog
91
- emptyDir: {}
92
-
93
- # Custom volumes
94
- # { my_volume: { kind: 'hostPath', mount_path: '/', settings: { path: '..', type: 'Directory' } } }
95
- <% (deployment.custom_volumes || {}).each do |name, vol| %>
96
- - name: <%= name %>
97
- <%= vol[:kind] %>:
98
- <% vol[:settings].each do |k, v| %>
99
- <%= k %>: <%= v %>
100
- <% end %>
101
- <% end %>
95
+ <%= include_template "_volumes.yml", { pod: 'web' } %>
102
96
 
103
97
 
104
98
  <% if deployment.job_name %>
@@ -124,22 +118,12 @@ documents:
124
118
  <% if deployment.job_command %>
125
119
  command: [ "/bin/bash", "-c", "<%= deployment.job_command %>" ]
126
120
  <% end %>
121
+ <%= include_template "_container_extra_settings.yml", { pod: 'job' } %>
127
122
 
128
123
  <% if deployment.job_sidekiq_alive_gem %>
129
124
  <%= include_template "_sidekiq_alive_gem.yml" %>
130
125
  <% else %>
131
- ports: [ ]
132
- <% if (deployment.job_services || []).any? %>
133
- livenessProbe: &liveness_probe
134
- exec:
135
- command: [ /bin/sh, -c,
136
- 'if [ $(ps -ef | grep "<%= deployment.job_services.join("\|") %>" | grep -v "grep" | wc -l) -lt <%= deployment.job_services.count %> ]; then
137
- echo "Some required services are not running"; exit 1;
138
- fi' ]
139
- initialDelaySeconds: 120
140
- periodSeconds: 30
141
- readinessProbe: *liveness_probe
142
- <% end %>
126
+ <%= include_template "_job_liveness.yml" %>
143
127
  <% end %>
144
128
 
145
129
  <% if deployment.cloud_secret_name %>
@@ -147,6 +131,11 @@ documents:
147
131
  <% end %>
148
132
 
149
133
  - <<: *logs_container
134
+
135
+ <%= include_template "_custom_containers.yml", { pod: 'job' } %>
136
+
137
+ volumes:
138
+ <%= include_template "_volumes.yml", { pod: 'job' } %>
150
139
  <% end %>
151
140
 
152
141
  <% if deployment.replicas_range %>
@@ -1,4 +1,4 @@
1
- <% if ingress.domain_name %>
1
+ <% if ingress.certificate_name %>
2
2
  <%= include_template "certificate.yml" %>
3
3
  <% end %>
4
4
 
@@ -17,7 +17,7 @@ metadata:
17
17
  kubernetes.io/ingress.global-static-ip-name: "<%=ingress.ip_name%>"
18
18
  <% end %>
19
19
 
20
- <% if ingress.domain_name %>
20
+ <% if ingress.certificate_name %>
21
21
  networking.gke.io/managed-certificates: '<%=ingress.certificate_name%>'
22
22
  <% end %>
23
23
 
@@ -4,7 +4,7 @@
4
4
  apiVersion: cloud.google.com/v1beta1
5
5
  kind: BackendConfig
6
6
  metadata:
7
- name: '<%=service.config_name%>'
7
+ name: '<%=service.name%>-bconfig'
8
8
  spec:
9
9
  timeoutSec: 1800
10
10
  ---
@@ -16,7 +16,7 @@ metadata:
16
16
  name: '<%=service.name%>'
17
17
  annotations:
18
18
  <% if cloud.name == 'gcloud' %>
19
- beta.cloud.google.com/backend-config: '{"ports": {"80":"<%=service.config_name%>"}}'
19
+ beta.cloud.google.com/backend-config: '{"ports": {"80":"<%=service.name%>-bconfig"}}'
20
20
  <% end %>
21
21
  spec:
22
22
  selector:
@@ -6,6 +6,7 @@ settings = {
6
6
  deployment: {
7
7
  name: app_name,
8
8
  replicas: is_production ? 2 : 1,
9
+ replicas_range: nil, # [min, max] or nil to ignore, sample: is_production ? [1, 2] : nil
9
10
  cloud_secret_name: "#{is_production ? 'production' : 'beta'}-cloud-secret",
10
11
  cloud_sql_instance: 'xxx:xxx:xxx=tcp:5432', # 5432 => postgres, 3306 => mysql
11
12
  env_vars: {}, # Sample: { 'CUSTOM_VAR' => 'value' }
@@ -20,10 +21,10 @@ settings = {
20
21
  name: "#{app_name}-ingress",
21
22
  ip_name: "#{app_name}-static-ip", # nil if static ip is not necessary
22
23
  certificate_name: "#{app_name}-lets-encrypt", # nil if ssl is not required
23
- domain_name: is_production ? 'myapp.com' : 'beta.myapp.com' # nil if domain is not required
24
+ certificate_domain: is_production ? 'myapp.com' : 'beta.myapp.com' # nil if domain is not required
24
25
  },
25
26
  continuous_deployment: {
26
- image_name: "gcr.io/my-account/#{app_name}",
27
+ image: "gcr.io/my-account/#{app_name}:latest",
27
28
  project_name: 'my-project-name',
28
29
  cluster_name: 'my-cluster-name',
29
30
  cluster_region: 'europe-west4-a',
@@ -36,8 +37,7 @@ settings = {
36
37
  service: {
37
38
  name: app_name,
38
39
  port_name: 'http-port', # max 15 characters
39
- backend_port_name: 'b-port', # max 15 characters
40
- config_name: "#{app_name}-backend-config"
40
+ backend_port_name: 'b-port' # max 15 characters
41
41
  }
42
42
  }
43
43
 
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.6.1
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - owen2345
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-06 00:00:00.000000000 Z
11
+ date: 2022-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erb
@@ -41,8 +41,13 @@ files:
41
41
  - lib/kubernetes_helper/version.rb
42
42
  - lib/templates/README.md
43
43
  - lib/templates/_cd_apply_images.sh
44
+ - lib/templates/_container_extra_settings.yml
45
+ - lib/templates/_custom_containers.yml
46
+ - lib/templates/_custom_volumes.yml
47
+ - lib/templates/_job_liveness.yml
44
48
  - lib/templates/_replicas.yml
45
49
  - lib/templates/_sidekiq_alive_gem.yml
50
+ - lib/templates/_volumes.yml
46
51
  - lib/templates/cd.sh
47
52
  - lib/templates/certificate.yml
48
53
  - lib/templates/deployment.yml