<?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>Forem: Ryan, Siu Long Wa</title>
    <description>The latest articles on Forem by Ryan, Siu Long Wa (@ryansiu1995).</description>
    <link>https://forem.com/ryansiu1995</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%2F428664%2F35090adc-abbd-4900-9779-fc90f1fe6d72.png</url>
      <title>Forem: Ryan, Siu Long Wa</title>
      <link>https://forem.com/ryansiu1995</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ryansiu1995"/>
    <language>en</language>
    <item>
      <title>Google Cloud Build Visualizer</title>
      <dc:creator>Ryan, Siu Long Wa</dc:creator>
      <pubDate>Sun, 21 Nov 2021 08:53:21 +0000</pubDate>
      <link>https://forem.com/ryansiu1995/google-cloud-build-visualizer-254m</link>
      <guid>https://forem.com/ryansiu1995/google-cloud-build-visualizer-254m</guid>
      <description>&lt;p&gt;Google Cloud Build (GCB) is a building system provided by GCP. Considering all the competitors like GitLab CI, CircleCI and Travis CI, GCB is definitely not a common option for building CI CD pipeline.&lt;/p&gt;

&lt;p&gt;In fact, I have tried to test GCB in my work at the early stage of adoption in GCP. The pros of GCB is definitely a full integration with GCP's resources. If you are using GCP and have no preference at the CI pipeline platform, I highly suggest you to try it out.&lt;/p&gt;

&lt;p&gt;Circling back to the GCB's pipeline, all the configurations are written in JSON or YAML format. Here is an example for the GCB configuration.&lt;br&gt;
&lt;/p&gt;

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

  - id: 'compile web app'
    name: 'gcr.io/cloud-builders/npm'
    dir: 'web'
    args: ['install']

  - id: 'web app unit tests'
    name: 'gcr.io/cloud-builders/npm'
    dir: 'web'
    args: ['test']
    waitFor: ['compile web app']

  - id: 'build web'
    name: 'gcr.io/cloud-builders/docker'
    args: [
      'build',
      '--tag=web', # use local registry for compatibility with local builds
      '--tag=gcr.io/$PROJECT_ID/web',
      '--cache-from=gcr.io/$PROJECT_ID/web:latest',
      'web/.',
    ]
    waitFor: ['web app unit tests']

  - id: 'build db'
    name: 'gcr.io/cloud-builders/docker'
    args: [
      'build',
      '--tag=mysql', # use local registry for compatibility with local builds
      '--tag=gcr.io/$PROJECT_ID/mysql',
      '--cache-from', 'gcr.io/$PROJECT_ID/mysql:latest',
      'mysql/.',
    ]
    waitFor: ['-'] # start immediately

  - id: 'compose up'
    name: 'gcr.io/$PROJECT_ID/docker-compose:latest'
    entrypoint: '/bin/bash'
    args:
      - '-c'
      - |
        docker-compose up -d
    env:
      - 'PROJECT_ID=$PROJECT_ID'
    waitFor: ['build web','build db']

  - id: 'integration tests'
    name: 'gcr.io/$PROJECT_ID/docker-compose:latest'
    entrypoint: '/bin/bash'
    args:
      - '-c'
      - |
        ### -r = retries; -i = interval; -k = keyword to search for ###
        ./test/test-connection.sh -r 20 -i 3 -u http://web:3000
        ./test/test-content.sh -r 20 -i 3 -u http://web:3000 -k 'Chocolate Chip'
    waitFor: ['compose up']

images:
  - gcr.io/$PROJECT_ID/web
  - gcr.io/$PROJECT_ID/mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Look intuitive? Yeah! It looks intuitive. It only has the following rules in the pipeline sequence.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No parallel by default&lt;/li&gt;
&lt;li&gt;You can specify the &lt;code&gt;waitFor&lt;/code&gt; to specify the dependencies. Each dependencies will be executed in parallel.&lt;/li&gt;
&lt;li&gt;You can use special character &lt;code&gt;-&lt;/code&gt; to specify this step for job without dependency to run in parallel. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, what is the problem with GCS? The issue here is that the UI itself does not provide you with a clear view on how the steps are depended on each other. Here is an example.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R7Wdx1kR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fikxpk7on5fxw1nuebj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R7Wdx1kR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fikxpk7on5fxw1nuebj.png" alt="Image description" width="880" height="448"&gt;&lt;/a&gt;&lt;br&gt;
Here, you can see the steps are showed in sequential manner. You cannot observe if this build has been executed in parallel.&lt;/p&gt;

