Tự động hóa mạng. Một trường hợp từ cuộc sống của một người

Này Habr!

Trong bài viết này chúng tôi muốn nói về tự động hóa cơ sở hạ tầng mạng. Sơ đồ hoạt động của mạng lưới hoạt động trong một công ty nhỏ nhưng rất đáng tự hào sẽ được trình bày. Tất cả các trận đấu với thiết bị mạng thực đều là ngẫu nhiên. Chúng ta sẽ xem xét một trường hợp xảy ra trong mạng lưới này, có thể dẫn đến việc doanh nghiệp phải ngừng hoạt động trong thời gian dài và tổn thất tài chính nghiêm trọng. Giải pháp cho trường hợp này rất phù hợp với khái niệm “Tự động hóa cơ sở hạ tầng mạng”. Bằng cách sử dụng các công cụ tự động hóa, chúng tôi sẽ chỉ ra cách bạn có thể giải quyết các vấn đề phức tạp một cách hiệu quả trong thời gian ngắn và chúng tôi sẽ suy nghĩ về lý do tại sao những vấn đề này nên được giải quyết theo cách này chứ không phải cách khác (thông qua bảng điều khiển).

Từ chối trách nhiệm

Các công cụ tự động hóa chính của chúng tôi là Ansible (dưới dạng công cụ tự động hóa) và Git (dưới dạng kho lưu trữ cho sách chơi Ansible). Tôi muốn đặt trước ngay rằng đây không phải là một bài viết giới thiệu, trong đó chúng ta nói về logic của Ansible hoặc Git và giải thích những điều cơ bản (ví dụ: mô-đun vai trò, tệp kiểm kê, biến trong Ansible hoặc điều gì xảy ra khi bạn nhập lệnh git push hoặc git commit). Câu chuyện này không phải về cách bạn có thể thực hành Ansible và định cấu hình NTP hoặc SMTP trên thiết bị của mình. Đây là câu chuyện về cách bạn có thể giải quyết vấn đề mạng một cách nhanh chóng và tốt nhất mà không gặp lỗi. Bạn cũng nên hiểu rõ về cách hoạt động của mạng, đặc biệt là ngăn xếp giao thức TCP/IP, OSPF, BGP là gì. Chúng tôi cũng sẽ loại bỏ lựa chọn Ansible và Git ra khỏi phương trình. Nếu bạn vẫn cần chọn một giải pháp cụ thể, chúng tôi khuyên bạn nên đọc cuốn sách “Khả năng lập trình và tự động hóa mạng. Kỹ năng dành cho Kỹ sư mạng thế hệ tiếp theo" của Jason Edelman, Scott S. Lowe và Matt Oswalt.

Bây giờ đến điểm.

Báo cáo sự cố

Hãy tưởng tượng một tình huống: lúc 3 giờ sáng, bạn đang ngủ say và đang mơ. Gọi điện. Giám đốc kỹ thuật gọi:

- Đúng?
— ###, ####, #####, cụm tường lửa đã sập và không tăng lên!!!
Bạn dụi mắt, cố gắng hiểu chuyện gì đang xảy ra và tưởng tượng xem điều này có thể xảy ra như thế nào. Trong điện thoại, bạn có thể nghe thấy tiếng tóc trên đầu của giám đốc bị xé toạc và ông ấy yêu cầu gọi lại vì tướng quân đang gọi ông ở đường dây thứ hai.

Nửa giờ sau, bạn thu thập những tờ giấy giới thiệu đầu tiên của ca trực, đánh thức tất cả những người có thể thức dậy. Kết quả là giám đốc kỹ thuật đã không nói dối, mọi thứ vẫn như cũ, cụm tường lửa chính đã sụp đổ và không có chuyển động cơ bản nào của cơ thể khiến anh ta tỉnh táo. Tất cả các dịch vụ mà công ty cung cấp đều không hoạt động.

