System của một System Engineer
Khi hệ thống và hệ thống quản trị hệ thống phát triển nhanh hơn mình tưởng.
Có thể nhiều người quen và biết về mình, thường sẽ có ấn tượng về mình là mình chuyên quan tâm về các thứ liên quan đến Data và Data Engineering. Tuy nhiên, nếu để nói về kinh nghiệm tuổi nghề, thì có lẽ thứ mà mình có kinh nghiệm và trải nghiệm lâu nhất thì nó lại là System Engineer.
Cái nghề System Engineer này kể ra thì cũng trải qua khá nhiều biến động trong 15-20 năm vừa qua. AWS bắt đầu từ những năm 2006, và khi bắt đầu phát triển rộng rãi từ thời đại của Startup những năm 201x, và công việc System Administration cũng biến động không kém. Các danh xưng, title cũng biến đổi theo, từ Sysadmin, Sysops, DevOps, SREs, Infrastructure Engineer, Platform Engineer, rất nhiều sự thay đổi, phân nhánh và biến chuyển xảy ra chỉ trong vòng 1 thập kỷ.
Mình chắc cũng sẽ viết lại câu chuyện của mình, và sẽ nhắc đến nó đơn giản là System Engineer (ok, kiểu Engineer mà đụng đến System ấy). Trải qua nhiều thứ lung tung cũng có cái hay, giúp mình thấm thía được hơn về sự phát triển chóng mặt của công nghệ.
System chọn tôi chứ tôi không chọn System
Câu chuyện chắc là bắt đầu từ khoảng năm 2010. Như các thanh niên trẻ thời đại mới, tôi rảnh rỗi không có việc gì làm (thực ra là có việc học nhưng hơi lười một xíu) nên lên mạng và tham gia các loại discussion forum cho nó vui. Do một số cơ duyên lòng vòng sau một hồi cãi cọ chém gió thì mình đã trở thành Technical Admin không công cho một forum quốc tế khá lớn thời bấy giờ (câu chuyện quá dài nên xin phép để dành cho một ngày khác). Mình vẫn chỉ là một sinh viên Computer Science cũng chưa biết gì quá nhiều, nhưng mà bản chất cũng khá là tò mò nên là cứ làm thử thôi cho biết. Đây cũng là nơi mà mình đã học được rất nhiều trong những năm đại học của mình.
Thời đó, các website sẽ thường được host ở trên cái Hosting Provider, và các Hosting Provider thường sẽ có một cụm máy chủ dùng chung(shared hosting). Bạn sẽ thường không được đụng đến máy chủ, mà sẽ có Management software(phần mềm quản lý) ở phía trên (thường là CPanel), và trên đó sẽ có khá là nhiều thứ để ban configure, cũng như động chạm vào các phần bên trong của hệ thống. Các website thời đó thường có Wordpress cho blog, Drupal/Magento cho Ecomm hoặc là nếu forum thì sẽ có phpBB và InvisionPower; hầu hết thời đó đều chạy LAMP stack. Chỉ riêng các bảng điều khiển của CPanel đã khá là massive, có rất nhiều thứ config để đụng vào, khá là hoa mắt chóng mặt. Website hồi đó thì chạy InvisionPower, Apache, MySQL và trên một con Linux(Nếu mình nhớ không nhầm thì là Centos).
Tuy nhiên, cái trang mình được quản lý cũng có khá nhiều traffic, thế nên là sau một thời gian thì nó được chuyển từ shared hosting sang chạy trên VPS(Virtual Private Server). Và từ đây, thay vì chỉ có đụng vào CPanel UI, thì mình lần đầu tiên được xông vào trong 1 con server để xem bên trong nó có gì. Vẫn còn nhớ thời đó là mình SSH vào bằng PuTTY (mãi về sau mình mới biết TTY có nghĩa là gì mà phải viết hoa). Lần đầu SSH vào con server mình cũng khá là ngợp, kiểu cảm giác lần đầu tiên được thấy phía bên trong của 1 trang web nó như thế nào.
Một điều may mắn trong giai đoạn này là trang web này khá là được yêu thích và có nhiều người tham gia; tự nhiên mình có rất nhiều trải nghiệm được vọc vào và tối ưu con server này, để nó có thể tiếp tục duy trì và sống sót. Mình còn nhớ một số thứ:
Upgrade MySQL: vì thời đó hệ thống còn cũ nên là database vẫn còn chạy MySQL 5.6 với storage engine là MyISAM, vẫn còn table-level locking. Khi trang web có quá nhiều người cùng post bài thì gần như là chết đứng luôn. Mình đã tự mày mò nghiên cứu migrate DB và update hệ thống lên 5.7 và chuyển qua InnoDB, để có row-level locking, từ đó giải thoát cho cái DB khổ sở giảm load xuống còn 1/3 =))
Fulltext Search: thời đó thì hệ thống vẫn còn chạy trên Full Text Index của MySQL và cái này nó chậmmmmm. Hồi đó thì còn quá cũ chưa có Elasticsearch phổ biến như bây giờ, và hệ thống thì chỉ support tích hợp mỗi cái Apache Solr(gốc trên Apache Lucene), lần đầu mình mò cách cài (huhuh mình còn nhớ dùng
yum install
các thứ). Lần đầu trong đời phải loay hoay với crontab, systemd(thời này còn chưa biết có supervisord), setup các thứ để nó tự rotate và update index, rồi maintain cho cái process nó chạy mãi. Một chuyện khác nữa cùng thời này là cái server thỉnh thoảng lại chết về đầy disk, và mình lại một lần nữa học đc bài logrotate các thứ, thấy thật sự là vi diệu.Apache to Nginx: Thực ra cũng không hẳn là migrate từ httpd sang nginx, mà đó là mình mò mẫm tìm cách cho cái trang web nó đỡ chậm hơn. Vọc một hồi thì tìm ra nginx reverse proxy, và biết xây varnish cache cho nginx để cache thêm static assets, rồi tune gzip-level các thứ cho nhẹ web server. Khoảng thời gian này mình cũng bắt đầu hiểu thêm được 1 chút về CDN, thêm cả Cloudflare các thứ phía ngoài, cũng bắt đầu check pagespeed các thứ để improve.
Search Console, SEO và GA: Lần đầu tiên trong đời mình cũng học được các khái niệm về SEO, và bắt đầu biết đến sự tồn tại của Search console và Google Analytics. Cũng là một chân trời khá mới đối với mình, học thêm được khá nhiều về các thứ mò mẫm trên web
Ngoài ra thì cũng còn khá nhiều thứ lung tung xảy ra trong thời gian này. Mình vẫn luôn nhớ những kỷ niệm loay hoay thời đó. Cũng có lẽ vì một thời gian dài loay hoay trong 1 cái server nên là mình rất là không ngại về đọc config, đọc log và đi debug. Chắc lúc đó máy mình lúc nào cũng đang có 1-2 tab stack overflow đang mở quá.
Lên mây và Ansible
Sau lần phỏng vấn đã kể trên Câu chuyện tháng 11, mình đã chính thức lên mây. Lên mây vì mình vui đã được có job đầu tiên trong đời, và lên mây thực sự là được chuyển mình vào thời đại của Cloud Computing. Công ty mình chạy cả hệ thống trên AWS, và mình bắt đầu được tiếp cận vào những công nghệ mới thời đó giờ.
Với kinh nghiệm bản thân thời đó, chỉ quản 1 cái trang web có 1000 concurrent users thì mình đã thấy là khá cực rồi. Kiểu, mình đã nghĩ đủ hướng để optimize thế này rồi thì cái server nó mới chịu được từng đó traffic; thế thì các app mà xử lý hàng trăm nghìn users thì nó sống thế nào nhỉ? Hay là nó có 1 cái server to vật vã? Vào đến công ty, thì mình mới dần dần hiểu ra.
Mình khá là thân với team Sysops của công ty, và chỉ có 5-6 người mà quản lý cả một hệ thống siêu to khổng lồ thời đó. Lần đầu tiên mình mới hiểu cách một hệ thống lớn được vận hành như thế nào. Thay vì chỉ có 1 cái server to vĩ đại khổng lồ, thì ở thời đại cloud, sẽ có rất nhiều server cùng xử lý một việc. Các server sẽ cùng được configured để chạy cùng 1 hệ thống, sẽ nhận được Traffic từ load balancer, chia đều tải cho các máy; ngoài ra, các server cũng được thiết lập để có khả năng autoscale: chúng được cho vào các autoscaling group, và tuỳ theo workload thì số lượng server sẽ tăng giảm tuỳ ý. Điều này phá vỡ những gì mình đã biết từ trước về quản lý server: Chúng tôi không quản lý server, chúng tôi quản lý một server farm.
Trao đổi nhiều với các anh Sysops, thì mình cũng hiểu thêm về cách họ giải quyết vấn đề. Thay vì chăm bón cho từng cái server như nuôi thú cưng, thì phải tư duy nó như là chăn một đàn bò hay đàn gà (Pets vs. Cattle). Thay vì quản lý từng server, thì họ xây dựng những playbook, như là các task mà mình thường xuyên phải làm. Việc quản lý hệ thống sẽ bao gồm 2 phần: xây dựng các playbook đó, và chạy các playbook đó khi cần thiết. Các service sẽ được thiết lập ở trong các AMI khác nhau, được xây dựng bằng cách build các artifacts từ codebase và config và trong các image.
Tool mình được dạy thêm trong giai đoạn này là Ansible (bây giờ nhìn nó khác nhiều rồi, chứ ngày xưa nó đơn giản hơn thế này nhiều). Ansible là một framework để xử lý các vấn đề liên quan đến Infrastructure thời bấy giờ; xây ra các playbooks như là những cái actions mình cần phải làm; và sau đó là chạy nó. Khi xây những playbook này thành template, hệ thống của bạn sẽ thành lập ra các standard và quy chuẩn về cách thức hoạt động của hệ thống thế nào. Sẽ có các kiểu playbook cho các công việc khác:
Infra Setup: thiết lập ra những EC2, ASG, ELB, RDS, Security groups cũng như một tỷ thứ khác liên quan
Build: Building AMI theo những tag nhất định và lưu lại dùng cho việc deployment
Deploy: Thay những AMI cũ bằng AMI mới một cách êm đẹp để update hệ thống
Ops: Các task cho admin để quản lý, dọn dẹp hệ thống lúc cần thiết.
Ở trung tâm của hệ thống là Ansible Tower, nơi quản lý các playbooks. Có thể thêm playbook, chạy playbook (có hoặc không có parameters), xem task logs, thiết lập retries, vân vân và mây mây. Đây là trung tâm chỉ huy của cả hệ thống vận hành, giúp quản trị các công việc hàng ngày của team SysOps dễ dàng hơn rất nhiều.
Đây là mình cũng tóm tắt sơ lược về cách hiểu của mình, vì mình cũng không quá trực tiếp đụng vào từng hệ thống và công việc của team. Mình cũng học được một hướng tư duy khác về cách quản lý hệ thống. Tuy nhiên, cái này lại phụ thuộc khá nhiều vào Cloud, và các sản phẩm riêng biệt của từng Cloud Provider. Nó cũng chuyên nghiệp hơn nhiều và giải quyết được nhiều vấn đề hơn so với cách setup VPS ngày xưa, nhưng nó lại tốn kém hơn kha khá.
Terraform, Docker và Kubernetes
Docker đã có tồn tại từ nhiều năm trước(mình nhớ ko nhầm là 2013) và đã bắt đầu được các engineering team trên thế giới ủng hộ, về khái niệm containerization. Software bắt đầu có thể được packaged thành những unit nhỏ hơn, đó là các docker image, để đảm bảo sự tách biệt giữa các service trong một hệ thống lớn (đặc biệt là khi phong trào microservices bắt đầu nổi lên). Docker bắt đầu được sử dụng rộng rãi hơn trong môi trường dev, khi các dev team muốn dựng lên hệ thống, test local và đảm bảo được sự đồng nhất trong môi trường (giữa local, staging, production). Đã có những attempt để xây dựng hệ thống bằng nhiều containers nhỏ khác nhau, như là Docker Swarm, tuy nhiên lại không được quá nhiều ủng hộ từ phía người sử dụng. Khó setup và khó sử dụng, Docker Swarm cũng không bao giờ đạt được 1 popularity nhất định.
Đến khi Kubernetes được ra đời, là một hệ thống Container Orchestration xuất phát từ Google, vấn đề chạy một hệ thống container ở large scale đã bắt đầu được giải quyết. Kubernetes gói gọn các khái niệm về cách setup một applications thành những Pod, ReplicaSets, những Services và vân vân, kết nối các thành phần trong một hệ thống phức tạp với nhau một cách dễ dàng. Kubernetes kết hợp được 2 phần quan trọng:
mô tả một applications bằng 1 cái manifest viết bằng YAML (desired state)
điều khiển bằng Controller Pattern, liên tục theo dõi tình trạng của applicate và self-repair để quay lại được desired state.
Với kiến trúc này, Kubernetes đã giải quyết được nhiều pain points của các team SysOps, và gần như đã trở thành sản phẩm được chọn để quản trị hệ thống ở tầng applications. (Cũng có 1 số sản phẩm khác như là Nomad by Hashicorp hay Apache Mesos, nhưng không thể nào nổi bằng)
Về phía các Cloud Resources, với sự bùng nổ của các công ty công nghệ trong những năm gần đây, số lượng Infra mà các team phải quản lý cũng tăng lên nhiều. Quản lý một hệ thống trở nên phức tạp hơn, các UI của cloud providers thì cũng không dễ dàng để sử dụng, lại còn cần sự liên kết giữa nhiều góc khác nhau (EC2 1 bên, ELB 1 bên, RDS 1 bên, Security groups lại 1 góc, IAM lại ở chỗ khác nữa…). Giải pháp nổi bật lên trong giai đoạn này Infrastructure-as-Code (IAC), với sản phẩm nổi bật hẳn lên đó là Terraform(cũng của Hashicorp). Sử dụng một ngôn ngữ gọi là HCL(yes, Hashicorp Configuration Language) để describe các cụm infra khác nhau, đi cùng với việc sử dụng các biến, các params giúp cho việc quản trị các Cloud Infra trở nên dễ dàng hơn.
Ở thời đại này, các hệ thống lớn có thể được chia thành 3 layers khác nhau:
Cloud Infrastructure: được quản lý bởi Terraform
Application Deployment: được quản lý bới Kubernetes
Application logic: gói gọn và containerized thành Docker Container.
Mình cũng định bổ sung thêm các kinh nghiệm cá nhân của mình về phần này, tuy nhiên chắc có lẽ nó sẽ hơi dài, nên có thể sẽ để dành cho một lần viết khác.
Các hướng đi khác và bước tiếp theo
Hầu hết các enterprise hiện tại đều hướng đến cấu trúc hệ thống bằng các giải pháp như trên. Tuy nhiên các team sẽ đều hơi khác nhau về cách họ khai thác và biến đổi các hệ thống ở trên(ngoại trừ Docker, which is pretty stable).
Terraform
Modules: các cloud providers xây ra những modules có sẵn để khách hàng dễ dàng sử dụng
IAC codegen: sử dụng Code để generate ra các Terraform manifest(Pulumi and the likes)
Multi environment: Terragrunt
Workflow: Terraform Enterprise hoặc Atlantis, tích hợp vào deployment/code release workflow
Kubernetes
Packaged application: Helm charts
Templated Manifest: Kustomize
CRD (Custom Resource Definition)
Với các dân hobbyist hoặc các team làm prototyping lấy tốc độ, nhiều team sẽ lựa chọn các hướng như Serverless(mình không phải là fan), hoặc các Development Platform(PaaS) như Netlify, Vercel(Next.js), Dokku, Fly.io vân vân. Các lựa chọn này sẽ lightweight hơn rất nhiều về việc quản trị, nhưng cũng đánh đổi về việc phải đi theo những quy luật ngầm của platform và cũng dễ bị stuck ở trong cùng ecosystem.
Ngoài ra, còn một phần khác mà mình chưa đề cập đến một chút nào, đó là CI/CD, các hệ thống liên quan đến Workflow Automation. Đây lại là một vấn đề sâu hơn, và chắc là không thể giải thích trong cùng một bài viết này.
Kết
Trải nghiệm qua từng bước tiến của các hệ thống, từ nhỏ đến to, cũng là một điều may mắn của mình. Có trải nghiệm cái pain points cũ, thì mới biết được vấn đề mà cái thứ mới muốn giải quyết; và đôi khi cũng giúp mình nhận ra những sự vấn đề nảy sinh ra thêm ở trong cái mới. Hy vọng câu chuyện lịch sử của mình cũng sẽ mang lại cho mọi người chút hứng thú, và nếu có muốn nghe thêm chuyện gì thì có thể request mình kể thêm :)
Vẫn là những cuộc dạo chơi. Giá như là một builder thì sẽ có nhiều câu truyện hay để kể hơn.anyway cũng đáng để nhiều người ngưỡng mộ chúc thành công nhiều hơn