&lt;p&gt;Therefore, I have tried to build a simple CLI to make sure we can understand how the steps are depended.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/RyanSiu1995"&gt;
        RyanSiu1995
      &lt;/a&gt; / &lt;a href="https://github.com/RyanSiu1995/gcb-visualizer"&gt;
        gcb-visualizer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Cloudbuild pipeline visualizer with graphviz
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Google Cloud Build Pipeline Visualizer&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://github.com/RyanSiu1995/gcb-visualizer/workflows/Go/badge.svg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iRPbFfyF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/RyanSiu1995/gcb-visualizer/workflows/Go/badge.svg" alt="build"&gt;&lt;/a&gt; &lt;a href="https://codecov.io/gh/RyanSiu1995/gcb-visualizer" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/acf9c21692ab8540e90dfa5ed0294304c550d2d87815a8107cd9635f723d92c8/68747470733a2f2f636f6465636f762e696f2f67682f5279616e536975313939352f6763622d76697375616c697a65722f6272616e63682f6d61737465722f67726170682f62616467652e7376673f746f6b656e3d3651415859525632355a" alt="codecov"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For the current version of Google cloud build, it supports the async process with the variable &lt;code&gt;waitFor&lt;/code&gt;. With the growth of complexity of your pipeline, it will be hard to maintain the async flow. Unlike Jenkins and CircleCI, there is no visualizer for your pipeline. This application aims at visualize the pipeline and help the developers to debug their cloud build.&lt;/p&gt;
&lt;h2&gt;
Current features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;YAML format cloud build definition digestion&lt;/li&gt;
&lt;li&gt;Temporary graph rendering&lt;/li&gt;
&lt;li&gt;Save graph as dot, png, jpg or jpeg&lt;/li&gt;
&lt;li&gt;JSON format support&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Rule of cloud build async process&lt;/h2&gt;
&lt;p&gt;From the Google &lt;a href="https://cloud.google.com/cloud-build/docs/configuring-builds/configure-build-step-order" rel="nofollow"&gt;docs&lt;/a&gt;, there are a few rules for the async process.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If no values are provided for waitFor, the build step waits for all prior build steps in the build request to complete successfully before running.&lt;/li&gt;
&lt;li&gt;A step is dependent on every id in its waitFor and will not launch until each…&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/RyanSiu1995/gcb-visualizer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;In this project, I built the CLI with cobra and graphviz. The logic is so simple that it will intake the JSON or YAML file. Then, it parses the configuration and turn the pipeline into a graph. Finally, the graph can be visualized by graphviz.&lt;/p&gt;

&lt;p&gt;You can get the CLI easily with 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;go get -u github.com/ryansiu1995/gcb-visualizer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to the link and check it out if you are using GCB in your company or personal project. It definitely helps you to understand how you have configured your pipeline in GCB.&lt;/p&gt;

&lt;p&gt;Please feel free to open an issue if you have configured out any features you want in the GCB Visualizer!&lt;/p&gt;

</description>
      <category>github</category>
      <category>go</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Quick walkthrough in CKAD, CKA and CKS</title>
      <dc:creator>Ryan, Siu Long Wa</dc:creator>
      <pubDate>Wed, 24 Mar 2021 08:31:48 +0000</pubDate>
      <link>https://forem.com/ryansiu1995/quick-walkthrough-in-ckad-cka-and-cks-1e27</link>
      <guid>https://forem.com/ryansiu1995/quick-walkthrough-in-ckad-cka-and-cks-1e27</guid>
      <description>&lt;p&gt;Certified Kubernetes Application Developer and Certified Kubernetes Administrator are the two certifications for most of the Kubernetes users to showcase their understanding in the Kubernetes ecosystem.&lt;/p&gt;

&lt;p&gt;Certified Kubernetes Security Specialist is the certification released last year to train and showcase the candidates on Kubernetes system hardening. It is definitely a new step for the community getting DevSecOps.&lt;/p&gt;

&lt;p&gt;In the past few months, I have finished all the examinations.  Here is my review and analysis for these examinations for not only examinees but also the recruiter.&lt;/p&gt;

&lt;h1&gt;
  
  
  Certified Kubernetes Application Developer (CKAD)
&lt;/h1&gt;

