<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Twelve Factor &#8211; Few Steps &#8211; ก้าวสั้นๆ แต่ไปเรื่อยๆ</title>
	<atom:link href="https://myifew.com/tag/the-twelve-factor/feed/" rel="self" type="application/rss+xml" />
	<link>https://myifew.com</link>
	<description></description>
	<lastBuildDate>Wed, 15 Sep 2021 04:24:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://myifew.com/wp-content/uploads/2018/07/cropped-logo6-ts-32x32.png</url>
	<title>The Twelve Factor &#8211; Few Steps &#8211; ก้าวสั้นๆ แต่ไปเรื่อยๆ</title>
	<link>https://myifew.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>วิธีเก็บ Sensitive Data บน Kubernetes ด้วย Secrets</title>
		<link>https://myifew.com/6012/sensitive-data-on-kubernetes/</link>
					<comments>https://myifew.com/6012/sensitive-data-on-kubernetes/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Tue, 14 Sep 2021 12:21:12 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[The Twelve Factor]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=6012</guid>

					<description><![CDATA[จากบล็อกที่แล้วได้ลองทำ Kubernetes บน Amazon EKS แบบง่ายๆ ด้วย eksctl แต่ก็ยังมีจุดที่กังวลอยู่ คือเรื่องการระบุ Sensitive Data เช่น Password, Token ต่างๆ ลงใน Environment&#8230;]]></description>
										<content:encoded><![CDATA[
<p>จากบล็อกที่แล้วได้<a rel="noreferrer noopener" href="https://myifew.com/5972/kubernetes-on-amazon-eks/" data-type="URL" data-id="https://myifew.com/5972/kubernetes-on-amazon-eks/" target="_blank">ลองทำ Kubernetes บน Amazon EKS แบบง่ายๆ ด้วย eksctl</a> แต่ก็ยังมีจุดที่กังวลอยู่ คือเรื่องการระบุ Sensitive Data เช่น Password, Token ต่างๆ ลงใน Environment Variable ที่ได้เขียนไว้ในไฟล์ Deployment YML </p>



<p>ซึ่งทาง Kubernetes เอง ได้ทำฟีเจอร์มารองรับการแก้ปัญหานี้แล้ว เป็น Kind ประเภท Secret นั่นเองครับ เลยขอบันทึกวิธีทำไว้สักหน่อย</p>



<span id="more-6012"></span>



<h2 class="wp-block-heading">ทำความเข้าใจก่อน ทำไมต้องแยก Sensitive Data</h2>



<p>ก่อนจะไปถึงวิธีการ มาทำความเข้าใจก่อนว่าทำไมเราต้องแยก Sentitive Data ออกไป (ขอนอกเรื่อง Kubernetes สักหลายย่อหน้า เดี๋ยวโพสต์จะสั้นไป!!)</p>



<p>หากใครทำงานคนเดียว เก็บ Source Code ไว้เป็น Private ในเครื่องตัวเองเท่านั้น (หรือ Git Repository แบบ Private) และไม่ได้ใช้ Clound หรือทำพวก Scaling ด้วยแล้ว อาจไม่จำเป็นต้องใช้ก็ได้</p>



<p>แต่ถ้าเราทำงานเป็นทีมเมื่อไร เรื่องการกำหนดขอบเขตการเข้าถึงข้อมูลเป็นเรื่องสำคัญมาก เราคงไม่ต้องการให้ทีมทุกคนรู้ Password ในการเข้าสู่ระบบ หรือไม่ต้องการให้รู้ Token ในการควบคุม API ของบริการสำคัญๆ ดังนั้นแล้ว เราจะมีวิธีการจัดการพวก Sensitive Data กันมาบ้างอยู่แล้ว ที่นิยมทำกัน เช่น</p>



<ol class="wp-block-list"><li><strong>ง่ายสุดๆ</strong> คือ ฝัง Sensitive Data ลงในโค้ดเลย แล้ว if-else จากเงื่อนไขอะไรบางอย่าง เช่น IP Server, URL Domain, Environment Variable</li><li><strong>ซับซ้อนขึ้นมาหน่อย</strong> คือ ทำไฟล์ Config แยกจากโค้ด และ ignore ไม่ขึ้นไปอยู่บน Repository ดังนั้นเมื่อ Deploy เสร็จ จะมีทีมหลีดหรือผู้มีสิทธิ์เข้าถึง Sensitive Data และ Server เท่านั้น ที่จะไปวางไฟล์ Config (หรือไฟล์ Config อาจจะไปอยู่บน Server แต่ละ Environment รอไว้อยู่แล้ว)</li><li><strong>ซับซ้อนขึ้นไปอีก</strong> คือ ผู้ดูแลระบบสร้าง Environment Variable ไว้ในแต่ละ Server Environment จากนั้น เมื่อ Deploy Code ไปที่ Environment ไหน โค้ดที่เขียนก็จะเรียกใช้ Environment Variable ตามชื่อ Key ที่ตกลงกันไว้</li><li><strong>Advance ไปเลย</strong> คือ ทำ Config File Server แยกไปอีกเครื่อง และ sync มาที่ server ของระบบที่จะใช้งาน จากนั้นโค้ดจะเรียกใช้ Config ตามที่อยู่ของไฟล์ที่ตกลงกันไว้</li></ol>



<p>และวิธีอื่นๆ อีกหลายวิธี ซึ่งแต่ละวิธีมันก็มีความเหมาะสมที่จะใช้งานในแต่ละระบบและกระบวนการทำงานของแต่ละทีม</p>



<p>แต่ถ้าทีมทำงานมีเงื่อนไขอยากทำ Scaling, Automate หรือ DevOps ล่ะ เช่น</p>



<ol class="wp-block-list"><li>Source Code ต้องมาจากแหล่งเดียว และเป็นชุดเดียวกันเสมอในทุก Environment (Single Source of Truth)</li><li>Sensitive Data จะต้องรู้ได้บางคนเท่านั้นที่มีสิทธิ์</li><li>โค้ดจะต้องทำ Continuous Integration และ Continuous Deployment ได้</li><li>โค้ดจะต้อรองรับการทำงานบน Server ที่ Scaling ได้</li><li>มีการควบคุม Version ใน Deployment (Version Control)</li></ol>



<p>เอาแค่ 5 เงื่อนไขนี้ วิธีการข้างต้น 4 ข้อ ก็ดูจะไม่ครอบคลุมทุกเงื่อนไข</p>



<p>ดังนั้น วิธีใช้ Secret ใน <meta charset="utf-8">Kubernetes ที่จะเขียนในโพสต์นี้ จะเป็นวิธีการมาตรฐานที่ Kubernetes ได้ทำฟีเจอร์ออกมาให้ใช้ มีความคล้ายกับการทำ Config File Server เพียงแต่เป็นเหมือน Container ที่ใช้คุณสมบัติของ Kubernetes นั่นเอง</p>



<h2 class="wp-block-heading">โครงสร้างของ Secret ใน Kubernetes</h2>



<p>ตามภาพเลยครับ จะแยก Secret ออกมาจาก Pod (แต่ยังอยู่ใน Node และ Cluster เดียวกัน) ดังนั้น เวลาจะใช้งานใน Pod ไหนก็ต้อง จะต้องระบุ Secret และ Key ที่จะใช้ เพื่ออ้างอิงถึง Sensitive Data ที่เราต้องการ</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="1200" height="721" src="https://myifew.com/wp-content/uploads/2021/09/k8s-secret-1200x721.png" alt="" class="wp-image-6022" srcset="https://myifew.com/wp-content/uploads/2021/09/k8s-secret-1200x721.png 1200w, https://myifew.com/wp-content/uploads/2021/09/k8s-secret-1024x615.png 1024w, https://myifew.com/wp-content/uploads/2021/09/k8s-secret-768x461.png 768w, https://myifew.com/wp-content/uploads/2021/09/k8s-secret-1536x923.png 1536w, https://myifew.com/wp-content/uploads/2021/09/k8s-secret-2048x1231.png 2048w, https://myifew.com/wp-content/uploads/2021/09/k8s-secret-700x421.png 700w, https://myifew.com/wp-content/uploads/2021/09/k8s-secret.png 2255w" sizes="(max-width: 1200px) 100vw, 1200px" /><figcaption>รูปจาก <a rel="noreferrer noopener" href="https://livebook.manning.com/book/gitops-and-kubernetes/chapter-7/v-6/57" target="_blank">https://livebook.manning.com/book/gitops-and-kubernetes/chapter-7/v-6/57</a></figcaption></figure></div>



<p class="has-text-align-center has-light-green-cyan-background-color has-background"><strong>ตัวอย่างที่จะใช้ในโพสต์ต่อไปนี้ จะอ้างอิงจากโพสต์เดิมที่ </strong><br><strong><a rel="noreferrer noopener" href="https://myifew.com/5972/kubernetes-on-amazon-eks/" data-type="URL" data-id="https://myifew.com/5972/kubernetes-on-amazon-eks/" target="_blank">ลองทำ Kubernetes บน Amazon EKS แบบง่ายๆ ด้วย eksctl</a></strong></p>



<h2 class="wp-block-heading">เริ่มต้นสร้าง Kubernetes Secret</h2>



<p>สร้างไฟล์ YML ขึ้นมา เพื่อสร้างชุด secret โดยในที่นี้ผมใช้ไฟล์ชื่อ eks-myweb-secret.yml</p>



<pre class="wp-block-code"><code>apiVersion: v1
kind: Secret
metadata:
  name: myweb-secret
  namespace: myweb
  labels:
    app: myweb-secret
data:
  secret_username: aWZldw==
  secret_password: cGFzczEyMzQ=</code></pre>



<p>จากนั้นทำการ apply ด้วยคำสั่งดังนี้</p>



<pre class="wp-block-code"><code>kubectl apply -f <strong>eks-myweb-secret.yml</strong></code></pre>



<p>และลองทำการเช็คดูว่าสร้างสำเร็จไหม ด้วยคำสั่งดังนี้</p>



<pre class="wp-block-code"><code>kubectl get secrets -n <strong>myweb</strong></code></pre>



<p>โดยในที่นี้ผมใช้ namespace ชื่อ myweb นะครับ</p>



<p>เราจะเห็นผลลัพธ์ตามภาพด้านล่าง</p>



<figure class="wp-block-image size-full"><img decoding="async" width="1040" height="122" src="https://myifew.com/wp-content/uploads/2021/09/eks-get-secret.png" alt="" class="wp-image-6014" srcset="https://myifew.com/wp-content/uploads/2021/09/eks-get-secret.png 1040w, https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-1024x120.png 1024w, https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-768x90.png 768w, https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-700x82.png 700w" sizes="(max-width: 1040px) 100vw, 1040px" /></figure>



<p>สังเกตว่า Type เป็น Opaque หมายถึง เป็นการกำหนดการเข้าถึงเองโดยผู้ใช้งาน ซึ่ง Type นี้จะเป็น default ให้อัตโนมัติ หากอยากใช้ Type อื่นๆ ก็มีให้เลือก 8 ตัว อยู่ที่รูปแบบที่เราอยากจะทำ สามารถไปหาอ่านได้ที่ <a href="https://kubernetes.io/docs/concepts/configuration/secret/#secret-types" data-type="URL" data-id="https://kubernetes.io/docs/concepts/configuration/secret/#secret-types">Kubernetes Secret</a> </p>



<h2 class="wp-block-heading">มาดูรายละเอียดภายใน Secret กัน</h2>



<p>หากต้องการดูรายละเอียดว่า Secret นี้มีอะไร ให้ใช้คำสั่งนี้</p>



<pre class="wp-block-code"><code>kubectl describe secrets/<strong>myweb-secret</strong> -n <strong>myweb</strong></code></pre>



<p>โดยชื่อ myweb-secret คือชื่อ Secret ของผมนะ (ตามที่ระบุใน YML File )</p>



<p>จะแสดงรายละเอียดของ Secret ขึ้นมา</p>



<figure class="wp-block-image size-full"><img decoding="async" width="1114" height="340" src="https://myifew.com/wp-content/uploads/2021/09/eks-describe-secret.png" alt="" class="wp-image-6015" srcset="https://myifew.com/wp-content/uploads/2021/09/eks-describe-secret.png 1114w, https://myifew.com/wp-content/uploads/2021/09/eks-describe-secret-1024x313.png 1024w, https://myifew.com/wp-content/uploads/2021/09/eks-describe-secret-768x234.png 768w, https://myifew.com/wp-content/uploads/2021/09/eks-describe-secret-700x214.png 700w" sizes="(max-width: 1114px) 100vw, 1114px" /></figure>



<p>คราวนี้เราเห็นแล้วว่า Secret มี Key อะไรบ้าง แต่อยากเห็นเนื้อหาข้างใน ก็สามารถดูได้ด้วยนะครับ ด้วยคำสั่งนี้</p>



<pre class="wp-block-code"><code>kubectl get secret <strong>myweb-secret</strong> -n <strong>myweb</strong> -o jsonpath='{.data}'</code></pre>



<p>เราก็จะเห็นข้อมูลใน Secret ดังนี้</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1200" height="108" src="https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-data-1200x108.png" alt="" class="wp-image-6016" srcset="https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-data-1200x108.png 1200w, https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-data-1024x92.png 1024w, https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-data-768x69.png 768w, https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-data-700x63.png 700w, https://myifew.com/wp-content/uploads/2021/09/eks-get-secret-data.png 1312w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<p>และหากใครใช้ Mac หรือ Linux ก็ decode ข้อมูล base64 ออกมาดูได้เลยว่าคืออะไร ตามภาพครับ</p>



<h2 class="wp-block-heading">ทำให้ Pod เรียกใช้งานตัวแปรใน Secret</h2>



<p>เมื่อเราสร้าง Secret รอไว้แล้ว คราวนี้ถึงเวลาเรียกใช้ โดยผมได้แก้ไข Source Code ให้มีการอ่าน Environment จาก Secret ไว้ สองตัว คือ SECRET_USERNAME กับ SECRET_PASSWORD</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="864" height="660" src="https://myifew.com/wp-content/uploads/2021/09/eks-secret-code-test.png" alt="" class="wp-image-6017" srcset="https://myifew.com/wp-content/uploads/2021/09/eks-secret-code-test.png 864w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-code-test-768x587.png 768w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-code-test-700x535.png 700w" sizes="auto, (max-width: 864px) 100vw, 864px" /></figure>



<p>จากนั้นทำการ build image, tag และ push image ไปไว้ใน Docker Repo เป็น version 3 (docker.io/ifew/docker-test-php:v3)</p>



<p>ต่อมา เราจะแก้ไขไฟล์ Deployment YML ที่เอาไว้สร้าง Pod, โดยแต่เดิม มีการเรียกใช้ Environment Variable ตรงๆ ในไฟล์เลย ดังนี้</p>



<pre class="wp-block-code"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-deployment
  namespace: myweb
  labels:
    app: myweb
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
      - name: phpfpm
        image: docker.io/ifew/docker-test-php:v3
        ports:
        - containerPort: 80
        env:
        - name: MYSQL_DB_HOST
          value: mydb.host.com
        - name: MYSQL_DATABASE
          value: test
        - name: MYSQL_USER
          value: ifew 
        - name: MYSQL_PASSWORD
          value: password1234
        - name: MYSQL_ROOT_PASSWORD
          value: password1234
        - name: TEST
          value: test</code></pre>



<p>โดยวิธีการเรียกใช้ Secret จะมีรูปแบบโค้ดดังนี้</p>



<pre class="wp-block-code"><code>- name: <strong>SECRET_USERNAME</strong>
  valueFrom:
    secretKeyRef:
      name: <strong>myweb-secret</strong>
      key: <strong>secret_username</strong></code></pre>



<p>อธิบายทีละค่า</p>



<ul class="wp-block-list"><li><strong>name: SECRET_USERNAME</strong> คือ กำหนด ชื่อ Key ของ Environment Variable ที่จะถูกนำไปใช้ในโค้ด</li><li><strong>valueFrom.secretKeyRef.name: myweb-secret</strong> คือ ชื่อ Secret ที่เราสร้าง</li><li><strong>valueFrom.secretKeyRef.key: secret_username</strong> คือ ชื่อ Key ที่ใช้อ้างไปหา Value ใน Secret</li></ul>



<p>ซึ่งผมจะเพิ่ม env สองตัว ที่เรียกใช้จาก Secret, ดังนั้นไฟล์ที่แก้ไขของ Deployment YML ผมจะได้รูปแบบนี้</p>



<pre class="wp-block-code"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-deployment
  namespace: myweb
  labels:
    app: myweb
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
      - name: phpfpm
        image: docker.io/ifew/docker-test-php:v3
        ports:
        - containerPort: 80
        env:
        - name: MYSQL_DB_HOST
          value: mydb.host.com
        - name: MYSQL_DATABASE
          value: test
        - name: MYSQL_USER
          value: ifew 
        - name: MYSQL_PASSWORD
          value: password1234
        - name: MYSQL_ROOT_PASSWORD
          value: password1234
        - name: TEST
          value: test
<strong>        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: myweb-secret
              key: secret_username
        - name: SECRET_PASSWORD
          valueFrom:
            secretKeyRef:
              name: myweb-secret
              key: secret_password</strong></code></pre>



<p>หลังจากแก้ไข Deployment YML เรียบร้อย ก็ทำการ Apply อีกครั้ง</p>



<pre class="wp-block-code"><code>kubectl apply -f eks-myweb-deploy.yml</code></pre>



<p>และลองทดสอบดูครับ ว่ามีการเรียกใช้งานถูกต้องไหม</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1200" height="307" src="https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-1200x307.png" alt="" class="wp-image-6018" srcset="https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-1200x307.png 1200w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-1024x262.png 1024w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-768x196.png 768w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-1536x393.png 1536w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-700x179.png 700w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test.png 1878w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<h2 class="wp-block-heading">หากต้องการอัพเดทค่าใน Secret ล่ะ ทำอย่างไร?</h2>



<p>ให้แก้ไข Secret YML ไฟล์ และทำการ Apply ใหม่ จากนั้นขั้นตอนสำคัญคือ จะต้อง Restart Pod ด้วย เพื่อให้อ่าน Environment Variable ใหม่ ด้วยคำสั่ง</p>



<pre class="wp-block-code"><code>kubectl -n <strong>myweb</strong> rollout restart deployment <strong>myweb-deployment</strong></code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1200" height="139" src="https://myifew.com/wp-content/uploads/2021/09/eks-update-secret-1200x139.png" alt="" class="wp-image-6019" srcset="https://myifew.com/wp-content/uploads/2021/09/eks-update-secret-1200x139.png 1200w, https://myifew.com/wp-content/uploads/2021/09/eks-update-secret-1024x119.png 1024w, https://myifew.com/wp-content/uploads/2021/09/eks-update-secret-768x89.png 768w, https://myifew.com/wp-content/uploads/2021/09/eks-update-secret-700x81.png 700w, https://myifew.com/wp-content/uploads/2021/09/eks-update-secret.png 1244w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<p>โดยที่ myweb คือชื่อ namespace และ <meta charset="utf-8">myweb-deployment คือชื่อของ Deployment ที่ผมตั้งไว้</p>



<p>จากนั้นลองทดสอบใหม่ ก็จะเห็นการเปลี่ยนแปลงทันที</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1200" height="289" src="https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-update-1-1200x289.png" alt="" class="wp-image-6034" srcset="https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-update-1-1200x289.png 1200w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-update-1-1024x247.png 1024w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-update-1-768x185.png 768w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-update-1-1536x370.png 1536w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-update-1-700x169.png 700w, https://myifew.com/wp-content/uploads/2021/09/eks-secret-web-test-update-1.png 1818w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<h2 class="wp-block-heading">สรุป</h2>



<p>Kubernetes ได้ทำฟีเจอร์ Secret ออกมาเพื่อให้เราใช้ เราก็ใช้เถอะ ซึ่งที่ผมเขียนมา เป็นหนึ่งในรูปแบบที่ Kubernetes แนะนำ แต่จริงๆ สามารถทำอีกวิธีหนึ่งได้คือ ทำเป็น Config File จาก Pod โดยการไปสร้าง Volumes และทำการ Mount Path จากนั้นก็เรียกข้อมูลจาก File Path นั้นได้เลย (เหมือนวิธี Config File Server ที่ทำๆ กันมา) ใครสนใจลองไปหาอ่านต่อได้ที่ <a rel="noreferrer noopener" href="https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod" data-type="URL" data-id="https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod" target="_blank">Using Secrets as Files from a Pod</a></p>



<h2 class="wp-block-heading">Reference</h2>



<ul class="wp-block-list"><li><a href="https://kubernetes.io/docs/concepts/configuration/secret/">https://kubernetes.io/docs/concepts/configuration/secret/</a></li><li>Cover Image from <a rel="noreferrer noopener" href="https://www.conjur.org/blog/four-ways-to-keep-kubernetes-secrets-secret/" target="_blank">https://www.conjur.org/blog/four-ways-to-keep-kubernetes-secrets-secret/</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/6012/sensitive-data-on-kubernetes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>อยากทำ The Twelve Factors จะเริ่มต้นอย่างไรดี และต้องเรียนรู้อะไรบ้าง</title>
		<link>https://myifew.com/5104/how-to-implement-the-twelve-factors/</link>
					<comments>https://myifew.com/5104/how-to-implement-the-twelve-factors/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Thu, 13 Sep 2018 12:22:16 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[12 Factors]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[The Twelve Factor]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=5104</guid>

					<description><![CDATA[มาเพิ่มเติมจากบล็อกที่แล้วที่ผมได้เขียน &#8220;สรุปแนวคิด THE TWELVE FACTORS ในภาพเดียวจบ&#8221; เพื่อให้เห็นภาพได้ชัดเจนขึ้นว่า ถ้าต้องการทำ The Twelve Factors เราต้องเรียนรู้อะไรบ้าง บล็อกเก่าผมวาดด้วยมืออาจจะอ่านไม่ค่อยออก บล็อกนี้เลยขอทำจากโปรแกรมแทน น่าจะดูดีขึ้น ฮ่าๆ 1. ขึงด้วยภาพ System&#8230;]]></description>
										<content:encoded><![CDATA[<p>มาเพิ่มเติมจากบล็อกที่แล้วที่ผมได้เขียน &#8220;<a href="https://myifew.com/5080/the-twelve-factors/">สรุปแนวคิด THE TWELVE FACTORS ในภาพเดียวจบ</a>&#8221; เพื่อให้เห็นภาพได้ชัดเจนขึ้นว่า ถ้าต้องการทำ The Twelve Factors เราต้องเรียนรู้อะไรบ้าง</p>
<p>บล็อกเก่าผมวาดด้วยมืออาจจะอ่านไม่ค่อยออก บล็อกนี้เลยขอทำจากโปรแกรมแทน น่าจะดูดีขึ้น ฮ่าๆ<span id="more-5104"></span></p>
<h2>1. ขึงด้วยภาพ System Architecture เดิมๆ ของคุณ</h2>
<p>ถ้าลองเอาภาพโครงสร้าง System Architecture มากางดู น่าจะคล้ายๆภาพนี้ ซึ่งผมขอแนะนำให้คุณลองประกอบภาพให้เป็นแบบ End to End หมายความว่า ตั้งแต่ Developer เขียนโค้ดเสร็จ ยาวไปจนถึง ขึ้น Production Environment และมีลูกค้าเข้ามาใช้งาน</p>
<p>เพราะอะไร ทำไมต้อง End to End? เพราะบางทีภาพของ System Architecture มันทับซ้อนกับ Network Architecture อยู่ และมักมีเพียงการเชื่อมโยงของ Server ว่าอะไรเชื่อมต่ออย่างไร แต่ไม่มีส่วนไหนไปเชื่อมโยงกับ Development Process, Support Process เลย แล้วจะรู้ได้อย่างไรว่า Source Code จะมาถูก Build และ Deployment เข้าสู่ Environment มันมีที่มาที่ไปอย่างไร</p>
<p>ถ้าบอกว่าองค์กรเราอยากเป็น DevOps ภาพพวกนี้ควรต้องมีอย่างแรกเลย และ Development Team กับ Infrastructure Team ต้องทำงานร่วมกันอย่างดูดดื่มด้วยนะ</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone wp-image-5109 size-large" src="https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-network-only-1200x1016.png" alt="" width="1100" height="931" srcset="https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-network-only-1200x1016.png 1200w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-network-only-1024x867.png 1024w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-network-only-768x651.png 768w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-network-only-600x508.png 600w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-network-only.png 1353w" sizes="auto, (max-width: 1100px) 100vw, 1100px" /><br />
ภาพจาก https://myifew.com (ผมวาดเอง ไม่แปะเครดิตให้รก แต่ถ้าเอาไปใช้ หรือลอกต่อ รบกวนใส่อ้างอิงด้วยนะ)</p>
<h2>2. เชื่อมต่อกับ The Twelve Factor ในแต่ละข้อ</h2>
<p>เมื่อได้ภาพ System Architecture ทั้งหมด ให้ลองไปทำความเข้าใจเรื่องของ The Twelve Factor และลองพิจารณาดูว่า ข้อไหน ควรต้องไป Implement ในตำแหน่งไหนบ้าง, หรือกำหนดว่าภาพสุดท้ายที่เราต้องการ ควรเป็นแบบไหน</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5111" src="https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors.png" alt="" width="1131" height="1141" srcset="https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors.png 1131w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-1015x1024.png 1015w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-768x775.png 768w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-600x605.png 600w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-100x100.png 100w" sizes="auto, (max-width: 1131px) 100vw, 1131px" /></p>
<p>ภาพจาก https://myifew.com (ผมวาดเอง ไม่แปะเครดิตให้รก แต่ถ้าเอาไปใช้ หรือลอกต่อ รบกวนใส่อ้างอิงด้วยนะ)</p>
<h2>3. ระบุ Practices ที่จะทำให้เกิดผลลัพธ์</h2>
<p>ขั้นตอนสุดท้าย น่าจะยากที่สุด และเจ็บปวดที่สุดแล้วหละครับ</p>
<p><strong>ยากที่สุดคือ คุณจะรู้ได้อย่างไรล่ะ ว่ามันต้องใช้ Practices อะไรในการทำให้เกิดในแต่ละข้อ?, แน่นอน มันไม่สามารถรู้ได้ ถ้าคุณไม่ทำการค้นคว้าไปทีละข้อ</strong></p>
<p>ซึ่งก็นับว่าโชคดีนิดหนึ่งที่เว็บต้นฉบับอย่าง <a href="https://12factor.net/" target="_blank" rel="noopener noreferrer">12factors.net</a> ได้พูดถึง Practices และเครื่องมือที่จะทำให้ได้ในแต่ละข้อได้บ้างแล้ว อย่างเช่น เรื่องของ Codebase</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-5113 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-sample-explain-practices-1200x942.png" alt="" width="1100" height="864" srcset="https://myifew.com/wp-content/uploads/2018/09/12factors-sample-explain-practices-1200x942.png 1200w, https://myifew.com/wp-content/uploads/2018/09/12factors-sample-explain-practices-1024x804.png 1024w, https://myifew.com/wp-content/uploads/2018/09/12factors-sample-explain-practices-768x603.png 768w, https://myifew.com/wp-content/uploads/2018/09/12factors-sample-explain-practices-600x471.png 600w, https://myifew.com/wp-content/uploads/2018/09/12factors-sample-explain-practices.png 1822w" sizes="auto, (max-width: 1100px) 100vw, 1100px" /></p>
<p style="text-align: center;">ภาพจาก https://12factor.net/codebase</p>
<p>ในหน้าที่อธิบาย Codebase มีการอธิบายอยู่สามแบบที่ผมตีกรอบไว้</p>
<p><span style="color: #ff0000;"><strong>กรอบสีแดง:</strong></span> บอกไว้ชัดๆเลยว่า ใช้เครื่องมืออะไร, แต่! เครื่องมือแต่ละตัวมันมี Practices ประกอบการใช้อยู่นะ เช่น ใช้ Git จะใช้ให้ดี คุณควรต้องรู้เรื่องการจัดการ Branch ต่างๆ (Branch Strategy)</p>
<p><span style="color: #0000ff;"><strong>กรอบสีน้ำเงิน:</strong></span> กล่าวถึงหัวข้อที่เกี่ยวข้องใน The Twelve Factors และ/หรือ หัวข้อ Practices อื่นๆ ที่คุณสามารถเอาชื่อพวกนี้ไปค้นคว้าต่อได้ เช่น  Dependency Management คืออะไร ทำอย่างไร ใช้เครื่องมืออะไร</p>
<p><strong><span style="color: #339966;">กรอบสีเขียว:</span> </strong>อันนี้ต้องตีความให้ออกว่าเป้าหมายคืออะไร อย่างในตัวอย่าง คือใช้ Source Code ที่โปรแกรมเมอร์ทุกคนทำเสร็จพร้อมรวมโค้ดกันเรียบร้อยแล้ว และต้องอยู่บนที่ที่เดียวกัน (Single Repository) และโค้ดนั้นต้องพร้อม Deploy ไปหลายๆ Environment ได้ด้วย&#8230; เออ นั่นหละครับ ปัญหาคือ โค้ดโปรแกรมเมอร์รวมกันแล้วมันทำงานได้ไหม? ต้องทดสอบก่อนไหม? ทดสอบอย่างไร? แล้ว config ที่ถูกตั้งไว้ของโปรแกรมเมอร์แต่ละเครื่องไม่เหมือนกันทำอย่างไร? แล้ว config ของแต่ละ Envinronment ก็ไม่เหมือนกันด้วย จะทำอย่างไร? &#8230;</p>
<p>ภาพด้านล่างเป็นตัวอย่าง Practices ที่ผมลองเชื่อมโยงให้เข้ากับ The Twelve Factors และถูกใช้งานจริงกับบริษัทลูกค้า, ลองเอาไปพิจารณาดูครับ</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-5114" src="https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-mapping-practices-1200x1055.png" alt="" width="1100" height="967" srcset="https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-mapping-practices-1200x1055.png 1200w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-mapping-practices-1024x900.png 1024w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-mapping-practices-768x675.png 768w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-mapping-practices-600x527.png 600w, https://myifew.com/wp-content/uploads/2018/09/The-Twelve-Factors-mapping-practices.png 1230w" sizes="auto, (max-width: 1100px) 100vw, 1100px" /></p>
<p style="text-align: center;">ภาพจาก https://myifew.com (ผมวาดเอง ไม่แปะเครดิตให้รก แต่ถ้าเอาไปใช้ หรือลอกต่อ รบกวนใส่อ้างอิงด้วยนะ)</p>
<p><strong>สุดท้ายยังเหลืออีกข้อที่ผมค้างอยู่ ที่บอกว่าเจ็บปวดที่สุด และก็ท้าทายที่สุด คือ</strong></p>
<ul>
<li><strong>ตอนนี้ ทีมเรา รู้อะไร ทำอะไรได้แล้วบ้าง?</strong></li>
<li><strong>ที่ทีมเราต้องเรียนรู้เพิ่มมีอะไรบ้าง?</strong></li>
<li><strong>หากต้องทำให้เกิดในองค์กร จะมีอุปสรรคอะไร และแก้ไขมันอย่างไร?</strong></li>
</ul>
<p>ขอให้โชคดี มีชัย อ่านบล็อกนี้แล้ว นอนหลับฝันดี&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/5104/how-to-implement-the-twelve-factors/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>สรุปแนวคิด The Twelve Factors ในภาพเดียวจบ</title>
		<link>https://myifew.com/5080/the-twelve-factors/</link>
					<comments>https://myifew.com/5080/the-twelve-factors/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Wed, 12 Sep 2018 03:37:33 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[12 Factors]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[The Twelve Factor]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=5080</guid>

					<description><![CDATA[สรุปแนวคิด หลัก 12 ประการ (The Twelve Factor) สำหรับการพัฒนาซอร์ฟแวร์เพื่อให้บริการบนอินเทอร์เน็ต (SaaS) อย่างมีประสิทธิภาพสูงสุด ]]></description>
										<content:encoded><![CDATA[<p>ถ้าจำครั้งที่ผมเขียนถึง<a href="https://myifew.com/3954/my-last-day-at-ookbeemall/">การทำงานที่ Ookbee Mall</a> และพยายามทำ AWS Cloud ให้มัน Auto-Scaling ได้เนียนๆ ผมรู้สึกเสียดายทันทีที่ไม่รู้จักวิธีการของ The Twelve Factors ในตอนนั้น, ซึ่งถ้ารู้ ก็จะเป็นไกด์อย่างดีที่จะพาผมไปพบ Solution ในการทำเว็บให้รองรับ Cloud และรองรับการขยายของ Cloud ได้ โดยไม่ต้องงมเข็มในมหาสมุทร</p>
<p>ผมมีโอกาสได้ฟังอาจารย์อู๋เล่าเรื่อง The Twelve Factors อยู่หลายครั้ง แต่เพิ่งมีโอกาสได้หาข้อมูลเพิ่มและคุยเพื่อประติดประต่อเรื่องนี้แบบจริงจัง เพื่อให้เห็นความเชื่อมโยงกันเป็นภาพเดียวกัน ผสมกับความรู้อื่นๆและประสบการณ์ตัวเอง เลยลองแชร์ให้ได้อ่านกัน<span id="more-5080"></span></p>
<h2>The Twelve Factors คืออะไร</h2>
<p>มันถูกคิดขึ้นมาโดยบริษัท Heroku ผู้ให้บริการ Cloud แห่งแรกของโลก เพื่อชี้ทางสว่างให้แก่เราว่าจะทำ Application Software เพื่อให้บริการผ่านอินเทอร์เนต (SaaS &#8211; Software-As-A-Service) อย่างไร และ/หรือ ทำงานร่วมกับ Cloud อย่างไร ให้มีประสิทธิภาพ</p>
<p><strong>ก่อนไปต่อ ขอว่าด้วยเรื่องคุณสมบัติพื้นฐานของ Cloud ก่อน</strong></p>
<ol class="postList">
<li id="d954" class="graf graf--li graf-after--p"><strong>Rapid Elasticity</strong> &#8211; ต้องมีความยืดหยุ่น สามารถเพิ่ม/ลด (Scaling) ทรัพยากรได้ตามความต้องการของผู้ใช้งาน</li>
<li id="34a7" class="graf graf--li graf-after--li"><strong>On Demand Self Service</strong> &#8211; ต้องปรับเปลี่ยนการใช้งานได้ตลอดเวลา เช่น ถอด storage เข้า/ออก ในช่วงเวลาใดก็ได้</li>
<li id="f47c" class="graf graf--li graf-after--li"><strong>Measured Service</strong> &#8211; ต้องสามารถวัดประมาณการใช้ทรัพยากรณ์และค่าใช้จ่ายได้ตามจริง (Pay as you go)</li>
</ol>
<p><strong>เมื่อเติมความสามารถของ The Twelve Factors เข้าไป</strong></p>
<ol>
<li><strong>จะช่วยลดความแตกต่างระหว่าง Production Environment และ Non-Production Environment</strong> (เช่น Development, SIT, UAT, Staging) เพื่อให้สามารถเกิด Continue Integration ได้คล่องตัวที่สุด</li>
<li><strong>จะช่วยให้ Software ของเรา พร้อมที่จะไปทำ Automation ต่างๆ ต่อไป</strong></li>
<li><strong>จะสามารถขยายทรัพยากร (Scale up/Scale out) ได้ โดยไม่ต้องเปลี่ยนแปลงสิ่งเดิม</strong> เช่น เครื่องมือ (tooling), สถาปัตยกรรม (architecture), หรือกระบวนการพัฒนาซอฟต์แวร์ (development practices)</li>
</ol>
<p>ซึ่งใน The Twelve Factors ตามชื่อคือมีปัจจัยอยู่ 12 ข้อ แต่พอจะแบ่งเป็นกลุ่มได้ 3 กลุ่ม คือ</p>
<ol>
<li><strong>Build</strong> &#8211; การจัดการ Source Code จนได้เป็น Software เพื่อให้พร้อมใช้งานบน Environment ต่างๆ
<ol>
<li id="8839" class="graf graf--li graf-after--p">Codebase</li>
<li id="a2ab" class="graf graf--li graf-after--li">Dependency</li>
<li id="20db" class="graf graf--li graf-after--li">Config</li>
<li id="3058" class="graf graf--li graf-after--li">Backing services</li>
<li id="45d4" class="graf graf--li graf-after--li">Build / Release / Run</li>
</ol>
</li>
<li><strong>Scalable</strong> &#8211; การรองรับขยายความสามารถของทรัพยากร หรือ Environment เพื่อให้รองรับปริมาณของผู้ใช้งานตามจริง
<ol>
<li>Processes</li>
<li id="f8af" class="graf graf--li graf-after--li">Port binding</li>
<li id="3556" class="graf graf--li graf-after--li">Concurrency</li>
<li id="55b3" class="graf graf--li graf-after--li">Disposability</li>
</ol>
</li>
<li><strong>Maintainable</strong> &#8211; การดูแลรักษา
<ol>
<li id="5eb6" class="graf graf--li graf-after--li">Dev/prod parity</li>
<li id="df99" class="graf graf--li graf-after--li">Logs</li>
<li id="8a69" class="graf graf--li graf-after--li graf--trailing">Admin Processes</li>
</ol>
</li>
</ol>
<h2>ว่าด้วยเรื่อง Build &#8211; เปลี่ยน Source Code ให้ได้เป็น Software</h2>
<h3>1. Codebase &#8211; One codebase tracked in revision control, many deploys</h3>
<p>Source Code ที่ดี ควรมีที่เก็บเพียงที่เดียว เพื่อลดความสับสนว่าโค้ดล่าสุดอยู่ที่ไหน กับใคร ถ้าดีหน่อยก็คือ ควรมีบันทึกว่าใครทำอะไรกับโค้ดไว้ล่าสุด อะไรบ้าง เมื่อไร หรือคือการนำ <strong>การจัดการซอร์สโค้ด (Source Code Management)</strong> เข้ามาปฏบิติตาม และหากพูดถึงเครื่องมือสมัยนี้ ก็คงเป็นพวก <strong>Version Control</strong> ต่างๆ เช่น Git, SVN</p>
<p>แต่ทั้งนี้ Source Code ที่เราเก็บไว้ จะต้องเป็นโค้ดที่พร้อม Build และ Deploy สู่ Environment ต่างๆเสมอ ไม่ว่าจะ Development Server หรือแม้กระทั่ง Production Server ก็ตาม ข้อนี้ข้อเดียวก็ท้าทายมากๆ เพราะต้องใช้การจัดการทางด้าน Busines และ Technical หลาย Practices พอสมควร เช่น</p>
<ol>
<li>ต้องมีกระบวนการรวบรวมโค้ดกันบ่อยๆ <strong>(Continuous Integration) </strong>เพื่อเก็บเข้าสู่ระบบหรือ Version Control</li>
<li>ต้องผ่านกระบวนการทดสอบอย่างครอบคลุมสมบูรณ์ <strong>(Comprehensive Test)</strong> มาเรียบร้อยแล้ว</li>
<li>ต้องมีการจัดการ Package, Library และสิ่งต่างๆที่เกี่ยวข้องกับโค้ดของเรา เพื่อทำการติดตั้งใหม่ได้ทุกครั้งที่ Deploy <strong>(Dependency Management)</strong><em> &#8211; จะขยายความในข้อ 2. Dependency</em></li>
<li>ต้องมีการจัดการ Config เพื่อให้สามารถใช้กับ Environment ต่างๆ ได้ โดยไม่ต้องทำการ Build ใหม่ <strong>(Configuration Management)</strong><em> &#8211; จะขยายความในข้อ 3. Config</em></li>
<li>จากข้อ 1 &#8211; 4 ทุกอย่างต้องเป็น <strong>Automation</strong> เพื่อที่ทุกครั้งมีการแก้ไขเปลี่ยนแปลงโค้ด ก็สามารถพร้อม Deploy ได้เสมอ <strong>(Automated Build and Automated Test) </strong><em>&#8211; จะขยายความในข้อ 5. Build/Release/Run</em></li>
</ol>
<p><strong>ความท้าทาย คือ</strong> 5 ข้อที่กล่าวมาทั้งหมด พร้อมแล้วหรือยัง, และเรื่องการใช้ Version Control อย่างเช่น Git เราออกแบบการกระบวนการทำงานอย่างไร (<strong>Branch Strategy</strong>)</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5098 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-single-codebase.jpg" alt="" width="638" height="479" srcset="https://myifew.com/wp-content/uploads/2018/09/12factors-single-codebase.jpg 638w, https://myifew.com/wp-content/uploads/2018/09/12factors-single-codebase-600x450.jpg 600w" sizes="auto, (max-width: 638px) 100vw, 638px" />รูปจาก https://www.slideshare.net/saffyre9/responsive-web-design-14770110/14-Single_Code_Base_Dawn_Wentzell</p>
<h3>2. Dependency &#8211; Explicitly declare and isolate dependencies</h3>
<p>เมื่อเรามี Source Code ที่พร้อมจะใช้งานแล้ว อย่าลืมว่าโค้ดจะไม่สามารถทำงานได้ด้วยตัวเอง ดังนั้นจะมีส่วนที่เกี่ยวข้องสองอย่างคือ</p>
<ol>
<li><strong>Application Dependency</strong> &#8211; โค้ดเรามี Package, Library อะไรที่ต้องใช้งานบ้าง เช่น CURL, ImageMagick, JSON, ฯลฯ</li>
<li><strong>Middleware Dependency</strong> &#8211; โค้ดเราต้องถูกทำงานผ่านซอฟต์แวร์ต่างๆ เช่น Web Server ฯลฯ</li>
</ol>
<p>ดังนั้นเราจะต้องกำหนดซอฟต์แวร์ Dependency รวมไปถึง Version ที่จะถูกใช้งาน (ในแต่ละ Environement) อย่างถูกต้องด้วย</p>
<p>และที่สำคัญ ทุกครั้งที่มีการแก้ไขเปลี่ยนแปลง Source Code และมีการ Build ใหม่ ก็จะต้องทำการเรียกใช้หรือติดตั้ง Dependency ใหม่เสมอ ดังนั้นถ้ากระบวนการเหล่านี้เป็น Automation ก็แทบจะหลีกเลี่ยงไม่ได้เลยที่จะต้องใช้เครื่องมือประเภท Package/Dependency Management เช่น Composer, Nuget, CPAN, Rubygems</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5099 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-dependency-graph.png" alt="" width="586" height="377" />รูปจาก http://slides.com/espenhovlandsdal/dependency-management-with-composer/fullscreen</p>
<h3>3. Config &#8211; Store config in the environment</h3>
<p>เมื่อ Source Code ที่ผ่านการทดสอบอย่างสมบูรณ์และ Build พร้อมจะ Deploy ไปทุกๆที่ แปลว่า เราจะต้องมีการจัดการเรื่องของ Config ไว้เรียบร้อยแล้ว</p>
<p>ซึ่งในความหมายของ Config ที่ว่ามานี้ เช่น</p>
<ul>
<li><strong>การจัดการข้อมูลที่ระบุถึง Resource ต่างๆ</strong> อย่าง Database, Memcached, ฯลฯ</li>
<li><strong>การจัดการรหัสผ่านหรือ Credentials ที่จะติดต่อไปยัง external services ต่างๆ</strong> เช่น Amazon S3, Facebook, Twitter, ฯลฯ</li>
<li><strong>การจัดการที่เกี่ยวกับข้อมูลของ Environment เอง</strong> เช่น Hostname, IP ฯลฯ</li>
</ul>
<p>ความท้าทายคือ ทำอย่างไร เมื่อเวลา Deploy ไปสู่ Environment ต่างๆ แล้วไม่ต้องมาแก้ Config ใหม่ทุกครั้ง เพื่อลดข้อผิดพลาด เช่น ขึ้นเครื่อง Develop เสร็จ ก็ไม่ต้องแก้ Config และ Build ใหม่ เพื่อขึ้น UAT หรือ Production อีกครั้ง</p>
<p>ผมเคยคิดในใจเล่นๆ ว่า &#8220;เอ้า ถ้าเช่นนั้นก็ทำ file config เตรียมไว้ แล้วให้โค้ดเรียกใช้ตาม Environment ต่างๆ ก็ได้นี่นา&#8230;&#8221;</p>
<p>คำตอบคือ  วิธีการแบบนี้ไม่สะดวกและไม่ปลอดภัยครับ เพราะคนที่เห็น Source Code เราทุกคน ก็จะเห็นรหัสผ่านเราทั้งหมด, หรือบางบริษัทมีนโยบายเปลี่ยนรหัสผ่านทุก 3 เดือน แปลว่าอนาคตก็ต้องมาแก้ Config, ทำการทดสอบระบบทั้งหมดใหม่ (Regression Test), ทำการ Build ใหม่ และ Deploy ใหม่ กระนั้นเชียวหรือ.. (ปล. อย่าฝืนทำเป็นไฟล์ และไปตั้งให้ใครสักคนมาดูแลไฟล์ Config นะ, มันบาป)</p>
<p>ซึ่งใน The Twelve Factors ได้บอกชัดๆเลยว่า ให้นำ Config ไปใส่ไว้ใน Environment ซะ เพราะทำการแก้ไขได้ง่าย ไม่ต้องแก้โค้ด, คนเขียนโค้ดไม่สามารถมองเห็นข้อมูลได้ (ถ้าไม่เข้าไปดูใน Server), ฝังอยู่ในแต่ละ Environment ของใครของมัน</p>
<p>ที่กล่าวมาทั้งหมด เรารู้จักมันในนามของ <strong>Environment Variable</strong> นั่นเอง</p>
<p><strong>ความท้าทาย คือ</strong> เราจะจัดการ Environment Variable ทุกตัว ของทุกระบบที่เรามีได้อย่างไร เพื่อไม่ให้สับสน ชื่อซ้ำ เข้าใจได้ง่าย และปลอดภัย</p>
<h3>4. Backing services &#8211; Treat backing services as attached resources</h3>
<p>ความหมายคือ Service ต่างๆ ที่ถูกใช้ใน Application Software ของเรา โดยเรียกใช้ผ่าน Network เช่น</p>
<ul>
<li>Database (อย่าง MySQL, MSSQL)</li>
<li>Messaging/Queueing Systems (อย่าง RabbitMQ)</li>
<li>SMTP services เพื่อใช้งาน email (อย่าง Postfix)</li>
<li>Caching Systems (อย่าง Redis, Memcached)</li>
</ul>
<p>ซึ่ง Service เหล่านี้ควรจะต้องแยกออกจาก Application ของเรา และสามารถนำเข้าใช้งาน หรือถอดออกจกาการใช้งาน เพื่อเปลี่ยนใหม่ได้โดยง่าย และไม่ต้องไปแก้ไข Source Code ใหม่ (โดยใช้หลักการแก้ไข Config ตามข้อ 2)</p>
<p>ดังนั้นจะสังเกตได้ว่า Cloud Service ต่างๆ ทำไมต้องมีบริการพวก Database, Caching, Messaging, Caching, ฯลฯ มาให้เราเสียเงินมากมาย ก็เพราะการนี้นี่เอง</p>
<p><strong>ความท้าทาย คือ</strong> การแยก External Service เหล่านี้ออกจากระบบเดิม และทำการ Migration เพื่อไม่ให้กระทบระบบทั้งหมด รวมถึงการจัดการ Service เหล่านี้ให้ไม่เกิดปัญหาคอขวด หากต้องใช้ร่วมกันหลายๆระบบ พร้อมกัน รวมถึงการทำสำรองข้อมูลต่างๆ และการดูแลตรวจสอบกรณีเกิดปัญหาทงาด้าน Network ที่ใช้รับส่งข้อมูล</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5085 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-attached-resources.png" alt="" width="872" height="454" srcset="https://myifew.com/wp-content/uploads/2018/09/12factors-attached-resources.png 872w, https://myifew.com/wp-content/uploads/2018/09/12factors-attached-resources-768x400.png 768w, https://myifew.com/wp-content/uploads/2018/09/12factors-attached-resources-600x312.png 600w" sizes="auto, (max-width: 872px) 100vw, 872px" />ภาพจาก https://12factor.net/backing-services</p>
<h3>5. Build / Release / Run &#8211; Strictly separate build and run stages</h3>
<p>เมื่อ Source Code พร้อมที่จะ Deploy แล้ว เราก็จะทำ 3 ขั้นตอน โดยแบ่งเป็น</p>
<ul>
<li><strong>Build stage</strong> &#8211; คือ แปลงจาก Source Code ไปเป็นซอฟต์แวร์ที่พร้อมจะทำงาน (executable)</li>
<li><strong>Release stage</strong> &#8211; คือ นำซอฟต์แวร์ที่ได้จากขั้นตอน Build มารวมกับ Config เพื่อเตรียมนำไปใช้งาน</li>
<li><strong>Run stage (หรือ &#8220;runtime&#8221;)</strong> &#8211; นำซอฟต์แวร์ไปใช้งานใน Environment ต่างๆ</li>
</ul>
<p><strong>ความท้าทาย คือ</strong> The Twelve Factors บอกว่า การกระทำทั้ง 3 ขั้นตอนนี้ จะต้องแยกออกจากกันชัดเจน ด้วยเหตุผลที่ว่า ถ้าขั้นตอนในการทำ Release มีปัญหา อย่างน้อยก็ไม่ต้อง Build ใหม่, หรือถ้า Run Stage มีปัญหา ก็แค่ทำคำสั่ง Run ใหม่อีกครั้ง ไม่ต้อง Build/Release ซ้ำอีกรอบ</p>
<p>ดังนั้น การ Build/Release หมายถึงไม่ได้ไปข้างหน้าอย่างเดียว แต่จะต้องถอยกลับได้ด้วย (Rollback) นะ ถ้ามันพังในขั้นตอนใดขั้นตอนหนึ่ง ซึ่งการจะ เดินหน้าหรือถอยหลังได้ จะต้องถูกกำหนดด้วย Release ID ที่ไม่ซ้ำกัน ขึ้นมา เพื่อบ่งบอกว่าถูก Build/Release เมื่อไหร่  จึงเป็นที่มาว่า เราจะต้องกำหนดเลข Build Version และเลข Release Version ของซอฟต์แวร์ไว้ด้วย</p>
<p>เมื่อมาถึงจุดนี้ เลี่ยงไม่ได้เลยที่จะต้องทำ <strong>Software versioning</strong> และมีที่เก็บซอฟต์แวร์เวอร์ชั่นต่างๆ ไว้ หรือที่เราเรียกว่า <strong>Artifacts Repository หรือ Binary Repository</strong></p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5086 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-release.png" alt="" width="560" height="233" />รูปจาก https://12factor.net/build-release-run</p>
<h3>สรุปขั้นตอนในการ Build</h3>
<p>ถ้าทำทั้งหมด 5 ข้อ ที่ว่ามานี้ เราจะได้ Source Code และ Environment ที่พร้อมทำการ Build / Release / Run ซึ่งถ้าคิดดีๆ มันคือ กระบวนการ Continue Integration และ Continue Deployment นั่นเอง และสิ่งที่จะทำให้สมบูรณ์ยิ่งขึ้น คงเลี่ยงไม่ได้ที่จะต้องทำทั้งหมดเป็น Automation ด้วย</p>
<h2>ว่าด้วยเรื่อง Scalable &#8211; เพื่อรองรับปริมาณของผู้ใช้งานตามจริง</h2>
<h3>6. Processes &#8211; Execute the app as one or more stateless processes</h3>
<p>ข้อนี้ เป็นหัวใจหลักอย่างหนึ่งในการทำ Application Software ให้รองรับการทำงานพร้อมกันในหลายๆ Server และถ้าเป็นคนไม่เคยทำมาก่อน อาจจะคิดไม่ถึงเลยทีเดียว เพราะปัญหาคือ ทุกครั้งที่ Application เราทำงาน มันจะมีการสร้าง Session ขึ้นมา (หรือกรณีที่เราเขียนโค้ดเพื่อตั้งใจให้ใช้ Session) ดังนั้น เมื่อ Cloud Server มีหลายตัว แต่ Session ถูกสร้างไว้แค่บนเครื่องใดเครื่องหนึ่ง คราวนี้งานเข้าแน่นอน เพราะถ้าผู้ใช้งานเปิดเว็บเราอีกครั้ง แปลว่าอาจถูกเรียก Cloud Server อีกตัวหนึ่งก็ได้ แล้วผู้ใช้คนนั่นก็จะไม่พบ Session เดิม เช่น ระบบ  Member Login เป็นต้น</p>
<p>หรือการทำงานที่มี Process ตั้งแต่ 2 ตัวขึ้นไป เช่น สั่งให้ Process A ทำงานเสร็จ แล้วส่งไปต่อให้ Process B ทำงานต่อ แบบนี้เมื่อ Cloud Server ไม่ได้ถูกทำงานบนเครื่องเดียวกัน มันจะไม่สามารถทำงานต่อกันได้อย่างสมบูรณ์</p>
<p>ซึ่งใน The Twelve Factors จึงบอกว่า ให้ Application ของเราทำงานเป็นแบบ <strong>Stateless Process</strong> ซะ</p>
<p>หมายความว่า Application ของเราจะไม่มีการเก็บข้อมูลบน Cloud Server ของตัวมันเอง เมื่อมันถูกสั่งให้ทำงาน, แต่หากจำเป็นต้องใช้ล่ะ เราจะต้องทำ Backing Services ขึ้นมาเก็บข้อมูลเหล่านั้นแทน เช่น การตั้ง Server กลาง อย่าง Redis, Memcached เพื่อเก็บ Session ที่ใช้ร่วมกันของทุกๆ Cloud Server</p>
<p>เมื่อก่อนที่ผมใช้ Amazon Cloud มันมีฟีเจอร์หนึ่งคือ &#8220;sticky sessions&#8221; พอคลิกเปิดใช้งานปุ๊บ มันจะทำการย้าย session ของเราทั้งหมดไปไว้ใน memory ที่หนึ่ง ซึ่งถ้าผู้ใช้คนเดิมเข้ามา เขาก็จะสามารถใช้ได้ต่อเนื่องโดยไม่เกิดปัญหาใดๆ ง่ายและสะดวกมาก แต่ The Twelve Factors บอกว่า ไม่ควรใช้ เพราะ Session data ที่ดี ควรมีเวลาหมดอายุด้วย ไม่ใช่ถูกจำไว้ตลอดจนกว่าผู้ดูแลระบบจะลบออกเอง ตัวอย่างที่ง่ายสุดว่าทำไมไม่ควรจดจำไว้ตลอดเวลาแบบเดิม เช่น การทำ Tokenize Session ในระบบ Member Login เป็นต้น อย่างน้อยต้องมีระยะเวลาหนึ่งที่ผู้ใช้ต้องกลับมา Login ใหม่อีกครั้ง เพื่อความปลอดภัย</p>
<p><strong>ความท้าทาย คือ</strong> ถ้า Backing Services ที่เก็บ Process พวกนี้ตาย ก็พินาศกันหมดแน่นอน ดังนั้นต้องวางแผนให้ดี ในการรับโหลดที่มากขึ้น จากทุกๆระบบ (อ่านเพิ่มเติมใน ข้อ 8. Concurrency)</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5089 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-process-stateful-problem.png" alt="" width="945" height="756" srcset="https://myifew.com/wp-content/uploads/2018/09/12factors-process-stateful-problem.png 945w, https://myifew.com/wp-content/uploads/2018/09/12factors-process-stateful-problem-768x614.png 768w, https://myifew.com/wp-content/uploads/2018/09/12factors-process-stateful-problem-600x480.png 600w" sizes="auto, (max-width: 945px) 100vw, 945px" />ภาพจาก http://www.indexnine.com/blog/</p>
<h3>7. Port binding &#8211; Export services via port binding</h3>
<p>เมื่อ Application ของเรามีการเรียกใช้งาน Backing Services หรือ Application เราเองเป็น Backing Services ให้กับ Application อื่นๆ จะเกิดการคุยกันผ่าน HTTP ดังนั้น เมื่อ Cloud Server ของเรา มีความยืดหยุ่น ถูกเพิ่ม/ลด ตลอดเวลา ทุกครั้งที่มีการเพิ่ม เราไม่สามารถระบุที่อยุ่ปลายทางชัดเจนได้ อย่างเช่น IP Address</p>
<p>ดังนั้น ใน The Twelve Factors จึงแนะนำว่า ให้ระบุเลยว่า Service เราแต่ละตัวใช้ Port อะไร จากนั้นเวลาเรียกใช้ ก็ไม่ต้องไปสนใจมันว่าอยู่ที่ IP Address ไหน รู้แค่ว่า ถ้าอยู่วง Network เดียวกัน แต่ต่อด้วย Port นี้ จะต้องได้ Service นี้เสมอ</p>
<p>เช่น http://localhost:5000/ เรียกหน้าเว็บ, แต่พอเรียกใช้ API จะต้องเข้าที่ http://localhost:5001/, หรือใช้ MySQL จะเรียกที่ http://localhost:3306/ เป็นต้น</p>
<p><strong>ความท้าทาย คือ</strong> นโยบาย Security ของเราเอง จากที่ประสบพบเจอมา บริษัทเกือบทุกที่มีการกำหนดให้ใช้งานได้เฉพาะบาง Port เราอาจต้อง Define กันให้ชัดแต่แรกว่าจะใช้ Port ใดในระบบไหนบ้าง และต้องอนุญาตขอเปิดใช้ตามนั้น และวางแผนป้องกันในเรื่องการเข้าถึงของแต่ละระบบด้วย</p>
<h3>8. Concurrency &#8211; Scale out via the process model</h3>
<p>เมื่อเราทำเป็น Stateless Process โดยแยกออกมาเป็น Backing Services ดังนั้นมันจึงเป็นอิสระจากกัน เราจึงขยายทรัพยากร (Scale out) ให้กับมันได้โดยไม่ส่งผลกระทบกับการทำงานทั้งหมดของระบบ หรือไม่จำเป็นต้องขยายทรัพยากรในส่วนอื่นๆที่ไม่เกี่ยวข้องด้วย</p>
<p>ซึ่งในหลักการข้อที่ 6. Process และ 8. Concurrency นี้ เป็นแนวคิดแบบเดียวกับ Microservices ที่แยกการทำงานออกเป็นส่วนๆ เมื่อตัวไหนใช้ทรัพยากรมาก ก็ทำการ Scale out เพิ่มออกไปให้รองรับได้กว้างขึ้น</p>
<p><strong>ความท้าทาย คือ</strong> หากผมสมมติว่า Application ของเรารองรับการ Scale out ได้แล้ว คำถามต่อมาคือ ระบบ Infrastructure ที่เราใช้ในปัจจุบัน รองรับแล้วหรือไม่ หรือยังเป็นการปิดเครื่อง Server เพิ่ม Memory เพิ่ม Harddisk อยู่แบบเดิม?</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5091 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-Horizontalversusverticalscaling.png" alt="" width="1173" height="592" srcset="https://myifew.com/wp-content/uploads/2018/09/12factors-Horizontalversusverticalscaling.png 1173w, https://myifew.com/wp-content/uploads/2018/09/12factors-Horizontalversusverticalscaling-1024x517.png 1024w, https://myifew.com/wp-content/uploads/2018/09/12factors-Horizontalversusverticalscaling-768x388.png 768w, https://myifew.com/wp-content/uploads/2018/09/12factors-Horizontalversusverticalscaling-600x303.png 600w" sizes="auto, (max-width: 1173px) 100vw, 1173px" />รูปจาก https://docs.bmc.com/docs/TSLogAnalytics/110/sizing-and-scalability-considerations-721194160.html</p>
<h3>9. Disposability &#8211; Maximize robustness with fast startup and graceful shutdown</h3>
<p>ในข้อนี้บอกว่า Application ของเราจะต้องมีการเริ่มต้นทำงานได้ไว (fast startup) และจบการทำงานได้อย่างสมบูรณ์แบบ (graceful shutdown) หมายความว่า Process ต่างๆ จะต้องถูกจัดการได้อย่างดี ตั้งแต่เริ่มต้นจนจบ</p>
<p>ข้อนี้ให้นึกถึง Microsoft Windows ที่เมื่อก่อนสมัยใช้ Windows 95,98,Me กว่าจะเปิดเครื่องใช้งานได้ เรานั่งมองโลโก้ Windows อยู่พักใหญ่ๆ เพราะมันโหลดทุกสิ่งทุกอย่างขึ้นมาเพื่อพร้อมทำงาน กลับกัน Windows รุ่นใหม่ๆ อย่าง 7,8,10 ที่เปิดขึ้นมาแล้ว ใช้เวลาไม่ถึง 1 นาที ไวอย่างเห็นได้ชัด</p>
<p>และเช่นกัน ในตอนที่เรากด Shutdown Windows เพื่อปิดการทำงาน ยิ่งเราเปิดโปรแกรมใหญ่ขนาดไหน หรือเยอะมากแค่ไหน มันก็จะใช้เวลาปิดนานขึ้น เพราะ Windows กำลังทำการ Shutdown Process อย่างสมบูรณ์แบบ เพื่อให้แน่ใจว่าทุกการทำงาน ทำงานจบครบถ้วน ไม่มีงานค้าง เช่น การบันทึกเอกสาร ก็จะต้องบันทึกให้เสร็จ ไม่ใช่ว่าผู้ใช้สั่งปิดปุ๊บ ก็ปิดทันที ทั้งที่ Process การบันทึกไฟล์ยังทำงานไม่จบ ผลคือ เอกสารเราก็จะเสียหายได้ นี่แหละที่เรียกว่า graceful shutdown</p>
<p>ในตัวอย่างงานจริง สมมติลูกค้ากำลังทำรายการโอนเงินจากบัญชีตนเองไปยังบัญชีปลายทาง แปลว่า Process นั้นจะต้อง บันทึกลดเงินเรา และทำการบันทึกเพิ่มเงินที่บัญชีปลายทาง และถ้าหากเวลานั้นลูกค้าใช้น้อย Cloud Server เราทำงานอัตโนมัติ ถูกสั่งให้ลดจำนวน Server ลง แล้วบังเอิญว่าตัวที่ถูกปิดเป็นตัวที่กำลังทำ Process บันทึกข้อมูลเพิ่มเงินปลายทาง คราวนี้จะมีปัญหาทันที เพราะ เงินเราหายไป แต่เงินปลายทางไม่เพิ่มขึ้น กรณีคล้ายๆแบบนี้ ผมเคยเจอในเหตุการณ์ทำงานจริงมาแล้ว แม้ระบบของ Cloud Provider จะช่วยเราได้ส่วนหนึ่ง แต่ก็มีโอกาสที่เกิดขึ้นได้</p>
<p><strong>ความท้าทาย คือ</strong> พวก Docker, Amazon Cloud ต่างๆ มันรองรับเรื่องนี้แล้ว แต่ Application เราล่ะ ต้องทำอย่างไร และปรับอย่างไร ซึ่งหลายภาษามีรองรับส่วนนี้อยู่แล้ว</p>
<h3>สรุปขั้นตอนในการ Scalable</h3>
<p>จะสังเกตได้ว่า พอพูดถึง Scalable เมื่อก่อนเราจะนึกถึง Infrastructure แต่เนื้อหาทั้งหมดที่กล่าวมาเกือบทุกข้อ (ยกเว้น Port Biding) ต้องแก้ไข Application เราให้รองรับ ซึ่งข้อนี้ผมเคยพลาดมาแล้วตอนพยายามใช้ Amazon Cloud ในการทำ Auto-Scaling สุดท้าย มาพบว่า ต้องทำ Process ให้เป็น Stateless รวมถึงการอัพโหลดไฟล์หรือใช้ไฟล์ร่วมกันต้องมี File Object Storage เป็น Backing Services เข้ามาร่วมด้วย ประมาณนี้</p>
<h2>ว่าด้วยเรื่อง Maintainable &#8211; การดูแลรักษา</h2>
<h3>10. Dev/Prod Parity &#8211; Keep development, staging, and production as similar as possible</h3>
<p>เป็นข้อที่อธิบายถึงการทำ Environment ให้มีความแตกต่างกันน้อยที่สุด เช่น Development/SIT/UAT กับ Production ใช้ซอร์ฟแวร์และเวอร์ชั่นเดียวกันทุกตัว มี Config ใกล้เคียงกันทุกอย่าง เป็นต้น รวมถึงการทำ Deployment จาก Environment หนึ่งไปยังอีก Environment หนึ่ง จะต้องทำได้ไว</p>
<p>ซึ่งปัญหาเหล่านี้เรียกรวมๆว่า มีช่องว่างของความแตกต่างระหว่างรูปเดิม (Traditional) กับรูปแบบใหม่ที่ The Twelve Factors แนะนำ ซึ่งแบ่งได้เป็น 3 เรื่อง ดังนี้</p>
<ul>
<li><strong>เรื่องของเวลา (The time gap):</strong> แต่เดิมที่นักพัฒนาต้องใช้เวลาเป็นวัน เป็นสัปดาห์ หรือเป็นเดือน เพื่อนำ Application เข้าสู่ Production <em>ก็จะต้องลดช่องว่างเหล่านี้ ให้เหลือเพียงหลักชั่วโมง หรือนาทีได้</em></li>
<li><strong>เรื่องของคนและกระบวนการ (The personnel gap)</strong>: แต่เดิมนักพัฒนาต้องเขียนโค้ด ส่งให้ทีม Tester ทดสอบ และส่งให้ทีม Infrastructure ทำการ Deploy ซึ่งการส่งกันไปๆมาๆ <em>ก็จะต้องลดช่องว่างเหล่านี้ได้ด้วยการทำ ให้จบเกือบทั้งหมดได้ด้วยนักพัฒนาเท่านั้น</em></li>
<li><strong>เรื่องของเครื่องมือ (The tools gap)</strong>: แต่เดิมนักพัฒนาใช้ Nginx, SQLite, OSX บนเครื่องตัวเอง แต่พอไปขึ้นที่ Production กลายเป็น Apache, MySQL, Linux <em>ก็จะต้องลดช่องว่างเหล่านี้ได้ด้วยการทำให้เครื่องของนักพัฒนาหรือ Development Environment ทั้งหมด มีความเหมือนกับ Production มากที่สุด</em></li>
</ul>
<p><strong>ความท้าทาย คือ</strong> เราจะต้องจำลองทุก Environment ให้คล้ายกัน ในเชิงรูปแบบ เครื่องมือ กระบวนการ แต่ไม่ใช่ในเชิงปริมาณ (อย่างเช่น บน Production มี Web Server ใช้ Apache 2.4 จำนวน 10 ตัว แต่ในเครื่อง Developer มี Apache 2.4 จำนวน 1 ตัวก็โอเคแล้ว) ซึ่งปัจจุบันมีเครื่องมือให้ใช้มากมายในกลุ่ม Containerization อย่าง <strong>Docker</strong> รวมถึงการทำให้เกิด <strong>Continue Integration</strong> และ <strong>Continue Deployment</strong> เพื่อให้มีการ Deploy ได้อย่างมีประสิทธิภาพและต่อเนื่อง</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5095 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-dev-prod-parity.png" alt="" width="1024" height="768" srcset="https://myifew.com/wp-content/uploads/2018/09/12factors-dev-prod-parity.png 1024w, https://myifew.com/wp-content/uploads/2018/09/12factors-dev-prod-parity-768x576.png 768w, https://myifew.com/wp-content/uploads/2018/09/12factors-dev-prod-parity-600x450.png 600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />รูปจาก https://www.infoq.com/presentations/12-Principles-Deploy-Apps</p>
<h3>11. Logs  &#8211; Treat logs as event streams</h3>
<p>โดยปกติแล้ว Application เรามักทำการเก็บ Logs ในรูปแบบข้อมูล เช่น เก็บเป็นไฟล์, ลง Database ซึ่งถ้าเกิดเราอยากรู้การทำงานใดๆ ทันที  ก็ต้องคอยเข้าไปเปิดชุดข้อมูลเหล่านั้น ยิ่งถ้าออกแบบไม่ดี ก็อ่านยาก ค้นยากไปอีก</p>
<p>ซึ่งใน The Twelve Factors แนะนำว่า ให้ทำการพ่น Logs การกระทำต่างๆ มันออกมาซะ ในรูปแบบของ <strong>stdout (Standard Output)</strong> จากนั้นค่อยเอาซอร์ฟแวร์เก็บ Logs มา capture และจัดการข้อมูลเหล่านี้อีกที ซึ่งข้อดีคือ พอ Application เราพ่น stdout ปุ๊บ เราจะสามารถเห็น logs การกระทำต่างๆ ได้เลย และถ้าต้องการดูย้อนหลัง ค่อยไปดูจากระบบ Logs อีกครั้ง (ซึ่งระบบพวกนี้เก็บได้ครอบคลุม ทำงานได้ไว และประหยัดเวลากว่าที่เราจะมาทำเอง) ในที่นี้ตัวอย่างของระบบ Logs ที่เป็น Open Source และทำงานได้ตามข้อนี้ เช่น <a href="https://github.com/heroku/logplex">Logplex</a> และ <a href="https://github.com/fluent/fluentd">Fluentd</a></p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-5097 aligncenter" src="https://myifew.com/wp-content/uploads/2018/09/12factors-fluentd-1200x445.png" alt="" width="1100" height="408" srcset="https://myifew.com/wp-content/uploads/2018/09/12factors-fluentd-1200x445.png 1200w, https://myifew.com/wp-content/uploads/2018/09/12factors-fluentd-1024x380.png 1024w, https://myifew.com/wp-content/uploads/2018/09/12factors-fluentd-768x285.png 768w, https://myifew.com/wp-content/uploads/2018/09/12factors-fluentd-600x223.png 600w, https://myifew.com/wp-content/uploads/2018/09/12factors-fluentd.png 2480w" sizes="auto, (max-width: 1100px) 100vw, 1100px" />ภาพจาก https://www.fluentd.org/architecture</p>
<h3>12. Admin processes &#8211; Run admin/management tasks as one-off processes</h3>
<p>หมายถึงการแยกชุดคำสั่งที่ใช้ทำงานระดับ Server Admin อย่างเช่น Database Migrations, หรือ Shell, Command อะไรบางอย่าง ออกจาก Application ของเราซะ</p>
<p>แต่ก็ต้องใช้คำสั่งข้างต้นเหล่านั้น อยู่ในชุดโค้ดเดียวกับ Application ของเรา, เมื่อใช้เสร็จแล้ว จะต้องทำลายทิ้งให้หมด</p>
<p>ยกตัวอย่างเช่น ผมดาวน์โหลดโค้ด WordPress มาติดตั้ง โดยมันจะมีชุดติดตั้งมาให้ ซึ่งกระบวนการติดตั้งนี้จะมีการ Import Database, การสร้างโฟลเดอร์, การ Change Permission File อยู่ในนั้นด้วย (เรียกว่า Admin processes) จากนั้นเมื่อผมติดตั้งเสร็จ ก็ต้องทำทำการลบไฟล์ติดตั้งทิ้งทั้งหมดเพื่อความปลอดภัย</p>
<p>หรืออีกตัวอย่างหนึ่งคือ การใช้ entrypoint ใน Docker เพื่อให้ทำคำสั่ง Shell อะไรบางอย่าง เช่น Import Database, Delete Cache หนึ่งครั้ง  จากนั้น Application ถึงเริ่มทำงานได้ โดยที่จะไม่มีใครสั่งคำสั่งนั้นได้อีก (ถ้าไม่เข้ามาถึงใน Shell Server ของเรา)</p>
<p>รวมถึงการปิดการเข้าถึงภายในระบบของ Server ด้วย เพื่อป้องกันการลักไก่เข้ามากระทำการเองนอกเหนือจากที่ทำชุดโค้ดไว้ให้</p>
<p><strong>ความท้าทาย คือ</strong> ต้องสร้าง Policy เหล่านี้กับเหล่าทีมที่ดูแล Infrastructure ทั้งหมด รวมถึงบุคคลที่จำเป็นต้องเข้าถึงทั้งหมด ว่าห้ามทำอะไรบ้าง และให้ใช้วิธีการอย่างอื่นทดแทนได้อย่างไรบ้าง</p>
<h3>สรุปขั้นตอนในการ Maintainable</h3>
<p>ผมมักพบว่ากลุ่มของ Maintainable สามข้อหลังนี้ เป็นสิ่งที่บริษัทหลายที่มักประสบภัยกันมาก โดยเฉพาะเรื่องการทำให้ Environment คล้ายกันทั้ง Developer และ Production จากนั้นพอ Application ขึ้นได้แล้ว ก็มักลืมที่จะทำหรือดู Logs ในส่วนของ Application เพราะส่วนมากดูแต่ Infrastructure ว่า CPU/Memory ฯลฯ ขยับขึ้นลงเป็นอย่างไร สิ่งเหล่านี้เองที่เรามักตกม้าตาย แล้วมาทำตามกันทีหลังเมื่อประสบปัญหาไปแล้ว</p>
<h2>สรุปเรื่องราวทั้งหมดของ The Twelve Factor</h2>
<p>ผมก็ยังรู้สึกเสียดายเหมือนตอนต้น ว่าทำไมไม่รู้จักกันให้เร็วกว่านี้ จะได้ใช้ Cloud ได้อย่างมีประสิทธิภาพมากขึ้นอีกเยอะ, และถ้าใครอยากจะเริ่มลองทำดู แต่ยังไม่อยากทำทั้งหมด 12 ข้อ ผมแนะนำให้ลองทำตั้งแต่ข้อ 1-6 ดูก่อนก็ได้ แค่นี้ Application ของเรา ก็จะมีประสิทธิภาพมากขึ้นแล้ว ไม่ว่าจะอยู่บน Cloud หรือไม่อยู่ก็ตาม</p>
<h2>ถ้าอ่านมาถึงตรงนี้ แล้วอยากทำ ลองไปอ่านต่อได้ที่</h2>
<h3 class="entry-title edgtf-post-title">อยากทำ THE TWELVE FACTORS จะเริ่มต้นอย่างไรดี และต้องเรียนรู้อะไรบ้าง</h3>
<p>&#8212;</p>
<p>ข้อมูล อ้างอิง</p>
<ul>
<li><a href="https://12factor.net/">https://12factor.net/</a></li>
</ul>
<p>เว็บน่าสนใจอื่นๆที่พูดถึง The Twelve Factor</p>
<ul>
<li><a href="http://www.somkiat.cc/develop-12-factor-app-with-python/" target="_blank" rel="noopener">Somkiat.cc &#8211;  การพัฒนาระบบตามแนวคิด 12 Factor</a></li>
<li><a href="https://medium.com/@karansivarat/12-factors-app-methodology-for-building-software-as-a-service-part-1-a4979ff61980">12 Factors App : Methodology for building software-as-a-service (Part 1)</a></li>
<li><a href="https://www.babelcoder.com/blog/posts/12-factor">สร้างเว็บให้มีประสิทธิภาพ ด้วย 12 บัญญัติจาก Twelve Factor App</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/5080/the-twelve-factors/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
