ორი ტრაფიკის მიმართულება, ერთი ყუთი
კეთილი იყოს თქვენი მობრძანება
არქიტექტურის დიაგრამების უმეტესობა ტრაფიკს მხოლოდ ერთი მიმართულებით აჩვენებს: კლიენტი ზემოთ, სერვერი ქვემოთ, ისარი ქვევით მიუთითებს. რეალობაში ტრაფიკი ორივე მიმართულებით მოძრაობს.
Ingress: გარე კლიენტები თქვენს სერვისებს ამ გზით აღწევენ. საზღვარზე მდებარე რევერსული პროქსი ასრულებს TLS-ის ტერმინაციას, აწესრიგებს მოთხოვნებს და აღასრულებს წვდომის წესებს.
Egress: თქვენი სერვისები გარე სერვისებს ამ გზით აღწევენ. გადახდის პროცესორის API-ის გამოძახება, webhook-ის მიზნის მიღება, პარტნიორთან მოთხოვნის გაგზავნა. ხშირად გამოიყენება წინ გამავალი პროქსი ან NAT გეიტვეი დაშვებული სიით (allowlist).
ბევრი არქიტექტურა იწყება ერთი ყუთით, რომელიც ორივე მიმართულებას ამუშავებს. ეს მუშაობს, სანამ ერთ დღეს აღარ მუშაობს. წარუმატებლობის რეჟიმი დახვეწილია, ჩნდება მხოლოდ მას შემდეგ, რაც საკმარისი შიდა სერვისები გაჩნდება, და გვასწავლის მნიშვნელოვან გაკვეთილს — პასუხისმგებლობების გამიჯვნის შესახებ.
ამ გაკვეთილის დასასრულს თქვენ გაიგებთ:
- რატომ წარმოადგენენ ingress და egress ფუნდამენტურად განსხვავებულ ტრაფიკის ნიმუშებს, რომლებსაც აქვთ განსხვავებული მასშტაბირების ღერძები და განსხვავებული წარუმატებლობის რეჟიმები
- Hairpin NAT-ს და იმას, თუ რატომ ვერ აკავშირებს პროქსი თავის თავთან
- არქიტექტურულ გაყოფას: ერთი ყუთი ხდება ორი, და რას ფლობს თითოეული მათგანი ექსკლუზიურად
- უსაფრთხოების იზოლაციის სარგებელს: თითოეულ მხარეს შეუძლია შეზღუდოს წვდომა მხოლოდ იმ რეალურ პარტნიორებზე, რომლებიც დაშვებულია
- როგორ გაარკვიოთ, რომ თქვენი ერთჯერადი ყუთის დიზაინი უკვე გადალახა იმ ზღვარს, სადაც გაყოფა აუცილებელი ხდება
რატომ მოითხოვს ორი მიმართულება განსხვავებულ ინსტრუმენტებს
ერთი ქსელის საზღვარზე ორი განსხვავებული დატვირთვა
შემომავალი ტრაფიკის (Ingress) მახასიათებლები:
- ინიცირებულია გარე მხარეების მიერ (ინტერნეტი მთლიანად)
- მოცულობა მასშტაბირდება თქვენი მომხმარებლების რაოდენობასთან ერთად
- TLS ტერმინაცია, მოთხოვნის რაუტინგი, წყაროს მიხედვით რეიტ ლიმიტირება
- ღრმა დაცვის საკითხები: DDoS, ბოროტად გამოყენება, სკრეპინგი
- საჯარო IP უნდა იღებდეს კავშირებს ნებისმიერისგან
გამავალი ტრაფიკის (Egress) მახასიათებლები:
- თქვენი საკუთარი სერვისებიდან ინიცირებული (ცნობილი, მცირე რაოდენობის კლიენტები)
- მოცულობა იზრდება თქვენი სერვის-სერვისსა და გარე API-ების გამოძახებების შაბლონებთან ერთად
- წყარო-IP-ის დაშვების სია (allowlisting) დაშორებულ endpoints-ზე (თქვენ გაქვთ ერთი ფიქსირებული გამავალი IP, რომელსაც პარტნიორები ენდობიან)
- თავდაცვის-სიღრმისეული საკითხები: მონაცემების გაჟონვა, კომპრომეტირებული შიდა სერვისების გარეთ გამოძახება
- უნდა უარყოფდეს კავშირებს ყველასგან, ვინც თქვენი საკუთარი სერვისები არ არის
ძირითადი ასიმეტრია: ingress-ი იღებს ტრაფიკს მსოფლიოდან; egress-ი კი იღებს ტრაფიკს მხოლოდ თქვენი საკუთარი სერვისებიდან. მათ ერთ მანქანაზე განთავსება ნიშნავს, რომ ეს მანქანა ერთდროულად უნდა იყოს მსოფლიოსთვის მისაწვდომი (ingress-ისთვის) და მხოლოდ თქვენი სერვისებისთვის მისაწვდომი (egress-ისთვის). firewall-ის წესები, რომლებიც ერთს აკმაყოფილებენ, მეორეს ეწინააღმდეგებიან.
განვითარების გზა: პატარა პროექტს შეუძლია ორივე ერთ IP-ს და ერთ ხელსაწყოს მიღმა დამალოს, რადგან მოცულობა მცირეა და პარტნიორ-IP-ების დაშვების სია მოკლე. პროექტის ზრდასთან ერთად ორ როლს შორის ხახუნი იზრდება და ერთ დღეს კონკრეტული შეცდომის რეჟიმი (hairpin NAT) აიძულებს გაყოფას.
ბაგი, რომელიც აიძულებს გაყოფას
გაწმენდილი გაუმართაობის ისტორია
წარმოიდგინეთ რეალური არქიტექტურული „ჩანგალი“ (fork), რომელიც პროდაქშენის ფლოტებში ხდება. ქვემოთ მოცემული სახელები შეცვლილია; სტრუქტურა კი იდენტურია იმისა, რასაც გუნდები რეალურად ხვდებიან.
ორგანიზაცია მართავს ერთ პროქსი სერვერს მისამართზე 203.0.113.5. ის ერთდროულად ამუშავებს შემომავალ ტრაფიკს (პორტი 443 მომხმარებლებისთვის) და გამავალ ტრაფიკს (პორტი 1080 SOCKS5 შიდა სერვისებისთვის, რომლებიც გარეთ უნდა გავიდნენ). შიდა სერვისები მდებარეობენ კერძო ქვექსელებში და მთელ გამავალ ტრაფიკს აგზავნიან ამ SOCKS5 პროქსის მეშვეობით 203.0.113.5:1080-ზე.
იგივე 203.0.113.5-ზე განთავსებული ერთ-ერთი სერვისია api.example.com. საჯარო DNS-ი api.example.com-ს აკავშირებს 203.0.113.5-თან.
ახლა სხვა შიდა სერვისს სჭირდება api.example.com-ის გამოძახება. მისი გამავალი მარშრუტი ასეთია:
1. შიდა სერვისი ამოხსნის api.example.com → 203.0.113.5
2. შიდა სერვისი თხოვნას აგზავნის SOCKS5 გამავალი პროქსის მეშვეობით 203.0.113.5:1080-ზე
3. პროქსი ცდილობს თავად გახსნას კავშირი საკუთარ თავთან, ანუ 203.0.113.5:443-ზე
All placeholders, formatting, IP addresses, domain names, and technical terms structure have been strictly preserved.
4. კავშირი უარყოფილია. პაკეტი უნდა გამოსულიყო და თავიდან შესულიყო იმავე NAT-ში, რასაც ქსელის უმეტესი სტეკები უარყოფენ. პროქსი ვერ უკავშირდება საკუთარ თავს საკუთარი საჯარო IP-ის მეშვეობით.
ეს არის hairpin NAT: პაკეტი, რომელიც გამოდის NAT-დან და უნდა თავიდან შევიდეს იმავე NAT-ში, რათა მიაღწიოს დანიშნულების ადგილამდე. სპეციალური hairpin მხარდაჭერის გარეშე რაუტინგის ფენაში, პაკეტი ჩამოიშლება.
რატომ ჩნდება ეს პრობლემა გვიან
პროექტის ადრეულ ეტაპზე ყველა შიდა სერვისი ან საუბრობდა სხვა შიდა სერვისებთან კერძო ჰოსტნეიმით (internal-api.local), ან საერთოდ არ უბრუნდებოდა საკუთარი ორგანიზაციის საჯარო სერვისებს. Hairpin-ის გზა უბრალოდ არ არსებობდა.
შემდეგ ახალმა ფუნქციამ მოითხოვა, რომ სერვის A-მ დაერეკა api.example.com-ზე (საჯარო ჰოსტნეიმი). Hairpin-ის გზა გააქტიურდა. კავშირი უარყოფილია. აუთეიჯი.
გამოსწორებამ შეაჩერა სიმპტომი (იძულებით მიეცა რეზოლვერს api.example.com-ის კერძო IP საჯაროს ნაცვლად). ძირითადი მიზეზი: ერთი მანქანა ძალიან ბევრ როლს ასრულებდა.
არქიტექტურული გაყოფა
ერთი ყუთი ხდება ორი
სუფთა გამოსავალი: პროქსის გაყოფა ორ მანქანად.
შემომავალი სერვერი (საჯარო IP 203.0.113.5):
- Caddy / რევერს პროქსი პორტებზე 80, 443
- საჯარო DNS ჩანაწერები აქ მიუთითებს
- მასპინძლობს api.example.com, app.example.com და სხვა
გამავალი სერვერი (სხვა საჯარო IP 203.0.113.99):
- SOCKS5 / წინ გადამისამართებელი პროქსი პორტ 1080-ზე
- ფაირვოლა ზღუდავს შემომავალ კავშირებს მხოლოდ შიდა ქვექსელის IP-ებზე
- შიდა სერვისები ყველა გამავალ ტრაფიკს ამ მისამართის გავლით აგზავნიან
რას გვაძლევს ეს:
1. Hairpin პრობლემა გადაწყვეტილია. შიდა სერვისი, რომელიც იძახებს api.example.com-ს, გამავალ ტრაფიკს გადის 203.0.113.99-ზე (egress), რომელიც შემდეგ ნორმალურად უკავშირდება 203.0.113.5-ს (ingress, სხვა IP). NAT-ის მარყუჟი ქრება, რადგან ორი IP სხვადასხვა მანქანაზეა.
2. უსაფრთხოების იზოლაცია. Egress სერვერის ფაირვოლას შეუძლია შეზღუდოს მხოლოდ მცირე რაოდენობის შიდა IP-ებზე. Ingress სერვერის ფაირვოლა კი ღია რჩება მთელი მსოფლიოსთვის. ორი განცალკევებული წესების კომპლექტი, თითოეული სუფთად გამოხატავს თავის როლს.
3. დამოუკიდებელი მასშტაბირება. Ingress-ის გ пропускная способность იზრდება მომხმარებლების რაოდენობასთან ერთად; egress-ის გ пропускная способность იზრდება შიდა სერვისების აქტივობასთან ერთად. ერთის განახლება შესაძლებელია მეორის შეხების გარეშე.
4. აღმოფხვრის იზოლაცია. არასწორად კონფიგურირებული egress აღარ აფუჭებს საჯარო საიტს. DDoS-ის თავდასხმა საჯარო საიტზე აღარ აყენებს egress-ის გ пропускная способность-ს შიმშილობას.
5. უფრო ნათელი მენტალური მოდელი. თითოეულ მანქანას აქვს ერთი კონკრეტული საქმე. ინჟინრებს შეუძლიათ იფიქრონ ingress-ის საკითხებზე egress-ის გათვალისწინების გარეშე, და პირიქით.
ორი ღერძი, ორი ზომის გადაწყვეტილება
დამოუკიდებელი მასშტაბირება
გაყოფამდე ზრდა ნებისმიერ მიმართულებაში ერთსა და იმავე მანქანას აწვდიდა სტრესს. გაყოფის შემდეგ თითოეულ მიმართულებას აქვს საკუთარი რესურსების განაწილება.
შემომავალი ტრაფიკის (Ingress) მასშტაბირება: მომხმარებლების რაოდენობასთან ერთად იზრდება. სიმძლავრის გადაწყვეტილებები მდებარეობს საჯარო ფენაში (reverse proxy-ის მეტი რეპლიკა, უფრო დიდი ვირტუალური მანქანები, CDN წინ). გამტარუნარიანობის ბიუჯეტი გამოითვლება მომხმარებლის ტრაფიკის პიკურ დატვირთვაზე.
გამავალი ტრაფიკის (Egress) მასშტაბირება: იზრდება შიდა სერვისებიდან გარე API-ებთან გამოძახებების მოცულობასთან ერთად. ხშირად დომინირებს webhook-ების გ рассылка, გადახდის პროცესორებთან კავშირი ან მესამე მხარის მონაცემების მიღება. გამტარუნარიანობის ბიუჯეტი გამოითვლება შიდა გამოძახებების შაბლონებზე.
აღმოჩენის იზოლაცია: საჯარო შემომავალი ტრაფიკის წინააღმდეგ მიმართული DDoS აღარ ჭამს გამავალი ტრაფიკის გამტარუნარიანობას (გადახდის პროცესორებთან კავშირები მაინც ხორციელდება). გამავალი პროქსის ავარია აღარ აჩერებს საჯარო საიტს (მომხმარებლები კვლავ ხედავენ საიტს; მხოლოდ შიდა გამავალი გამოძახებები ვერ მუშაობს).
განსხვავებული SLOები: შემომავალი ტრაფიკის ხელმისაწვდომობა მომხმარებლებისთვისაა მნიშვნელოვანი (ხილული გათიშვა); გამავალი ტრაფიკის ხელმისაწვდომობა ოპერატორებისთვისაა მნიშვნელოვანი (ფონური შეცდომები, რომლებიც შეიძლება გვიან აღმოაჩინონ). თითოეულ მხარეს შეუძლია ჰქონდეს საკუთარი SLO.
რამდენიმე გამავალი სერვერი
როგორც კი გამავალი როლი გახდება ცალკე მანქანა, შემდეგი ლოგიკური ნაბიჯია რამდენიმე გამავალი მანქანის გაშვება ლოდბალანსერის უკან მაღალი ხელმისაწვდომობისთვის (HA). ყველა ახალი შიდა სერვისი მიმართავს გამავალი ჰოსტნეიმს (რომელიც წყდება ლოდბალანსირებულ 풀ზე) და არა ერთ კონკრეტულ IP-ს.
დანარჩენი განაწილებული სისტემების გაკვეთილის მსგავსია: როგორც კი ტიერი უწყვეტი (stateless) ხდება და საკუთარ როლს იღებს, ის იაფად მრავლდება.
ახალი პარტნიორის ინტეგრაცია
თქვენი ორგანიზაცია მუშაობს შემოსული/გამომავალი (ingress/egress) გაყოფით, როგორც დაგეგმილი იყო. გამომავალი სერვერი აქვს ფიქსირებული საჯარო IP (203.0.113.99), რომელიც დამტკიცებული გაქვთ სამ არსებულ პარტნიორ API-თან (გადახდის პროცესორი, SMS გეიტვეი, ელფოსტის პროვაიდერი).
პროდუქტის გუნდი უნდა დაამატოს მეოთხე ინტეგრაცია: webhook-ების მიწოდების სისტემა, რომელიც მომხმარებლის endpoints-ებს უწოდებს მთელ მსოფლიოში. მოსალოდნელი მოცულობა: 10,000 ზარი წუთში, მწვერვალებით 30,000-მდე.
შექმენით ქსელის საზღვარი მზარდი სერვისისთვის
სინთეზი
თქვენ ისწავლეთ, რატომ საჭიროებს შემომავალი და გამავალი ტრაფიკი სხვადასხვა ინსტრუმენტებს, რა არის hairpin NAT-ის შეცდომა, რომელიც რეალურ ფლოტებში აიძულებს ამ გამიჯვნას, და როგორ გროვდება დამოუკიდებელი მასშტაბირება, უსაფრთხოების იზოლაცია და წარუმატებლობის იზოლაცია მას შემდეგ, რაც გამიჯვნა განხორციელდება.
გამოიყენეთ ყველა ოთხი.
საშუალო ზომის SaaS კომპანია მართავს სამ პროდუქტის ქვედომენს (app, api, admin) თავისი მომხმარებლებისთვის, პლუს ოთხ გამავალ ინტეგრაციას (Stripe, Twilio, SendGrid, მომხმარებლის webhook სისტემა). დღეს ყველაფერი ერთი პროქსი მანქანის უკან ერთ საჯარო IP-ზეა განთავსებული. მათ დაიწყეს მიღება ინტერმიტენტული hairpin შეცდომების შესახებ, როდესაც შიდა სერვისები ცდილობენ api.example.com-ზე დარეკვას. მათ სურთ შექმნან მუდმივი გადაწყვეტა.
სად მიდის ეს კურსი შემდეგ
სად მიდის ეს კურსი შემდეგ
თქვენ ახლახანს ნახეთ ერთ-ერთი ყველაზე სუფთა separation-of-concerns რეფაქტორინგი განაწილებულ სისტემებში: ერთი ყუთი ხდება ორი, თითოეული მათგანს აქვს ნათელი როლი, და სისტემა იღებს სკალირების, უსაფრთხოებისა და უკმარისობის იზოლაციის სარგებელს ამ გზით.
შემდეგი გაკვეთილი (cs_distsys_failure_modes_and_blast_radius) აგრძელებს ჩავარდნის იზოლაციის მსჯელობას. თქვენ წაიკითხავთ გაწმენდილ DNS-SERVFAIL-ის პოსტმორტემს, ამოიცნობთ კასკადური ჩავარდნის ნიმუშს და დაწერთ უდანაშაულო სამოქმედო პუნქტებს, რომლებიც მიზნად ისახავს სისტემებს, და არა ადამიანებს.
თანმხვედრი გაკვეთილი: geometry_of_ingress_egress_separation წარმოადგენს გაყოფას ორნაწილიანი გრაფის სახით და იკვლევს საჭრელ წვეროებს, ქსელის პარტიციებსა და იმას, რასაც გრაფთეორია გვეუბნება ქსელის საზღვარზე.
კარგად შეასრულეთ. წინსვლა.