&lt;p&gt;Certified Kubernetes Application Developer is my first examination among the series. For the actual examination details, please refer to the actual documentation from CNCF.&lt;/p&gt;

&lt;p&gt;CKAD, as its name, aims to train and examine the basic Kubernetes operation. The examinee will need to demonstrate their understanding in application deployment under Kubernetes. &lt;/p&gt;

&lt;p&gt;Most of the questions inside CKAD can be generalized into the concepts or best practice under Kubernetes ecosystem. Therefore, if you understand how to architect the apps inside Kubernetes, this exam will be easy for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example - Sidecar pattern
&lt;/h2&gt;

&lt;p&gt;If you need to deploy an application which will write the logs to file instead of the stdout, how could you stream the logs to stdout without changing the actual configuration? This will require the sidecar pattern under Kubernetes. Here is the example from the Kubernetes &lt;a href="https://kubernetes.io/docs/concepts/cluster-administration/logging/"&gt;doc&lt;/a&gt;.&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="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pod&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;counter&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;count&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;busybox&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/bin/sh&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;-c&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;i=0;&lt;/span&gt;
      &lt;span class="s"&gt;while true;&lt;/span&gt;
      &lt;span class="s"&gt;do&lt;/span&gt;
        &lt;span class="s"&gt;echo "$i: $(date)" &amp;gt;&amp;gt; /var/log/1.log;&lt;/span&gt;
        &lt;span class="s"&gt;echo "$(date) INFO $i" &amp;gt;&amp;gt; /var/log/2.log;&lt;/span&gt;
        &lt;span class="s"&gt;i=$((i+1));&lt;/span&gt;
        &lt;span class="s"&gt;sleep 1;&lt;/span&gt;
      &lt;span class="s"&gt;done      &lt;/span&gt;
    &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;varlog&lt;/span&gt;
      &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/log&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;count-log-1&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;busybox&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;/bin/sh&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;-c&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tail&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-n+1&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-f&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/1.log'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;varlog&lt;/span&gt;
      &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/log&lt;/span&gt;
  &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;varlog&lt;/span&gt;
    &lt;span class="na"&gt;emptyDir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under this example, a couple of concepts can be extracted. &lt;/p&gt;

&lt;p&gt;The first concept, of course, is the sidecar pattern. The sidecar pattern will be important when the software engineers architect their application under Kubernetes. It is very important that the software engineers make use of the sidecar pattern to achieve the best practice, single process per container. &lt;/p&gt;

&lt;p&gt;The second concept here is the temporarily storage. It is common that an empty directory is created within a pod and shares the files across different containers. &lt;/p&gt;

&lt;h2&gt;
  
  
  Example - Usage in the Deployment, DaemonSet and StatefulSet
&lt;/h2&gt;

&lt;p&gt;CKAD examinees in general are required to demonstrate their understanding between Deployment, DaemonSet and StatefulSet. Although they can be used for deploying your applications, they are served for different purpose based on the different usage.&lt;/p&gt;

&lt;p&gt;If you are asked to deploy FluentD, a log aggregator, to stream all the logs to your own logging system, what type of ReplicaSet you will use? You can simply inject the sidecar to each pod but that is hard to manage. The better way on this will be the DaemonSet. Deploying the containers interact with each node can help you to a cluster-wide log streaming in this case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who should take this examination?
&lt;/h2&gt;

&lt;p&gt;CKAD is quite different from the CKA and CKS. It aims to test the users on the basic architecture and design pattern under Kubernetes. If you are the following group of engineers, I suggests that you can give a try on this certification.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beginner in Kubernetes&lt;/li&gt;
&lt;li&gt;Software engineers who use Kubernetes for your production environment&lt;/li&gt;
&lt;li&gt;DevOps/Site Reliability Engineers&lt;/li&gt;
&lt;li&gt;System Engineers&lt;/li&gt;
&lt;li&gt;etc...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the examination, you can expect that you are able to use Kubernetes to architect and design your application.&lt;/p&gt;

&lt;h1&gt;
  
  
  Certified Kubernetes Administrator (CKA)
&lt;/h1&gt;

&lt;p&gt;If CKAD is a beginner under Kubernetes certification series, CKA will be the next level. It will cover parts of the CKAD knowledge, for example, the application development. At the same time, CKA examinees will start to interact with the actual Kubernetes implementation.&lt;/p&gt;

&lt;p&gt;You need to understand how the Kubernetes is built behind the scene. Unlike CKAD, you need to configure not only the highest level of objects inside Kubernetes, like Pod, Deployment but also the actual key components inside the cluster. &lt;/p&gt;