Chọn một vấn đề theo sở thích của bạn, mọi người sẽ nhớ điều gì đó khác nhau. Ví dụ: sau khi cập nhật qua đêm mà không tải nặng, mọi thứ đều hoạt động tốt và mọi người đều vui vẻ đi ngủ. Lưu lượng truy cập bắt đầu chảy và bộ đệm giao diện bắt đầu tràn do lỗi trong trình điều khiển card mạng.

Thành Long có thể mô tả tình huống này rất tốt.

Tự động hóa mạng. Một trường hợp từ cuộc sống của một người

Cảm ơn bạn, Jackie.

Đó không phải là một tình huống dễ chịu lắm phải không?

Hãy rời xa mạng lưới của chúng ta với những suy nghĩ buồn bã của mình một thời gian nhé.

Hãy thảo luận về cách các sự kiện sẽ phát triển hơn nữa.

Chúng tôi đề xuất thứ tự trình bày tài liệu sau đây

  1. Hãy nhìn vào sơ đồ mạng và xem nó hoạt động như thế nào;
  2. Chúng tôi sẽ mô tả cách chúng tôi chuyển cài đặt từ bộ định tuyến này sang bộ định tuyến khác bằng Ansible;
  3. Hãy nói về tự động hóa toàn bộ cơ sở hạ tầng CNTT.

Sơ đồ và mô tả mạng

Đề án

Tự động hóa mạng. Một trường hợp từ cuộc sống của một người

Hãy xem xét sơ đồ logic của tổ chức của chúng tôi. Chúng tôi sẽ không nêu tên các nhà sản xuất thiết bị cụ thể; vì mục đích của bài viết này, điều đó không quan trọng (Bạn đọc kỹ sẽ đoán được loại thiết bị nào được sử dụng). Đây chỉ là một trong những lợi ích tốt khi làm việc với Ansible; khi thiết lập, chúng ta thường không quan tâm đó là loại thiết bị gì. Hiểu nôm na đây là thiết bị của các hãng nổi tiếng như Cisco, Juniper, Check Point, Fortinet, Palo Alto... các bạn có thể thay thế theo lựa chọn của mình.

Chúng tôi có hai nhiệm vụ chính để di chuyển giao thông:

  1. Đảm bảo việc xuất bản các dịch vụ của chúng tôi, vốn là hoạt động kinh doanh của công ty;
  2. Cung cấp liên lạc với các chi nhánh, trung tâm dữ liệu từ xa và các tổ chức bên thứ ba (đối tác và khách hàng), cũng như khả năng truy cập Internet của các chi nhánh thông qua văn phòng trung tâm.

Hãy bắt đầu với các yếu tố cơ bản:

  1. Hai bộ định tuyến biên giới (BRD-01, BRD-02);
  2. Cụm tường lửa (FW-CLUSTER);
  3. Công tắc lõi (L3-CORE);
  4. Bộ định tuyến sẽ trở thành cứu cánh (khi chúng tôi giải quyết vấn đề, chúng tôi sẽ chuyển cài đặt mạng từ FW-CLUSTER sang KHẨN CẤP) ( KHẨN CẤP);
  5. Bộ chuyển mạch quản lý cơ sở hạ tầng mạng (L2-MGMT);
  6. Máy ảo có Git và Ansible (VM-AUTOMATION);
  7. Một máy tính xách tay để thực hiện thử nghiệm và phát triển playbook cho Ansible (Laptop-Automation).

Mạng được cấu hình với giao thức định tuyến OSPF động với các khu vực sau:

  • Khu vực 0 – khu vực bao gồm các bộ định tuyến chịu trách nhiệm di chuyển lưu lượng truy cập trong vùng EXCHANGE;
  • Khu vực 1 – khu vực bao gồm các bộ định tuyến chịu trách nhiệm vận hành các dịch vụ của công ty;
  • Khu vực 2 – khu vực bao gồm các bộ định tuyến chịu trách nhiệm quản lý lưu lượng định tuyến;
  • Khu vực N – khu vực của mạng lưới chi nhánh.

