#chuyencuasys.com

“DevOps is bullshit”

[Fix lỗi] rpmdb: Thread/process xxx failed: Thread died in Berkeley DB library September 19, 2018

Hỏi nhỏ

Bạn có biết command này để làm gì ko?

rpm -q –queryformat ‘%{VERSION}’ centos-release

Command này để lấy được version CentOS của server , thường được tìm thấy trong /etc/centos-release, ví dụ, đây là con server của mình.

cat /etc/centos-release

CentOS release 6.9 (Final)

Nhưng không may là khi chạy thì nó gặp lỗi sau:

rpmdb: Thread/process 15564/140193669781248 failed: Thread died in Berkeley DB library
error: db3 error(-30974) from dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
error: cannot open Packages index using db3 – (-30974)
error: cannot open Packages database in /var/lib/rpm
rpmdb: Thread/process 15564/140193669781248 failed: Thread died in Berkeley DB library
error: db3 error(-30974) from dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
error: cannot open Packages database in /var/lib/rpm
package centos-release is not installed

🙁 Có vẻ như là DB của rpm có vấn đề.

Cách giải quyết

Mình thử yum clean all thử:

yum clean all

rpmdb: Thread/process 15564/140193669781248 failed: Thread died in Berkeley DB library
error: db3 error(-30974) from dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
error: cannot open Packages index using db3 – (-30974)
error: cannot open Packages database in /var/lib/rpm
CRITICAL:yum.main:

Error: rpmdb open failed

Éc, rõ ràng là rpmdb ko thể mở được rồi, giờ chỉ có cách xóa đi và rebuild lại thôi.

Mình thử các command sau:

[[email protected] ~]# mkdir /var/lib/rpm/backup
[[email protected] ~]# cp -a /var/lib/rpm/__db* /var/lib/rpm/backup/
[[email protected] ~]# rm -f /var/lib/rpm/__db.[0-9][0-9]*
[[email protected] ~]# rpm –quiet -qa
[[email protected] ~]# rpm –rebuilddb

 

[[email protected] ~]# yum clean all

Loaded plugins: fastestmirror, security
Cleaning repos: base centos-sclo-rh centos-sclo-sclo epel extras google-cloud-compute labs_consol_stable updates
Cleaning up Everything
Cleaning up list of fastest mirrors

Sau đó check lại:

rpm -q –queryformat ‘%{VERSION}’ centos-release

6

Ra kết quả rồi này 😀

Cảm ơn bài viết đã giúp mình xử lý vấn đề trong 1p.

 

No Comments on [Fix lỗi] rpmdb: Thread/process xxx failed: Thread died in Berkeley DB library
Tags: ,
Categories: Linh tinh

Đằng sau hệ thống Stack Overflow trông như thế nào? (Part 2) August 30, 2017

Tiếp tục câu chuyện ở part 1, trong bài viết này sẽ trình bày các thành phần tiếp theo của hệ thống Stack Overflow theo kiến trúc được cập nhật đến năm 2016.

Cache & Pub/Sub (Redis)

SO sử dụng Redis cho 2 việc là caching và pub/sub cho hệ thống, mặc dù chịu tải khoảng 160 tỷ câu lệnh trong vòng 1 tháng, những mỗi instance chỉ chạy khoảng 2% CPU, ở mức rất thấp. (Chắc chỉ tốn RAM).

SO sử dụng Redis làm caching 2 lớp L1/L2, L1 sử dụng cho HTTP Cache cho web server và bất kỳ ứng dụng nào đang chay, còn L2 dùng để lấy giá trị từ Redis, có thể hiểu là L1 dùng để write, còn L2 dùng để read. Giá trị của key trong Redis theo định dạng protobuf thông qua thư viện protobuf-dot-net của Marc Gravell.  Thư viện sử dụng cho client là StackExchange.Redis là một opensource và tự phát triển. Khi mà web server bị miss ở cả 2 L1 và L2, chúng sẽ lấy dữ liệu từ database thông qua query hoặc gọi API…và ghi kết quả vào cache local và Redis, khi đó 1 web server khác muốn lấy giá trị nào đó, có thể miss ở L1 nhưng chắc chắn sẽ lấy được ở L2 hoặc database hoặc thông qua việc gọi API.

Các trang Q&A đều có caching theo dạng key prefix thì đặt ở L1 còn L2 thì chứa database ID.

Bên cạnh 2 server Redis chạy master/slave cho toàn bộ các site hiện có, thì SO còn có thêm 1 server slave machine learning sử dụng cho việc thể hiện các câu hỏi khuyến nghị, job matching …được gọi là Providence.

Server Redis chính thì có 256GB RAM (96GB đã sử dụng) và Providence thì có 384GB RAM (125GB đã sử dụng).

Và tất nhiên không chỉ dùng để caching, SO còn dùng Redis theo cơ chế pub/sub để public 1 message cho toàn bộ subcriber bao gồm đã downstream ở Redis slave, SO dùng cơ chế này để xóa 1 lưu trữ trên L1 của 1 web server khi 1 web server khác bị loại bỏ khỏi tính đồng bộ của hệ thống.

Redis isn’t just for cache though, it also has a publish & subscriber mechanism where one server can publish a message and all other subscribers receive it—including downstream clients on Redis slaves. We use this mechanism to clear L1 caches on other servers when one web server does a removal for consistency, but there’s another great use: websockets.

(Đoạn này hơi rắc rối, mình xin phép để nguyên văn)

NetGain WebSockets

SO sử dụng websocket để push real-time cập nhật  của user ví dụ như các thông báo trên top bar, số lượng vote, hay câu hỏi hay câu trả lời mới và 1 vài thứ khác.

Và các server socket này sử dụng raw socket và chạy trên các web tier sử dụng thư viện StackExchange.NetGain, trong peak time( giờ cao điểm) ,số lượng kết nối đồng thời lên tới 500.000, và có những kết nối kéo dài 18 tháng, tác giả không chắc là người đó có tắt browser của mình hay có còn sống không nữa?

Search (Elasticsearch)

Nói chung là không có điều gì thú vị ở đây cả, SO sử dụng Elasticsearch 1.4 và thư viện StackExchange.Elastic cho client và sử dụng cho đường /search trên website, tính toán các câu hỏi có liên quan, và đề xuất khi đặt câu hỏi.

