kubernetes_helper 0.2.1 → 0.3.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: 0ca97bfb3e3dcb157198cf9f76092c740ecb3674bb76cdf7c91f6da7755d11fe
4
- data.tar.gz: 581dfe0dbf80c2a7d0115430d6045edfca0d532f10d89ca5db7bcbc70beac706
3
+ metadata.gz: c95b3029857b4b9793c337abb65f8d983376db3055bd411b8982907cce9b5a1d
4
+ data.tar.gz: '08a11127589a60bd3fc340c11a2ddecd635a44347dd77506686d932093a53f4f'
5
5
  SHA512:
6
- metadata.gz: 1642945b8ca5ea192812c686ef4afad9b285deae77ebbdd4734af1b3a877ad0db819c2e306f738303f84a361cbc3d697f02cf711e5ba35ce1a0e0f1148c12878
7
- data.tar.gz: 0f23916d6007d02e858e2db22f563724bf422f59a47807eec956349c60f5141795c7e8c392d4d0c3c2c7ff67ca8f430033120f4dac72a372763c65c9f93f3d62
6
+ metadata.gz: 05e61bc79a77cbce7894430788ccfdddfceb3ac17041453f55dda0809ba42b8f50ab970dc72a566726f5548b1df3aa9bff068ef98adfd21e867d729b0bed316f
7
+ data.tar.gz: 5464337442b676f531ff14f294652ebe43270110f054dcba401045e5e75b92352ac1432ebb7b281bf84cd91c87c0f1ee9984ed0578d535287926b6751f1e446c
data/README.md CHANGED
@@ -22,16 +22,16 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
26
-
27
- ## Development
28
-
29
-
30
25
  ## TODO
31
26
  - Documentation
32
- - Tests
33
- - Rake generate
27
+ - Include conditional blocks
28
+ - Include hardcoded env values
29
+ - Tasks
30
+ - Add docs to include partials using `include_template 'sample.yml.erb'`
34
31
  - Rake verify files
32
+ - Add one_step_configuration.sh
33
+ - Fix if/end_if for blocks
34
+ - Ability to copy specific template
35
35
 
36
36
  ## Contributing
37
37
 
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rspec/core/rake_task'
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- task :default => :spec
8
+ task default: :spec
9
9
 
10
10
  path = File.expand_path(__dir__)
11
11
  Dir.glob("#{path}/lib/tasks/**/*.rake").each { |f| import f }
@@ -4,34 +4,30 @@ require 'kubernetes_helper'
4
4
 
5
5
  case ARGV[0]
6
6
  # Parse variables and run provided command.
7
- # Sample: DEPLOY_ENV=beta rake kubernetes_helper:run_command "gcloud compute addresses create \#{ingress.ip_name} --global"'
7
+ # Sample: DEPLOY_ENV=beta rake kubernetes_helper:run_command
8
+ # "gcloud compute addresses create \#{ingress.ip_name} --global"'
8
9
  when 'run_command'
9
10
  KubernetesHelper::Core.new(ENV['DEPLOY_ENV']).run_command(ARGV[1])
10
-
11
11
  # Run the deployment script.
12
- # Sample: DEPLOY_ENV=beta rake kubernetes_helper:run_deployment "cd_gcloud.sh"
12
+ # Sample: DEPLOY_ENV=beta kubernetes_helper run_deployment "cd_gcloud.sh"
13
13
  when 'run_deployment'
14
- script_path = KubernetesHelper.settings_path(ARGV[1])
15
- KubernetesHelper::Core.new(ENV['DEPLOY_ENV']).run_cd_script(script_path)
16
-
14
+ script_path = KubernetesHelper.settings_path(ARGV[1], use_template: true)
15
+ KubernetesHelper::Core.new(ENV['DEPLOY_ENV']).run_script(script_path)
17
16
  # Parses kubernetes yml files (supporting multiple documents, Config variables replacement, include secrets).