Trên các bộ định tuyến biên giới, một bộ định tuyến ảo (VRF-INTERNET) được tạo, trên đó chế độ xem đầy đủ eBGP được cài đặt với AS được chỉ định tương ứng. iBGP được cấu hình giữa các VRF. Công ty có một nhóm địa chỉ màu trắng được xuất bản trên các VRF-INTERNET này. Một số địa chỉ màu trắng được định tuyến trực tiếp đến FW-CLUSTER (địa chỉ mà các dịch vụ của công ty hoạt động), một số được định tuyến qua vùng EXCHANGE (các dịch vụ nội bộ của công ty yêu cầu địa chỉ IP bên ngoài và địa chỉ NAT bên ngoài cho văn phòng). Tiếp theo, lưu lượng truy cập đến các bộ định tuyến ảo được tạo trên L3-CORE với địa chỉ màu trắng và xám (vùng bảo mật).

Mạng quản lý sử dụng các thiết bị chuyển mạch chuyên dụng và đại diện cho một mạng chuyên dụng về mặt vật lý. Mạng quản lý cũng được chia thành các vùng bảo mật.
Bộ định tuyến KHẨN CẤP sao chép FW-CLUSTER về mặt vật lý và logic. Tất cả các giao diện trên đó đều bị vô hiệu hóa ngoại trừ những giao diện nhìn vào mạng quản lý.

Tự động hóa và mô tả của nó

Chúng tôi đã tìm ra cách hoạt động của mạng. Bây giờ chúng ta hãy xem từng bước những gì chúng ta sẽ làm để chuyển lưu lượng truy cập từ FW-CLUSTER sang KHẨN CẤP:

  1. Chúng tôi vô hiệu hóa các giao diện trên switch lõi (L3-CORE) kết nối nó với FW-CLUSTER;
  2. Chúng tôi vô hiệu hóa các giao diện trên kernel switch L2-MGMT kết nối nó với FW-CLUSTER;
  3. Chúng tôi định cấu hình bộ định tuyến KHẨN CẤP (theo mặc định, tất cả các giao diện đều bị tắt trên nó, ngoại trừ những giao diện được liên kết với L2-MGMT):

  • Chúng tôi kích hoạt giao diện trong trường hợp KHẨN CẤP;
  • Chúng tôi định cấu hình địa chỉ IP bên ngoài (cho NAT) trên FW-Cluster;
  • Chúng tôi tạo các yêu cầu gARP để các địa chỉ cây thuốc phiện trong bảng arp L3-CORE được thay đổi từ FW-Cluster thành KHẨN CẤP;
  • Chúng tôi đăng ký tuyến mặc định là tĩnh tới BRD-01, BRD-02;
  • Tạo quy tắc NAT;
  • Nâng lên OSPF KHẨN CẤP Khu vực 1;
  • Nâng lên OSPF KHẨN CẤP Khu vực 2;
  • Chúng tôi thay đổi chi phí của các tuyến đường trong Khu vực 1 thành 10;
  • Chúng tôi thay đổi chi phí của tuyến đường mặc định ở Khu vực 1 thành 10;
  • Chúng tôi thay đổi địa chỉ IP được liên kết với L2-MGMT (thành địa chỉ trên FW-CLUSTER);
  • Chúng tôi tạo các yêu cầu gARP để các địa chỉ cây thuốc phiện trong bảng arp L2-MGMT được thay đổi từ FW-CLUSTER thành KHẨN CẤP.

Một lần nữa, chúng ta quay trở lại công thức ban đầu của bài toán. Ba giờ sáng, căng thẳng tột độ, một sai sót ở bất kỳ khâu nào cũng có thể dẫn đến những vấn đề mới. Sẵn sàng gõ lệnh thông qua CLI? Đúng? Được rồi, ít nhất hãy đi rửa mặt, uống chút cà phê và lấy lại ý chí.
Bruce, làm ơn giúp đỡ mọi người.

Tự động hóa mạng. Một trường hợp từ cuộc sống của một người