Mỗi cụm cluster ES đều có 3 node trên từng datacenter , và mỗi site đều đánh 1 index. Như site Careers thì có nhiều index hơn và được cấu hình theo 1 cách khác không theo dạng chuẩn, với 3 cụm cluster lớn hơn với SSD và 192 GB RAM và 2x10GBps cho card mạng.

Lý do chính để sử dụng ES là cho việc tìm kiếm full-text SQL một cách dễ dàng và ít chi phí hơn so với việc sử dụng database SQL. Vậy tại sao lại không dùng Solr thay thế cho ES? Việc này có thể xảy ra trong tương lai với version 2.x.

Databases (SQL Server)

SO sử dụng SQL Server là Single_source_of_truth , mọi dữ liệu trên Redis hay ES đều đến từ database và có 2 cụm cluster SQL Server được cài đặt, với mỗi cluster đều có 1 master và 1 replica ở New York, thêm vào đó là 1 replica ở Colorado, và tất cả các bản sao đều chạy bất đồng bộ.

Cụm đầu tiên bao gồm server Dell R720xd, mỗi con có 384GB Ram, 4TB PCIe SSD và 2×12 cores, chúng chứa Stack Overflow, Sites, PRIZM, và dữ liệu Mobile.

Cụm thứ 2 bao gồm server Dell R730xd, mỗi con có 768GB RAM, 6TB PCIe SSD và 2×8 core, chạy những thứ còn lại, bao gồm Talent, OpenID, Chat, Exception log và toàn bộ các trang Q&A ví dụ Super UserServer Fault

 

Mức sử dụng CPU hiện tại còn khá cao mặc dù đã được optimize, có thể thấy trong biểu đồ sau, với 04 là master, 01 và 03 là replica.

Thư viện

