News:

Brought to you NINE-T Co.,ltd.

Main Menu

Recent posts

#1
วันนี้เราไปดูวิธีการติดตั้ง Apache Cassandra ซึ่งเป็น NoSQL แบบ distributed กันตัวนี้ต้องบอกว่ามีประโยชน์มาก สำหรับองค์กร นำไปประยุกต์ใช้ได้หลายอย่าง สำหรับการติดตั้งวันนี้เราจะใช้ Debian 13 Trixie กัน

ก่อนอื่นต้องบอกว่า Java ที่มาพร้อม Debian 13 นั้นเป็น JDK 21 ซึ่งเป็นเวอร์ชั่นใหม่มาก แต่ Cassandra จะใช้ JDK 17 เพราะฉะนั้นท่านจะต้องทำการติดตั้ง JDK 17 ก่อน โดยการเพิ่ม repo ใหม่เข้าไป เพราะว่า repo เดิมนั้นจะไม่มี JDK 17

sudo apt install -y wget gpg apt-transport-https lsb-release

sudo mkdir -p /etc/apt/keyrings
wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public \
  | sudo gpg --dearmor -o /etc/apt/keyrings/adoptium.gpg

echo "deb [signed-by=/etc/apt/keyrings/adoptium.gpg] \
  https://packages.adoptium.net/artifactory/deb $(lsb_release -cs) main" \
  | sudo tee /etc/apt/sources.list.d/adoptium.list

แล้วก็ติดตั้ง JDK 17

sudo apt update
sudo apt install -y temurin-17-jdk

กรณีที่ท่านมี Java 21 อยู่แล้วในระบบ ท่านจะต้องเลือก java version ที่ต้องการใช้ ด้วยคำสั่ง

sudo update-alternatives --config java

ต่อมาคือการติดตั้ง Cassandra

ก่อนอื่นต้องเพิ่ม repo ก่อน
echo "deb [signed-by=/etc/apt/keyrings/apache-cassandra.asc] https://debian.cassandra.apache.org 50x main" | sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list

ทำการดาวน์โหลด GPG Key

curl -o /etc/apt/keyrings/apache-cassandra.asc https://downloads.apache.org/cassandra/KEYS

ทำการอัพเดท index ใหม่และติดตั้ง cassandra

sudo apt update
audo apt install cassandra


#2
Cloud Image สำหรับทำ OpenShift (OKD) สามารถดาวน์โหลดได้จาก
https://cloud.centos.org/centos/scos/10/prod/streams/10.0.20251103-0/x86_64/
#3
/etc/ganesha/ceph.conf

#
# It is possible to use FSAL_CEPH to provide an NFS gateway to CephFS. The
# following sample config should be useful as a starting point for
# configuration. This basic configuration is suitable for a standalone NFS
# server, or an active/passive configuration managed by some sort of clustering
# software (e.g. pacemaker, docker, etc.).
#
# Note too that it is also possible to put a config file in RADOS, and give
# ganesha a rados URL from which to fetch it. For instance, if the config
# file is stored in a RADOS pool called "nfs-ganesha", in a namespace called
# "ganesha-namespace" with an object name of "ganesha-config":
#
# %url  rados://nfs-ganesha/ganesha-namespace/ganesha-config
#
# If we only export cephfs (or RGW), store the configs and recovery data in
# RADOS, and mandate NFSv4.1+ for access, we can avoid any sort of local
# storage, and ganesha can run as an unprivileged user (even inside a
# locked-down container).
#

NFS_CORE_PARAM
{
        # Ganesha can lift the NFS grace period early if NLM is disabled.
        Enable_NLM = false;

        # rquotad doesn't add any value here. CephFS doesn't support per-uid
        # quotas anyway.
        Enable_RQUOTA = false;

        # In this configuration, we're just exporting NFSv4. In practice, it's
        # best to use NFSv4.1+ to get the benefit of sessions.
        Protocols = 4;
}