Vâng, chúng tôi tiếp tục cải thiện khả năng tự động hóa của mình.
Dưới đây là sơ đồ về cách hoạt động của playbook theo thuật ngữ Ansible. Sơ đồ này phản ánh những gì chúng tôi đã mô tả ở trên, đây chỉ là một cách triển khai cụ thể trong Ansible.
Tự động hóa mạng. Một trường hợp từ cuộc sống của một người

Ở giai đoạn này, chúng tôi đã nhận ra những gì cần phải làm, phát triển cẩm nang, tiến hành thử nghiệm và bây giờ chúng tôi đã sẵn sàng ra mắt cẩm nang đó.

Một sự lạc đề trữ tình nhỏ khác. Sự dễ dàng của câu chuyện không nên đánh lừa bạn. Quá trình viết playbook không đơn giản và nhanh chóng như người ta tưởng. Việc thử nghiệm mất khá nhiều thời gian, một giá đỡ ảo được tạo ra, giải pháp được thử nghiệm nhiều lần, khoảng 100 thử nghiệm được thực hiện.

Hãy khởi động... Có cảm giác mọi thứ diễn ra rất chậm, có sai sót ở đâu đó, cuối cùng sẽ có điều gì đó không ổn. Cảm giác khi nhảy dù nhưng dù không muốn bung ra ngay… điều này là bình thường.

Tiếp theo, chúng tôi đọc kết quả của các hoạt động được thực hiện của Playbook Ansible (địa chỉ IP đã được thay thế vì mục đích bảo mật):

[xxx@emergency ansible]$ ansible-playbook -i /etc/ansible/inventories/prod_inventory.ini /etc/ansible/playbooks/emergency_on.yml 

PLAY [------->Emergency on VCF] ********************************************************

TASK [vcf_junos_emergency_on : Disable PROD interfaces to FW-CLUSTER] *********************
changed: [vcf]

PLAY [------->Emergency on MGMT-CORE] ************************************************

TASK [mgmt_junos_emergency_on : Disable MGMT interfaces to FW-CLUSTER] ******************
changed: [m9-03-sw-03-mgmt-core]

PLAY [------->Emergency on] ****************************************************

TASK [mk_routeros_emergency_on : Enable EXT-INTERNET interface] **************************
changed: [m9-04-r-04]

TASK [mk_routeros_emergency_on : Generate gARP for EXT-INTERNET interface] ****************
changed: [m9-04-r-04]

TASK [mk_routeros_emergency_on : Enable static default route to EXT-INTERNET] ****************
changed: [m9-04-r-04]

TASK [mk_routeros_emergency_on : Change NAT rule to EXT-INTERNET interface] ****************
changed: [m9-04-r-04] => (item=12)
changed: [m9-04-r-04] => (item=14)
changed: [m9-04-r-04] => (item=15)
changed: [m9-04-r-04] => (item=16)
changed: [m9-04-r-04] => (item=17)

TASK [mk_routeros_emergency_on : Enable OSPF Area 1 PROD] ******************************
changed: [m9-04-r-04]

TASK [mk_routeros_emergency_on : Enable OSPF Area 2 MGMT] *****************************
changed: [m9-04-r-04]

TASK [mk_routeros_emergency_on : Change OSPF Area 1 interfaces costs to 10] *****************
changed: [m9-04-r-04] => (item=VLAN-1001)
changed: [m9-04-r-04] => (item=VLAN-1002)
changed: [m9-04-r-04] => (item=VLAN-1003)
changed: [m9-04-r-04] => (item=VLAN-1004)
changed: [m9-04-r-04] => (item=VLAN-1005)
changed: [m9-04-r-04] => (item=VLAN-1006)
changed: [m9-04-r-04] => (item=VLAN-1007)
changed: [m9-04-r-04] => (item=VLAN-1008)
changed: [m9-04-r-04] => (item=VLAN-1009)
changed: [m9-04-r-04] => (item=VLAN-1010)
changed: [m9-04-r-04] => (item=VLAN-1011)
changed: [m9-04-r-04] => (item=VLAN-1012)
changed: [m9-04-r-04] => (item=VLAN-1013)
changed: [m9-04-r-04] => (item=VLAN-1100)

