How to Install Magento 2.4.6 on Ubuntu 22.04

Magento
Install Diagram

สวัสดีครับ วันนี้ จะมาพูดถึงการ Install Magento 2 (Adobe Commerce) นะครับ
เป็น eCommerce Software ตัวนึง ที่น่าใช้มากๆ มาพร้อมกับ feature ที่ครบครัน ..

รายละเอียดเพิ่มเติม https://business.adobe.com/products/magento/magento-commerce.html

รายละเอียดของ System ประมาณนี้ครับ

- OS: Ubuntu 22.04
- Magento: 2.4.6-p2 (Open Source)
- Apache: 2.4.x
- PHP: 8.1.2
- Composer: 2.2.6
- MySQL: 8.0.34
- Elasticsearch: 7.17.13

มาเริ่มกันเลย ..

Step 1: Update Operating System

# apt update && apt upgrade -y

Step 2: Install Apache Web Server

# apt install apache2

Step 3: Install PHP and PHP extensions

# apt install php php-common libapache2-mod-php php-cli php-fpm php-mysql php-json php-opcache php-gmp php-curl php-intl php-mbstring php-xmlrpc php-gd php-xml php-zip php-soap php-bcmath php-apcu

Modify php.ini file (/etc/php/8.1/cli/php.ini)

memory_limit = 1GB
upload_max_filesize = 256M
zlib.output_compression = On
max_execution_time = 600
max_input_time = 900
date.timezone = Asia/Bangkok

Step 4: Install the MySQL server

# apt install mysql-server
# mysql_secure_installation

Step 5: Create a Magento Database

# mysql -u root -p
mysql> CREATE DATABASE magento;
mysql> CREATE USER 'magento'@'localhost' IDENTIFIED BY 'Str0ngPa$$w0rd';
mysql> GRANT ALL PRIVILEGES ON magento.* TO 'magento'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> EXIT;

Step 6. Install Elasticsearch

# curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
# echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list

# apt update && apt install elasticsearch

# systemctl start elasticsearch
# systemctl enable elasticsearch

Verify Elasticsearch

curl -X GET "localhost:9200"