NFSv4
{
        # Modern versions of libcephfs have delegation support, though they
        # are not currently recommended in clustered configurations. They are
        # disabled by default but can be re-enabled for singleton or
        # active/passive configurations.
        # Delegations = false;
        # One can use any recovery backend with this configuration, but being
        # able to store it in RADOS is a nice feature that makes it easy to
        # migrate the daemon to another host.
        #
        # For a single-node or active/passive configuration, rados_ng driver
        # is preferred. For active/active clustered configurations, the
        # rados_cluster backend can be used instead. See the
        # ganesha-rados-grace manpage for more information.
        RecoveryBackend = rados_ng;

        # NFSv4.0 clients do not send a RECLAIM_COMPLETE, so we end up having
        # to wait out the entire grace period if there are any. Avoid them.
        Minor_Versions =  1,2;
}

# The libcephfs client will aggressively cache information while it
# can, so there is little benefit to ganesha actively caching the same
# objects. Doing so can also hurt cache coherency. Here, we disable
# as much attribute and directory caching as we can.
MDCACHE {
        # Size the dirent cache down as small as possible.
        Dir_Chunk = 0;
}

EXPORT
{
        # Unique export ID number for this export
        Export_ID=100;

        # We're only interested in NFSv4 in this configuration
        Protocols = 4;

        # NFSv4 does not allow UDP transport
        Transports = TCP;

        #
        # Path into the cephfs tree.
        #
        # Note that FSAL_CEPH does not support subtree checking, so there is
        # no way to validate that a filehandle presented by a client is
        # reachable via an exported subtree.
        #
        # For that reason, we just export "/" here.
        Path = /;

        #
        # The pseudoroot path. This is where the export will appear in the
        # NFS pseudoroot namespace.
        #
        Pseudo = /cephfs_a/;

        # We want to be able to read and write
        Access_Type = RW;

        # Time out attribute cache entries immediately
        Attr_Expiration_Time = 0;

        # Enable read delegations? libcephfs v13.0.1 and later allow the
        # ceph client to set a delegation. While it's possible to allow RW
        # delegations it's not recommended to enable them until ganesha
        # acquires CB_GETATTR support.
        #
        # Note too that delegations may not be safe in clustered
        # configurations, so it's probably best to just disable them until
        # this problem is resolved:
        #
        # http://tracker.ceph.com/issues/24802
        #
        # Delegations = R;

        # NFS servers usually decide to "squash" incoming requests from the
        # root user to a "nobody" user. It's possible to disable that, but for
        # now, we leave it enabled.
        # Squash = root;

        FSAL {
                # FSAL_CEPH export
                Name = CEPH;

                #
                # Ceph filesystems have a name string associated with them, and
                # modern versions of libcephfs can mount them based on the
                # name. The default is to mount the default filesystem in the
                # cluster (usually the first one created).
                #
                # Filesystem = "cephfs_a";

                #
                # Ceph clusters have their own authentication scheme (cephx).
                # Ganesha acts as a cephfs client. This is the client username
                # to use. This user will need to be created before running
                # ganesha.
                #
                # Typically ceph clients have a name like "client.foo". This
                # setting should not contain the "client." prefix.
                #
                # See:
                #
                # http://docs.ceph.com/docs/jewel/rados/operations/user-management/
                #
                # The default is to set this to NULL, which means that the
                # userid is set to the default in libcephfs (which is
                # typically "admin").
                #
                # User_Id = "ganesha";

                #
                # Key to use for the session (if any). If not set, it uses the
                # normal search path for cephx keyring files to find a key:
                #
                # Secret_Access_Key = "YOUR SECRET KEY HERE";
        }
}

# Config block for FSAL_CEPH
CEPH
{
        # Path to a ceph.conf file for this ceph cluster.
        # Ceph_Conf = /etc/ceph/ceph.conf;

        # User file-creation mask. These bits will be masked off from the unix
        # permissions on newly-created inodes.
        # umask = 0;
}