18
- # Sample: DEPLOY_ENV=beta rake kubernetes_helper:run_deployment "deployment.yml" "kubectl create"
17
+ # Sample: DEPLOY_ENV=beta kubernetes_helper run_deployment "deployment.yml" "kubectl create"
19
18
  when 'run_yml'
20
19
  output_path = KubernetesHelper.settings_path('tmp_result.yml')
21
20
  KubernetesHelper::Core
22
21
  .new(ENV['DEPLOY_ENV'])
23
- .parse_yml_file(KubernetesHelper.settings_path(ARGV[1]), output_path)
22
+ .parse_yml_file(KubernetesHelper.settings_path(ARGV[1], use_template: true), output_path)
24
23
  KubernetesHelper.run_cmd("#{ARGV[2]} -f #{output_path}")
25
-
26
24
  # Generate template files
27
- when 'generate'
28
- # TODO: ...
29
-
30
- # Verify yml files for possible errors.
31
- # Sample: DEPLOY_ENV=beta rake kubernetes_helper:verify_yml_files
25
+ when 'generate_templates' # Sample: kubernetes_helper generate basic
26
+ mode = ARGV[1] || 'basic'
27
+ KubernetesHelper.copy_templates(mode)
32
28
  when 'verify_yml'
33
- # TODO: ...
34
-
29
+ # Verify yml files for possible errors.
30
+ # TODO: ...
35
31
  else
36
32
  puts 'Invalid command'
37
33
  end
@@ -14,15 +14,18 @@ module KubernetesHelper
14
14
 
15
15
  # @param env_name (String)
16
16
  # @return [Hash]
17
- def self.load_settings(env_name)
17
+ def self.load_settings
18
18
  config_file = File.join(settings_path, 'settings.rb')
19
19
  load config_file
20
- settings[env_name.to_sym]
20
+ settings
21
21
  end
22
22
 
23
- def self.settings_path(file_name = nil)
23
+ def self.settings_path(file_name = nil, use_template: false)
24
24
  path = File.join(Dir.pwd, FOLDER_NAME)
25
- path = File.join(path, file_name) if file_name
25
+ if file_name
26
+ app_path = File.join(path, file_name)
27
+ path = use_template && !File.exist?(app_path) ? templates_path(file_name) : app_path
28
+ end
26
29
  path
27
30
  end
28
31
 
@@ -30,4 +33,20 @@ module KubernetesHelper
30
33
  res = Kernel.system cmd
31
34
  Kernel.abort("::::::::CD: failed running command: #{title || cmd} ==> #{caller}") if res != true
32
35
  end
36
+
37
+ def self.templates_path(file_name = nil)
38
+ path = File.join(File.expand_path(__dir__), 'templates')
39
+ file_name ? File.join(path, file_name) : path
40
+ end
41
+
42
+ # @param mode (basic, advanced)
43
+ def self.copy_templates(mode)
44
+ FileUtils.mkdir(settings_path) unless Dir.exist?(settings_path)
45
+ files = %w[README.md secrets.yml settings.rb]
46
+ files += %w[deployment.yml cd.sh ingress.yml service.yml] if mode == 'advanced'
47
+ files.each do |name|
48
+ path = settings_path(name)
49
+ FileUtils.cp(templates_path(name), path) unless File.exist?(path)
50
+ end
51
+ end
33
52
  end
@@ -2,20 +2,33 @@
2
2
 
3
3
  require 'yaml'
4
4
  require 'json'
5
+ require 'erb'
6
+ # require 'byebug' rescue nil
7
+
5
8
  module KubernetesHelper
9
+ class ErbBinding < OpenStruct
10
+ def get_binding # rubocop:disable Naming/AccessorMethodName:
11
+ binding
12
+ end
13
+
14
+ def include_template(name)
15
+ render_template.call(name)
16
+ end
17
+ end
18
+
6
19
  class Core