&lt;p&gt;In the community, there are a couple of ways to bootstrap the cluster. In the examination, it only focuses on the &lt;code&gt;kubeadm&lt;/code&gt; method. The operation, like node joining, upgrading, etc, will be asked. It is quite similar to the system administrator but it focuses on the maintenance under Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example - &lt;code&gt;kubelet&lt;/code&gt;, &lt;code&gt;kube-apiserver&lt;/code&gt; and &lt;code&gt;etcd&lt;/code&gt; configuration
&lt;/h2&gt;

&lt;p&gt;Under &lt;code&gt;kubeadm&lt;/code&gt; implementation, you can easily configure the args parsing into the &lt;code&gt;kubelet&lt;/code&gt;, &lt;code&gt;kube-apiserver&lt;/code&gt; and &lt;code&gt;etcd&lt;/code&gt;. But unlike configuring the Kubernetes objects, you cannot use &lt;code&gt;kubectl&lt;/code&gt; to interact with these components directly. You will need to understand how the &lt;code&gt;kubeadm&lt;/code&gt; bootstraps a node. In general, &lt;code&gt;kubeadm&lt;/code&gt; generates a set of configuration files under a particular path. &lt;/p&gt;

&lt;h2&gt;
  
  
  Example - CNI and CRI
&lt;/h2&gt;

&lt;p&gt;Container Network Interface (CNI) and Container Runtime Interface (CRI) are two important interfaces under Kubernetes. This allows us to change the implementation of the container networking and runtime easily. &lt;/p&gt;

&lt;p&gt;But, you may ask why you will need to change them. Different CNIs' and CRIs' implementation actually provides different features. According to your business need, you may need to choose the best CNI and CRI. Beyond choosing the correct one, you will need to understand how to configure them within the clusters. &lt;/p&gt;

&lt;h2&gt;
  
  
  Who should take this examination?
&lt;/h2&gt;

&lt;p&gt;CKA starts to interact with &lt;code&gt;kubelet&lt;/code&gt;, &lt;code&gt;kube-apiserver&lt;/code&gt; and &lt;code&gt;etcd&lt;/code&gt; directly. You will need to understand how the Kubernetes works behind the scene and how to maintain it. Here are the candidates that may benefit from passing the examination in my mind.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Advanced Kubernetes users, like operator maintainer&lt;/li&gt;
&lt;li&gt;DevOps/Site Reliability Engineers&lt;/li&gt;
&lt;li&gt;System Engineers&lt;/li&gt;
&lt;li&gt;Security Engineers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Advanced users, they want to interact with the &lt;code&gt;kube-apiserver&lt;/code&gt; and &lt;code&gt;etcd&lt;/code&gt; to develop their own controllers or operators, the knowledge from CKA is quite helpful to you. &lt;/p&gt;

&lt;p&gt;For the last one, it is important for the security engineers to understand how the Kubernetes is bootstrapped. Kubernetes is more and more prevalent in recent years. When you works for a company with Kubernetes orchestration, you definitely need to explore Kubernetes from the system level instead of simply the usage level.&lt;/p&gt;

&lt;h1&gt;
  
  
  Certified Kubernetes Security Specialist (CKS)
&lt;/h1&gt;

&lt;p&gt;CKS is the last certification. You need to pass the CKA in order to get this certified. Therefore, you can know that the difficulty of CKS will not be lower than CKA.&lt;/p&gt;

&lt;p&gt;CKS aims to examine the candidates from more advanced usage. Under CKAD and CKS, you only focuses on the built-in APIs from Kubernetes. You can open the API cookbook under Kubernetes.io to finish most of the tasks in the examination. But, for CKS, you start to integrate your cluster and applications with the community-driven application. &lt;/p&gt;

&lt;h2&gt;
  
  
  Example - Annotation-based API
&lt;/h2&gt;

&lt;p&gt;The most important part here is how to extend the Kubernetes features with annotation. Security is simply the smokescreen.  In Kubernetes ecosystem, if there are some features not coming with the official APIs, it is pretty common that the APIs are placed in the annotation. &lt;/p&gt;