#
# This is the config block for the RADOS RecoveryBackend. This is only
# used if you're storing the client recovery records in a RADOS object.
#
RADOS_KV
{
        # Path to a ceph.conf file for this cluster.
        # Ceph_Conf = /etc/ceph/ceph.conf;

        # The recoverybackend has its own ceph client. The default is to
        # let libcephfs autogenerate the userid. Note that RADOS_KV block does
        # not have a setting for Secret_Access_Key. A cephx keyring file must
        # be used for authenticated access.
        # UserId = "ganesharecov";

        # Pool ID of the ceph storage pool that contains the recovery objects.
        # The default is "nfs-ganesha".
        # pool = "nfs-ganesha";

        # Consider setting a unique nodeid for each running daemon here,
        # particularly if this daemon could end up migrating to a host with
        # a different hostname (i.e. if you're running an active/passive cluster
        # with rados_ng/rados_kv and/or a scale-out rados_cluster). The default
        # is to use the hostname of the node where ganesha is running.
        # nodeid = hostname.example.com
}

# Config block for rados:// URL access. It too uses its own client to access
# the object, separate from the FSAL_CEPH and RADOS_KV client.
RADOS_URLS
{
        # Path to a ceph.conf file for this cluster.
        # Ceph_Conf = /etc/ceph/ceph.conf;

        # RADOS_URLS use their own ceph client too. Authenticated access
        # requires a cephx keyring file.
        # UserId = "ganeshaurls";
# used if you're storing the client recovery records in a RADOS object.
#
RADOS_KV
{
        # Path to a ceph.conf file for this cluster.
        # Ceph_Conf = /etc/ceph/ceph.conf;

        # The recoverybackend has its own ceph client. The default is to
        # let libcephfs autogenerate the userid. Note that RADOS_KV block does
        # not have a setting for Secret_Access_Key. A cephx keyring file must
        # be used for authenticated access.
        # UserId = "ganesharecov";

        # Pool ID of the ceph storage pool that contains the recovery objects.
        # The default is "nfs-ganesha".
        # pool = "nfs-ganesha";

        # Consider setting a unique nodeid for each running daemon here,
        # particularly if this daemon could end up migrating to a host with
        # a different hostname (i.e. if you're running an active/passive cluster
        # with rados_ng/rados_kv and/or a scale-out rados_cluster). The default
        # is to use the hostname of the node where ganesha is running.
        # nodeid = hostname.example.com
}

# Config block for rados:// URL access. It too uses its own client to access
# the object, separate from the FSAL_CEPH and RADOS_KV client.
RADOS_URLS
{
        # Path to a ceph.conf file for this cluster.
        # Ceph_Conf = /etc/ceph/ceph.conf;

        # RADOS_URLS use their own ceph client too. Authenticated access
        # requires a cephx keyring file.
        # UserId = "ganeshaurls";

        # We can also have ganesha watch a RADOS object for notifications, and
        # have it force a configuration reload when one comes in. Set this to
        # a valid rados:// URL to enable this feature.
        # watch_url = "rados://pool/namespace/object";
}



/etc/ganesha/ganesha.conf

NFS_CORE_PARAM {
    Allow_Set_Io_Flusher_Fail = true;
    Protocols = 4;
}

EXPORT_DEFAULTS {
    Access_Type = RW;
    Attr_Expiration_Time = 0;
    Squash = None;
}

EXPORT {
    Export_Id = 1;
    Path = "/";
    Pseudo = "/cephfs";
    Access_Type = RW;
    Squash = None;
    Protocols = 4;
    Transports = TCP;

    FSAL {
        Name = "CEPH";
        User_Id = "ganesha";
        Filesystem = "cephfs";
        Ceph_Conf = "/etc/ceph/ceph.conf";
    }

    CLIENT {
        Clients = 10.X.X.0/24; # Replace with your network address
        Access_Type = RW;
    }
}

LOG {
    Default_Log_Level = DEBUG;
 Facility {
        name = FILE;
        destination = "/var/log/ganesha.log";
        max_level = FULL_DEBUG;
        enable = active;
    }
}

#4
จากการเข้มงวดเรื่องการใช้งานของ Anydesk มากขึ้นทำให้ ผู้คนกำลังมองหา Remote Access/Remote Assistance/Remote Desktop ซอฟต์แวร์ตัวใหม่ วันนี้เราเลยจะมาแนะนำ RustDesk ซึ่งเป็นซอฟต์แวร์ตัวใหม่ สำหรับการเข้าถึงที่เป็น OpenSource และ ติดตั้งในลักษณะเซิร์ฟเวอร์ของเราได้ด้วย
https://rustdesk.com/
#5
1. เข้าไปที่ command line
2. ดาวน์โหลด acme.sh ที่ https://github.com/acmesh-official/get.acme.sh
3. พิมพ์ เพื่อทำการใช้ dns ในการ gen cert
acme.sh --issue -d mgw.mydom.com --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please
ระบบจะบอกว่า ให้ท่านไปใส่ txt record เพื่อแสดงความเป็นเจ้าของโดเมน
4. ทำการติดตั้ง โดยพิมพ์
acme.sh --renew -d mgw.mydom.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
5. ทำการสำรองpmg-api.pem ที่อยู่ใน folder /etc/pmg ก่อนด้วยคำสั่ง
mv pmg-api.pem pmg-api.pem.bak
6. หลังจาก เราจะได้ไฟล์ /root/.acme.sh/<domain>
ให้เอาไฟล์ที่ชื่อ fullchain.cer ไปรวมกับชื่อ mgw.mydom.com.key
ด้วยคำสั่ง
cat fullchain.cert mgw.mydom.com.key > /etc/pmg/pmg-api.pem

เรียบร้อย เพียงเท่านี้ก็สั่ง restart service
pmgdaemon pmgproxy ก็จะได้ใช้ TLS over SMTP แล้ว
#6
หากเป็น Windows สามารถใช้ PowerShell script ได้เลยครับตามนี้
$sw = [System.Diagnostics.Stopwatch]::StartNew()

$fs = [System.IO.File]::Create("C:\test1.img")
$buffer = New-Object byte[] (1MB)

1..1024 | ForEach-Object {
    $fs.Write($buffer, 0, $buffer.Length)
}

$fs.Flush($true)
$fs.Close()

$sw.Stop()
$speed = 1024 / $sw.Elapsed.TotalSeconds

"Elapsed: $($sw.Elapsed.TotalSeconds) sec"
"Write Speed: $([math]::Round($speed,2)) MB/s"

หลังจากนั้น save ในชื่ออะไรก็ได้เช่น testdiskspeed.ps1

ส่วนบน Linux ใช้คำสั่งนี้ได้เลย
dd if=/dev/zero of=/tmp/test1.img bs=1G count=1 oflag=dsync

ระบบจะทดสอบการเขียนไฟล์ /tmp/test1.img มีขนาด 1G และแสดงความเร็ว
แต่ถ้าอยากทดสอบการอ่านให้ใช้คำสั่ง

dd if=/tmp/test1.img of=/dev/null bs=1G iflag=direct


หากต้องการเพิ่มขนาดไฟล์ก็ปรับตรง count ซึ่งมีคุณสมบัติเป็นตัวคูณนั่นเอง
#7
ปกติ nakivo ผ่าน UI มันจะให้อพัเดทได้เฉพาะภายใน sub version เท่านั้น
เช่นภายใน 11.1.1 ไป 11.1.2-x
แต่ถ้ากระโดดไป 11.2 11.3 ไม่ได้

ถ้าทันจะอัพเดทข้ามดังกล่าว สามารถทำได้โดยการใช้ Updater script ซึ่ง วิธีการทำก็ง่ายมาก
เข้าไปดาวน์โหลดได้ที่ https://www.nakivo.com/resources/download/update/

หลังจากนั้น ถ้าบน Linux ก็ใช้คำสั่ง
wget -o Updater.sh https://d111xps0uy3x00.cloudfront.net/res/product/NAKIVO%20Backup_Replication%20v11.2.1.104556%20Updater.exe
chmod +w ./Updater.sh
sudo Updater.sh

หรือถ้าใครใช้ Linux แบบ graphic ก็ดาวน์โหลดได้โดยตรง
#8
สำหรับ Chipset LSI ที่อยู่ใน ThinkSystem RAID 530 นั้น จะไม่สนับสนุนใน Debian 13 อีกต่อไป เมื่อท่านติดตั้งระบบที่มี OS ที่มีพื้นฐานมาจาก Debian Trixie หรือ Kernel 7 ก็จะไม่สามารถใช้งานได้อีกต่อไป หรือพูดง่ายๆ RAID5/6/10 ที่สร้างขึ้นบน chipset ดังกล่าวไม่สามารถติดตั้งได้ และ อาจจะเกิด error ดังกล่าวข้างบน

วิธีการแก้ : เปลี่ยนเป็น JBOD หรือใช้ hypervisor รุ่นเก่า (ซึ่งไม่แนะนำ)
#9
1. เช็คดูสถานะของ Cilium ก่อนด้วยคำสั่ง
cilium status

ผลลัพธ์ก็จะได้ประมาณนี้
Cilium:             OK
Operator:           OK
Envoy DaemonSet:    OK

เช็คว่ามีการใช้ Proxy Replacement หรือไม่ด้วยคำสั่ง

kubectl -n kube-system get cm cilium-config -o yaml | grep kube-proxy

ผลลัพธ์ควรจะเป็น
kube-proxy-replacement: "true"

เช็คดูว่า Envoy เปิดใช้งานไปหรือยังด้วยคำสั่ง
kubectl -n kube-system get cm cilium-config -o yaml | grep envoy

สิ่งที่ควรได้รับคือ
envoy.enabled: "true"

เช็คว่า Gateway API เปิดใช้หรือยัง
kubectl -n kube-system get cm cilium-config -o yaml | grep gateway

สิ่งที่ควรจะได้รับคือ
gatewayAPI.enable: "true"

2. เปิดการใช้งาน L2 Annoucement ด้วยคำสั่ง
helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values --set l2announcements.enabled=true

เช็คว่ามันได้เปิดไปหรือยัง ด้วยคำสั่ง
kubectl -n kube-system get cm cilium-config -o yaml | grep l2

ผลลัพธ์ที่ได้ควรจะเป็น
enable-l2-announcements: "true"


3. สร้าง LoadBalancer IP Pool
สร้างไฟล์ อาจจะตั้งชื่อว่า cilium-lb-pool.yaml และภายในไฟล์มีเนื้อหาดังนี้
apiVersion: cilium.io/v2alpha1
kind: CiliumLoadBalancerIPPool
metadata:
  name: lan-pool
spec:
  blocks:
  - start: XX.XX.XX.200
    stop: XX.XX.XX.220
โดยที่ XX.XX.XX = subnet class ของท่านใช่ 192.168.10
หลังจากนั้น ทำการ apply เข้าไปด้วยคำสั่ง
kubectl apply -f cilium-lb-pool.yaml

และทดสอบว่ามันได้เปลี่ยนแปลงหรือยัง โดยการพิมพ์
kubectl get ciliumloadbalancerippools

4. สร้าง L2 Announcement Policy
สร้างไฟล์ที่ชื่อว่า cilium-l2-policy.yaml
โดยมีเนื้อหา
apiVersion: cilium.io/v2alpha1
kind: CiliumL2AnnouncementPolicy
metadata:
  name: lan-policy
spec:
  nodeSelector:
    matchLabels: {}

  serviceSelector:
    matchLabels: {}

  interfaces:
  - ens18

  loadBalancerIPs: true

แล้วทำการ apply ด้วยคำสั่ง
kubectl apply -f cilium-l2-policy.yaml

ตรวจสอบด้วยคำสั่ง

kubectl get ciliuml2announcementpolicies

5. ทำการทดสอบด้วย application
kubectl create deployment nginx --image=nginx

6. สร้างบริการ LoadBalancer
kubectl expose deployment nginx --name nginx --type LoadBalancer --port 80 --target-port 80

ทดสอบด้วยคำสั่ง
kubectl describe svc nginx

ผลลัพธ์จะได้ประมาณนี้คือ
Type:           LoadBalancer
Port:           80/TCP
TargetPort:     80/TCP
LoadBalancer Ingress:
                xx.xx.xx.x

7. ตรวจสอบการทำงาน
kubectl get svc nginx
#10
หากท่านได้รับ Error ประมาณนี้
here was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["startvm", "", "--type", "headless"]

Stderr: VBoxManage: error: VirtualBox can't enable the AMD-V extension. Please disable the KVM kernel extension, recompile your kernel and reboot (VERR_SVM_IN_USE)
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component ConsoleWrap, interface IConsole
ให้ท่านแก้ไขโดยการลบ module kvm ดังนี้
sudo rmmod kvm_amd