TASK [mk_routeros_emergency_on : Change OSPF area1 default cost for to 10] ******************
changed: [m9-04-r-04]

TASK [mk_routeros_emergency_on : Change MGMT interfaces ip addresses] ********************
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n.254', u'name': u'VLAN-803'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+1.254', u'name': u'VLAN-805'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+2.254', u'name': u'VLAN-807'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+3.254', u'name': u'VLAN-809'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+4.254', u'name': u'VLAN-820'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+5.254', u'name': u'VLAN-822'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+6.254', u'name': u'VLAN-823'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+7.254', u'name': u'VLAN-824'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+8.254', u'name': u'VLAN-850'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+9.254', u'name': u'VLAN-851'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+10.254', u'name': u'VLAN-852'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+11.254', u'name': u'VLAN-853'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+12.254', u'name': u'VLAN-870'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+13.254', u'name': u'VLAN-898'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+14.254', u'name': u'VLAN-899'})

TASK [mk_routeros_emergency_on : Generate gARPs for MGMT interfaces] *********************
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n.254', u'name': u'VLAN-803'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+1.254', u'name': u'VLAN-805'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+2.254', u'name': u'VLAN-807'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+3.254', u'name': u'VLAN-809'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+4.254', u'name': u'VLAN-820'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+5.254', u'name': u'VLAN-822'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+6.254', u'name': u'VLAN-823'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+7.254', u'name': u'VLAN-824'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+8.254', u'name': u'VLAN-850'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+9.254', u'name': u'VLAN-851'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+10.254', u'name': u'VLAN-852'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+11.254', u'name': u'VLAN-853'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+12.254', u'name': u'VLAN-870'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+13.254', u'name': u'VLAN-898'})
changed: [m9-04-r-04] => (item={u'ip': u'х.х.n+14.254', u'name': u'VLAN-899'})

PLAY RECAP ************************************************************************

Xong!

Trên thực tế, nó vẫn chưa hoàn toàn sẵn sàng, đừng quên sự hội tụ của các giao thức định tuyến động và tải một số lượng lớn các tuyến đường vào FIB. Chúng tôi không thể ảnh hưởng đến điều này bằng bất kỳ cách nào. Chúng tôi đợi. Nó đã thành công. Bây giờ nó đã sẵn sàng.

Và tại làng Vilabajo (nơi không muốn tự động hóa việc thiết lập mạng), họ vẫn tiếp tục rửa bát. Bruce (phải thừa nhận là đã khác biệt nhưng không kém phần ngầu) đang cố gắng tìm hiểu xem việc cấu hình lại thiết bị theo cách thủ công sẽ diễn ra bao nhiêu lần nữa.

Tự động hóa mạng. Một trường hợp từ cuộc sống của một người

Tôi cũng muốn tập trung vào một điểm quan trọng. Làm thế nào chúng ta có thể lấy lại mọi thứ? Sau một thời gian, chúng tôi sẽ đưa FW-CLUSTER của mình hoạt động trở lại. Đây là thiết bị chính, không phải thiết bị dự phòng, mạng phải chạy trên đó.

