នៅខែមិថុនា ឆ្នាំ 2022 ខ្ញុំបានជួប Kickstarter អំពីក្តារដែលមានសមត្ថភាពរហូតដល់ 4 Raspberry Pi 4 Compute Modules ក្នុងពេលតែមួយ។
ដោយគ្មានការពិចារណាច្រើនទេ ខ្ញុំបានសម្រេចចិត្តគាំទ្រគម្រោង និងទិញក្តារ។
លឿនជាងពីរឆ្នាំហើយ Turing Pi 2 របស់ខ្ញុំនៅតែអង្គុយមិនបើកក្នុងប្រអប់របស់វានៅលើធ្នើ ហើយខ្ញុំមិនច្បាស់ថាហេតុអ្វីបានជាខ្ញុំទិញវាតាំងពីដំបូង។
ទោះយ៉ាងណាក៏ដោយ ទីបំផុតខ្ញុំបានសម្រេចចិត្តសាកល្បងវា។ ខ្ញុំចង់ស្វែងយល់បន្ថែមអំពីការដាក់ចង្កោម ហើយមិនដែលបានបង្កើតចង្កោម Kubernetes ពេញលេញពីដំបូងឡើយ។ ដូច្នេះខ្ញុំបានចូលទៅក្នុងរបៀបចំណាយ ហើយទទួលបាន Raspberry Pi 4s ចំនួនបី (RAM 8GB, អង្គផ្ទុកទិន្នន័យខាងក្នុង 8GB) និងមួយ Nvidia Jetson Nano (4GB)។
ដោយមើលឃើញពីភាពបត់បែនរបស់ក្រុមប្រឹក្សាភិបាល ខ្ញុំអាចលាយម៉ូឌុលគណនាផ្សេងគ្នា។ ខ្ញុំបានសម្រេចចិត្តដាក់បញ្ចូល Jetson Nano ដោយគិតថាវាអាចអនុញ្ញាតឱ្យខ្ញុំធ្វើការពិសោធន៍ជាមួយអ្នកបើកបរ CUDA នាពេលអនាគត និងស្វែងយល់អំពីម៉ាស៊ីនរៀន។ អ្នកណាដឹង? ខ្ញុំថែមទាំងអាចបញ្ចប់ការបង្ហោះជំនួយការ GPT ផ្ទាល់ខ្លួនរបស់ខ្ញុំនៅលើក្រុម Kubernetes នេះ។
(Spoilers: It didn't happen)
ផែនការដំបូងរបស់ខ្ញុំរួមមាន 3 Pi 4 CM និង Jetson Nano ដែលរៀបចំនៅលើក្តារ។ ដូចគ្នាដែរ ខ្ញុំបានគ្រោងនឹងប្រើដ្រាយ 1TB SSD សម្រាប់ការផ្ទុក និងកាត Wi-Fi សម្រាប់ចូលប្រើអ៊ីនធឺណិត។ ទោះជាយ៉ាងណាក៏ដោយ បន្ទាប់ពីជួបប្រទះការលំបាកជាច្រើនជាមួយនឹងដំណើរការដំឡើងរបស់ Jetson Nano និងឯកសារមិនល្អ ខ្ញុំបានសម្រេចចិត្តប្រគល់វាមកវិញ។ ផ្ទុយទៅវិញ ខ្ញុំបានជ្រើសរើស Raspberry Pi 4 ទីបួន។
លើសពីនេះទៀត ខ្ញុំមាន Raspberry Pi 4 ចាស់ដែលមាន RAM 4GB ស្ថិតនៅជុំវិញ ដូច្នេះខ្ញុំបានសម្រេចចិត្តបញ្ចូលវាជាថ្នាំងទីប្រាំ។
Turing Pi 2 គឺជាបន្ទះកត្តាទម្រង់ Mini ITX ដែលអាចផ្ទុកបានរហូតដល់ទៅបួន Raspberry Pi Compute Modules (ក៏អាចប្រើបានជាមួយ Jetson Nanos និង Turing Compute Module)។ វាមានច្រក PCI Express, ច្រក NVME ពីរ, ច្រក SATA ពីរ និងច្រក USB សម្រាប់បំភ្លឺម៉ូឌុលគណនា។
ថ្នាំង 1 ៖
ច្រក USB 2.0 (សម្រាប់បំភ្លឺម៉ូឌុលកុំព្យូទ័រ)
រន្ធ HDMI (សម្រាប់បំបាត់កំហុស)
ច្រក PCI Express (សម្រាប់កាត Wi-Fi)
ថ្នាំង 2 ៖
ខ្ញុំនឹងប្រើវាសម្រាប់ការផ្ទុក NVME ប៉ុន្តែវាមិនត្រូវគ្នាជាមួយ Raspberry Pi 4s ទេ។
ថ្នាំង 3 ៖
ទោះយ៉ាងណាក៏ដោយ ច្រក SATA អាចត្រូវបានប្រើនៅទីនេះ។ ដូច្នេះ ថ្នាំងនេះនឹងមានដ្រាយចែករំលែក NFS ។
ថ្នាំង 4 ៖
ច្រក USB 3.0 (ប្រសិនបើខ្ញុំត្រូវការវា) ។
Raspberry ចាស់របស់ខ្ញុំ ៖
ទីបំផុត គំនិតគឺរៀបចំម៉ាស៊ីនមេមេឌៀជាមួយកម្មវិធីបន្ថែមមួយចំនួន។
មួយរយៈនេះខ្ញុំបានដាក់កុំព្យូទ័ររួមគ្នា ហើយវាជាលើកទីមួយហើយដែលខ្ញុំបានលេងជាមួយ Compute Modules និងអាដាប់ទ័ររបស់ពួកគេ ដូច្នេះហើយវាពិតជាសប្បាយខ្លាំងណាស់សម្រាប់ចុងសប្តាហ៍។ ដោយសារកាបូបរបស់ខ្ញុំក្តៅ ប៉ុន្តែនៅតែមិនឆេះ ខ្ញុំក៏គិតថា ហេតុអ្វីក៏នរកមិនបន្ថែមស្រោមដ៏ស្រស់ស្អាតសម្រាប់វា?
ដោយទទួលបានកត្តាទម្រង់ Mini ITX នៃក្រុមប្រឹក្សាភិបាល ខ្ញុំអាចបញ្ចូលវាទៅក្នុងករណី ITX ណាមួយដែលខ្ញុំអាចរកបាននៅលើ Amazon ។ Qube 500 បានធ្វើឱ្យខ្ញុំឆ្លងកាត់និងឆ្លងកាត់។ ខ្ញុំកំពុងបង្កើតចង្កោម DIY រួចហើយ ដែលជាករណីដ៏ល្អបំផុតសម្រាប់រឿងនោះ គឺជា DIY ផងដែរ។
ខ្ញុំក៏បានបន្ថែមការផ្គត់ផ្គង់ថាមពល 650W (សរុបលើស) កាត Wi-Fi Mini PCI Express តូចមួយ និង 1TB SATA SSD ។
ការដាក់ 'វត្ថុ' រួមគ្នាគឺសាមញ្ញណាស់។ ការបិទភ្ជាប់កម្ដៅបន្តិចរវាងម៉ូឌុលកុំព្យូទ័រ និងឧបករណ៍កម្តៅរបស់ពួកគេ ហើយតោងវារួមគ្នាជាមួយអាដាប់ទ័ររបស់ពួកគេ មុនពេលរៀបចំពួកវាតាមលំដាប់លំដោយនៅក្នុងក្រុមប្រឹក្សាភិបាល Turing ។
ខ្ញុំបានលើកឡើងពីការបញ្ជាទិញ ព្រោះវាជាផ្នែកសំខាន់នៃគម្រោង។ Turing Pi 2 ផ្តល់នូវការគ្រប់គ្រងច្រករបស់វាចែកចាយទូទាំងម៉ូឌុលគណនា។ ក្នុងករណីនេះ PCI Express 1 ត្រូវបានគ្រប់គ្រងដោយថ្នាំងទីមួយ ខណៈពេលដែលដ្រាយ SSD ត្រូវបានគ្រប់គ្រងដោយថ្នាំងទី 3 ។ ទី 2 អាចគ្រប់គ្រងច្រក NVME និងទី 4 នៅលើ SSD IIRC ផ្សេងទៀត ប៉ុន្តែខ្ញុំគ្មានប្រយោជន៍សម្រាប់ពួកគេទេឥឡូវនេះ។
ខ្ញុំបានដំឡើង Raspberry Pis ពីមុនមក ប៉ុន្តែមិនដែល Compute Modules ទេ។ Turing Pi 2 មានរន្ធ USB នៅខាងក្រោយដែលប្រើសម្រាប់បញ្ចេញពន្លឺនៃម៉ូឌុលគណនា។
ជាអកុសល ខ្ញុំបានព្យាយាមប្រើខ្សែ USB A ទៅ USB A ដែលមិនមែនជាខ្សែផ្ទេរទិន្នន័យ ដូច្នេះខណៈពេលដែលខ្ញុំរង់ចាំ Amazon ផ្តល់ខ្សែ ខ្ញុំបានរកឃើញវិធីមួយផ្សេងទៀតនៃការបំភ្លឺម៉ូឌុលកុំព្យូទ័រ។
Turing Pi 2 មានឧបករណ៍ CLI ដែលអាចប្រើមិនត្រឹមតែដើម្បីបញ្ចេញម៉ូឌុលគណនាប៉ុណ្ណោះទេប៉ុន្តែថែមទាំងគ្រប់គ្រងថាមពលរបស់ពួកគេ កំណត់ពួកវាឡើងវិញ ពិនិត្យមើលស្ថិតិមួយចំនួន និងអ្វីៗផ្សេងទៀត។
ពាក្យបញ្ជាដែលប្រើសម្រាប់ដំឡើង Compute Modules គឺ៖
tpi flash -i /path/to/image -n {nodes 1 to 4}
ដំណើរការត្រង់ស្អាត ខ្ញុំបានគិតខ្លួនឯងមុននឹងដឹងថា រូបភាព Raspbian មិនភ្ជាប់មកជាមួយ SSH ត្រូវបានបើកតាមលំនាំដើម។
ជាការពិតណាស់ នេះមិនមែនជាទំនួលខុសត្រូវរបស់ Turing ទេ។ ខ្ញុំគួរតែរង់ចាំខ្សែនោះ ប៉ុន្តែអូបាទ។
ដើម្បីជួសជុលវា ខ្ញុំត្រូវភ្ជាប់រូបភាពនៅលើម៉ាស៊ីនមូលដ្ឋានរបស់ខ្ញុំ ហើយបន្ថែមឯកសារទទេមួយដែលមានឈ្មោះថា ssh
នៅក្នុងភាគថាសចាប់ផ្ដើម។ វានឹងបើក SSH តាមលំនាំដើម។
sudo mkdir /mnt/pi-boot sudo mount /dev/sdX1 /mnt/pi-boot sudo touch /mnt/pi-boot/ssh sudo umount /mnt/pi-boot
ឥឡូវនេះ ភីសទាំងអស់របស់ខ្ញុំបានត្រៀមរួចរាល់ក្នុងការប្រើប្រាស់។ ខ្ញុំបានភ្ជាប់ពួកវាទៅបណ្តាញ ហើយចាប់ផ្តើមកំណត់រចនាសម្ព័ន្ធពួកវា។ វាមានការកំណត់តិចតួចណាស់ព្រោះខ្ញុំនឹងប្រើពួកវាជាថ្នាំង Kubernetes។
ប៉ុន្តែអ្វីៗដូចជា vim និងការអាប់ដេតប្រព័ន្ធគឺចាំបាច់។
នេះក៏ផ្តល់ឱកាសឱ្យខ្ញុំរៀនពីរបៀបប្រើ Tmux ផងដែរ។ ឧបករណ៍ដ៏ល្អបំផុតដែលខ្ញុំបានរៀនមួយរយៈ។
ប្រសិនបើអ្នករំលឹកកថាខណ្ឌមួយចំនួនខាងលើ ខ្ញុំបានរៀបរាប់ថាថ្នាំងទី 3 នឹងត្រូវបានប្រើសម្រាប់ដ្រាយចែករំលែក NFS ។ ខ្ញុំមានដ្រាយ SSD 1TB ដែលខ្ញុំនឹងប្រើសម្រាប់គោលបំណងនេះ។ ខ្ញុំត្រូវធ្វើទ្រង់ទ្រាយវាហើយដំឡើងវាក្នុងថ្នាំងទី 3 ។
ប៉ុន្តែខ្ញុំក៏ត្រូវដំឡើងម៉ាស៊ីនមេ NFS នៅក្នុងថ្នាំងនេះ ហើយកំណត់រចនាសម្ព័ន្ធវានៅក្នុងថ្នាំងផ្សេងទៀត។ តើវាត្រូវបានណែនាំសម្រាប់បរិយាកាសផលិតកម្មទេ? នរកទេ ប៉ុន្តែវាជាចង្កោមផ្ទះ ដូច្នេះខ្ញុំមិនបារម្ភពេកអំពីវាទេ។
នេះជាជំហានដែលខ្ញុំបានធ្វើដើម្បីកំណត់រចនាសម្ព័ន្ធម៉ាស៊ីនមេ NFS៖
pi@turing-03:/mnt/ssd/data $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 953.9G 0 disk /mnt/ssd mmcblk0 179:0 0 7.3G 0 disk ├─mmcblk0p1 179:1 0 512M 0 part /boot/firmware └─mmcblk0p2 179:2 0 6.8G 0 part / mmcblk0boot0 179:32 0 4M 1 disk mmcblk0boot1 179:64 0 4M 1 disk
ដំបូងខ្ញុំពិនិត្យមើលថាដ្រាយត្រូវបានម៉ោនត្រឹមត្រូវ។ បន្ទាប់មកខ្ញុំបានដំឡើងម៉ាស៊ីនមេ NFS៖
sudo mkdir /mnt/nfs_share sudo mount /dev/sda /mnt/nfs_share
បន្ថែមវាទៅឯកសារ fstab ដើម្បីប្រាកដថាវាត្រូវបានម៉ោននៅពេលចាប់ផ្ដើម៖
(បន្ថែមបន្ទាត់ខាងក្រោមទៅឯកសារ /etc/fstab
)
echo '/dev/sda /mnt/ssd ext4 defaults 0 0' | sudo tee -a /etc/fstab
ឥឡូវនេះ ដំឡើង nfs-kernel-server៖
sudo apt update sudo apt install nfs-kernel-server
ហើយបន្ថែមដ្រាយរបស់ខ្ញុំទៅឯកសារ /etc/exports
៖
echo '/mnt/ssd *(rw,sync,no_subtree_check,no_root_squash)' | sudo tee -a /etc/exports
ឥឡូវនេះនៅលើថ្នាំងផ្សេងទៀតខ្ញុំត្រូវដំឡើង nfs-common:
sudo apt update sudo apt install nfs-common
ហើយភ្ជាប់ drive ទៅថ្នាំងនីមួយៗ៖
sudo mount -t nfs {IP-for-the-drives-node}:/mnt/ssd /mnt
Neofetch ត្រូវបានដំឡើងនៅគ្រប់ថ្នាំងទាំងអស់ ដោយសារខ្ញុំចូលចិត្ត
ខ្ញុំមិនដែលបង្កើតក្រុម Kubernetes ពីដំបូងពីមុនមកទេ ប៉ុន្តែខ្ញុំបានមើល វីដេអូជាច្រើនរបស់ Jeff Geerling លើប្រធានបទ... នេះជាបទពិសោធន៍គ្រប់គ្រាន់ហើយមែនទេ?
Jeff បាននាំខ្ញុំទៅ K3s ដោយប្រើ Ansible ដែលជាការចែកចាយ Kubernetes ទម្ងន់ស្រាលដែលល្អឥតខ្ចោះសម្រាប់ចង្កោមផ្ទះរបស់ខ្ញុំ និងវិធីដែលបានកំណត់ជាមុនក្នុងការដំឡើងវា ដោយសារខ្ញុំមិនមានតម្រូវការជាមុន ឬគំនិតនៃរបៀបដំឡើងវាផ្សេង។
ការដំឡើងគឺសាមញ្ញណាស់។ ខ្ញុំត្រូវដំឡើងវានៅគ្រប់ថ្នាំងទាំងអស់ ប៉ុន្តែខ្ញុំត្រូវប្រាកដថាថ្នាំងមេជាថ្នាំងដំបូងដែលត្រូវដំឡើង។
ដូច្នេះដំបូង ខ្ញុំបានក្លូនឃ្លាំង k3s-ansible៖
git clone https://github.com/k3s-io/k3s-ansible.git
បន្ទាប់មកខ្ញុំត្រូវកំណត់រចនាសម្ព័ន្ធឯកសារសារពើភ័ណ្ឌ។ ថ្នាំងមេរបស់ខ្ញុំ ដូចដែលខ្ញុំបានលើកឡើងពីមុនគឺជា Raspberry Pi 4 ចាស់របស់ខ្ញុំ។ ដូច្នេះខ្ញុំត្រូវប្រាកដថាវាជាថ្នាំងទីមួយនៅក្នុងឯកសារសារពើភ័ណ្ឌ។ ខ្ញុំក៏ត្រូវប្រាកដថាថ្នាំងផ្សេងទៀតស្ថិតនៅក្នុងក្រុមត្រឹមត្រូវ។៖
k3s_cluster: children: server: hosts: 192.168.2.105: agent: hosts: 192.168.2.101: 192.168.2.102: 192.168.2.103: 192.168.2.104:
ក្នុងឯកសារដដែលនោះ ខ្ញុំត្រូវដំឡើងសញ្ញាសម្ងាត់ការអ៊ិនគ្រីប។ ឯកសារបង្ហាញពីរបៀបធ្វើវា ដូច្នេះខ្ញុំនឹងមិនចូលទៅក្នុងព័ត៌មានលម្អិតនៅទីនេះទេ។
បន្ទាប់មកខ្ញុំត្រូវដំណើរការសៀវភៅលេង៖
cd k3s-ansible ansible-playbook playbooks/site.yml -i inventory.yml
នោះហើយជាវា។ ដរាបណាការដំឡើងដំណើរការ ខ្ញុំមានចង្កោម Kubernetes និងដំណើរការ។ ខ្ញុំត្រូវដំឡើង K9s នៅលើម៉ាស៊ីនមូលដ្ឋានរបស់ខ្ញុំ ដើម្បីគ្រប់គ្រងចង្កោម និងចងចង្កោមទៅឯកសារ ./kube/config
។
ចុងក្រោយ ខ្ញុំត្រូវដំឡើងកម្មវិធីដែលខ្ញុំចង់ដំណើរការក្នុងចង្កោម។ ខ្ញុំមានគំនិតមួយចំនួនលើអ្វីដែលខ្ញុំចង់បាន។
នោះហើយជាកន្លែងដែល ឃ្លាំងរបស់ខ្ញុំ ចូលមក។
សម្រាប់ Media Server ខ្ញុំបានសម្រេចចិត្តប្រើ៖
ជាឧទាហរណ៍ ខ្ញុំនឹងបង្ហាញអ្នកពីរបៀបដែលខ្ញុំបានដំឡើង Sonarr ដោយប្រើ kubectl
។ កម្មវិធីផ្សេងទៀតត្រូវបានដំឡើងតាមរបៀបស្រដៀងគ្នា។
សម្រាប់កម្មវិធីនីមួយៗ ខ្ញុំបានបង្កើតឯកសារចំនួន 3៖
deployment.yaml
គឺជាការកំណត់រចនាសម្ព័ន្ធសម្រាប់ pods នីមួយៗដែលកំពុងដំណើរការកម្មវិធី
apiVersion: apps/v1 kind: Deployment metadata: name: sonarr spec: replicas: 1 selector: matchLabels: app: sonarr template: metadata: labels: app: sonarr spec: containers: - name: sonarr image: linuxserver/sonarr ports: - containerPort: 8989 env: - name: PUID value: "911" - name: PGID value: "911" - name: TZ value: "Europe/Amsterdam" volumeMounts: - mountPath: /data name: data - name: config mountPath: /config volumes: - name: data persistentVolumeClaim: claimName: nfs-pvc - name: config persistentVolumeClaim: claimName: nfs-config-pvc
service.yaml
គឺជាការកំណត់រចនាសម្ព័ន្ធសម្រាប់សេវាកម្មដែលនឹងបង្ហាញកម្មវិធីទៅចង្កោម
apiVersion: v1 kind: Service metadata: name: sonarr spec: selector: app: sonarr ports: - port: 80 targetPort: 8989 type: ClusterIP
ingress.yaml
ហើយនេះគឺជាការកំណត់រចនាសម្ព័ន្ធសម្រាប់ ingress ដែលនឹងបង្ហាញកម្មវិធីទៅកាន់បណ្តាញរបស់ខ្ញុំ
បន្ទាប់មកយើងដាក់ពង្រាយពួកវាទាំងអស់ដោយប្រើ kubectl
៖
kubectl apply -f sonarr/deployment.yaml kubectl apply -f sonarr/service.yaml kubectl apply -f sonarr/ingress.yaml
ដូចដែលអ្នកអាចមើលឃើញ ខ្ញុំកំពុងប្រើការផ្ទុកជាប់លាប់ដែលគាំទ្រដោយ NFS សម្រាប់ទិន្នន័យ និងការកំណត់រចនាសម្ព័ន្ធកម្មវិធី។
នៅក្នុងឃ្លាំង អ្នកអាចរកឃើញឯកសារ nfs-pv.yaml និង nfs-pvc.yaml ដែលខ្ញុំធ្លាប់បង្កើតកន្លែងផ្ទុក NFS ។
លើសពីនេះទៀត ខ្ញុំបានបង្កើតការទាមទារកម្រិតសំឡេងជាប់លាប់មួយផ្សេងទៀតសម្រាប់ការកំណត់រចនាសម្ព័ន្ធនៃកម្មវិធី។
ទោះបីជាករណីនេះមើលទៅអស្ចារ្យក៏ដោយ វាពិតជាធំពេកសម្រាប់ Raspberry Pi Cluster ។ ស្រោម ITX ខ្នាតតូចនឹងសាកសមនឹងតម្រូវការរបស់ខ្ញុំផងដែរ ប៉ុន្តែខ្ញុំត្រូវតែទទួលស្គាល់ថា ខ្ញុំជាអ្នកជញ្ជក់យកវត្ថុ DIY ។
ដូចគ្នានេះផងដែរ Sucker សម្រាប់ LEDs ជាទូទៅ។ ខ្ញុំមិនបានបន្ថែមភ្លើងបន្ថែមទៅលើករណីនេះទេ ប៉ុន្តែខ្ញុំគិតថាបន្ទះនេះធ្វើបានល្អហើយ។ ជាអកុសល ម្ជុលកង្ហារមិនត្រូវគ្នាជាមួយក្តារ ហើយខ្ញុំមិនបានទិញឧបករណ៍បញ្ជាកង្ហារ ឬម្ជុលសម្រាប់ motherboard ទេ។ ខ្ញុំប្រហែលជានាពេលអនាគត។
ពេលខ្លះអ្នកគ្រាន់តែអង្គុយមើលទេសភាព។
ហើយទីបំផុត ចង្កោមផ្ទះ Turing Pi 2 បានដំណើរការហើយ ហើយផ្ទះរបស់ខ្ញុំមិនរញ៉េរញ៉ៃទៀតទេ។
មានតែពេលវេលាទេដែលនឹងប្រាប់ពីអ្វីដែលខ្ញុំនឹងធ្វើជាមួយចង្កោមនេះ។
ទោះយ៉ាងណាក៏ដោយ ខ្ញុំបានគិតពីការបន្ថែម Prometheus និង Grafana ដើម្បីឱ្យមានម៉ែត្រ និងក្រាហ្វល្អ ៗ ដើម្បីពិនិត្យមើលលើចង្កោម។
ការផ្ទេរឯកសារ Kubernetes របស់ខ្ញុំទាំងអស់ទៅ Helm ក៏ជាគំនិតដ៏ល្អផងដែរ។
ជាចុងក្រោយ គំរូ Retroarch នៅតែដំណើរការ។ ប្រហែលជានៅក្នុងការងារគឺមានសុទិដ្ឋិនិយមបន្តិចដោយសារតែ pod រស់នៅក្នុងរដ្ឋ CrashLoopBackOff ។ ប៉ុន្តែខ្ញុំនឹងទៅដល់ទីនោះ។
ប្រសិនបើអ្នកបានឈានដល់ចុងបញ្ចប់នៃប្រកាសនេះ ខ្ញុំសូមអរគុណអ្នកសម្រាប់ពេលវេលារបស់អ្នក។ ខ្ញុំសង្ឃឹមថាអ្នកបានរីករាយនឹងវាដូចដែលខ្ញុំបានធ្វើទាំងពីររួមគ្នា ហើយសរសេរអំពីវា។