&lt;p&gt;For example, one important third party application under Kubernetes ecosystem is cert manager. When you configure an ingress with cert manager, you can put the annotation like the following example from &lt;a href="https://cert-manager.io/docs/usage/ingress/"&gt;official doc&lt;/a&gt; to tell the cert manager to generate TLS cert for you.&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="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# add an annotation indicating the issuer to use.&lt;/span&gt;
    &lt;span class="s"&gt;cert-manager.io/cluster-issuer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nameOfClusterIssuer&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myIngress&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myIngress&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;
    &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;serviceName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myservice&lt;/span&gt;
          &lt;span class="na"&gt;servicePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
  &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt; placing a host in the TLS config will indicate a certificate should be created&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;
    &lt;span class="na"&gt;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myingress-cert&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt; cert-manager will store the created certificate in this secret.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example - API server and &lt;code&gt;Kubelet&lt;/code&gt; Hardening
&lt;/h2&gt;

&lt;p&gt;In CKA, you need to configure the API server and &lt;code&gt;kubelet&lt;/code&gt; with the basic function. No matter what configuration you have in the API server and &lt;code&gt;kubelet&lt;/code&gt;, it is more than enough for that evaluation. &lt;/p&gt;

&lt;p&gt;In CKS, you will need to configure the cluster with the best practice. Kubernetes is designed to fit in a lot of different situations. Therefore, some of the settings may contain the attack surface if you enable them. If you put the Kubernetes into production, you need to fine tune your configuration in order to prevent the cluster from hacking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who should take this examination?
&lt;/h2&gt;

&lt;p&gt;CKS is the latest certification released by CNCF. It actually brings the Kubernetes certification series into more production level. In CKAD and CKA, you can assume the certified can use the Kubernetes. But that is the best for the production usage. &lt;/p&gt;

&lt;p&gt;Under the production usage, you definitely need to consider the security no matter which industry you are in. CKS provides a way to teach the candidates how to harden the Kubernetes system. Here are the groups I recommend them to take this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DevOps/Site Reliability Engineers&lt;/li&gt;
&lt;li&gt;System Engineers&lt;/li&gt;
&lt;li&gt;Security Engineers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A side track message - Please be reminded that security is not just the responsibility of security engineers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;To be honest, as a Kubernetes engineer, CNCF has tried their best in the design of these three certification. Unlike other certifications, you will need to have the hands-on operations during the examination.&lt;/p&gt;

&lt;p&gt;One more suggestion from me is that you will need to be super super familiar in living in shell. If you used the dashboard or UI for your Kubernetes journey, it is time to change your habit! &lt;/p&gt;

&lt;h1&gt;
  
  
  Disclaimer
&lt;/h1&gt;

&lt;p&gt;I have tried my best not to disclose any kind of examination questions within my sharing. Please leave the comments or email me at &lt;a href="mailto:findme@ryansiulw.com"&gt;findme@ryansiulw.com&lt;/a&gt; if there are any improper contents. I will remove that part or simply delete this sharing directly.&lt;/p&gt;

</description>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Dev Blog - Celery Operator - Part 1 - Initial Design</title>
      <dc:creator>Ryan, Siu Long Wa</dc:creator>
      <pubDate>Sat, 05 Sep 2020 13:27:51 +0000</pubDate>
      <link>https://forem.com/ryansiu1995/dev-blog-celery-operator-part-1-initial-design-3hn2</link>
      <guid>https://forem.com/ryansiu1995/dev-blog-celery-operator-part-1-initial-design-3hn2</guid>
      <description>&lt;p&gt;This is the first part of my development blog in celery operator. Here is the disclaimer. This operator is purely my personal learning product. It does not go through the official CEP process in celery community. Please refer to the official one if you seek for an operator with LTS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;With the heavy usage of operators in my career, the abstraction in the Kubernetes layer is so awesome that engineers could easily monitor and scale their applications with kubectl.&lt;/p&gt;

&lt;p&gt;In my current company, in order to separate the loading from web server, some of the tasks are delegated to a task queue application. It is called celery in python. A ton of apps are now supporting celery as their task queuing backend.&lt;/p&gt;

&lt;p&gt;The great thing of celery is similar to other task queuing service. It provides multiple queues for different requirements from the task. It also provides us with a cronjob service to run tasks periodically. This provides a super handy way to create both on-demand and corn-based task execution to a web server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issues spotted
&lt;/h3&gt;

&lt;p&gt;In the Kubernetes world, the biggest advantages Kubernetes has are scaling and observability.&lt;/p&gt;

