<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Keigo Yamamoto</title>
    <description>The latest articles on DEV Community by Keigo Yamamoto (@k5trismegistus).</description>
    <link>https://dev.to/k5trismegistus</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F702077%2F58e7c7c5-acb9-4dc7-bf8c-405487fbe6af.png</url>
      <title>DEV Community: Keigo Yamamoto</title>
      <link>https://dev.to/k5trismegistus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/k5trismegistus"/>
    <language>en</language>
    <item>
      <title>Use CloudWatch to monitor EKS cluster and gather logs from Rails app on Kubernetes</title>
      <dc:creator>Keigo Yamamoto</dc:creator>
      <pubDate>Mon, 30 Jan 2023 02:53:34 +0000</pubDate>
      <link>https://dev.to/k5trismegistus/use-cloudwatch-to-monitor-eks-cluster-and-gather-logs-from-rails-app-on-kubernetes-35g8</link>
      <guid>https://dev.to/k5trismegistus/use-cloudwatch-to-monitor-eks-cluster-and-gather-logs-from-rails-app-on-kubernetes-35g8</guid>
      <description>&lt;p&gt;This article was wrote 2019.&lt;br&gt;
Be careful there may be deprecated contents.&lt;/p&gt;
&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;The purpose is monitor EKS, an AWS managed Kubernetes cluster, and manage logs emitted by Ruby on Rails apps running on Kubernetes with AWS CloudWatch.&lt;/p&gt;