Bạn có cảm thấy các nhà mạng đang bắt đầu kiệt sức như thế nào không? Giám đốc kỹ thuật sẽ nghe thấy hàng ngàn lý lẽ tại sao việc này không nên làm, tại sao việc này có thể làm sau. Thật không may, đây là cách mạng hoạt động từ một loạt các bản vá, phần và tàn tích của sự xa xỉ trước đây của nó. Hóa ra là một chiếc chăn chắp vá. Nhiệm vụ của chúng tôi nói chung, không phải trong tình huống cụ thể này, mà về nguyên tắc chung, với tư cách là các chuyên gia CNTT, là đưa công việc của mạng trở thành từ tiếng Anh đẹp đẽ “tính nhất quán”, nó rất nhiều nghĩa, có thể dịch là: mạch lạc , tính nhất quán, tính logic, tính mạch lạc, tính hệ thống, tính so sánh được, tính mạch lạc. Tất cả là về anh ấy. Chỉ ở trạng thái này, mạng mới có thể quản lý được, chúng tôi hiểu rõ cái gì hoạt động và như thế nào, chúng tôi hiểu rõ những gì cần thay đổi, nếu cần, chúng tôi biết rõ phải tìm ở đâu nếu có vấn đề phát sinh. Và chỉ trong mạng lưới như vậy, bạn mới có thể thực hiện các thủ thuật như những thủ thuật mà chúng tôi vừa mô tả.

Trên thực tế, một playbook khác đã được chuẩn bị để đưa các cài đặt về trạng thái ban đầu. Logic hoạt động của nó là như nhau (điều quan trọng cần nhớ là thứ tự các nhiệm vụ là rất quan trọng), để không kéo dài một bài viết vốn đã khá dài, chúng tôi quyết định không đăng danh sách thực thi playbook. Sau khi thực hiện những bài tập như vậy, bạn sẽ cảm thấy bình tĩnh và tự tin hơn rất nhiều trong tương lai, hơn nữa, bất kỳ chiếc nạng nào bạn chất lên đó sẽ ngay lập tức lộ diện.

Bất kỳ ai cũng có thể viết thư cho chúng tôi và nhận nguồn của tất cả các mã đã viết, cùng với tất cả các sách màu. Danh bạ trong hồ sơ.

Những phát hiện

Theo chúng tôi, các quy trình có thể được tự động hóa vẫn chưa được kết tinh. Dựa trên những gì chúng tôi đã gặp và những gì các đồng nghiệp phương Tây đang thảo luận, cho đến nay có thể thấy các chủ đề sau:

  • Cung cấp thiết bị;
  • Thu thập dữ liệu;
  • Báo cáo;
  • Xử lý sự cố;
  • Tuân thủ.

Nếu có hứng thú, chúng ta có thể tiếp tục thảo luận về một trong những chủ đề nhất định.

Tôi cũng muốn nói một chút về tự động hóa. Theo sự hiểu biết của chúng tôi thì nó nên như thế nào:

  • Hệ thống phải tồn tại mà không cần con người, đồng thời được cải thiện bởi con người. Hệ thống không nên phụ thuộc vào con người;
  • Hoạt động phải là chuyên gia. Không có lớp chuyên gia nào thực hiện các công việc thường ngày. Có những chuyên gia đã tự động hóa toàn bộ quy trình và chỉ giải quyết những vấn đề phức tạp;
  • Các tác vụ tiêu chuẩn thường xuyên được thực hiện tự động “chỉ bằng một nút bấm”, không lãng phí tài nguyên. Kết quả của những nhiệm vụ như vậy luôn có thể dự đoán được và dễ hiểu.

Và những điểm này sẽ dẫn đến điều gì:

  • Tính minh bạch của cơ sở hạ tầng CNTT (Ít rủi ro trong vận hành, hiện đại hóa, triển khai. Ít thời gian ngừng hoạt động mỗi năm hơn);
  • Khả năng lập kế hoạch tài nguyên CNTT (Hệ thống lập kế hoạch năng lực - bạn có thể xem mức tiêu thụ, bạn có thể xem số lượng tài nguyên được yêu cầu trong một hệ thống chứ không phải bằng thư từ và các chuyến thăm tới các bộ phận hàng đầu);
  • Khả năng giảm số lượng nhân viên CNTT.

Tác giả của bài viết: Alexander Chelovekov (CCIE RS, CCIE SP) và Pavel Kirillov. Chúng tôi quan tâm thảo luận và đề xuất giải pháp về chủ đề tự động hóa cơ sở hạ tầng CNTT.


Nguồn: www.habr.com

Thêm một lời nhận xét