&lt;p&gt;For example, it is common to implement the horizontal pod autoscaler(HPA) with different affinity and selector rules. High availability and high redundancy becomes a super easy task to accomplish in this realm.&lt;/p&gt;

&lt;p&gt;Object status is also a powerful utility when we deal with the custom resource definition. It provides us with a handy way to list out the status of apps itself. If you have deal with operator before, you will know a good operator design could give you a full overview in kubectl interaction.&lt;/p&gt;

&lt;p&gt;Let’s circle back to the celery itself. My experience in the deployment of celery onto Kubernetes is so bad that the app itself could not fully utilize the modern infra design in the Kubernetes.&lt;/p&gt;

&lt;p&gt;For example, celery requires a number of resources in order to provide the full functioning app stack. Broker, result backend, worker and schedule are required. In my current company, the helm chart to deploy celery stack is pretty complex. This handicaps our maintainability of the charts.&lt;/p&gt;

&lt;p&gt;Observability is also a serious issue in celery. Celery does not come with tracing or monitoring feature. We need to deploy an additional app called flower to show up the status of celery. Unfortunately, my colleagues had a really terrible experience in flower... It consumed a myriad of resources in his laptop... Anyway, in order to provide more detailed info, we may need to enter the pods and execute the celery command. This introduces a serious security issue because you gives out the permission of exec in the cluster to the engineers. Eventually, this increases the workload in my team drastically when dealing with celery.&lt;/p&gt;

&lt;p&gt;Last but not least, the scaling with Kubernetes is so terrible for celery. In order to scale the celery against with the queue size (of course based on queue size but not the built-in CPU or memory way). We need to setup celery exporter and Prometheus. And Prometheus turns the metric into Kubernetes-native metrics format. Umm... When you see this action, you know how complicated it is... But without scaling, we need to pay extra cost in maintaining those potentially unused instances...What a dilemma it is!&lt;/p&gt;

&lt;h2&gt;
  
  
  Design of operator
&lt;/h2&gt;

&lt;p&gt;In order to resolve the issues spotted, I have decided to move onto operator. Originally, I just want to make use of the official one. But I just realized that the official one is still under POC and it cannot fully support what I want to do in the operator.&lt;/p&gt;

&lt;p&gt;Therefore, I have decided to design and develop my own celery operator!&lt;/p&gt;

&lt;p&gt;We have a ton of methods to build a Kubernetes operator. As the officially supported celery operator, it takes an approach like a templating method, similar to helm and kustomize. For my celery operator, I want to try something different, operator SDK with kubebuilder!&lt;/p&gt;

&lt;p&gt;Originally, I want to create an all-in-one celery CRD. However, after a careful thinking, I felt all-in-one celery CRD is pretty hard to maintain. Imagine that there are over 1000 lines within a reconcile function. This definitely is not a good style in coding.&lt;/p&gt;

&lt;p&gt;Therefore, I eventually separated all the controllers and use an all-in-one celery CRD to wrap the rest of CRDs. The resultant structure is like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Celery&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Schedulers&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;CeleryScheduler&lt;/span&gt;
  &lt;span class="n"&gt;Broker&lt;/span&gt; &lt;span class="n"&gt;CeleryBroker&lt;/span&gt;
  &lt;span class="n"&gt;Workers&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;CeleryWorker&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or using graphviz to visualize the relation.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRyanSiu1995%2Fcelery-operator%2Fmaster%2Fassets%2Fimg%2Fcontroller-relation.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FRyanSiu1995%2Fcelery-operator%2Fmaster%2Fassets%2Fimg%2Fcontroller-relation.svg" alt="controllers-relation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this design, the users could simply fit in their own usage. If they want to keep their existing stack with a newly introduced workers, they could simply create the workers CRD. And the code itself could be separated easier.&lt;/p&gt;

&lt;p&gt;Under the controller, I originally chose the deployment as the way to control the pod spawning. However, I have foreseen that deployment possibly is not a good way to go if I want to control the pod spawning with custom metrics, like queue size.&lt;/p&gt;

&lt;p&gt;Eventually, I change the design from deployment to pod directly. This is a really tough decision because I needed to implement all the CRUD issues on my own... This is another story to go...&lt;/p&gt;

&lt;p&gt;For now, the celery operator has already implemented the &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt; and &lt;code&gt;delete&lt;/code&gt; method. The last step before releasing the first Alpha version is the metric extraction. This will be included in the next article in this series. &lt;/p&gt;