{
"name" : "magento-01",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "-Or5raP6T5uEG3bUG1JYHw",
"version" : {
"number" : "7.17.13",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "2b211dbb8bfdecaf7f5b44d356bdfe54b1050c13",
"build_date" : "2023-08-31T17:33:19.958690787Z",
"build_snapshot" : false,
"lucene_version" : "8.11.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}

Step 7: Install Composer

# apt install composer

Step 8: Install Magento

Goto Magento Marketplace https://marketplace.magento.com/

Get Access Keys
My profile > Marketplace > My products > Access Keys

# composer global config http-basic.repo.magento.com Your-Public-Key Your-Private-Key

# composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.6-p2 /var/www/magento
# cd /var/www/magento

# bin/magento setup:install \
--base-url=http://your-domain.com \
--db-host=localhost \
--db-name=magento \
--db-user=magento \
--db-password=Str0ngPa$$w0rd \
--admin-firstname=Admin \
--admin-lastname=User \
--admin-email=admin@your-domain.com \
--admin-user=admin \
--admin-password=admin123 \
--language=en_US \
--currency=USD \
--timezone=Asia/Bangkok \
--use-rewrites=1

# chown -R www-data: /var/www/magento

Step 9: Setup Cron jobs

# sudo -u www-data bin/magento cron:install

Step 10: Configure Apache for Magento

Create /etc/apache2/sites-available/magento.conf

<VirtualHost *:80>
ServerAdmin admin@your_domain.com
DocumentRoot /var/www/magento/pub
ServerName your_domain.com
ServerAlias www.your_domain.com

<Directory /var/www/magento>
AllowOverride All
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
# a2ensite magento.conf
# a2enmod rewrite

# systemctl restart apache2

Step 11: Access your Magento installation

Store Front: http://your_domain.com
Admin Dashboard: http://your_domain.com/admin_xxxxxx

Step 12: Diasable 2FA

# bin/magento mod:dis Magento_AdminAdobeImsTwoFactorAuth Magento_TwoFactorAuth
# bin/magento setup:di:compile

Options: Tuning Magento

https://experienceleague.adobe.com/docs/commerce-operations/performance-best-practices/software.html

Facebook Comments Box

Setup IKEA VINDRIKTNING + WeMos D1 mini (Tasmota Firmware)

IKEA VINDRIKTNING + WeMos D1 mini (Tasmota Firmware)

IoT 101 ของเรา วันนี้ จะมาพูดถึงวิธีการ Setup IKEA VINDRIKTNING + WeMos D1 mini (Tasmota Firmware) กันครับ
โดยมีขั้นตอนต่างๆ ประมาณนี้

1. เกาะ WiFi (AP): tasmota-XXXXXX-XXXX

2. เปิด Web Browser เข้า http://192.168.4.1

3. ทำการ Setup WiFi ที่ต้องการใช้งาน

4. จากนั้นเข้าผ่าน IP ใหม่ ของ Tasmota ที่ได้จาก WiFi ที่คุณใช้งาน

5. คลิก Configuration > Configure Module เลือก Generic (0) กด Save แล้วรอ Tasmota Restart

6. คลิกเข้า Configure Module อีกครั้ง
– PIN: D1 GPIO5 เลือก VINDRIKTNING
– PIN: D6 GPIO12 เลือก DHT11
กด Save แล้วรอ Tasmota Restart

7. เมื่อเรา config ถูกต้อง ก็จะได้ค่า Temperature, Humidity, Dew point และ PM 2.5 ตามรูปครับ

8. คลิก Configuration > Configure MQTT
– Host: mqtt.tono.tech
– Port: 1883
– Client: DVES_%06X (ค่า default)
– User: mqtt
– Password: XXXXXX
– Topic: tasmota_%06X (ค่า default)
* จากตัวอย่าง จะได้ค่า tasmota_1AB59B ตามเลข MAC Address ของตัว ESP8266
– Full Topic: %prefix%/%topic%/ (ค่า default)
กด Save แล้วรอ Tasmota Restart

9. คลิก Console จะเห็น Logs ที่ Tasmota ประมาณนี้ เป็นอันใช้ได้แล้ว

07:48:21.453 MQT: tele/tasmota_1AB59B/SENSOR = {"Time":"2023-03-21T07:48:21","DHT11":{"Temperature":24.7,"Humidity":72.0,"DewPoint":19.3},"VINDRIKTNING":{"PM2.5":7},"TempUnit":"C"}

10. Download IoT MQTT Panel จาก Play Store

11. เลือก Backup and Restore
จากนั้นเลือก RESTORE จาก pm25dashboard.json นี้ หรือจะเลือกสร้าง Dashboard ใหม่เองก็ได้
เปลี่ยนชื่อ topic เป์นของ Tasmota Device ของเรา
อย่างเช่นของผมจะเป็น tele/tasmota_1AB59B/SENSOR

pm25dashboard.json

{"dataVersion":120,"globalSettings":{"runInBackground":true,"appTheme":"dark"},"connections":[{"connectionName":"Tasmota PM2.5","clientId":"ub5bvpTlZA","host":"mqtt.tono.tech","port":1883,"connectionType":"tcp","username":"mqtt","password":"XXXXXX","connectionTimeout":30,"keepAlive":60,"autoConnect":true,"disableHostnameCheck":false,"caCertificateFileName":"","clientCertificateFileName":"","clientKeyFileName":"","sslClientPassword":"","enableWillMessage":false,"willTopic":"","willPayload":"","willRetain":false,"willQoS":0,"defaultDashboard":"dashboard_0","connectionId":"connection_0","notifyOnDisconnect":false}],"dashboards":[{"connectionId":"connection_0","dashboardId":"dashboard_0","dashboardName":"PM 2.5","dashboardPrefixTopic":"","lockPanels":true}],"panels":[{"connectionId":"connection_0","dashboardId":"dashboard_0","panelId":"panel_7","panelName":"WiFi Signal","type":"progress","mqttType":"sub","topic":"tele\/tasmota_1AB59B\/STATE","payloadMin":0,"payloadMax":100,"qos":0,"defaultColor":"success","dynamicColor":true,"firstColor":"danger","secondColor":"warning","thirdColor":"success","firstColorEnd":50,"secondColorEnd":80,"disableDashboardPrefix":true,"panelWidth":"100","panelMergeClass":"","showReceivedTimeStamp":true,"unit":"%","orientation":"horizontal","enableNotification":false,"notificationFilter":"all","notificationMin":"","notificationMax":"","notificationValue":"","notificationRegex":"","notificationMessage":"","isJSONPayload":true,"jsonPath":"$.Wifi.RSSI","messageFactor":1,"step":1},{"connectionId":"connection_0","dashboardId":"dashboard_0","panelId":"panel_1","panelName":"Temp","type":"gauge","mqttType":"sub","topic":"tele\/tasmota_1AB59B\/SENSOR","payloadMin":0,"payloadMax":100,"qos":0,"disableDashboardPrefix":false,"panelWidth":"33","firstColor":"#009600","secondColor":"#fac800","thirdColor":"#ff5722","firstColorEnd":33.33,"secondColorEnd":66.67,"panelMergeClass":"","showReceivedTimeStamp":false,"unit":"°C","enableNotification":false,"notificationFilter":"all","notificationMin":"","notificationMax":"","notificationValue":"","notificationRegex":"","notificationMessage":"","isJSONPayload":true,"jsonPath":"$.DHT11.Temperature","messageFactor":"","step":1},{"connectionId":"connection_0","dashboardId":"dashboard_0","panelId":"panel_2","panelName":"Humidity","type":"gauge","mqttType":"sub","topic":"tele\/tasmota_1AB59B\/SENSOR","payloadMin":0,"payloadMax":100,"qos":0,"disableDashboardPrefix":false,"panelWidth":"33","firstColor":"#009600","secondColor":"#fac800","thirdColor":"#ff5722","firstColorEnd":70,"secondColorEnd":100,"panelMergeClass":"","showReceivedTimeStamp":false,"unit":"%","enableNotification":false,"notificationFilter":"all","notificationMin":"","notificationMax":"","notificationValue":"","notificationRegex":"","notificationMessage":"","isJSONPayload":true,"jsonPath":"$.DHT11.Humidity","messageFactor":1,"step":1},{"connectionId":"connection_0","dashboardId":"dashboard_0","panelId":"panel_3","panelName":"PM 2.5","type":"gauge","mqttType":"sub","topic":"tele\/tasmota_1AB59B\/SENSOR","payloadMin":0,"payloadMax":1000,"qos":0,"disableDashboardPrefix":false,"panelWidth":"33","firstColor":"#009600","secondColor":"#fac800","thirdColor":"#ff5722","firstColorEnd":35,"secondColorEnd":85,"panelMergeClass":"","showReceivedTimeStamp":false,"unit":"ug\/m3","enableNotification":false,"notificationFilter":"all","notificationMin":"","notificationMax":"","notificationValue":"","notificationRegex":"","notificationMessage":"","isJSONPayload":true,"jsonPath":"$.VINDRIKTNING.['PM2.5']","messageFactor":1,"step":10},{"connectionId":"connection_0","dashboardId":"dashboard_0","panelId":"panel_0","panelName":"PM 2.5","type":"line-graph","mqttType":"sub","qos":0,"comboItemList":[{"topic":"tele\/tasmota_1AB59B\/SENSOR","label":"ug\/m3","color":"#7b00f5","showArea":true,"showPoints":true,"unit":"","enableNotification":false,"notificationFilter":"all","notificationMin":"","notificationMax":"","notificationValue":"","notificationRegex":"","notificationMessage":"","isJSONPayload":true,"jsonPath":"$.VINDRIKTNING.['PM2.5']","messageFactor":1}],"disableDashboardPrefix":false,"panelWidth":"100","panelMergeClass":"","maxPersistence":50,"smoothCurve":true},{"connectionId":"connection_0","dashboardId":"dashboard_0","panelId":"panel_4","panelName":"Temp","type":"line-graph","mqttType":"sub","qos":0,"comboItemList":[{"topic":"tele\/tasmota_1AB59B\/SENSOR","label":"°C","color":"#99ff99","showArea":true,"showPoints":true,"unit":"°C","enableNotification":false,"notificationFilter":"all","notificationMin":"","notificationMax":"","notificationValue":"","notificationRegex":"","notificationMessage":"","isJSONPayload":true,"jsonPath":"$.DHT11.Temperature","messageFactor":1}],"disableDashboardPrefix":false,"panelWidth":"100","panelMergeClass":"","maxPersistence":50,"smoothCurve":true},{"connectionId":"connection_0","dashboardId":"dashboard_0","panelId":"panel_5","panelName":"Humidity ","type":"line-graph","mqttType":"sub","qos":0,"comboItemList":[{"topic":"tele\/tasmota_1AB59B\/SENSOR","label":"%","color":"#007bf5","showArea":true,"showPoints":true,"unit":"%","enableNotification":false,"notificationFilter":"all","notificationMin":"","notificationMax":"","notificationValue":"","notificationRegex":"","notificationMessage":"","isJSONPayload":true,"jsonPath":"$.DHT11.Humidity","messageFactor":1}],"disableDashboardPrefix":false,"panelWidth":"100","panelMergeClass":"","maxPersistence":50,"smoothCurve":true}]}

12. ถ้าเสร็จเรียบร้อย เราก็จะได้ Dashboard ไว้ใช้งานแล้วครับ

PM 2.5 Dashboard

* เพิ่มเติมครับ วิธีการ Hard Reset Tasmota กลับไปเป็นค่า default

1. ถอดสาย USB ออก 30s
2. เสียบสาย ถอดสาย สลับกัน 7 ครั้ง (ครั้งละไม่เกิน 5s)

เป็นอย่างไรกันบ้างครับ ไม่ยากเลยใช่ไหมครับ ในการทำ Dashboard ดีๆ ไว้ดูคุณภาพอากาศ สำหรับช่วง PM 2.5 ประเทศเรา เป็นผู้นำอันดับโลก แบบนี้ 🙂
ถ้าสงสัยหรืออยากสอบถามเพิ่มเติม comment ไว้ตรงนี้ หรือ add LINE ID: pornpasok เข้ามาพูดคุยกันได้ครับ ..

Facebook Comments Box

Filebeat Lightweight shipper for logs from k8s to Elasticsearch

Beat

สวัสดีครับ DevOps 101 ของเรา วันนี้ จะมาพูดถึง Filebeat นะครับ ..

Filebeat คืออะไร?
Filebeat = Lightweight shipper for logs
“Whether you’re collecting from security devices, cloud, containers, hosts, or OT, Filebeat helps you keep the simple things simple by offering a lightweight way to forward and centralize logs and files.”

ถ้าเอาแบบเข้าใจง่ายๆ ก็คือ ตัวกวาด logs จากที่ต่างๆ เข้ามาที่ centralize logs ในที่นี้ ผมจะพูดถึง k8s cluster (EKS) logs ไปเก็บที่ Elasticsearch ละกันนะครับ ..

จริงๆ ยังมี ตัวอื่นๆ อีก นะครับ ที่ทำงานคล้ายๆ Filebeat เช่น Fluentd, Fluentbit

ในเมื่อเราใช้ ELK Stack ใน Ecosystem ของเราแล้ว การที่เราอยาก search logs ต่างๆ ที่เกิดจาก container ของเรา ได้ง่ายสุด ก็คือการ ship logs จาก k8s cluster ของเรา ไปเก็บไว้บน Elasticsearch แล้วทำการ search ผ่าน Kibana ..

วิธีการ Install Filebeat ใน k8s cluster

ทำได้หลายวิธีครับ ในที่นี้ ผมจะใช้วิธีง่ายๆ ผ่าน kubectl ดังต่อไปนี้

1. Create Secret โดยใส่ค่าที่จำเป็น พวกนี้ลงไป

ELASTICSEARCH_HOST = Endpoint ของ Elasticsearch เรา
ELASTICSEARCH_PORT = Port ที่ Elasticsearch เราทำงานอยู่
ELASTICSEARCH_USERNAME = Username ของ Elasticsearch
ELASTICSEARCH_PASSWORD = Password ของ Elasticsearch
ELASTIC_CLOUD_ID = Cloud ID ในกรณีที่เราใช้ผ่าน Cloud Service ของ Elastic.co
ELASTIC_CLOUD_AUTH = Username:Password ของ Elasticsearch

filebeat-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: filebeat
  namespace: kube-system
type: Opaque
data:
  ELASTICSEARCH_HOST: aHR0cDovL2xvY2FsaG9zdA==
  ELASTICSEARCH_PASSWORD: 
  ELASTICSEARCH_PORT: OTIwMA==
  ELASTICSEARCH_USERNAME: 
  ELASTIC_CLOUD_AUTH: 
  ELASTIC_CLOUD_ID: 

จากนั้น สั่ง create secret

kubectl create -f filebeat-secret.yaml

2. Create Deployment และ Resource อื่นๆ

filebeat-kubernetes.yaml

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: kube-system
  labels:
    k8s-app: filebeat
data:
  filebeat.yml: |-
    # To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this:
    filebeat.autodiscover:
      providers:
       - type: kubernetes
         node: ${NODE_NAME}
         hints.enabled: true
         hints.default_config:
           type: container
           paths:
             - /var/log/containers/*${data.kubernetes.container.id}.log

    # Filter by container.name
    # filebeat.autodiscover:
    #   providers:
    #     - type: kubernetes
    #       node: ${NODE_NAME}
    #       templates:
    #         - condition:
    #             contains:
    #               kubernetes.container.name: "container01"
    #           config:
    #             - type: container
    #               paths:
    #                 - "/var/log/containers/*-${data.kubernetes.container.id}.log"
    #         - condition:
    #             contains:
    #               kubernetes.container.name: "container02"
    #           config:
    #             - type: container
    #               paths:
    #                 - "/var/log/containers/*-${data.kubernetes.container.id}.log"

    processors:
      - add_cloud_metadata:
      - add_host_metadata:

    cloud.id: ${ELASTIC_CLOUD_ID}
    cloud.auth: ${ELASTIC_CLOUD_AUTH}

    output.elasticsearch:
      hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      #index: "%{[fields.my_type]}-%{[agent.version]}-%{+yyyy.MM.dd}" 
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: kube-system
  labels:
    k8s-app: filebeat
spec:
  selector:
    matchLabels:
      k8s-app: filebeat
  template:
    metadata:
      labels:
        k8s-app: filebeat
    spec:
      serviceAccountName: filebeat
      terminationGracePeriodSeconds: 30
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
        - name: filebeat
          image: docker.elastic.co/beats/filebeat:8.6.2
          args: ["-c", "/etc/filebeat.yml", "-e"]
          env:
            - name: ELASTICSEARCH_HOST
              valueFrom:
                secretKeyRef:
                  name: filebeat
                  key: ELASTICSEARCH_HOST
            - name: ELASTICSEARCH_PORT
              valueFrom:
                secretKeyRef:
                  name: filebeat
                  key: ELASTICSEARCH_PORT
            - name: ELASTICSEARCH_USERNAME
              valueFrom:
                secretKeyRef:
                  name: filebeat
                  key: ELASTICSEARCH_USERNAME
            - name: ELASTICSEARCH_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: filebeat
                  key: ELASTICSEARCH_PASSWORD
            - name: ELASTIC_CLOUD_ID
              valueFrom:
                secretKeyRef:
                  name: filebeat
                  key: ELASTIC_CLOUD_ID
            - name: ELASTIC_CLOUD_AUTH
              valueFrom:
                secretKeyRef:
                  name: filebeat
                  key: ELASTIC_CLOUD_AUTH
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
          securityContext:
            runAsUser: 0
            # If using Red Hat OpenShift uncomment this:
            #privileged: true
          resources:
            limits:
              memory: 200Mi
            requests:
              cpu: 100m
              memory: 100Mi
          volumeMounts:
            - name: config
              mountPath: /etc/filebeat.yml
              readOnly: true
              subPath: filebeat.yml
            - name: data
              mountPath: /usr/share/filebeat/data
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
            - name: varlog
              mountPath: /var/log
              readOnly: true
      volumes:
        - name: config
          configMap:
            defaultMode: 0640
            name: filebeat-config
        - name: varlibdockercontainers
          hostPath:
            path: /var/lib/docker/containers
        - name: varlog
          hostPath:
            path: /var/log
        # data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
        - name: data
          hostPath:
            # When filebeat runs as non-root user, this directory needs to be writable by group (g+w).
            path: /var/lib/filebeat-data
            type: DirectoryOrCreate
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: filebeat
subjects:
  - kind: ServiceAccount
    name: filebeat
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: filebeat
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: filebeat
  namespace: kube-system
subjects:
  - kind: ServiceAccount
    name: filebeat
    namespace: kube-system
roleRef:
  kind: Role
  name: filebeat
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: filebeat-kubeadm-config
  namespace: kube-system
subjects:
  - kind: ServiceAccount
    name: filebeat
    namespace: kube-system
roleRef:
  kind: Role
  name: filebeat-kubeadm-config
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: filebeat
  labels:
    k8s-app: filebeat
rules:
  - apiGroups: [""] # "" indicates the core API group
    resources:
      - namespaces
      - pods
      - nodes
    verbs:
      - get
      - watch
      - list
  - apiGroups: ["apps"]
    resources:
      - replicasets
    verbs: ["get", "list", "watch"]
  - apiGroups: ["batch"]
    resources:
      - jobs
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: filebeat
  # should be the namespace where filebeat is running
  namespace: kube-system
  labels:
    k8s-app: filebeat
rules:
  - apiGroups:
      - coordination.k8s.io
    resources:
      - leases
    verbs: ["get", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: filebeat-kubeadm-config
  namespace: kube-system
  labels:
    k8s-app: filebeat
rules:
  - apiGroups: [""]
    resources:
      - configmaps
    resourceNames:
      - kubeadm-config
    verbs: ["get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: filebeat
  namespace: kube-system
  labels:
    k8s-app: filebeat
---
 

จากนั้น สั่ง create deployment

kubectl create -f filebeat-kubernetes.yaml

3. Search k8s cluster logs ผ่าน Kibana

ถ้า config ทุกอย่างเราถูกต้อง container ทำงานได้ เราก็จะได้ logs ของ k8s cluster เรา ไปเก็บบน Elasticsearch และทำการ search ผ่าน Kibana ได้เลย

Kibana Search

* เราสามารถ filter input ของ Logs ที่จะ ship ไปเก็บ ที่ Elasticsearch ได้

ตัวอย่างอยู่ใน filebeat-kubernetes.yaml ที่ comment ไว้

เป็นอย่างไรกันบ้างครับ ไม่ยากเลยใช่ไหมครับ สำหรับการ ship logs จาก k8s cluster ของเรา ไปเก็บบน Elasticsearch 🙂

Git Repo: https://github.com/pornpasok/k8s-logs-es-filebeat
Ref: https://www.elastic.co/beats/filebeat

Facebook Comments Box

Happy New Year 2023 สวัสดีปีใหม่ 2566

กย 9666 จันทุบรี

สวัสดีปีใหม่ 2023 ครับ อาจจะช้าไปสักนิด พอดีช่วงหยุดปีใหม่ ที่ผ่านมา
ผมเองมีภารกิจ กลับไปทำ checklist ที่ list ไว้ว่าจะไปทำที่บ้าน
เพราะว่า นานๆ กลับที ไม่ได้กลับบ่อย ก็เลยต้องไปทำให้เสร็จครับ ..
จริงๆ list ไว้หลายอย่างมาก แต่ทำไม่สำเร็จ เพราะว่า ไม่มีเวลาพอ
บางอย่าง ก็ทำเองไม่ได้ทั้งหมด +___+
ที่ทำเสร็จไปแล้ว ก็มีประมาณนี้
– ติดม่านกันแสง UV หน้าต่าง ประตู ทั่วบ้าน หลังจากปล่อยโล่งๆ มา 8 ปี
– ติดกล้องวงจรปิดใหม่ ครอบคลุม และมีประสิทธิภาพมากขึ้น
– ติดระบบไฟ Solar รอบบ้าน ให้แสงสว่าง ประหยัดพลังงาน
– ซ่อมแซม เครื่องมือเครื่องใช้ต่างๆ ให้ทำงานได้ปกติ เหมือนเดิม
– ซ่อมแซม และทำระบบเพิ่ม ทั้ง IoT และ Weather Station
– ซ่อมแซม ตรวจสอบ Jeep ให้ทำงานได้ปกติ (ยังเหลือ switch ประตู และระบบไฟ)
– อื่นๆ ก็ทำนั้นทำนี่ ให้ดีขึ้น ให้สมบูรณ์ขึ้น

สำหรับปี 2022 ที่ผ่านมา ถือว่าเป็นปีที่เกิดการเปลี่ยนแปลง อย่างยิ่งเหมือนกันสำหรับผม
– เข้ามาอยู่ กทม. อีกรอบ ช่วงโควิด (Dec 2021) เช่าคอนโด อยู่ใจกลางเมือง ย่านรัชโยธิน
– งานส่วนใหญ่ ก็ยังเป็น เกี่ยวกับ DevOps ทำ Infrastructure, CI/CD Tools, Monitoring Tools ให้ Developers ใช้งาน
– ได้เข้าไปทำงาน ในระบบธุรกิจใหม่ๆ ที่ไม่เคยทำมาก่อน ก็สนุกดี ได้เจออะไรแปลกๆ ใหม่ๆ เยอะดี
– บริษัทที่ทำงานด้วย ดีมาก ไม่ได้เน้นระเบียบ หรือกระบวนการ ที่ไม่จำเป็น ทำให้ทำงานได้แบบมีประสิทธิภาพและคุณภาพ มากขึ้น, ไม่ต้องเข้า office ทุกวัน
– เดินทาง ท่องเที่ยว มากขึ้น เพราะโควิด เริ่มไม่รุนแรง
– รายได้ ของปีนี้ เริ่มดีขึ้น ทุกอย่างเริ่มลงตัวขึ้น
– หันมาออกกำลังกาย ช่วงปลายปี เพื่อสุขภาพ
– งดดื่ม ถ้าไม่จำเป็น +____+
– ผลตรวจสุขภาพ ประจำปี แบบละเอียด (package 5500 ของ รพ.สมิติเวช) พบว่าสุขภาพดีขึ้น จากปีก่อนๆ ที่ร่างกายหักโหม ดื่มหนัก ไม่ได้ออกกำลังกาย
– ได้มีเวลา หยุดยาว ช่วงปลายปี กลับไปอยู่บ้าน ที่จันทบุรี
– ได้ทะเบียนใหม่ มาใส่ Jeep ละครับ กย 9666 จันทบุรี ผลรวม = 36 ก็ถือว่าดีมาก สำหรับเลขนี้ ผลรวมนี้ ส่วนตัวผม เลขนี้ ก็มีความหมายของมันเอง สำหรับรถ ก็คือรถปี 1996 แล้วก็ทะเบียน ได้มาใช้ปี 2566 อีกด้วย ลงตัวเป๊ะ 🙂

สำหรับปี 2023 ที่คาดหวังไว้ และอยากทำ มีประมาณนี้
– ก็ยังคงเหมือนปี 2022 ที่ยังทำไม่ได้ทั้งหมด +___+
– ออกกำลังกาย มากขึ้น เลือกกินอาหาร ที่ดีต่อร่างกาย เน้นเรื่องสุขภาพเป็นหลัก
– ลดน้ำหนัก ให้เหลือ <= 75 (ปัจจุบัน 81-82)
– ทำงานที่ได้รับมอบหมาย ให้มีประสิทธิภาพ ดีที่สุด ให้เกินกว่าที่ต้องทำ ในทุกมิติ
– ศึกษาหาความรู้ เพิ่มเติมเสมอ
– เดินทาง ท่องเที่ยว ให้มากขึ้น ไปที่ใหม่ๆ ที่ไม่เคยไปบ้าง
– ใช้จ่ายอย่างประหยัด ใช้เท่าที่จำเป็น, ลงทุน หลายๆ ทางที่พอมีความเป็นไปได้
– ทำธุรกิจ เกี่ยวกับ technology ด้านการเกษตร (Agritech) จริงๆ จังๆ
– อยากทำ มอเตอร์ไซค์ ให้เช่าที่ปาย และเมืองท่องเที่ยวอื่นๆ
– เก็บสะสม รถที่ชอบ และราคาไม่น่าจะตกแล้ว
– กลับบ้านให้บ่อยขึ้น
– ช่วยเหลือสังคม เท่าที่กำลังกาย และกำลังทรัพย์ พอจะทำได้ 🙂

Facebook Comments Box

Setup Elasticsearch and Kibana OpenID Connect with Azure AD

elastic.co with Azure AD

สวัสดีครับ DevOps 101 ของเรา วันนี้มีเรื่องมาแนะนำ การ setup Single Sign-On (SSO) ของ App เรา .. ด้วย Azure AD โดยที่เรา ไม่จำเป็นต้องมีสิทธิเป็น admin ของ org นั้นๆ .. เป็น user ธรรมดา ก็สามารถ ทำได้
ในที่นี้ จะใช้ในส่วนของ OpenID Connect (OIDC) นะครับ ซึ่งสามารถ ใช้งานทั้งกับ Google, GitHub, AWS Cognito และอื่นๆ ได้ .. แต่ในที่นี้ผมจะใช้เป็น Azure AD นะครับ

จากความต้องการขององค์กร ที่ต้องการให้ พนักงานทุกคน login ด้วย Azure AD หรือถ้าพูดให้เข้าใจง่าย ก็คือใช้ email บริษัท ในทุกๆ App ที่ใช้งาน เนื่องจากเราใช้ Office365 อยู่แล้ว .. จะได้สะดวกในการจัดการ พนักงาน ที่มีการเข้าออก เปลี่ยนแปลงอยู่เสมอ ไม่ต้อง add แบบ local user ..

ในที่นี้ผมจะยกตัวอย่างการ นำ Azure AD (OpenID Connect) มาใช้กับ ELK Stack โดยสามารถใช้ได้ กับ ELK Stack ที่เรา hosted เอง และใช้ได้กับ elastic.co นะครับ ..

วิธีการ Setup OpenID Connect เราสามารถทำตามขั้นตอน ใน docs ของ elastic.co ได้เลยดังนี้
https://www.elastic.co/guide/en/cloud/current/ec-securing-clusters-oidc-op.html#ec-securing-clusters-oidc-op

จากนั้น เราสามาถทำ Role Mappings ได้ใน Kibana อย่างในที่นี้ ผมจะให้ user ที่ login ผ่าน Azure AD (OIDC) ทั้งหมด มี สิทธิแค่ viewer ก็สามารถทำได้ประมาณนี้

User field: realm.name
Type: text
Value: oidc1 (ชื่อ realm ที่เรา config ในหน้า login ของ Kibana)

Kibana Role Mappings

หรือถ้าเรา ต้องการสร้าง Role mapping เฉพาะเจาะจงว่า user (email) คนไหน สามารถทำอะไรเพิ่มเติมได้ บ้าง เราก็สามารถ สร้างเพิ่มได้ ประมาณนี้

User field: username
Type: text
Value: user@email.com (email ของ user ที่เราต้องการ)

Kibana Role Mappings Specific by Email

จะเห็นว่า เราสามารถนำ Azure AD (OpenID Connect) มาใช้กับ Kibana ของเราได้ ทำให้เราสะดวก ในการจัดการ user และการ ทำ Role Mappings ก็ช่วยให้เรา สามารถกำหนด permission ของแต่ละ user ให้แตกต่างกันได้ .. เราไม่ต้องไป add local user บน Elasticsearch และเราสามารถนำ OpenID Connect ไปใช้กับ App อื่นๆ ของเราได้ด้วยเช่นกันครับ .. ไม่ว่าจะเป็น App ที่เราเขียนเอง หรือ OpenSource ต่างๆ ก็รองรับ OpenID Connect กันเป็นส่วนใหญ่ 🙂

ถ้าเพื่อนๆ สงสัยตรงไหน comment กันเข้ามาถามได้นะครับ ไม่ยากครับ ลองไปทำเล่นดู elastic.co เอง ใช้งานได้ฟรี 14 วันครับ หรือถ้าจะ Hosted เองด้วย docker-compose ง่ายๆ ก็ได้ครับ 🙂

ตัวอย่าง: https://github.com/pornpasok/docker-elk

Facebook Comments Box

ลองใช้ Argo CD deploy application บน EKS

Argo CD Dashboard
Argo CD Dashboard

DevOps 101 ของเราวันนี้ จะมาทดลองใช้งาน Argo CD กันนะครับ .. ว่ามันดียังไง ทำอะไรได้บ้าง และเหมาะกับใคร? Logo ของ Argo CD ก็น่ารักดีครับ เป็นรูป มนุษย์ต่างดาว หรือ หมึก ก็ไม่รู้ ..

นิยามที่ทาง Argo CD เค้าบอกไว้ ในเว็บเค้าเองก็คือ ..

What Is Argo CD?
“Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.”

ถ้าสรุปให้เข้าใจได้ง่ายๆ ก็คือ เป็น Tools สำหรับทำ CD (Continuous Delivery) ที่ตรงไปตรงมา
ไม่ซับซ้อน สำหรับ deploy Application บน k8s ด้วยการใช้หลักการของ GitOps

รายละเอียดเพิ่มเติม : https://argo-cd.readthedocs.io/

เท่าที่ลองเล่นดู หลังจากที่เรามี k8s cluster แล้ว (ในที่นี่ผมใช้ EKS) เราก็จะต้อง Install เจ้า Argo CD ใน k8s cluster ของเรา จากนั้น เราก็จะใช้ความสามารถของ Argo CD ได้ ด้วยการผูกกับ Git Repository ที่ใช้ในการ deploy Application ของเรา เท่านี้ก็เป็นอันเรียบร้อยครับ .. เมื่อเรามีการเปลี่ยนแปลง configuration บน git เจ้า Argo CD ก็จะมา sync config ไป deploy บน k8s cluster ให้เรา ..

ดูรายละเอียดเพิ่มเติมที่ YouTube ของ Nana ได้ที่นี่ครับ : https://www.youtube.com/watch?v=MeU5_k9ssrs

สรุปความคิดเห็นส่วนตัว ที่ลองใช้งาน (ยังไม่ได้ใช้จริงๆ จังๆ บน Production)

ข้อดี
– Install ง่ายมาก ไม่เจอปัญหาอะไรเลย ใช้ resource น้อยมาก
– ไม่ต้องวุ่นวาย เรื่องการ Install kubectl เพราะอยู่ใน k8s cluster อยู่แล้ว
– ไม่ต้องวุ่นวาย เรื่องการจัดการ Credentials ในการเข้าถึง k8s cluster
– มี Dashboard ที่แสดงรายละเอียด ของการ deploy Application ได้ละเอียด ครบถ้วน
– Sync manifest จาก Git Repository ได้รวดเร็ว
– หน้าตาดูดี สวยงาม

ข้อเสีย
– Deploy (CD) บน k8s cluster ได้เท่านั้น
– ในส่วนของ CI (Continuous Integration) ยังต้องใช้ 3rd-party อื่นช่วย ไม่ว่าจะเป็น GitHub Action, GitLab CI, Jenkins
– ถ้าดูพวก Metrics ได้ด้วย น่าจะดีเลย แต่คิดว่า คงออกแบบมา ให้ simple ทำงาน CD ได้อย่างดี ก็พอ

Facebook Comments Box

[Trick] Deploy Docker Images with Jenkins Pipeline

docker-jenkins-love

DevOps 101 วันนี้ มาขอเล่าเรื่อง trick ง่ายๆ ในการ deploy docker images กันครับ

1. เรื่อง Time Zone โดยปกติแล้ว ถ้าเราไม่กำหนด ตัว container ที่ run จะเป็น UTC นะครับ ในตัวอย่าง ถ้าอยากให้ Time Zone ตรงกับบ้านเรา (UTC +7) เราสามารถ เข้าไป กำหนดได้ง่ายๆ ประมาณนี้ครับ
Dockerfile

FROM python:3.9
ENV TZ="Asia/Bangkok"
RUN date

Build

docker build -t dockertest .

Run

docker run -it dockertest -c "date"

ถ้าเป็น alpine based image จะต้อง install tzdata ก่อน ประมาณนี้ครับ

RUN apk add --no-cache tzdata
ENV TZ Asia/Bangkok

2. เวลา run docker ด้วย tag:latest แล้ว อาจจะมี การ cache บน local ทำให้ ไม่ได้ image ล่าสุด เราสามารถแก้ไขได้โดย ใส่ options –pull=always ตัวอย่างเช่น

docker run --pull=always

3. ถ้าอยาก run Jenkins Pipeliine แบบ trigger ด้วย cron เราสามารถเพิ่ม cron เข้าไปได้ ประมาณนี้


pipeline {
    agent any
    triggers {
        cron('00 20 * * *')
    }

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

สำหรับการ Set Time Zone ในตัว Jenkins เอง ผมเคยเขียนรายละเอียดไว้แล้วครับ อ่านเพิ่มเติมได้ที่
https://ton.packetlove.com/blog/devops/devops-101-jenkins-set-time-zone.html

อันนี้เป็น trick เล็กๆ น้อยๆ ที่เอามาเล่าสู่กันฟังนะครับ ที่เจอตอน deploy app ที่เป็น docker images ด้วย Jenkins Pipeline 🙂

Facebook Comments Box

Happy New Year 2022 สวัสดีปีใหม่ 2565

Jeep ZJ

สวัสดี ปีใหม่ 2022 ครับ .. สำหรับปี 2021 ที่ผ่านมาถือว่าเป็นปีที่ มีอะไรให้ทำเยอะพอสมควรเลย .. เป็นปีที่มีการเปลี่ยนแปลงเยอะมาก เนื่องมาจาก COVID19 ทำให้มีโอกาสได้กลับไป WFH อยู่บ้าน เกือบทั้งปี ..

เพิ่งเข้ามา กทม. ช่วง Dec 2021 ได้มาเจอหน้าตาเพื่อนพ้องน้องพี่ เพื่อนร่วมงานสักหน่อย .. ก่อนที่โควิด รอบใหม่ (โอมิคอน) จะมาอีกรอบ +___+

ช่วงปีใหม่ปีนี้ ก็น่าจะเป็นในรอบ หลายๆ ปี ที่ผม อยู่ กทม. ปกติก็จะเดินทาง ต่างประเทศ ต่างจังหวัด ไม่ก็กลับบ้าน ที่จันทบุรี .. แต่ปีนี้ ไม่ได้ไปไหนครับ ไม่อยากเสี่ยง เพราะว่ายังฉีดวัคซีน แค่เข็มเดียว ..

สำหรับปี 2021 ที่ผ่านมา ก็มีเรื่องราวหลายๆ อย่าง เข้ามาในชีวิต ที่อยากบันทีกไว้ ..
– ผ่านค่าย Super AI Engineer #1 รุ่นแรก (สอบคัดเลือก 100 คนจากผู้สนใจ 3-4000 คน ทั่วประเทศ) ได้ความรู้ดีๆ เยอะมาก และได้รู้จักเพื่อนๆ พี่ๆ น้องๆ เก่งๆ มากมาย ทุกวันนี้ ก็ยังคุยกันอยู่ทุกวัน กับแก็งค์ ที่ไปพักด้วยกัน สนิทกัน (ศาลพระภูมิ)
– กลับไป WFH ที่บ้าน แทบทั้งปี เพราะ COVID19 รอบใหม่มา ดีที่แถวบ้านมี 7deli เลยพอได้สั่งกาแฟ ขนม มากินบ้าง
– อยู่บ้านพอมีเวลา ได้อยู่กับครอบครัว ญาติพี่น้อง ทำนั่นทำนี่ เข้าสวนบ้าง ไรบ้าง .. ได้ซื้อสิ่งที่ขาด เฟอร์นิเจอร์ มาเติมเต็มบ้าน ให้อยู่ได้จริง ใช้ทำงานได้จริง
– การอยู่บ้าน WFH เป็นสิ่งที่ดีมาก ไม่ต้องเดินทาง ไม่ต้องเจอฝุ่นควัน มีอาหารอร่อยๆ กิน .. และประหยัดมากๆ (ไปกินข้าวที่บ้านแม่) ทำให้ ไม่อยากอยู่ กทม. เลย
– ทำงานด้าน Data Engineer อย่างจริงจัง ได้ทำ MLOps, MLFlow ให้เป็น CI/CD Pipeline
– เข้าไปวุ่นกับ ELK Stack แบบที่เป็น cloud service (elastic.co) ทำให้เข้าใจเลย ว่า cost แพงขนาดนี้ ทำไมจ่ายได้
– ได้เข้าไปมีส่วนเกี่ยวข้องกับ App 7-Eleven ในส่วนของ 7deli ทำให้เข้าใจมุมมองของบริษัทใหญ่ อย่าง CPAll ที่ปรับตัวได้เร็วมาก ในช่วงโควิด พลิกวิกฤติ ได้อย่างน่าชื่นชมมาก ..
– ได้มามีส่วนร่วมกับ App Start-Up ของคนไทย ด้าน Food Delivery ที่ทำเพื่อคนไทย โดยแนวคิดเพื่อช่วยเหลือพี่น้องชาวไทย ที่ประสบปัญหา ในช่วงโควิด .. ที่แข่งขันกับ App ของต่างชาติ ทุนหนาๆ ได้เลย ..
– ได้ Jeep ZJ มาใช้งานสักที หลังจาก ทำมาเกือบ 2 ปี .. แต่ได้มาปุ๊บ ก็เข้า กทม. ปั๊บ ไม่มีโอกาส ได้ใช้งาน
– รายได้จากงานนอก จากลูกค้า รายเล็กๆ ลดลงเยอะมาก เพราะเจอพิษโควิดกัน
– จากวิกฤติโควิด ทำให้อยากอยู่อย่างสมถะ ไม่อยากได้ อยากมี อะไรที่ไม่จำเป็น เพราะอะไรที่เยอะไปจะเป็นภาระ มากเปล่าๆ

สำหรับ ปี 2022 ที่คาดหวัง ว่าจะทำได้ และอยากทำ
– ตั้งใจ เรื่องการมีครอบครัว ให้มากขึ้น อายุเข้าเลข 4 แล้ว +___+
– หาธุรกิจ ที่ไม่ใช่งาน ด้าน tech อย่างเดียวทำ ให้มีหลากหลายรายได้ เพราะว่า รายได้ จากความรู้ทางเดียว ไม่ยั่งยืน
– อยากลงไปทำสวน ทำการเกษตร จริงๆ จังๆ มากขึ้น
– ทำ product ของตัวเอง ที่พัฒนามา จริงๆ จังๆ ออกสู่ตลาด สักที
– ตั้งใจทำงานประจำ ให้ดีที่สุด ในเมื่อได้รับโอกาสแล้ว ก็ต้องเต็มที่ ต้องทุ่มเท แบบสมัย WeLove
– อยากเดินทาง ถ้ามีโอกาส เพราะพิษโควิด ทำให้ไม่ได้เดินทางมา 2-3 ปีแล้ว
– ช่วยเหลือสังคม เท่าที่จะช่วยได้ ทั้งแรงกาย แรงใจ แรงเงิน

Facebook Comments Box

Lens The Kubernetes IDE + Grafana Dashboard

Lens The Kubernetes IDE

สวัสดีครับ DevOps 101 ของเราวันนี้ นำเสนอ Lens ครับ .. ตอนนี้ ก็ออกมาถึง version 5.x.x กันแล้ว ณ ตอนที่ผมเขียน blog ก็เป็น version 5.1.3 เพื่อนๆ บางท่าน อาจจะเคยใช้งานกันมาบ้างแล้ว .. แต่สำหรับบางท่านที่ยังไม่เคยใช้งาน อาจจะยังสงสัยว่ามันคืออะไรกัน เจ้า Lens .. จากคำอธิบายในเว็บของเค้าคือ ..

“Lens is the only IDE you’ll ever need to take control of your Kubernetes clusters. It’s built on open source and free.”

สรุปสั้นๆ เข้าใจง่ายๆ ก็คือ Lens เป็น IDE ที่ช่วยจัดการ Kubernetes (k8s) cluster ของเรา เป็น Open Source และ Free 🙂
สำหรับท่านที่เคยใช้ kube-proxy ที่เป็น Dashboard ของ k8s เอง .. จะพบว่า มันใช้งานไม่ค่อยสะดวกเท่าไรนัก .. ลองเปลี่ยนมาใช้ Lens ดูครับ จะพบว่าสะดวกกว่ามากๆ ..

สำหรับวิธีการติดตั้ง Lens ก็ไป download ได้เลยครับที่ https://k8slens.dev/ มีทั้งบน Mac OS, Windows และ Linux ครับ .. ตัว Lens เองจะใช้ file config เดียวกับ kubectl ของเราคือจะอยู่ที่ ~/.kube/config ซึ่งถ้าใครใช้งาน kubectl ได้อยู่แล้ว ก็จะไม่มีปัญหา อะไร .. แต่ถ้าเปิด Lens ขึ้นมาแล้ว ยังใช้งานไม่ได้ ก็ให้ไปลองดูที่ ~/.kube/config ว่ามีค่า config ต่างๆ ถูกต้องไหม .. หรือถ้าใครใช้ EKS อยู่ วิธีการง่ายๆ ก็คือ การสั่ง update kube config ครับ ดังตัวอย่าง ..

aws eks update-kubeconfig --name tono-eks \
--region ap-southeast-1 \
--profile tono-admin

สิ่งที่อยากจะนำเสนอเพิ่มเติม สำหรับเจ้า Lens ก็คือ Lens Metrics ซึ่งตรงนี้ จะทำให้เราดู resource ของ k8s cluster เราได้ง่ายขึ้น สะดวกขึ้นครับ .. จริงๆ แล้ว ก็คือการติดตั้ง Prometheus + Kube State Metrics + node exporter เข้าไป เพื่อเก็บ metrics ต่างๆ จาก k8s cluster เราลงบน Prometheus นั่นเองครับ .. มาดูวิธีการ enable ตรงนี้กันครับ ..

1.คลิกขวาที่ icon ของ k8s cluster ของเรา แล้วเลือก Settings

คลิกขวา ที่ icon k8s cluster แล้วเลือก Settings

2.มาที่ Lens Metrics แล้วทำการ Enable PROMETHEUS, KUBE STATE METRICS, NODE EXPORTER จากนั้นกด Apply

Lens Metrics กด Enable ทั้ง 3 อัน

3.กลับมาที่หน้าหลักของ Lens ไปที่ Workloads > Pods ก็จะเห็นว่า pods ต่างๆ ที่เกี่ยวข้องกับ Lens Metrics ของเราเขียวแล้ว

Pods ที่เกี่ยวกับ Lens Metrics เขียวแล้ว

4.กดไปที่ Cluster หรือ Nods ก็จะเห็น Metrics ต่างๆ แสดงผลแล้วครับ

แสดง Metrics ของ k8s cluster ได้แล้ว

ขั้นตอนต่างๆ ก็ง่ายๆ ประมาณนี้ครับ เราก็จะได้ Lens Metrics ที่เป็น Dashboard & Monitoring สำหรับ ดู รายละเอียดต่างๆ ของ k8s cluster ของเรากันแล้วครับ ..

Update!!! (2021-09-25) Grafana Dashboard

วันนี้ มา update การทำ Dashboad & Monitoring ของ k8s cluster ที่จะดูได้ละเอียดกว่านี้ ด้วย Grafana ครับ ..

หลายๆ ท่าน คงอยากมี dashboard (Grafana) เอาไว้ดู metrics ต่างๆ ของ k8s cluster ของเรา ให้คนในทีมได้เอาไว้ดู ในทุกที่ ทุกเวลา .. ซึ่งเราก็สามารถติดตั้งได้ผ่าน Lens เลยครับ โดยมีขั้นตอน เพิ่มเติมดังนี้ ..

1.ไปที่ Apps > Charts แล้ว search “prometheus-operator”

prometheus-operator

2.กด install ใน namespace ที่เราต้องการ ในที่นี้ผม create ns ชื่อ prometheus มาเพิ่มเติม

หรือถ้าอยากลอง install เอง ก็สามารถทำตามขั้นตอน ของ prometheus-operator ได้ตามนี้เลยครับ ..
[Link] https://github.com/prometheus-operator/prometheus-operator

3.ไปที่ Network > Services จะพบ service ที่ชื่อ “prometheus-operator-xxx-grafana”

prometheus-operator-grafana

4.ทำการ login เข้า Grafana โดย default user-password สามารถดูได้ที่ Configuration > Secrets เลือกดู secret “prometheus-operator-xxx-grafana”

prometheus-operator-grafana-password

5.ไปที่ Dashboard จะเห็นว่า มี k8s cluster dashboard ที่จำเป็นมาให้เราเรียบร้อย

Grafana k8s Dashboard & Monitoring

เป็นอย่างไรกันบ้างครับ ไม่ยากเลยใช่ไหมครับ? แต่การที่เราจะ expose Grafana dashboard ของเรา ให้คนอื่น สามารถเข้ามาได้นั้น เราต้องมี ingress มาต่อ กับ service grafana ของเราด้วยนะครับ .. ในครั้งต่อไป ผมจะมาพูดถึงการสร้าง ingress ให้กับ k8s cluster ของเรากันครับ .. 🙂

มาต่อกันครับ ในขั้นตอนการทำให้ Grafana ของเรา สามารถเข้าจากที่ไหน ก็ได้

6. สร้าง Ingress ให้กับ Grafana เรา ให้สามารถเข้าดูจาก public ได้

ในที่นี้ ผมจะ ทำการ create ingress ให้กับ Grafana ของเรากันครับ ด้วย manifest (YAML) ประมาณนี้

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: grafana
  namespace: prometheus
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: grafana.domain.com
      http:
        paths:
          - backend:
              serviceName: prometheus-operator-xxx-grafana
              servicePort: 80

7. ทำการ Add CNAME record ของ Grafana มาที่ Ingress Endpoint ของเรา

อย่างในที่นี้ ผมใช้บริการ DNS ของ CloudFlare อยู่ ผมก็จะไป Add เพิ่ม ประมาณนี้ครับ

CloudFlare DNS
CloudFlare DNS

เพียงเท่านี้ เราก็จะสามารถเรียกใช้งาน URL ของ Grafana จากที่ไหน ก็ได้แล้วครับ ..

Facebook Comments Box

DevOps 101 Jenkins set Time Zone

สวัสดีครับทุกท่าน DevOps 101 ของเราวันนี้ จะมาพูดถึงการ set Time Zone ของ Jenkins กัน .. ผมเชื่อว่าทุกคนคงเคยใช้ Jenkins กันมาแล้ว ก็เลยไม่ได้ลงรายละเอียดตรงส่วนของการใช้งาน Jenkins .. แต่อาจจะเขียนบทความแยก ในส่วนของการ ติดตั้งใช้งาน Jenkins และการสร้าง CI/CD Pipeline บน Jenkins (Jobs) แยกไปอีกบทความนึงนะครับ ..

โดยปกติแล้ว Jenkins จะอ้างอิงเวลา ที่เป็น UTC นะครับ .. เวลาเรา build Jobs เราอาจจะอยากดูเวลาที่เป็นเวลาประเทศไทย (UTC +7) เราก็ต้องนับ +7 เอาเอง ถึงจะเป็นเวลาจริงๆ ณ ตอนนั้น ใน Time Zone ของเรา .. แต่มี trick ง่ายๆ ในการ set ให้ Jenkins แสดงเวลา เป็น Time Zone ของเราครับ แบ่งเป็น 2 วิธีคือ ..

1.Set ให้ทั้งระบบแสดงเวลาให้ default เป็น Time Zone ที่เราต้องการ

เลือก Manage Jenkins > Script Console จากนั้น ใส่ script ดังนี้ครับ แล้วกด Run

System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Asia/Bangkok')

2.Set การแสดงผล ของแต่ละ user ให้เป็น Time Zone ที่เราต้องการ

เลือก People > เลือก user เราเอง > Configure > User Defined Time Zone จากนั้นให้เลือก Time Zone ที่เราต้องการครับ

เสร็จแล้วจะเห็นว่า เวลาที่แสดง จะเป็นเวลาที่ตรงกับเวลา ที่เป็น Time Zone ของเราครับ ตัวอย่างผมใส่ Asia/Bangkok เวลาที่แสดง ก็จะเป็นเวลา ณ ปัจจุบัน ของประเทศไทยครับ

ก็สั้นๆ ง่ายๆ นะครับ ในการปรับเวลาของ Jenkins ให้ตรงกับ Time Zone ของเรา ทำให้เราดูได้ง่ายขึ้นครับ .. 🙂

Facebook Comments Box