Dưới đây là toàn bộ các thư viện tự phát triển hoặc opensource được sử dụng cho SO.

  • Dapper (.Net Core) – High-performance Micro-ORM for ADO.Net
  • StackExchange.Redis – High-performance Redis client
  • MiniProfiler – Lightweight profiler we run on every page (also supports Ruby, Go, and Node)
  • Exceptional – Error logger for SQL, JSON, MySQL, etc.
  • Jil – High-performance JSON (de)serializer
  • Sigil – A .Net CIL generation helper (for when C# isn’t fast enough)
  • NetGain – High-performance websocket server
  • Opserver – Monitoring dashboard polling most systems directly and feeding from Orion, Bosun, or WMI as well.
  • Bosun – Backend monitoring system, written in Go

 

Sau một bài viết khá dài và chi tiết của tác giả Nick Craver, chúng ta có thể thấy được toàn bộ những gì phía sau của 1 hệ thống website vô cùng đồ sộ và đáp ứng được hàng triệu người dùng trên toàn thế giới. Bài viết của mình xin dừng ở đây và hi vọng sẽ trở lại với việc tìm hiểu những hệ thống lớn khác.

No Comments on Đằng sau hệ thống Stack Overflow trông như thế nào? (Part 2)

Đằng sau hệ thống Stack Overflow trông như thế nào? (part 1)

Không cần phải giới thiệu nhiều về Stack Overflow (SO), bởi vì nó quá nổi tiếng và phổ biến trong cộng đồng developer và có nguyên cụm từ “The full stackoverflow developer” để mô tả những developer sống không thể thiếu website này 😀 System Engineer cũng không ngoại lệ đâu nhé!

Vậy bạn có bao giờ tự hỏi Đằng sau SO là 1 hệ thống được xây dựng như thế nào chưa? Bài viết của Nick Craver, Architecture Lead, Developer, Site Reliability Engineer & DBA Stack Overflow viết năm 2016 trên website của ổng sẽ bật mí cho chúng ta biết phía sau cô gái ấy có gì. Trong bài viết này mình sẽ tóm tắt lại những ý chính trong bài viết trên, chi tiết thì các bạn có thể theo dõi trực tiếp theo link phía trên nhé.

SO là 1 hệ thống khổng lồ, phục vụ hàng triệu người dùng, được thể hiện qua các con số biết nói như sau, số liệu vào năm 2016:

  • 209,420,973 HTTP requests tới gateway ( load balancer)
  • 66,294,789 page loads
  • 1,240,266,346,053  bytes (1.24 TB) HTTP traffic gửi đến
  • 569,449,470,023 bytes (569 GB) tổng nhận
  • 3,084,303,599,266  bytes (3.08 TB) tổng gửi
  • 504,816,843  SQL Queries (từ HTTP requests)
  • 5,831,683,114  Redis hits
  • 17,158,874 Elastic searches
  • 3,661,134 Tag Engine requests
  • 607,073,066 ms (168 hours) xử lý SQL queries
  • 10,396,073 ms (2.8 hours) xử lý Redis hits
  • 147,018,571 ms (40.8 hours) xử lý Tag Engine requests
  • 1,609,944,301  ms (447 hours) xử lý trong ASP.Net
  • 22.71 ms trung bình (19.12 ms trong ASP.Net) cho 49,180,275 truy cập trang câu hỏi
  • 11.80 ms trung bình (8.81 ms trong ASP.Net) cho 6,370,076 truy cập trang home

Thật đáng kinh ngạc, để đạt được những con số này, thật không đơn giản, chúng ta cùng xem nhé. Bắt đầu nào!!

Dưới đây là sơ đồ logic tổng quan của hệ thống SO. Bao gồm:

“Everything is redundant” mọi thứ đều dư thừa là tôn chỉ của SO trong xây dựng hệ thống, luôn luôn là vậy trong mọi cài đặt.

  • Tất cả các server hay thiết bị mạng đều có tối thiểu 2x 10 Gbps cho card mạng.
  • Tất cả các server đều có 2 nguồn cấp điện thông qua 2 hệ thống UPS được hỗ trợ bởi 2 hệ thống cấp điện và 2 nguồn tiện ích khác.
  • Tất cả các server đều có dự phòng giữa 2 rack A và B.
  • Tất cả các server và dịch vụ đều có dự phòng ở datacenter khác (Colorado backup cho New York).

Kết nối Internets

Mỗi request khi truy cập vào trang web, sẽ đến với DNS đầu tiên, ta có thể thấy là stackoverflow.com được trỏ tới 4 ip .69 (có vẻ như mấy ổng thích con số này), truy cập nhanh chóng phục vụ cho toàn bộ user trên toàn thế giới, sử dụng CloudFlare làm DNS, tuy nhiên thì vẫn có những server chạy DNS dự phòng cho trường hợp có sự cố xảy ra.

Sau đó request sẽ đi đến từ 1 trong 4 nhà cung cấp mạng và đi qua 1 trong 4 router tương ứng. SO sử dụng đường truyền thì được cung cấp bởi 4 nhà mạng ISP tại New York đó là Level 3, Zayo, Cogent, và Lightower và sử dụng giao thức BGP để định tuyến. Tiếp đó sử dụng 2 cặp router  ASR-1001  và ASR-1001-X và mỗi cái thì gắn 2 nhà mạng dưới dạng active/active và băng thông của mỗi line là 10Gbps.

Tiếp đó, request sẽ được đón nhận tại load balancer.

Haproxy

Haproxy được dùng làm load balancer, đang chạy version 1.5.15 trên Centos 7 và sẽ sớm chuyển sang version 1.7 có hỗ trợ http/2. Tất cả các traffic TLS(SSL) đều được chặn và xử lý tại đây.

Khác với những server khác, sử dụng 2 interface 10 GBps chạy LACP, thì server LB này có 1 interface dành cho external và 1 dành cho DMZ, có thể giải thích là 1 card public, 1 card private. Với bộ nhớ từ 64GB trở lên để cache lại TLS và SSL.

Việc cài đặt haproxy tương đối đơn giản, chỉ cần bắt đúng Host header và route chúng tới backend dựa trên ip và domain từ DNS.

Web Tier (IIS 8.5, ASP.Net MVC 5.2.3, và .Net 4.6.1)

Load balancer sẽ đá các request xuống 9 web server primary chạy production và 2 server phụ dành cho môi trường dev/staging. Các site trên IIS cụ thể cho 2 môi trường như sau:

Các web server như sau:

Service Tier (IIS, ASP.Net MVC 5.2.3, .Net 4.6.1, and HTTP.SYS)

Phía dưới của các web tier đó chính là các service chạy dưới IIS 8.5 trên Windows 2012 R2. Các serivce này chỉ chạy và xử lý nội bộ và phục vụ cho web server. Có 2 dịch vụ lớn đó là “Stack server” chạy trên HTTP.SYS và Providence API chạy trên IIS.

Mời các bạn theo dõi tiếp ở part 2

Bài viết ở trên còn nhiều trúc trắc do khả năng đọc hiểu của mình còn chưa tốt, nên mong nhận được sự góp ý của mọi người để mình có thể viết tốt hơn. Thanks.

No Comments on Đằng sau hệ thống Stack Overflow trông như thế nào? (part 1)

[HA] – Sử dụng Anycast, OSPF, Quagga để load balancing cho hệ thống – P2 August 2, 2017

Tiếp tục ở phần 1, sau đây tôi sẽ hướng dẫn chi tiết cài đặt, cũng như cấu hình Anycast, OSPF, và Quagga để load balancing cho hệ thống. Chúng ta cùng xem lại mô hình:

Các máy chủ GW1 và GW2 đều chạy HDH Centos 7.2, dùng nginx làm Reverse proxy để load balancing cho các Web Server ở Backend. Phần cấu hình Reverse proxy và ở dưới Backend, tôi không đề cập trong bài viết này.

  1. Cấu hình địa chỉ IP anycast + allow iptables trên GW1 và GW2
  • Config Anycast IP

Ta gán địa chỉ Anycast IPv4 cho card mạng, địa chỉ anycast có thể trùng subnet hoặc khác subnet với interface khác của server. Anycast thường được cấu hình trên interface loopbacks.

#ifconfig lo:2 172.30.27.219 netmask 255.255.255.255 up

#ifconfig

Cách cấu hình trên sẽ bị mất khi restart lại network, nếu muốn không bị mất, hãy vào /etc/sysconfig/network-script để tạo file cấu hình cho card lo:2.

  • Cấu hình iptables

#iptables -A INPUT -p 89 -j ACCEPT

  • Allow forward ip

#echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf

#sysctl -p

  • Tắt Selinux
  1. Compile Quagga + OSPF trên GW1 và GW2
  • Khai báo services

#vi /etc/services

zebrasrv       2600/tcp        # zebra service
zebra           2601/tcp        # zebra vty
ospfd           2604/tcp        # OSPFd vty
ospfapi        2607/tcp        # ospfapi
isisd            2608/tcp        # ISISd vty
pimd           2611/tcp         # PIMd vty
nhrpd         2612/tcp         # nhrpd vty

 

  • Compile quagga

Mặc định nếu dùng yum để install quagga, chúng ta sẽ có quagga version 0.99. Vì để cài đặt version mới nhất, nên tôi compile.

Update và cài đặt các gói cần thiết:

#yum update

#yum groupinstall “Development Tools”

#yum install c-ares-devel.x86_64

#useradd -s /sbin/nologin quagga

#mkdir /usr/local/quagga

#chown -R quagga:quagga /usr/local/quagga

#mkdir /usr/local/quaggaconf

#chown -R quagga:quagga /usr/local/quaggaconf

#chmod 755 -R /usr/local/quagga

#chmod 755 -R /usr/local/quaggaconf/

#chmod 755 -R /usr/local/quaggaconf

#mkdir /var/run/quagga

#chmod -R 755 /var/run/quagga

#chown -R quagga:quagga /var/run/quagga

#mkdir /var/log/quagga

#chmod 755 -R /var/log/quagga

#chown quagga:quagga -R /var/log/quagga

Download source:

#wget http://download.savannah.gnu.org/releases/quagga/quagga-1.2.1.tar.gz

#tar -xvzf quagga-1.2.1.tar.gz

#cd quagga-1.2.1

#./configure –prefix=/usr/local/quagga –sysconfdir=/usr/local/quaggaconf –localstatedir=/var/run/quagga –disable-ripd –disable-ripngd –disable-ospf6d

#make

#make install

Giải thích các giá trị ở trên:

–prefix=/usr/local/quagga: Thư mục cài đặt quagga

–sysconfdir=/usr/local/quaggaconf: Thư mục chứa các file cấu hình của các daemon zebra, ospfd, ripd…

–localstatedir=/var/run/quagga: Thư mục chứa file pid

Cấu hình zebra và ospfd như sau:

Do chỉ sử dụng routing ospf, nên ta chỉ cần cấu hình zebra và ospfd, không quan tâm tới các daemon khác của quagga.

Tại GW1

  • Config Zebra

Khai báo các card mạng trong zebra.conf

#vi //usr/local/quaggaconf/zebra.conf

 

hostname GW1
log file /var/log/quagga/zebra.log
log stdout
log record-priority
!
interface eno16777984
ip address 172.30.27.47/32
!
interface lo
!
interface lo:2
ip address 172.30.27.219/32
!
ip forwarding
!
line vty
!

  • Config ospfd

Ospfd chỉ ra các trường của giao thức ospf. Ospfd cần phải lấy các thông tin trên zebra, vì vậy zebra phải chạy trước khi khởi động ospfd. Ngoài ra, nếu zebra khởi động lại, ospfd cũng phải vậy.

#vi /usr/local/quaggaconf/ospfd.conf

hostname GW1
log file /var/log/quagga/ospfd.log
!
interface eno16777984
ip ospf hello-interval 1
ip ospf dead-interval 5
!
router ospf
ospf router-id 172.30.27.47
redistribute connected
network 172.30.27.0/24 area 172.30.27.0
!

Ở trên là các trường cơ bản để có thể routing ospf, các bạn có thể tìm hiểu thêm về giao thức ospf để cấu hình tuỳ theo nhu cầu của hệ thống, có thể thêm các tham số mã hoá MD5, cấu hình authentication, access-list…

Tạo systemd service file cho zebra và ospfd :

#vim /usr/lib/systemd/system/zebra.service

[Unit]
Description=GNU Zebra routing manager
Wants=network.target
Before=network.target
After=network-pre.target
ConditionPathExists=/usr/local/quaggaconf/zebra.conf

[Service]
PIDFile=/var/run/quagga/zebra.pid
Type=forking
ExecStart=/usr/local/quagga/sbin/zebra -d -A 127.0.0.1 -f /usr/local/quaggaconf/zebra.conf
Restart=on-abort

[Install]
WantedBy=multi-user.target

#vim /usr/lib/systemd/system/ospfd.service

[Unit]
Description=OSPF routing daemon
BindsTo=zebra.service
Wants=network.target
After=zebra.service network-pre.target
Before=network.target
ConditionPathExists=/usr/local/quaggaconf/ospfd.conf

[Service]
Type=forking
PIDFile=/var/run/quagga/ospfd.pid
ExecStart=/usr/local/quagga/sbin/ospfd -d -A 127.0.0.1 -f /usr/local/quaggaconf/ospfd.conf
Restart=on-abort

[Install]
WantedBy=multi-user.target

Start zebra và ospfd

#systemctl daemon-reload

#systemctl enable zebra

#systemctl enable ospfd

#service zebra start

#service ospfd start

Thực hiện tương tự như vậy đối với GW2: 

#vi /usr/local/quaggaconf/zebra.conf

hostname GW2
log file /var/log/quagga/zebra.log
log stdout
log record-priority
!
interface eno16777984
ip address 172.30.27.42/32
!
interface lo
!
interface lo:2
ip address 172.30.27.219/32
!
ip forwarding
!
line vty
!

#vi /usr/local/quaggaconf/ospfd.conf

hostname GW2
log file /var/log/quagga/ospfd.log
!
interface eno16777984
ip ospf hello-interval 1
ip ospf dead-interval 5
!
router ospf
ospf router-id 172.30.27.47
redistribute connected
network 172.30.27.0/24 area 172.30.27.0
!

Tạo file systemd và start zebra, ospfd…

  1. Cấu hình Router

router ospf 1
router-id 172.30.27.10
ip ospf hello-interval 1
ip ospf dead-interval 5
network 172.30.27.0 0.0.0.255 area 172.30.27.0

 

Sau đó vào GW1 và GW2 kiểm tra kết quả:

#/usr/local/quagga/bin/vtysh

#show ip ospf database

#show ip ospf neighbor

Các thông tin về ospf database và ospf neighbor đều hiện trên cả GW1 và GW2

Bây giờ, nếu có request gửi đến địa chỉ 172.30.27.219 hoặc một DNS name nào đó được trỏ tới IP trên, thì Router sẽ dựa trên ospf để tìm Server nào gần nhất, sau đó sẽ forward request đến đó.

Chú ý: Các giá trị hello-interval và dead-interval trên cả GW1, GW2 và Router phải bằng nhau. hello-interval là thời gian Server gửi gói tin hello OSPF cho Router và dead-interval là thời gian cập nhật lại bảng định tuyến của Router. Nếu không thấy bất kì gói hello nào được gửi tới nó trong thời gian dead trên, Router sẽ remove Server đó ra khỏi bảng định tuyên. Ngoài ra, các giá trị mtu của card mạng trên các thiết bị phải bằng nhau.

Nếu không thấy quá trình ospf thành công, có thể xem log file tại /var/log/quagga để biết rõ thêm hoặc comment bên dưới, tôi sẽ hỗ trợ các bạn.

Tôi tạm dừng phần 2 ở đây, trong phần tiếp theo, sẽ hướng dẫn các bạn monitor các daemon của quagga, cũng như control được quá trình quảng bá OSPF của quagga. Nếu các services (nginx…)  ở GW bị lỗi mà quagga vẫn quảng bá ospf lên cho router, request vẫn được đẩy xuống GW thì không hợp lý chút nào đúng không? 😀

 

 

3 Comments on [HA] – Sử dụng Anycast, OSPF, Quagga để load balancing cho hệ thống – P2

[HA] – Sử dụng Anycast, OSPF, Quagga để load balancing cho hệ thống – P1 August 1, 2017

Đặt vấn đề: Cân bằng tải là một vấn đề muôn thuở đối với mọi hệ thống, đặc biệt là các hệt thống web server, api… Hiện nay, có nhiều cách để xây dựng một hệ thống cân bằng tải như HA proxy + Keepalived, Nginx + Keepalived.. Tuy nhiên, khi xây dựng các hệ thống trên, ta đều gặp một vấn đề chung là nếu sử dụng keepalived, một VIP được tạo ra, thì cùng lúc chỉ có 1 server Master chạy, server còn lại sẽ ở chế độ Standby -> Lãng phí tài nguyên.

Vậy, làm sao để cùng lúc các Server đều được sử dụng ?

Anycast’ing là một phương thức rất hay, kết hợp với OSPF và DNS giúp ta có thể giải quyết vấn đề ở trên.

Trước tiên, ta đi tìm hiểu các định nghĩa về anycast, ospf, và phần mềm định tuyến quagga.

  • Anycast: Là từ một nguồn có thể truyền tin tới một host gần nhất trong một nhóm các host được cấu hình cũng một địa chỉ IP. Sự khác nhau giữa anycast và multicast là thay vì chuyển tới tất cả các host trong nhóm, thì gói tin sẽ chỉ được chuyển tới host gần nhất trong bảng định tuyến. Đồng thời ở anycast, các host đều được cấu hình chung một địa chỉ Anycast giống nhau. Có thể hiểu thông qua mô hình sau:

Anycast được sử dụng để quảng bá một địa chỉ IP từ nhiều node khác nhau trong hệ thống mạng, với sự linh hoạt của giao thức dynamic routing, các gói tin sẽ được gửi tới node gần nhất.

Có thể ứng dụng Anycast trong một trường hợp cụ thể như sau: Một địa chỉ Anycast duy nhất sẽ được gán cùng lúc cho nhiều máy chủ cung cấp dịch vụ, các bộ định tuyến sẽ thực hiện công việc chọn đích đến tốt nhất và gần nhất, sau đó forward gói tin tới server đích đó.

IP Anycast thường được sử dụng hơn, nó được sử dụng cho dịch vụ DNS. DNS là một giao thức phản hồi duy nhất, không quan trọng response từ máy chủ. Vì DNS sử dụg UDP, không cần phải xác thực việc kết nối như TCP.

Anycast không được thiết kế để loadbalancing, mục đích chính của nó là giảm độ trễ và dư thừa khi định tuyến. Tuy nhiên phụ thuộc vào cách cấu hình, anycast có thể loadbalancing nhẹ.

Thêm một IP anycast của một domain vào hệ thống khai báo DNS, sau đó có thể sử dụng các giao thức định tuyến như RIP, OSPF hoặc BGP.

Cần có các phần mềm định tuyến hỗ trợ việc cấu hình các giao thức trên dưới Server như Quagga Routing.

  • Giao thức OSPF

OSPF – Open Shortest Path First là một giao thức định tuyến link-state. Mỗi khi router chạy giao thức sẽ gửi các trạng thái đường link của nó cho tất cả các router trong vùng (area). Các gói tin LSA (Link State Advertisement) được quảng bá cho các Router khác. Sau một thời gian trao đổi, các router sẽ đồng nhất bảng trạng thái đường link (Link State Database – LSDB) với nhau, mỗi router sẽ có bản đồ mạng của cả vùng. Từ đó chạy giải thuật Dijkstra tính toán ra đường đi ngắn nhất.

  • OSPF cos AD = 110
  • Metric (cost) được tính theo bandwith trên cổng chạy OSPF
  • Chạy trên nền IP, protocol number = 89

Các bước hoạt động OSPF:

  1. Bầu chọn Router – id.
  2. Thiết lập quan hệ láng giềng (neighbor).
  3. Trao đổi LSDB.
  4. Tính toán xây dựng bảng định tuyến
  • Quagga Routing

Quagga là một phần mềm routing mà nguồn mở, cung cấp cách hỗ trợ triển khai OSPFv2, OSPFv3, RIP và BGP-4 trên các nền tảng Unix như FreeBSD, Linux, Solaris and NetBSD.

Kiến trúc của Quagga gồm một core daemon, gọi là zebra. Zebra có nhiệm vụ giả lập như một router, thực hiện quản lý, update các giao thức định tuyến và truyền thông định tuyến. Ngoài ra còn có các daemon khác quản lý giao thức định tuyến được liệt kê như trên ospfd, ripd, bgpd…

Quagga được cấu hình thông qua một giao diện dòng lệnh CLI (gọi là ‘vty’). Ngoài ra có thêm công cụ ‘vtysh’, giúp quản lý tập trung các hoạt động của Quagga daemon.

Sau đây là mô hình thực tế của hệ thống loadbalancer của chúng ta như sau:

Ở phần hai, tôi sẽ hướng dẫn chi tiết về việc cấu hình Anycast, OSPF, và Quagga để load balancing cho hệ thống.

No Comments on [HA] – Sử dụng Anycast, OSPF, Quagga để load balancing cho hệ thống – P1

Con đường sự nghiệp của 1 *nix system admin July 25, 2017

Khi đã và đang làm việc như là 1 system admin, “một nghề cao quý trong những nghề cao quý”, bạn sẽ dần được trải qua những mốc ghi dấu của con đường sự nghiệp của mình, 1 vài giây nhìn lại những nấc thang mà bạn đã vượt qua, nếu như bạn sẽ và mới bắt đầu với con đường này, đây là bài viết cho bạn 1 cái nhìn tổng quan nhất, giúp bạn định hình được những thứ bạn sẽ phải trải qua, tuy khó khăn gian khổ, nhưng trái ngọt luôn chờ bạn 🙂

Level 0

Bắt đầu sẽ là 1 cái title dành cho các bạn học sinh, sinh viên, lúc còn đang học ở trường, trung tâm đào tạo …Đây là thời điểm bạn được bắt đầu làm quen với mọi thứ, những lý thuyết cơ bản nhất về mạng máy tính, về hạ tầng mạng và hệ thống, về lập trình cơ bản, về bảo mật và an toàn thông tin.. Tất cả là 1 mớ lý thuyết vô cùng to lớn được gói gọn trong 1 chương trình học cực kỳ ngắn, thường là 1-2 môn trong 1-2 học kỳ, hoặc là 1 khóa đào tạo ngắn hạn từ 3-4 tháng.  Bạn rất may mắn khi đã được trải qua level này với đầy đủ lý thuyết và phần thực hành tương xứng, nếu có những bài luận văn hay chứng chỉ về mạng và hệ thống trong thời điểm này hoặc được nhận vào thực tập ở 1 công ty lớn thì thật là tuyệt.

Bạn sẽ ghi toàn bộ những thứ mình học và làm được trong hồ sơ xin việc của mình và gửi nó đi khắp nơi, nếu may mắn, nghề sẽ chọn được bạn và bạn sẽ bắt đầu cuộc phiêu lưu của mình ở level khác.

Entry/Junior Level

Đây là level bạn sẽ bắt đầu khi mới vào nghề và từ 6 tháng đến 2 năm, và ở level này, bạn cần đạt được những yêu cầu như sau:

Về kiến thức hệ thống

“- Nắm vững kiến thức cơ bản về mạng: các protocol cơ bản (DHCP, ARP, DNS…), NAT & firewall, các trạng thái của kết nối TCP
– Nắm kiến thức cơ bản về phần cứng, chủ yếu là các chỉ số system utilization: CPU (# cores, frequency), RAM (frequency), Disk (IOPS)
– Các kiến thức cơ bản của OS (linux/Windows): process & thread, các service cơ bản, permission & policy
– Các kiến thức cơ bản về Databases: MySQL, Oracle, …”

Về kỹ năng vận hành

“- Có khả năng sử dụng các công cụ cơ bản để quản lý, theo dõi và phân tích các vấn đề kỹ thuật (ssh/Remote Desktop, ping, netstat, top/htop…)
– Hiểu & tuân thủ quy trình vận hành, cài đặt & bảo trì hệ thống
– Có khả năng xử lý sự cố mức độ thấp”

Về bảo mật

“- Có kiến thức cơ bản về các khái niệm bảo mật: ACL, virus, spyware, backdoor
– Có kiến thức, kỹ năng trong việc đảm bảo bảo mật mức thấp (setup firewall, sử dụng anti-virus)
– Tuân thủ quy trình và các nguyên tắc bảo mật”

Về nghiên cứu và ứng dụng

“- Có khả năng ứng dụng công nghệ mới vào công việc vận hành hàng ngày”

Mid Level

Đây là nấc thang tiếp theo, bạn sẽ đạt được sau khoảng từ 2 năm tới 3 năm 😀 nhanh hay lâu tùy thuộc vào bản thân của bạn, nhưng tối thiểu bạn phải đáp ứng được những yêu cầu sau:

Về kiến thức hệ thống

“- Nắm vững kiến thức chuyên sâu về mạng: phân biệt & hiểu rõ tất cả các tầng của OSI model
– Nắm vững kiến thức về quá trình phần cứng vận hành & sự phối hợp của các phần cứng trong một hệ thống
– Có kiến thức về optimization, high scalibility, high performance, high availability”

Về kỹ năng vận hành

“- Có khả năng tối ưu hóa hệ thống ở mức vừa (tăng ít nhất 10% hiệu suất hệ thống có sẵn, có ít nhất 5 server)
– Có khả năng xử lý, tìm ra nguyên nhân & khắc phục các sự cố có độ phức tạp vừa
– Vận hành, theo dõi & bảo trì bằng script (automation)
– Theo dõi & phát hiện các nguy cơ tiềm ẩn trong hệ thống mình quản lý & theo dõi”

Về bảo mật

“- Thực hiện kiểm tra & đánh giá nguy cơ bảo mật định kỳ & mỗi khi hệ thống được cập nhật
– Có khả năng khắc phục, xử lý các sự cố liên quan đến bảo mật ở mức độ vừa (xử lý backdoor/virus, vá lỗ hổng bảo mật…)”

Về nghiên cứu và ứng dụng

“- Chủ động nghiên cứu, đánh giá các công nghệ mới để áp dụng vào công việc vận hành chung của team”

Senior Level 

Đây là thành quả cày cuốc của bạn sau từ 3-5 năm, bạn sẽ đạt được level này:

Về kiến thức hệ thống

“- Nắm vững kiến thức chuyên sâu về hệ điều hành: Linux kernel, Windows architecture (kernel, drivers, HAL…)
– Có kiến thức về thư viện, framework mà các software service sử dụng (libc, jdk, php, .NET…)”

Về kỹ năng vận hành

“- Có thể thiết kế, tư vấn, đánh giá & triển khai các giải pháp kỹ thuật phức tạp cho hệ thống lớn (>20 server)
– Quản lý và phân công các team giải quyết các sự cố có độ phức tạp cao
– Chịu trách nhiệm chính, ra quyết định trong các dự án lớn”

Về bảo mật

“- Chuyên sâu trong lĩnh vực bảo mật: có cơ chế/giải pháp hạn chế các rủi ro bảo mật có thể xảy ra
– Hỗ trợ, tư vấn trong việc phòng chống, điều tra và xử lý các lỗi bảo mật trong phạm vi toàn công ty”

Về nghiên cứu và ứng dụng

“- Có khả năng tự nghiên cứu, phát triển & triển khai các giải pháp phức tạp phục vụ cho mục tiêu tối ưu hóa công nghệ, mang lại lơi ích kinh doanh (tính năng ưu việt, cắt giảm chi phí…)”

Bài viết chỉ mới đề cập tới các level liên quan tới cấp bậc là nhân viên, chưa đề cập tới các cấp bậc khác như trưởng nhóm, giám sát hay quản lý và cũng là ý kiến chủ quan của cá nhân mình nên có thể không đúng hoàn toàn khi áp dụng vào công ty hay cho bản thân bạn, vì hiện tại mình cũng chưa trải qua những cấp bậc đó nên chưa viết 🙂 Đón đọc blog của mình sau 5 – 10 năm nữa nhé.

2 Comments on Con đường sự nghiệp của 1 *nix system admin

Hướng dẫn compile Nginx từ source trên Centos July 14, 2017

Nginx là gì?

NGINX (Pronounced as Engine-X) is an open source, lightweight, high-performance web server or proxy server. Nginx used as reverse proxy server for HTTP, HTTPS, SMTP, IMAP, POP3 protocols, on the other hand, it is also used for servers load balancing and HTTP Cache. Nginx accelerates content and application delivery, improves security, facilitates availability and scalability for the busiest websites on the Internet.

Trong bài viết này mình không đi sâu về khái niệm cũng như chi tiết của nginx, vì ngoài là 1 phần mễm mã nguồn mở thì bên trong nó là cả 1 đại dương rộng lớn về ngôn ngữ, cấu hình, cách hoạt động, tính năng, hiệu suất… mà chỉ để cập tới việc cài đặt nó, nhưng không dùng cách thông thường là cài đặt từ yum mà là complile từ source.

Compile Nginx from source with SSL support

  • Install dependencies

yum install pcre pcre-devel zlib zlib-devel

wget https://www.openssl.org/source/openssl-1.1.0e.tar.gz
tar -xvzf openssl-1.1.0e.tar.gz
cd openssl-1.1.0e/
./config –openssldir=/usr/local/ssl
make
make install
openssl version

  • Compile nginx to custom location

wget http://nginx.org/download/nginx-1.12.0.tar.gz
tar -xvzf nginx-1.12.0.tar.gz
cd nginx-1.12.0
./configure –prefix=/zserver/nginx –with-http_gzip_static_module –with-http_stub_status_module –with-http_ssl_module –with-openssl=/path/to/openssl-1.1.0e

make
make install
/zserver/nginx/sbin/nginx -V
nginx version: nginx/1.12.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.1.0e 16 Feb 2017
TLS SNI support enabled
configure arguments: –prefix=/zserver/nginx –with-http_gzip_static_module –with-http_stub_status_module –with-http_ssl_module –with-openssl=/root/sources/openssl-1.1.0e

  • More information

http://nginx.org/en/docs/configure.html

No Comments on Hướng dẫn compile Nginx từ source trên Centos
Categories: Tài liệu

Hiểu thêm về timezone và localtime trên Centos 6/7 July 10, 2017

Khi tiến hành cài đặt 1 server Centos 6/7, bạn có thể chọn cài đặt Date & Time ngay từ đầu, tuy nhiên, với 1 số VPS hay server trên cloud như Sakura, Google Cloud Engine…timezone phụ thuộc vào nơi mà bạn chọn để đặt server đó. Vì vậy, có thể thời gian của server và thời gian local của bạn không trùng khớp, nên nhất thiết cần phải đặt lại theo múi giờ mình chọn trước.

Trên Centos, thư mục /usr/share/zoneinfo/ là nơi chứa toàn bộ thông tin của các múi giờ của hệ thống.

ls /usr/share/zoneinfo/
Africa Atlantic Chile Eire GB GMT+0 Indian Japan MST Pacific PRC Singapore UTC Zulu
America Australia CST6CDT EST GB-Eire Greenwich Iran Kwajalein MST7MDT Poland PST8PDT Turkey WET
Antarctica Brazil Cuba EST5EDT GMT Hongkong iso3166.tab Libya Navajo Portugal right UCT W-SU
Arctic Canada EET Etc GMT0 HST Israel MET NZ posix ROC Universal zone1970.tab
Asia CET Egypt Europe GMT-0 Iceland Jamaica Mexico NZ-CHAT posixrules ROK US zone.tab

Và file /etc/localtime chính file thể hiện múi giờ hiện tại, thường được symlink tới 1 múi giờ chính xác được quy định trong /usr/share/zoneinfo/

Ví du:

ll /etc/localtime
lrwxrwxrwx 1 root root 30 Jun 12 01:09 /etc/localtime -> /usr/share/zoneinfo/Asia/Tokyo

Có nghĩa múi giờ hiện tại của bạn là “Asia/Tokyo”

Để thay đổi giờ hệ thống cho server của bạn, làm theo các bước sau:

Với Centos 7

Kiểm tra timzone list có sẵn trên hệ thống

timedatectl list-timezones |grep Asia| head
Asia/Aden
Asia/Almaty
Asia/Amman
Asia/Anadyr
Asia/Aqtau
Asia/Aqtobe
Asia/Ashgabat
Asia/Baghdad
Asia/Bahrain
Asia/Baku

Kiểm tra timzone hiện tại

ll /etc/localtime
lrwxrwxrwx. 1 root root 38 Apr 24 2016 /etc/localtime -> ../usr/share/zoneinfo/Asia/Ho_Chi_Minh

Thay đổi timezone bằng câu lệnh

timedatectl set-timezone Asia/Tokyo

Kiểm tra thay đổi

ll /etc/localtime
lrwxrwxrwx. 1 root root 38 Apr 24 2016 /etc/localtime -> ../usr/share/zoneinfo/Asia/Tokyo

Với Centos 6

Xóa file localtime hiện tại ( có thể backup)

rm -rf /etc/localtime

Tạo softlink tới chính xác múi giờ bạn cần

ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

Thay đổi thời gian trong clock

vi /etc/sysconfig/clock

Change ZONE=”Asia/Tokyo”

hwclock –systohc –localtime

Chúc bạn thành công.

 

 

No Comments on Hiểu thêm về timezone và localtime trên Centos 6/7
Tags:
Categories: Tài liệu

Hướng dẫn cài đặt TestLink Test Management Tool July 9, 2017

Testlink là gì?

Test-link is most widely used web based open source test management tool. It synchronizes both requirements specification and test specification together. User can create test project and document test cases using this tool. With Test-Link you can create an account for multiple users and assign different user roles. Admin user can manage test cases assignment task.

It supports both automated and manual execution of Test cases. The testers can generate Test Plan and Test Report in a fraction of the time with this tool. It supports test reports in various formats like Excel, MS word, and HTML formats. Apart from these, it also supports integration with many popular defect tracking system like JIRA, MANTIS, BUGZILLA, TRAC, etc. Since it is a web based tool, multiple users can access its functionality at the same time with their credentials and assigned roles. 

Tóm lại, Testlink là 1 công cụ hữu ích cho QA/Tester quản lý các testcase của mình, hỗ trợ cả tự động và manual, có thế kết với các công cụ tracking khác như JIRA, BUGZILLA…

TestLink Stable (NEW!!!! – 1.9.16 – Moka Pot – 20170121)

Vào thời điểm hiện tại thì bản 1.9.16 vẫn là bản Stable, hóng chờ bản 2.x nhưng có vẻ cộng đồng càng lúc càng ít người sử dụng cũng như xây dựng phiên bản mới 🙂

Việc cài đặt Testlink khá đơn giản và có tài liệu hướng dẫn khá rõ ràng, chỉ cần thực hiện step by step là có thể có 1 tool sau vài phút.

Sau đây mình sẽ hướng dẫn cài đặt bản 1.9.16 trên Centos 7

Để chạy được Testlink thì cần có những thành phần sau: database (mysql, mariadb…), php, và nginx là web server.

Thông tin:

php -version
PHP 5.6.30 (cli) (built: Jan 19 2017 22:31:39)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

MySQL Server version: 10.1.21-MariaDB MariaDB Server

/zserver/nginx/sbin/nginx -v
nginx version: nginx/1.10.0

Download: https://sourceforge.net/projects/testlink/files/TestLink%201.9/TestLink%201.9.16/testlink-1.9.16.tar.gz
tar -xvzf testlink-1.9.16.tar.gz
mv testlink-1.9.16 /zserver/

Tạo database trên mysql và chạy câu lệnh tạo database

Create a new empty MySQL database.
CREATE DATABASE testlink CHARACTER SET utf8 COLLATE utf8_general_ci;
Create user to access
GRANT ALL PRIVILEGES ON *.* TO ‘testlink’@’lab4’ identified by ‘test123’;
Install the sql into the newly created database.
mysql -u testlink -h lab4 -p testlink < /zserver/testlink-1.9.16/install/sql/mysql/testlink_create_tables.sql
mysql -u testlink -h lab4 -p testlink < /zserver/testlink-1.9.16/install/sql/mysql/testlink_create_default_data.sql

Taọ file config để chứa thông tin kết nối đến database

Config database

cat /zserver/testlink-1.9.16/config_db.inc.php

<?php // Automatically Generated by TestLink Installer

define(‘DB_TYPE’, ‘mysql’);

define(‘DB_USER’, ‘testlink’);

define(‘DB_PASS’, ‘test123’);

define(‘DB_HOST’, ‘lab4’);

define(‘DB_NAME’, ‘testlink’);

?>

Tạo thư mục để chứa logs và upload

mkdir -p /var/testlink/logs/
mkdir -p /var/testlink/upload_area/

Chú ý:

On Linux or UNIX you must change the permissions of the templates_c directory to be writable by the webserver. From the TestLink root directory run
chmod 777 gui/templates_c

Chạy php dưới user nginx.

chown -R nginx. /var/lib/php/session/

Cấu hình nginx: vi /zserver/nginx/conf/vhost/testlink.conf

server {
listen 8081;
server_name lab4;
root /zserver/testlink-1.9.16;
client_max_body_size 20M;
location / {
index index.php;
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/zserver/tmp/php-fpm.sock;
fastcgi_read_timeout 300;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ /\.ht {
deny all;
}
}

Như vậy là đã cài đặt xong, bạn có thể login vào tool bằng link sau:

Try :http://lab4:8081/login.php
Login : admin/admin

 

3 Comments on Hướng dẫn cài đặt TestLink Test Management Tool
Categories: Tài liệu

Linux là cái gì?

Việc cần làm đầu tiên của 1 Linux system admin đọc được tiếng Anh và hiểu được Linux là gì?

Từ điện thoại, xe hơi, siêu máy tính cho đến đồ gia dụng, tất cả đều có mặt của hệ điều hành Linux.

Linux. It’s been around since the mid ‘90s, and has since reached a user-base that spans industries and continents. For those in the know, you understand that Linux is actually everywhere. It’s in your phones, in your cars, in your refrigerators, your Roku devices. It runs most of the Internet, the supercomputers making scientific breakthroughs, and the world\’s stock exchanges. But before Linux became the platform to run desktops, servers, and embedded systems across the globe, it was (and still is) one of the most reliable, secure, and worry-free operating systems available.

Vậy nó có giống như Windows XP, Windows 7, Windows 10, MacOS X hay không? Nó bao gồm những thành phần nào? Tại sao lại sử dụng nó?

Just like Windows XP, Windows 7, Windows 8, and Mac OS X, Linux is an operating system. An operating system is software that manages all of the hardware resources associated with your desktop or laptop. To put it simply – the operating system manages the communication between your software and your hardware.

This is the one question that most people ask. Why bother learning a completely different computing environment, when the operating system that ships with most desktops, laptops, and servers works just fine? To answer that question, I would pose another question. Does that operating system you’re currently using really work “just fine”? Or are you constantly battling viruses, malware, slow downs, crashes, costly repairs, and licensing fees?

Ubuntu, Fedora, Arch … khác nhau như thế nào? tại sao lại lắm chuyện khi đưa ra 1 đống “distro”như thế?

Linux has a number of different versions to suit nearly any type of user. From new users to hard-core users, you’ll find a “flavor” of Linux to match your needs. These versions are called distributions (or, in the short form, “distros.”) Nearly every distribution of Linux can be downloaded for free, burned onto disk (or USB thumb drive), and installed (on as many machines as you like).

Nên dùng RedHat hay Ubuntu cho server của bạn? Cái nào là miễn phí hoàn toàn, cái nào phải trả tiền để mua gói dịch vụ hỗ trợ?

Which distribution you use will depend upon the answer to three simple questions:

  • How skilled of a computer user are you?
  • Do you prefer a modern or a standard desktop interface?
  • Server or desktop?

Đọc tới đây là bắt đầu rối tinh rối mù rồi, nhưng vẫn phải quyết định “thử” 1 cái nào đó phù hợp với nhu cầu của mình. Nếu như là 1 system admin hoặc muốn trở thành 1 thứ gì đó tương tự, thì hãy bắt đầu ngay và luôn. Hãy cài đặt nó 🙂

For most, the idea of installing an operating system might seem like a very daunting task. Believe it or not, Linux offers one of the easiest installations of all operating systems. In fact, most versions of Linux offer what is called a Live distribution – which means you run the operating system from either a CD/DVD or USB flash drive without making any changes to your hard drive. You get the full functionality without having to commit to the installation. Once you’ve tried it out, and decided you wanted to use it, you simply double-click the “Install” icon and walk through the simple installation wizard.

Tôi chọn Ubuntu 14.04 LTS cho laptop đang sử dụng và Centos, Ubuntu cho hệ thống máy chủ mình đang vận hành.

Tới đây thì chắc bạn cũng đang bận bịu với việc google cách cài đặt 1 hệ điều hành Linux như thế nào? hoặc là đang google dịch để hiểu bài viết trên nói gì, nhưng dù sao, thì cũng chào mừng các bạn đến 1 thế giới mới sau khi gõ “Linux là gì?”

 

 

 

No Comments on Linux là cái gì?
Tags:
Categories: Linh tinh