&lt;p&gt;Ref: &lt;br&gt;
celery-operator - &lt;a href="https://github.com/RyanSiu1995/celery-operator" rel="noopener noreferrer"&gt;https://github.com/RyanSiu1995/celery-operator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>celery</category>
      <category>kubernetes</category>
      <category>python</category>
      <category>go</category>
    </item>
    <item>
      <title>Will you map Ctrl to CapLock?</title>
      <dc:creator>Ryan, Siu Long Wa</dc:creator>
      <pubDate>Tue, 25 Aug 2020 02:52:25 +0000</pubDate>
      <link>https://forem.com/ryansiu1995/will-you-map-ctrl-to-caplock-p6k</link>
      <guid>https://forem.com/ryansiu1995/will-you-map-ctrl-to-caplock-p6k</guid>
      <description>&lt;p&gt;In my keyboard setting, I always map ctrl key to caplock such that I could press the ctrl key easier. However, this makes a big trouble when someone uses my keyboard lol. I tried to find a keycap that will indicate this change but cannot find any vendors provided this printing service.&lt;/p&gt;

&lt;p&gt;How's about you? Do you map the key?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>vim</category>
      <category>emacs</category>
    </item>
    <item>
      <title>A quick way to prune local branches</title>
      <dc:creator>Ryan, Siu Long Wa</dc:creator>
      <pubDate>Tue, 18 Aug 2020 14:44:05 +0000</pubDate>
      <link>https://forem.com/ryansiu1995/a-quick-way-to-prune-local-branches-hi8</link>
      <guid>https://forem.com/ryansiu1995/a-quick-way-to-prune-local-branches-hi8</guid>
      <description>&lt;p&gt;When I worked with a lot of features at the same time, it was really common to create a bunch of branches locally.&lt;/p&gt;

&lt;p&gt;I felt really annoyed when I run &lt;code&gt;git branch&lt;/code&gt; locally... It gives me a ton of legacy branches... This is super annoying especially when I use the tab-complete function.&lt;/p&gt;

&lt;p&gt;When I searched for the way to clean up my local environment, it is common that the community will suggest &lt;code&gt;git fetch origin -p&lt;/code&gt;. But, in fact, this is just a way to clean up the remote branches cached locally, i.e. the branches you see when you run &lt;code&gt;git branch -r&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It seems that the current git does not implement such handy feature. I have quickly created this snippet in GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash -e&lt;/span&gt;

git fetch origin &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;span class="nv"&gt;REMOTE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git branch &lt;span class="nt"&gt;-r&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s2"&gt;"s/origin&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;//g"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;BRANCHES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git branch | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s1"&gt;' +'&lt;/span&gt; &lt;span class="s1"&gt;'! /\(no branch\)/ {print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;branch &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$BRANCHES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$REMOTE&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;git branch &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="nv"&gt;$branch&lt;/span&gt;
  &lt;span class="k"&gt;fi
done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ref: &lt;a href="https://gist.github.com/RyanSiu1995/da44646f747623d9f51ec52724f16066"&gt;https://gist.github.com/RyanSiu1995/da44646f747623d9f51ec52724f16066&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you create a file with this code, run the following command to put it to your &lt;code&gt;PATH&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;777 git-prune-branches
&lt;span class="nb"&gt;mv &lt;/span&gt;git-prune-branches /usr/local/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enjoy!&lt;/p&gt;

</description>
      <category>git</category>
      <category>bash</category>
      <category>gists</category>
    </item>
    <item>
      <title>Kubebuilder Installer</title>
      <dc:creator>Ryan, Siu Long Wa</dc:creator>
      <pubDate>Mon, 17 Aug 2020 13:48:23 +0000</pubDate>
      <link>https://forem.com/ryansiu1995/kubebuilder-installer-5hl1</link>
      <guid>https://forem.com/ryansiu1995/kubebuilder-installer-5hl1</guid>
      <description>&lt;h3&gt;
  
  
  Kubebuilder Installer
&lt;/h3&gt;