7
20
  # @return [Hash]
8
21
  attr_accessor :config_values
9
22
 
10
- # @param env_name (String)
11
- def initialize(env_name)
12
- env_name = env_name.to_s.length > 1 ? env_name : 'beta'
13
- @config_values = KubernetesHelper.load_settings(env_name)
23
+ # @param _env_name (String)
24
+ def initialize(_env_name)
25
+ @config_values = KubernetesHelper.load_settings
14
26
  end
15
27
 
16
28
  def parse_yml_file(file_path, output_path)
17
29
  parsed_content = replace_config_variables(File.read(file_path))
18
- old_yaml = YAML.load_stream(parsed_content) # rubocop:disable Security/YAMLLoad
30
+ File.open(output_path, 'w+') { |f| f << parsed_content } # save as draft to be reviewed if failed
31
+ old_yaml = YAML.load_stream(parsed_content)
19
32
  json_data = old_yaml.to_json # fix to skip anchors
20
33
  yml_data = JSON.parse(json_data)
21
34
  export_documents(yml_data, output_path)
@@ -24,9 +37,13 @@ module KubernetesHelper
24
37
  # @param text (String)
25
38
  # Sample: replicas: '#{deployment.replicas}'
26
39
  def replace_config_variables(text)
27
- text.gsub(/(\#{([^}])*})/) do |code|
28
- find_setting_value(code.gsub('#{', '').gsub('}', ''))
29
- end
40
+ values = config_values.map do |key, value| # rubocop:disable Style/HashTransformValues
41
+ [key, value.is_a?(Hash) ? OpenStruct.new(value) : value]
42
+ end.to_h
43
+ values[:render_template] = method(:render_template)
44
+ bind = ErbBinding.new(values).get_binding
45
+ template = ERB.new(text)
46
+ template.result(bind)
30
47
  end
31
48
 
32
49
  def run_command(command)
@@ -34,9 +51,9 @@ module KubernetesHelper
34
51
  KubernetesHelper.run_cmd(command)
35
52
  end
36
53
 
37
- def run_cd_script(script_path)
54
+ def run_script(script_path)
38
55
  content = replace_config_variables(File.read(script_path))
39
- tmp_file = KubernetesHelper.settings_path('tmp_cd.sh')
56
+ tmp_file = KubernetesHelper.settings_path('tmp_script.sh')
40
57
  File.write(tmp_file, content)
41
58
  KubernetesHelper.run_cmd("chmod +x #{tmp_file}")
42
59
  KubernetesHelper.run_cmd(tmp_file)
@@ -58,20 +75,26 @@ module KubernetesHelper
58
75
  end
59
76
  end
60
77
 
61
- # @param setting_key (String)
62
- # sample: deployment.replicas
63
- def find_setting_value(setting_key)
64
- parent = @config_values
65
- setting_key.split('.').each do |key|
66
- parent = parent[key.to_sym]
78
+ def render_template(template_name)
79
+ path = KubernetesHelper.settings_path(template_name, use_template: true)
80
+ text = "\n#{File.read(path)}"
81
+ replace_config_variables(text)
82
+ end
83
+
84
+ def static_env_vars
85
+ (config_values.dig(:deployment, :env_vars) || {}).map do |key, value|
86
+ {
87
+ 'name' => key.to_s,
88
+ 'value' => value
89
+ }
67
90
  end
68
- parent
69
91
  end
70
92
 
71
93
  # parse secrets auto importer
72
94
  def parse_import_secrets(document)
73
95
  containers = document.dig('spec', 'template', 'spec', 'containers') || []
74
96
  containers.each do |container|
97
+ container['env'] = (container['env'] || []) + static_env_vars
75
98
  if container['import_secrets']
76
99
  container['env'] = container['env'] + import_secrets(*container['import_secrets'])
77
100
  container.delete('import_secrets')
@@ -80,13 +103,21 @@ module KubernetesHelper
80
103
  end
81
104
 
82
105
  def export_documents(yml_data, file_path)
83
- documents = yml_data.delete('documents') || Array(yml_data)
84
106
  File.open(file_path, 'w+') do |f|
85
- documents.each do |document|
107
+ parse_documents(yml_data).each do |document|
86
108
  parse_import_secrets(document)
87
- f << document.to_yaml
109
+ f.write(document.to_yaml)
88
110
  end
89
111
  end
90
112
  end
113
+
114
+ # @return [Array<Hash>]
115
+ def parse_documents(yml_data)
116
+ documents = []
117
+ Array(yml_data).each do |document|
118
+ document['documents'] ? documents.push(*document['documents']) : documents.push(document)
119
+ end
120
+ documents
121
+ end
91
122
  end
92
123
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KubernetesHelper
2
- VERSION = "0.2.1"
4
+ VERSION = '0.3.0'
3
5
  end
@@ -0,0 +1,96 @@
1
+ # Kubernetes app configuration
2
+
3
+ ## Configure a new application environment
4
+ - Create the project on Gcloud
5
+ - Set the project where to work on
6
+ `gcloud config set project my-project`
7
+
8
+ - Create the cluster (Only if not exist)
9
+ `gcloud container clusters create my-cluster`
10
+ `# gcloud container clusters list --region europe-west4-a # to list clusters`
11
+
12
+ - Use the cluster/project as default
13
+ `gcloud container clusters get-credentials my-cluster --zone europe-west4-a`
14
+
15
+ - Install helper for the next commands
16
+ `gem install kubernetes_helper`
17
+
18
+ - Verify or update k8s settings in .kubernetes/settings.rb
19
+
20
+ - Register shared cloudsql proxy configuration (only if not exists)
21
+ ```bash
22
+ DEPLOY_ENV=beta kubernetes_helper run_command "kubectl create secret generic <%=deployment.cloud_secret_name%> --from-file=credentials.json=<path-to-downloaded/credentials.json>"
23
+ ```
24
+
25
+ - Register manually env vars (values must be encrypted using base64)
26
+ Open and register secret values in `.kubernetes/secrets.yml`
27
+ Note: Enter base64 encoded values
28
+ ```bash
29
+ DEPLOY_ENV=beta kubernetes_helper run_yml 'secrets.yml' 'kubectl create'
30
+ # kubectl get secrets # to list all secrets registered
31
+ ```
32
+
33
+ - Create deployment to run application
34
+ ```bash
35
+ DEPLOY_ENV=beta kubernetes_helper run_yml 'deployment.yml' 'kubectl create'
36
+ # kubectl get deployment # to list deployments
37
+ ```
38
+
39
+ - Create service to connect pods and ingress
40
+ ```bash
41
+ DEPLOY_ENV=beta kubernetes_helper run_yml 'service.yml' 'kubectl create'
42
+ # kubectl get services # to list all registered services
43
+ ```
44
+
45
+ - Create the public ip address (only if static ip is required)
46
+ ```bash
47
+ DEPLOY_ENV=beta kubernetes_helper run_command "gcloud compute addresses create <%=ingress.ip_name%> --global"
48
+ # gcloud compute addresses list # to list static ips generated
49
+ # Copy new external ip generated by the previous command and point your domain to it
50
+ ```
51
+
52
+ - Register ingress to receive external http calls (includes ssl certificates if defined)
53
+ ```bash
54
+ DEPLOY_ENV=beta kubernetes_helper run_yml 'ingress.yml' 'kubectl create'
55
+ # kubectl get ingress # to list all registered ingresses
56
+ # kubectl get ManagedCertificate # to list all certificates
57
+ # Domain and ssl propagation can take more than 10 minutes
58
+ # You can start accessing to the app using the generated ip address
59
+ # `kubectl get ManagedCertificate` # to see the status of ssl provisionning
60
+ ```
61
+
62
+ ## Apply any k8s setting changes
63
+ - Secrets
64
+ Open kubernetes secrets and add/edit/remove values and then save it
65
+ `kubectl edit secret ...`
66
+ 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
67
+
68
+ - Other settings
69
+ ```bash
70
+ DEPLOY_ENV=beta kubernetes_helper run_yml 'deployment.yml' 'kubectl apply'
71
+ ```
72
+
73
+ ## Configure continuous deployment for github actions
74
+ * Go to github repository settings
75
+ * Register a new secret variable with content downloaded from https://console.cloud.google.com/iam-admin/serviceaccounts
76
+ (Make sure to attach a "Editor", "Storage Admin" and "Kubernetes engine cluster admin" role to the service account)
77
+ ```bash
78
+ beta: BETA_CLOUD_TOKEN=<secret content here>
79
+ production: PROD_CLOUD_TOKEN=<secret content here>
80
+ ```
81
+
82
+ * Add action to run deployment:
83
+ ```bash
84
+ env:
85
+ KB_AUTH_TOKEN: secrets.BETA_CLOUD_TOKEN
86
+ run: DEPLOY_ENV=beta kubernetes_helper run_deployment 'cd.sh'
87
+ ```
88
+
89
+ * Sample:
90
+ ```yml
91
+ - name: Staging deployment
92
+ env: # Env variable saved in github that contains gcloud credential (json format)
93
+ KB_AUTH_TOKEN: ${{ secrets.BETA_GOOGLE_AUTH }}
94
+ run: DEPLOY_ENV=beta kubernetes_helper run_deployment 'cd.sh'
95
+ if: ${{ !contains(fromJson('["main", "master"]'), env.DEPLOY_BRANCH) }}
96
+ ```
@@ -0,0 +1,18 @@
1
+ ports:
2
+ - containerPort: &sidekiq_alive_port 7433
3
+ livenessProbe: &sidekiq_liveness
4
+ httpGet:
5
+ path: /
6
+ port: *sidekiq_alive_port
7
+ initialDelaySeconds: 80 # app specific. Time your sidekiq takes to start processing.
8
+ timeoutSeconds: 5 # can be much less
9
+ readinessProbe: *sidekiq_liveness
10
+ lifecycle:
11
+ preStop:
12
+ exec:
13
+ # SIGTERM triggers a quick exit; gracefully terminate instead
14
+ command: [
15
+ "/bin/bash",
16
+ "-c",
17
+ "SIDEKIQ_PID=$(ps aux | grep sidekiq | grep busy | awk '{ print $2 }') && kill -SIGTERM $SIDEKIQ_PID",
18
+ ]
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+ set -e
3
+ # expected ENV VAR "KB_AUTH_TOKEN"
4
+
5
+ SCRIPT_DIR=`dirname "$(realpath -s "$0")"`
6
+
7
+ DEPLOYMENTS="<%=[deployment.name, deployment.job_name].join(',')%>"
8
+ IMAGE_NAME="<%=continuous_deployment.image_name%>"
9
+ CLUSTER_NAME="<%=continuous_deployment.cluster_name%>"
10
+ PROJECT_NAME="<%=continuous_deployment.project_name%>"
11
+ CLUSTER_REGION="<%=continuous_deployment.cluster_region%>"
12
+ DOCKER_BUILD_CMD="<%=continuous_deployment.docker_build_cmd%>"
13
+
14
+ CI_COMMIT_SHA=$(git rev-parse --verify HEAD)
15
+ DEPLOY_NAME="${IMAGE_NAME}:${CI_COMMIT_SHA}"
16
+ LATEST_NAME="${IMAGE_NAME}:latest"
17
+ AUTH_PATH="$SCRIPT_DIR/k8s-auth-token.json"
18
+ echo $KB_AUTH_TOKEN >> $AUTH_PATH
19
+
20
+ ## ***** GOOGLE CONNECTOR
21
+ # Download and install Google Cloud SDK
22
+ if [ -z "$(which gcloud)" ]; then
23
+ export CLOUDSDK_CORE_DISABLE_PROMPTS=1; curl https://sdk.cloud.google.com | bash && source /home/runner/google-cloud-sdk/path.bash.inc && gcloud --quiet components update kubectl
24
+ fi
25
+
26
+ # Connect to cluster
27
+ gcloud auth activate-service-account --key-file $AUTH_PATH --project $PROJECT_NAME
28
+ gcloud docker --authorize-only --project $PROJECT_NAME
29
+ gcloud container clusters get-credentials $CLUSTER_NAME --region $CLUSTER_REGION
30
+ ## ***** END GOOGLE CONNECTOR
31
+
32
+
33
+ ## Build and push containers
34
+ docker $DOCKER_BUILD_CMD -t $DEPLOY_NAME .
35
+ docker tag $DEPLOY_NAME $LATEST_NAME
36
+ docker push $DEPLOY_NAME
37
+ docker push $LATEST_NAME
38
+
39
+ ## Apply deployments
40
+ IFS=',' read -r -a deployments <<< "$DEPLOYMENTS"
41
+ for deployment in "${deployments[@]}"; do
42
+ [ -z "$deployment" ] && continue # if empty value
43
+
44
+ kubectl set image deployment/$deployment $deployment=$DEPLOY_NAME
45
+ [ "$deployment" = "${deployments[0]}" ] && kubectl rollout status deployment/$deployment
46
+ done
@@ -0,0 +1,118 @@
1
+ documents:
2
+ - apiVersion: apps/v1
3
+ kind: Deployment
4
+ metadata:
5
+ name: &app_name <%=deployment.name%>
6
+ spec: &default_spec
7
+ replicas: <%=deployment.replicas%>
8
+ selector:
9
+ matchLabels:
10
+ name: *app_name
11
+ strategy:
12
+ type: RollingUpdate
13
+ rollingUpdate:
14
+ maxSurge: 1
15
+ maxUnavailable: 1
16
+ minReadySeconds: 5
17
+ template:
18
+ metadata:
19
+ labels:
20
+ name: *app_name
21
+ spec: &template_spec
22
+ containers:
23
+ - &app_container
24
+ image: '<%=continuous_deployment.image_name%>:latest'
25
+ <% if deployment.command %>
26
+ command: ["/bin/bash", "-c", "<%= deployment.command %>"]
27
+ <% end %>
28
+ name: *app_name
29
+ import_secrets: ['secrets.yml', '<%=secrets.name%>']
30
+ ports:
31
+ - containerPort: &port 3000
32
+ name: '<%=service.backend_port_name%>'
33
+
34
+ <% if deployment.liveness_path %>
35
+ livenessProbe: &liveness_probe
36
+ httpGet:
37
+ path: <%=deployment.liveness_path%>
38
+ port: *port
39
+ initialDelaySeconds: 50
40
+ timeoutSeconds: 3
41
+ periodSeconds: 15
42
+ readinessProbe: *liveness_probe
43
+ <% end %>
44
+
45
+ volumeMounts:
46
+ - &log_volume
47
+ name: applog
48
+ mountPath: /app/log
49
+
50
+ - &cloudsql_container
51
+ image: gcr.io/cloudsql-docker/gce-proxy:1.09 # Cloud sql proxy
52
+ name: cloudsql-proxy
53
+ command: ["/cloud_sql_proxy", "--dir=/cloudsql",
54
+ "-instances=<%=deployment.cloud_sql_instance%>",
55
+ "-credential_file=/secrets/cloudsql/credentials.json"]
56
+ volumeMounts:
57
+ - name: cloudsql-creds
58
+ mountPath: /secrets/cloudsql
59
+ readOnly: true
60
+
61
+ - &logs_container # print to stdout all log files
62
+ name: print-logs
63
+ image: busybox
64
+ command: [/bin/sh, -c, 'until find log/*.log; do sleep 1; done; tail -n+1 -f log/*.log']
65
+ volumeMounts:
66
+ - *log_volume
67
+
68
+ volumes:
69
+ - name: cloudsql-creds
70
+ secret:
71
+ secretName: '<%=deployment.cloud_secret_name%>'
72
+ - name: applog
73
+ emptyDir: {}
74
+
75
+ <% if deployment.job_name %>
76
+ - apiVersion: apps/v1
77
+ kind: Deployment
78
+ metadata:
79
+ name: &job_app_name <%=deployment.job_name%>
80
+ spec:
81
+ <<: *default_spec
82
+ replicas: 1
83
+ selector:
84
+ matchLabels:
85
+ name: *job_app_name
86
+ template:
87
+ metadata:
88
+ labels:
89
+ name: *job_app_name
90
+ spec:
91
+ <<: *template_spec
92
+ containers:
93
+ - <<: *app_container
94
+ name: *job_app_name
95
+ <% if deployment.job_command %>
96
+ command: [ "/bin/bash", "-c", "<%= deployment.job_command %>" ]
97
+ <% end %>
98
+
99
+ <% if deployment.job_sidekiq_alive_gem %>
100
+ <%= include_template "_sidekiq_alive_gem.yml.erb" %>
101
+ <% else %>
102
+ ports: [ ]
103
+ <% if (deployment.job_services || []).any? %>
104
+ livenessProbe: &liveness_probe
105
+ exec:
106
+ command: [ /bin/sh, -c,
107
+ 'if [ $(ps -ef | grep "<%= deployment.job_services.join("\|") %>" | grep -v "grep" | wc -l) -lt <%= deployment.job_services.count %> ]; then
108
+ echo "Some required services are not running"; exit 1;
109
+ fi' ]
110
+ initialDelaySeconds: 120
111
+ periodSeconds: 30
112
+ readinessProbe: *liveness_probe
113
+ <% end %>
114
+ <% end %>
115
+
116
+ - *cloudsql_container
117
+ - <<: *logs_container
118
+ <% end %>
@@ -0,0 +1,33 @@
1
+ <% if ingress.domain_name %>
2
+ apiVersion: networking.gke.io/v1beta1
3
+ kind: ManagedCertificate
4
+ metadata:
5
+ name: '<%=ingress.certificate_name%>'
6
+ spec:
7
+ domains: # does not support for willcard domains
8
+ - '<%=ingress.domain_name%>'
9
+ <% end %>
10
+
11
+ ---
12
+
13
+ apiVersion: extensions/v1beta1
14
+ kind: Ingress
15
+ metadata:
16
+ name: '<%=ingress.name%>'
17
+ annotations:
18
+ kubernetes.io/ingress.class: "gce"
19
+ kubernetes.io/ingress.allow-http: "true"
20
+ ingress.kubernetes.io/ssl-redirect: "true"
21
+
22
+ <% if ingress.ip_name %>
23
+ kubernetes.io/ingress.global-static-ip-name: "<%=ingress.ip_name%>"
24
+ <% end %>
25
+
26
+ <% if ingress.domain_name %>
27
+ networking.gke.io/managed-certificates: '<%=ingress.certificate_name%>'
28
+ <% end %>
29
+
30
+ spec:
31
+ backend:
32
+ serviceName: '<%=service.name%>'
33
+ servicePort: '<%=service.port_name%>'
@@ -0,0 +1,11 @@
1
+ # Every Value has to be base64 encoded
2
+ # IMPORTANT: For security reason, never ever commit secret values, only keys
3
+
4
+ apiVersion: v1
5
+ kind: Secret
6
+ metadata:
7
+ name: '<%=secrets.name%>'
8
+ type: Opaque
9
+ data:
10
+ my_key1: "based_64_value_encoded"
11
+ my_key2: "based_64_value_encoded"
@@ -0,0 +1,27 @@
1
+ ---
2
+ # used to increase request timeout
3
+ apiVersion: cloud.google.com/v1beta1
4
+ kind: BackendConfig
5
+ metadata:
6
+ name: '<%=service.config_name%>'
7
+ spec:
8
+ timeoutSec: 1800
9
+
10
+ ---
11
+
12
+
13
+ kind: Service
14
+ apiVersion: v1
15
+ metadata:
16
+ name: '<%=service.name%>'
17
+ annotations:
18
+ beta.cloud.google.com/backend-config: '{"ports": {"80":"<%=service.config_name%>"}}'
19
+ spec:
20
+ selector:
21
+ name: '<%=deployment.name%>'
22
+ type: NodePort
23
+ ports:
24
+ - port: 80
25
+ protocol: TCP
26
+ name: '<%=service.port_name%>'
27
+ targetPort: '<%=service.backend_port_name%>'
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ is_beta = ENV['DEPLOY_ENV'] == 'beta'
4
+ app_name = is_beta ? 'my_beta_app' : 'my_app'
5
+ settings = {
6
+ deployment: {
7
+ name: app_name,
8
+ replicas: is_beta ? 1 : 2,
9
+ cloud_secret_name: "#{is_beta ? 'beta' : 'production'}-cloud-secret",
10
+ cloud_sql_instance: 'xxx:xxx:xxx=tcp:5432', # 5432 => postgres, 3306 => mysql
11
+ env_vars: {}, # Sample: { 'CUSTOM_VAR' => 'value' }
12
+ # command: '', # custom container command (default empty to be managed by Dockerfile)
13
+ # liveness_path: '/check_liveness', # nil if not exist
14
+ # job_name: "#{app_name}-job", # enable if there is any background service
15
+ # job_command: 'bundle exec sidekiq -C config/sidekiq.yml',
16
+ # job_services: ['sidekiq', 'cron'] # list of linux services needed.
17
+ },
18
+ ingress: {
19
+ name: "#{app_name}-ingress",
20
+ ip_name: "#{app_name}-static-ip", # nil if static ip is not necessary
21
+ certificate_name: "#{app_name}-lets-encrypt", # nil if ssl is not required
22
+ domain_name: is_beta ? 'beta.myapp.com' : 'myapp.com' # nil if domain is not required
23
+ },
24
+ continuous_deployment: {
25
+ image_name: "gcr.io/my-account/#{app_name}",
26
+ project_name: 'my-project-name',
27
+ cluster_name: 'my-cluster-name',
28
+ cluster_region: 'europe-west4-a'
29
+ },
30
+ secrets: {
31
+ name: "#{app_name}-secrets"
32
+ },
33
+ service: {
34
+ name: app_name,
35
+ port_name: 'http-port', # max 15 characters
36
+ backend_port_name: 'b-port', # max 15 characters
37
+ config_name: "#{app_name}-backend-config"
38
+ }
39
+ }
40
+
41
+ KubernetesHelper.settings(settings)
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kubernetes_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.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-07-19 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-08-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: erb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: ''
14
28
  email:
15
29
  - owenperedo@gmail.com
@@ -25,6 +39,14 @@ files:
25
39
  - lib/kubernetes_helper/core.rb
26
40
  - lib/kubernetes_helper/railtie.rb
27
41
  - lib/kubernetes_helper/version.rb
42
+ - lib/templates/README.md
43
+ - lib/templates/_sidekiq_alive_gem.yml.erb
44
+ - lib/templates/cd.sh
45
+ - lib/templates/deployment.yml
46
+ - lib/templates/ingress.yml
47
+ - lib/templates/secrets.yml
48
+ - lib/templates/service.yml
49
+ - lib/templates/settings.rb
28
50
  homepage: https://github.com/owen2345/kubernetes_helper
29
51
  licenses:
30
52
  - MIT