&lt;p&gt;For cluster monitoring, we can use Container Insights. (Now Container Insights got GA &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;And fluentd-kubernetes-daemonset is used to gather application logs.&lt;/p&gt;

&lt;p&gt;Kubernetes version 1.12 or higher is required because ConfigMap is necessary.&lt;/p&gt;

&lt;p&gt;But even if you are using an older version, you can easily update it by just clicking the button if you are using EKS.&lt;/p&gt;
&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Policy settings for EC2 instances of Kubernetes worker nodes
&lt;/h3&gt;

&lt;p&gt;First, configure IAM so that Kubernetes workers can send logs to CloudWatch.&lt;/p&gt;

&lt;p&gt;Simply attach CloudWatchAgentServerPolicy to the worker’s role.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Introduction of Container Insights
&lt;/h3&gt;

&lt;p&gt;First, install Container Insights to monitor the cluster.&lt;/p&gt;

&lt;p&gt;Create a namespace, service account, and ConfigMap for CloudWatch, and deploy the Container Insights daemon set.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.amazonaws.cn/en_us/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-metrics.html" rel="noopener noreferrer"&gt;https://docs.amazonaws.cn/en_us/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-metrics.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, run this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;$ kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/master/k8s-yaml-templates/cloudwatch-namespace.yaml&lt;/span&gt;
&lt;span class="s"&gt;$ kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/master/k8s-yaml-templates/cwagent-kubernetes-monitoring/cwagent-serviceaccount.yaml&lt;/span&gt; 
&lt;span class="s"&gt;$ curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/master/k8s-yaml-templates/cwagent-kubernetes-monitoring/cwagent-configmap.yaml&lt;/span&gt; 
&lt;span class="s"&gt;$ micro cwagent-configmap.yaml&lt;/span&gt; &lt;span class="c1"&gt;# replace {{cluster_name}} by your cluster name.&lt;/span&gt;
&lt;span class="s"&gt;$ kubectl apply -f cwagent-configmap.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this alone, logs can be sent to CloudWatch.&lt;/p&gt;

&lt;p&gt;Next, let’s enable to send the Rails application log to CloudWatch.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Logging settings of Rails app
&lt;/h3&gt;

&lt;p&gt;fluentd-kubernetes-daemonset makes it easy to send the standard output of each pod to CloudWatch.&lt;/p&gt;

&lt;p&gt;So, change all the Rails application logs to standard output. Edit &lt;code&gt;config/{{environment}}.rb&lt;/code&gt; and &lt;code&gt;config/puma.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rails5 has the following description in production.log, so if you set the environment variable, that’s it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"RAILS_LOG_TO_STDOUT"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
  &lt;span class="n"&gt;stdout_logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;stdout_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log_formatter&lt;/span&gt;
  &lt;span class="n"&gt;multiple_loggers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout_logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;multiple_loggers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For puma, if stdout_redirect is set, just delete that line.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Deploy fluentd-kubernetes-daemonset
&lt;/h3&gt;

&lt;p&gt;Since you have already added a namespace for CloudWatch, just run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -O https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/fluentd/fluentd.yml
// fill cluster_name and region_name by your environment
$ kubectl create configmap cluster-info --from-literal=cluster.name=cluster_name --from-literal=logs.region=region_name -n amazon-cloudwatch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will transfer the application logs to CloudWatch.&lt;/p&gt;

&lt;p&gt;If this is all you need, it’s OK.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Formatting logs
&lt;/h3&gt;

&lt;p&gt;If the log output by Rails is left as default, it will be output in multiple lines, so each line will be treated as a separate log on CloudWatch.&lt;/p&gt;

&lt;p&gt;Therefore, instead of outputting in multiple lines, output it as a single line log in JSON format.&lt;/p&gt;

&lt;p&gt;If it is in JSON format, you can search on CloudWatch.&lt;/p&gt;

&lt;p&gt;Use lograge to change the request log in json format. Add lograge to Gemfile and run bundle install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rails.application.configure do
  config.lograge.enabled = true
  config.lograge.formatter = Lograge::Formatters::Json.new   
  config.lograge.custom_options = Proc.new do |event|
    exceptions = %w(controller action format id)
    {
      time: event.time,
      host: event.payload[:host],
      remote_ip: event.payload[:remote_ip],
      params: event.payload[:params].except(*exceptions),
      exception_object: event.payload[:exception_object],
      exception: event.payload[:exception],
      backtrace: event.payload[:exception_object].try(:backtrace),
    }.compact
  end      
  ...
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ApplicationController &amp;lt; ActionController::Base
  def append_info_to_payload(payload)
    super
    payload[:user_agent] ||= request.user_agent
    payload[:request_id] ||= request.request_id
    if @exception.present?
      payload[:exception_object] ||= @exception
      payload[:exception] ||= [@exception.class, @exception.message]
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, if only this, outside the ActionController, it can not respond to RoutingError that occurs at the ActionDispatch level, so add the following monkey patch&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if defined? Lograge
  class ActionDispatch::DebugExceptions
    alias_method :org_log_error, :log_error
    def log_error(request, wrapper)
      msg = {
        exception: wrapper.exception,
        backtrace: wrapper.exception.try(:backtrace),
        raw_request: request,
        raw_wrapper: wrapper
      }      Rails.logger.fatal(msg.to_json)
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the Rails log output in JSON format is just an escaped string.&lt;/p&gt;

&lt;p&gt;Therefore, change the setting of fluentd.&lt;/p&gt;

&lt;p&gt;In the fluend.yml downloaded in the previous article, add the following to parse the json log. This will cause the log parsed with the key parsed_logto be recorded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;filter **&amp;gt;
  @type parser
  format json
  key_name log
  reserve_time true
  reserve_data true
  emit_invalid_record_to_error false
  hash_value_field parsed_log
 &amp;lt;/filter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/fluentd/fluentd.yml" rel="noopener noreferrer"&gt;https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/fluentd/fluentd.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Around line 125. Add the above settings and apply them.&lt;/p&gt;

&lt;p&gt;Also, if the log stream name is defalut, it becomes the pod name, and if the pod changes, it creates a different log stream.&lt;/p&gt;

&lt;p&gt;Personally, I want the log stream to appear in the same log stream even if the pod changes, so take it from the label.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;filter **&amp;gt;
  @type record_transformer
  @id filter_containers_stream_transformer
  enable_ruby # 追加
  &amp;lt;record&amp;gt;
    stream_name ${record["kubernetes"]["labels"]["app"]}
  &amp;lt;/record&amp;gt;
&amp;lt;/filter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;You can now monitor the cluster and aggregate application logs with CloudWatch.&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>learning</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Making Nuxt.js web apps compatible with IE11 (Only about Javascript)</title>
      <dc:creator>Keigo Yamamoto</dc:creator>
      <pubDate>Fri, 23 Sep 2022 15:56:53 +0000</pubDate>
      <link>https://dev.to/k5trismegistus/making-nuxtjs-web-apps-compatible-with-ie11-only-about-javascript-551</link>
      <guid>https://dev.to/k5trismegistus/making-nuxtjs-web-apps-compatible-with-ie11-only-about-javascript-551</guid>
      <description>&lt;p&gt;This post was moved from Medium (&lt;a href="https://k5trismegistus.medium.com/making-nuxt-js-web-apps-compatible-with-ie11-only-about-javascript-83f5bbcbe3c8"&gt;https://k5trismegistus.medium.com/making-nuxt-js-web-apps-compatible-with-ie11-only-about-javascript-83f5bbcbe3c8&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Nuxt.js will generate code which can run on IE9, but this is only for Nuxt.js itself and the code you write, but not for external libraries.&lt;/p&gt;

&lt;p&gt;So you need to configure them yourself as long as you use external libraries.&lt;/p&gt;

&lt;p&gt;I’ve seen a lot of how-to articles that say that external libraries need to be transpiled, so let’s set them up!&lt;/p&gt;

&lt;p&gt;But I couldn’t find anything that answered the question of which one I should do, so I tried to do it myself.&lt;/p&gt;

&lt;p&gt;I’m going to add libraries that use the new notation to the transpile list, and load the script for Polyfill.&lt;/p&gt;

&lt;p&gt;(What is transpiling and Polyfill is attached at the end of this article.)&lt;/p&gt;

&lt;p&gt;Let’s start with the following.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Polyfill
&lt;/h2&gt;

&lt;p&gt;At polyfill.io, there is a useful site that returns the required Polyfill code for the accessing browser.&lt;/p&gt;

&lt;p&gt;You can select features to be polyfilled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://polyfill.io/v3/url-builder/"&gt;https://polyfill.io/v3/url-builder/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But it’s hard to look up which features need to be polyfilled one by one, so you should load them all together.&lt;/p&gt;

&lt;p&gt;If user isusing a modern browser like Firefox or Chrome, and user has updated it properly, user will get empty files back&lt;/p&gt;

&lt;p&gt;User have to wait a little more to download that file, but user shouldn’t have any problems with Polyfill overwriting browser-supported features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default {  ...  head: { ...    script: [...      { src: 'https://polyfill.io/v3/polyfill.min.js' } // add this    ],  },  ...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think I don’t have to do this because Nuxt.js must use polyfill in nuxt build to generate code that is compatible with IE9, but I couldn’t find the way to apply polyfill to external libraries…&lt;/p&gt;

&lt;h2&gt;
  
  
  Transpiling external libraries
&lt;/h2&gt;

&lt;p&gt;Unlike Polyfill, this one is a bit more difficult.&lt;/p&gt;

&lt;p&gt;To include a library in the transpile target, simply write the library name in nuxt.config.js as follows. You can also use a regular expression to specify a group of libraries with a specific pattern of names.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default {  ...  build: { ...    transpile: ['vuetify'], { ...  },  ...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first I thought I’d take the easy way out and put&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transpile: [/. +/]  // You can use regex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but sadly, the current project broke even in Chrome. Also, the build time got quite long. You shouldn’t do that…&lt;/p&gt;

&lt;p&gt;So, you should detect which libraries must be transpiled one by one, but it was hard way.&lt;/p&gt;

&lt;p&gt;Since I didn’t have a Windows testing machine, I could only borrow a Windows PC from my colleague and have access to production build from it.&lt;/p&gt;

&lt;p&gt;This is why I had to do something a bit complicated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detect which libraries must be transpiled
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Find the syntax error in IE
&lt;/h3&gt;

&lt;p&gt;Open the page using IE in the production environment.&lt;/p&gt;

&lt;p&gt;Open the console of the developer tools and look at the line that is causing the error to see what is happening.&lt;/p&gt;

&lt;p&gt;If the error is SCRIPT1002, see if there are any arrow functions or class being used.&lt;/p&gt;

&lt;p&gt;The following article was very helpful in identifying the error. (Written in Japanese, you can use translator)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qiita.com/siruku6/items/3465fd6e0588ee35cc78"&gt;https://qiita.com/siruku6/items/3465fd6e0588ee35cc78&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Find what library cause syntax error
&lt;/h3&gt;

&lt;p&gt;Start up the Nuxt server in dev mode and access it with Firefox or Chrome.&lt;/p&gt;

&lt;p&gt;Analyze the file _nuxt/vendors/app.js, which is a collection of bundled external libraries.&lt;/p&gt;

&lt;p&gt;For example, if the arrow function &lt;code&gt;=&amp;gt;&lt;/code&gt; is causing problems in IE, find the place where the arrow function is used, and look a few lines above it to find the name of the original library.&lt;/p&gt;

&lt;p&gt;In the example below, the library named ansi-regex looks suspicious.&lt;/p&gt;

&lt;p&gt;Once you know the name, add this library to the target of the nuxt.config.js transpile as before.&lt;/p&gt;

&lt;p&gt;Reload and check that the arrow function that was there earlier is gone.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. repeat steps 1 and 2
&lt;/h3&gt;

&lt;p&gt;It would be nice if all the errors came out in step 1, but we can only find the first non-IE syntax.&lt;/p&gt;

&lt;p&gt;I dealt with each one one by crushing the arrow function, then crushing the class, then the next, and so on.&lt;br&gt;
This is what I did, I hope this will help anyone!&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisite knowledge: Transpile and polyfill
&lt;/h2&gt;

&lt;p&gt;To make new Javascript compatible with older browsers, there are two things to do.&lt;/p&gt;

&lt;p&gt;One is “transpile”. Transpiling is to rewrite code with the NEW Javascript syntax that would cause syntax errors (ex. Arrow functions)to the old Javascript for the purpose browser’s Javascript interpreter.&lt;/p&gt;

&lt;p&gt;For example,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;() =&amp;gt; {  [1, 2, 3].map(e =&amp;gt; console.log(e * 2))} // Arrow function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will be transpiled into&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function () {  [1, 2, 3].map(function (e) {    return console.log(e * 2);  });});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The other is Polyfill. Polyfill will give support of features that is syntactically correct but does not work.&lt;/p&gt;

&lt;p&gt;For example, Array.prototype.includes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 2, 3].includes(3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above code is syntactically correct, but don’t work in old browser.&lt;/p&gt;

&lt;p&gt;Polyfill code will inject new methods in Array.prototype and make above code work.&lt;/p&gt;

&lt;p&gt;I was going to post an example, but it was too long.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://polyfill.io/v3/polyfill.js?features=Array.prototype.includes"&gt;https://polyfill.io/v3/polyfill.js?features=Array.prototype.includes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see it by accessing with IE or wget.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
    </item>
    <item>
      <title>Using Amazon EFS file system as a permanent volume for EKS cluster</title>
      <dc:creator>Keigo Yamamoto</dc:creator>
      <pubDate>Fri, 23 Sep 2022 15:50:17 +0000</pubDate>
      <link>https://dev.to/k5trismegistus/using-amazon-efs-file-system-as-a-permanent-volume-for-eks-cluster-m0h</link>
      <guid>https://dev.to/k5trismegistus/using-amazon-efs-file-system-as-a-permanent-volume-for-eks-cluster-m0h</guid>
      <description>&lt;p&gt;This post was moved from Medium. I wrote this in 2019, so content may be out of date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I have been struggling with EKS / Kubernetes in this several months.&lt;/p&gt;

&lt;p&gt;As long as the application is containerized, it is best practice to keep the container as little as possible and save the state in the database or object storage, but there may be cases where you want to save the file in the file system.&lt;/p&gt;

&lt;p&gt;In such cases, you can mount a non-volatile file system on a pod using Kubernetes’ Persistent Volumes feature.&lt;br&gt;
However, you must prepare the file system to be mounted by yourself.&lt;/p&gt;

&lt;p&gt;You can choose several mount targets, but it seems better to mount an NFS file system to be able to read from multiple pods at the same time and share their state.&lt;/p&gt;

&lt;p&gt;Therefore, I tried to use Amazon EFS file system, which is a managed NFS file system for peristent volume for EKS cluster.&lt;br&gt;
I thought that EKS and EFS were both AWS managed services, and it would be easy. However I had to spend whole of a day to achieve this. That’s why I wrote this article, I hope that this article will help for you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Create an EFS file system
&lt;/h3&gt;

&lt;p&gt;Create an EFS file system from the AWS console.&lt;/p&gt;

&lt;p&gt;At this time, add all subnets where EKS worker nodes exist to the mount target, and set up a security groups for EKS worker nodes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/jp/about-aws/whats-new/2019/02/deploy-a-kubernetes-cluster-using-amazon-eks-with-new-quick-start/"&gt;https://aws.amazon.com/jp/about-aws/whats-new/2019/02/deploy-a-kubernetes-cluster-using-amazon-eks-with-new-quick-start/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you used this quick start, you’ll have xxx-NodeSecurityGroup-yyysecurity groups.&lt;br&gt;
Sorry for not in English&lt;/p&gt;
&lt;h3&gt;
  
  
  Worker node IAM role
&lt;/h3&gt;

&lt;p&gt;Add the policy for EFS volume created in 1 to the role of EKS worker node. It ’s also called “Quick Start” xxx-NodeInstanceRole-yyy.&lt;/p&gt;

&lt;p&gt;If this role is granted “list, read, write” permission for the EFS file system created earlier, it is OK.&lt;/p&gt;
&lt;h2&gt;
  
  
  efs-provisioner settings
&lt;/h2&gt;

&lt;p&gt;To use EFS as a Kubernetes persistent volume, efs-provisioneryou need to use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kubernetes-retired/external-storage/tree/master/aws/efs"&gt;https://github.com/kubernetes-retired/external-storage/tree/master/aws/efs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, there is a trap that this does not work if you follow the README.&lt;br&gt;
This is because the sample manifests in the repository areincorrect. . 😡&lt;/p&gt;

&lt;p&gt;I fount a solution in this issue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kubernetes-incubator/external-storage/issues/1209"&gt;https://github.com/kubernetes-incubator/external-storage/issues/1209&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you just want to mount EFS file system for Pods, you have to apply 2 yaml files,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kubernetes-incubator/external-storage/blob/master/aws/efs/deploy/rbac.yaml"&gt;https://github.com/kubernetes-incubator/external-storage/blob/master/aws/efs/deploy/rbac.yaml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and&lt;br&gt;
&lt;a href="https://github.com/kubernetes-incubator/external-storage/blob/master/aws/efs/deploy/manifest.yaml"&gt;https://github.com/kubernetes-incubator/external-storage/blob/master/aws/efs/deploy/manifest.yaml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both need to be fixed.&lt;/p&gt;

&lt;p&gt;First of all, rbac.yaml, there are definitions of Role and ClusterRole, but I’m going to unify them into ClusterRole. You must also add a description of the service role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: efs-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

---

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-efs-provisioner
subjects:
  - kind: ServiceAccount
    name: efs-provisioner
    namespace: development # Set namespace
roleRef:
  kind: ClusterRole
  name: efs-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

---

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: development # Set namespace
  name: efs-provisioner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  namespace: development # Set namespace
  name: efs-provisioner
  spec:
    serviceAccount: efs-provisioner
    containers:
      - name: efs-provisioner
        image: quay.io/external_storage/efs-provisioner:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mount EFS filesystem
&lt;/h2&gt;

&lt;p&gt;Then, you can use EFS filesystem from your Pods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kind: Pod
apiVersion: v1
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod
    image: gcr.io/google_containers/busybox:1.24
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/SUCCESS &amp;amp;&amp;amp; exit 0 || exit 1"
    volumeMounts:
      - name: efs-pvc
        mountPath: "/mnt"
  restartPolicy: "Never"
  volumes:
    - name: efs-pvc
      persistentVolumeClaim:
        claimName: efs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Directory splitting
&lt;/h2&gt;

&lt;p&gt;As you can see if you create an appropriate EC2 instance and mount the EFS file system, the directory is cut for each PersistentVolumeClaim, and each pod can only see inside it.&lt;br&gt;
So, if you want to use one EFS file system for multiple pods, you can define multiple PersistentVolumeClaim sharing one StorageClass .&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now the EFS file system can now be used as a Pod’s persistent volume running on an EKS cluster.&lt;br&gt;
I thought that EKS and EFS are both AWS products, so it is common use case that combine them. But unexpectedly I could not find good information, so I hope thiswould be helpful.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Nexxtrack</title>
      <dc:creator>Keigo Yamamoto</dc:creator>
      <pubDate>Thu, 09 Sep 2021 11:37:00 +0000</pubDate>
      <link>https://dev.to/k5trismegistus/nexxtrack-4noi</link>
      <guid>https://dev.to/k5trismegistus/nexxtrack-4noi</guid>
      <description>&lt;p&gt;Hello, I'm Keigo, new to dev.to.&lt;/p&gt;

&lt;p&gt;Let me introduce my works. The first one is Nexxtrack.&lt;br&gt;
I do DJing for hobby and wanted to improve my skill with hacking.&lt;br&gt;
So I analyzed popular mix created by pro DJs and created recommend app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dvcxyMM_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvstg6nrwqgy150u9kpy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dvcxyMM_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvstg6nrwqgy150u9kpy.png" alt="demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This app show what song tend to be mixed with certain song.&lt;/p&gt;

&lt;p&gt;Using Nuxt.js for frontend, flask for api.&lt;/p&gt;

&lt;p&gt;If you have interest, please try and give me feedbacks.&lt;/p&gt;

&lt;p&gt;Thanks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nexxtrack.club/"&gt;https://nexxtrack.club/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wrote an introduction on medium too.&lt;br&gt;
&lt;a href="https://k5trismegistus.medium.com/for-dj-beginners-having-trouble-selecting-songs-use-nexxtrack-8a3cfdd1d5a0"&gt;https://k5trismegistus.medium.com/for-dj-beginners-having-trouble-selecting-songs-use-nexxtrack-8a3cfdd1d5a0&lt;/a&gt;&lt;/p&gt;

</description>
      <category>firstpost</category>
      <category>vue</category>
      <category>nuxt</category>
    </item>
  </channel>
</rss>