&lt;p&gt;This is the sugar action that helps me to replace the script inside my operator action development.&lt;br&gt;
It will download the corresponding version of kubebuilder and keep it under &lt;code&gt;/usr/local/kubebuilder&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Maintainer Must-Haves, Wacky Wildcards (Mainly used for the CI in Kubernetes operator development)&lt;/p&gt;
&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/RyanSiu1995"&gt;
        RyanSiu1995
      &lt;/a&gt; / &lt;a href="https://github.com/RyanSiu1995/kubebuilder-action"&gt;
        kubebuilder-action
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      GitHub Action module to install kubebuilder
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Kubebuilder installation docker action&lt;/h1&gt;
&lt;p&gt;This action provides a sugar syntax to install the kubebuilder in the ubuntu machine. The installation process is based on kubebuilder v2.3.1.&lt;/p&gt;
&lt;h2&gt;
Inputs&lt;/h2&gt;
&lt;h3&gt;
&lt;code&gt;version&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Required&lt;/strong&gt; The version going to be installed. Default &lt;code&gt;"2.3.1"&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
Example usage&lt;/h2&gt;
&lt;div class="highlight highlight-source-yaml"&gt;&lt;pre&gt;&lt;span class="pl-ent"&gt;uses&lt;/span&gt;: &lt;span class="pl-s"&gt;RyanSiu1995/kubebuilder-action@v1&lt;/span&gt;
&lt;span class="pl-ent"&gt;with&lt;/span&gt;:
  &lt;span class="pl-ent"&gt;version&lt;/span&gt;: &lt;span class="pl-s"&gt;2.3.1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
License&lt;/h2&gt;
&lt;p&gt;This software is released under Apache License 2.0. Please refer to &lt;a href="https://raw.githubusercontent.com/RyanSiu1995/kubebuilder-action/master/LICENSE"&gt;LICENSE&lt;/a&gt; file for more details.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/RyanSiu1995/kubebuilder-action"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;The first version of this action is just to use the &lt;code&gt;child_process&lt;/code&gt; inside JS. In the next release, it will change back to the standard libraries in JS.&lt;/p&gt;

</description>
      <category>actionshackathon</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Interview to GAFA</title>
      <dc:creator>Ryan, Siu Long Wa</dc:creator>
      <pubDate>Fri, 10 Jul 2020 16:35:49 +0000</pubDate>
      <link>https://forem.com/ryansiu1995/interview-to-gafa-5b6i</link>
      <guid>https://forem.com/ryansiu1995/interview-to-gafa-5b6i</guid>
      <description>&lt;p&gt;With two years experience in IT and non-CS background, I really want to challenge myself and see how far I can go. Then, I have applied for the big tech companies. Eventually, I got defeated but I know more about my weaknesses.&lt;/p&gt;

&lt;h1&gt;
  
  
  Coding Test
&lt;/h1&gt;

&lt;p&gt;All positions in the big tech companies must start with coding challenge. The coding challenge in general does not aim to make you feel bad. Instead, you need to present your mindset verbosely and show how well you understand the complexity and data structure.&lt;/p&gt;

&lt;p&gt;It is not necessary to run the code but analyze your code well. As a starting point, it is better if you can actually explain your mindset first.&lt;/p&gt;

&lt;p&gt;And one thing I have learned. No one cares if you could memorize all the standard libraries. Spend more time on your oral presentation, algorithm design and coding practice instead!&lt;/p&gt;

&lt;h1&gt;
  
  
  Deep understanding on computer
&lt;/h1&gt;

&lt;p&gt;I lived in a practical world. I learned all the Linux and networking from my work. However, it is really common to test your understanding on the story behind the scene.&lt;/p&gt;

&lt;p&gt;For every button, every single step and every command you run, you have to know it from its root. For example, when you talk about TCP, you need to know how it does the three way handshake. But this is just a basic. You need to also memorize and know all the parts inside the pocket and how they actually make the TCP works. Always ask why when you hit an action in your work.&lt;/p&gt;

&lt;h1&gt;
  
  
  Think about the private cloud
&lt;/h1&gt;

&lt;p&gt;A lot of companies nowadays use public cloud. But when you enter the big tech companies, they use private cloud instead. You need to know how to manage the cluster in the data center, like rack.&lt;/p&gt;

&lt;p&gt;And you also need to know how to handle the distributive computing inside the private cloud.&lt;/p&gt;

&lt;p&gt;You will hit a lot of problems if you only know how to handle the public cloud, especially for those who only know how to point and click in the UI.&lt;/p&gt;

&lt;h1&gt;
  
  
  Sum up
&lt;/h1&gt;

&lt;p&gt;I am still too green in the IT industry. I have planed for studying the basic knowledge again and consolidate all the area before taking their challenges again.&lt;/p&gt;

&lt;p&gt;My target is to finish my selected MIT open course first!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
