Εξοικονομήστε κόστος στο cloud Kubernetes στο AWS

Η μετάφραση του άρθρου ετοιμάστηκε την παραμονή της έναρξης του μαθήματος "Πλατφόρμα υποδομής βασισμένη στο Kubernetes".

Εξοικονομήστε κόστος στο cloud Kubernetes στο AWS

Πώς να εξοικονομήσετε κόστος στο cloud όταν εργάζεστε με την Kubernetes; Δεν υπάρχει ενιαία σωστή λύση, αλλά αυτό το άρθρο περιγράφει πολλά εργαλεία που μπορούν να σας βοηθήσουν να διαχειριστείτε τους πόρους σας πιο αποτελεσματικά και να μειώσετε το κόστος υπολογισμού νέφους.

Έγραψα αυτό το άρθρο έχοντας κατά νου το Kubernetes για το AWS, αλλά θα ισχύει (σχεδόν) ακριβώς με τον ίδιο τρόπο και σε άλλους παρόχους cloud. Υποθέτω ότι το σύμπλεγμα σας έχει ήδη διαμορφώσει την αυτόματη κλιμάκωση (cluster-autoscaler). Η κατάργηση πόρων και η μείωση της ανάπτυξής σας θα εξοικονομήσει χρήματα μόνο εάν μειώσει επίσης τον στόλο των εργαζομένων σας κόμβων (περιπτώσεις EC2).

Αυτό το άρθρο θα καλύψει:

  • καθαρισμός αχρησιμοποίητων πόρων (kube-θυροφύλακας)
  • Μειώστε την κλιμάκωση κατά τις μη εργάσιμες ώρες (kube-downscaler)
  • χρησιμοποιώντας οριζόντια αυτόματη κλιμάκωση (HPA),
  • μείωση της υπερβολικής δέσμευσης πόρων (kube-resource-report, VPA)
  • χρησιμοποιώντας στιγμιότυπα Spot

Καθαρισμός αχρησιμοποίητων πόρων

Η εργασία σε περιβάλλον με γρήγορους ρυθμούς είναι εξαιρετική. Θέλουμε τεχνολογικούς οργανισμούς επιταχύνθηκε. Ταχύτερη παράδοση λογισμικού σημαίνει επίσης περισσότερες αναπτύξεις δημοσίων σχέσεων, περιβάλλοντα προεπισκόπησης, πρωτότυπα και λύσεις αναλυτικών στοιχείων. Όλα έχουν αναπτυχθεί στο Kubernetes. Ποιος έχει το χρόνο να καθαρίσει χειροκίνητα τις δοκιμαστικές αναπτύξεις; Είναι εύκολο να ξεχάσετε τη διαγραφή ενός πειράματος μιας εβδομάδας. Ο λογαριασμός cloud θα καταλήξει να αυξάνεται λόγω κάτι που ξεχάσαμε να κλείσουμε:

Εξοικονομήστε κόστος στο cloud Kubernetes στο AWS

(Χένινγκ Τζέικομπς:
Zhiza:
(αποσπάσματα) Corey Quinn:
Μύθος: Ο λογαριασμός σας AWS είναι συνάρτηση του αριθμού των χρηστών που έχετε.
Γεγονός: Η βαθμολογία σας στο AWS είναι συνάρτηση του αριθμού των μηχανικών που έχετε.

Ivan Kurnosov (σε απάντηση):
Πραγματικό γεγονός: Η βαθμολογία AWS είναι συνάρτηση του αριθμού των πραγμάτων που ξεχάσατε να απενεργοποιήσετε/διαγράψετε.)

Επιστάτης Kubernetes (kube-janitor) βοηθά να καθαρίσετε το σύμπλεγμα σας. Η διαμόρφωση θυρωρού είναι ευέλικτη τόσο για παγκόσμια όσο και για τοπική χρήση:

  • Οι κανόνες σε όλο το σύμπλεγμα μπορούν να ορίσουν τον μέγιστο χρόνο ζωής (TTL) για αναπτύξεις PR/δοκιμών.
  • Οι μεμονωμένοι πόροι μπορούν να σχολιαστούν με janitor/ttl, για παράδειγμα για αυτόματη αφαίρεση του spike/prototype μετά από 7 ημέρες.

Οι γενικοί κανόνες ορίζονται στο αρχείο YAML. Η διαδρομή του περνά μέσα από την παράμετρο --rules-file στο kube-janitor. Ακολουθεί ένα παράδειγμα κανόνα για την κατάργηση όλων των χώρων ονομάτων -pr- στο όνομα μετά από δύο ημέρες:

- id: cleanup-resources-from-pull-requests
  resources:
    - namespaces
  jmespath: "contains(metadata.name, '-pr-')"
  ttl: 2d

Το ακόλουθο παράδειγμα ρυθμίζει τη χρήση της ετικέτας εφαρμογής στα pod Deployment και StatefulSet για όλες τις νέες Deployments/StatefulSets το 2020, αλλά ταυτόχρονα επιτρέπει την εκτέλεση δοκιμών χωρίς αυτήν την ετικέτα για μια εβδομάδα:

- id: require-application-label
  # удалить deployments и statefulsets без метки "application"
  resources:
    - deployments
    - statefulsets
  # см. http://jmespath.org/specification.html
  jmespath: "!(spec.template.metadata.labels.application) && metadata.creationTimestamp > '2020-01-01'"
  ttl: 7d

Εκτελέστε μια επίδειξη περιορισμένου χρόνου για 30 λεπτά σε ένα σύμπλεγμα που εκτελεί το kube-janitor:

kubectl run nginx-demo --image=nginx
kubectl annotate deploy nginx-demo janitor/ttl=30m

Μια άλλη πηγή αυξανόμενου κόστους είναι οι μόνιμοι όγκοι (AWS EBS). Η διαγραφή ενός Kubernetes StatefulSet δεν διαγράφει τους μόνιμους τόμους του (PVC - PersistentVolumeClaim). Οι αχρησιμοποίητοι τόμοι EBS μπορούν εύκολα να οδηγήσουν σε κόστος εκατοντάδων δολαρίων ανά μήνα. Το Kubernetes Janitor έχει μια δυνατότητα καθαρισμού αχρησιμοποίητων PVC. Για παράδειγμα, αυτός ο κανόνας θα καταργήσει όλα τα PVC που δεν είναι τοποθετημένα από μια μονάδα και τα οποία δεν αναφέρονται από StatefulSet ή CronJob:

# удалить все PVC, которые не смонтированы и на которые не ссылаются StatefulSets
- id: remove-unused-pvcs
  resources:
  - persistentvolumeclaims
  jmespath: "_context.pvc_is_not_mounted && _context.pvc_is_not_referenced"
  ttl: 24h

Το Kubernetes Janitor μπορεί να σας βοηθήσει να διατηρήσετε το cluster σας καθαρό και να αποτρέψετε την αργή συσσώρευση του κόστους υπολογιστικού νέφους. Για οδηγίες ανάπτυξης και διαμόρφωσης, ακολουθήστε README kube-janitor.

Μειώστε την κλιμάκωση κατά τις μη εργάσιμες ώρες

Τα συστήματα δοκιμής και σταδιοποίησης απαιτούνται συνήθως για λειτουργία μόνο κατά τις εργάσιμες ώρες. Ορισμένες εφαρμογές παραγωγής, όπως τα εργαλεία back office/admin, απαιτούν επίσης περιορισμένη διαθεσιμότητα και ενδέχεται να απενεργοποιηθούν κατά τη διάρκεια της νύχτας.

Kubernetes Downscaler (kube-downscaler) επιτρέπει στους χρήστες και τους χειριστές να μειώσουν το σύστημα κατά τις μη εργάσιμες ώρες. Οι αναπτύξεις και τα StatefulSets μπορούν να κλιμακωθούν σε μηδενικά αντίγραφα. Το CronJobs ενδέχεται να ανασταλεί. Το Kubernetes Downscaler έχει ρυθμιστεί για ένα ολόκληρο σύμπλεγμα, έναν ή περισσότερους χώρους ονομάτων ή μεμονωμένους πόρους. Μπορείτε να ορίσετε είτε "χρόνο αδράνειας" ή, αντίθετα, "χρόνο εργασίας". Για παράδειγμα, για να μειώσετε όσο το δυνατόν περισσότερο την κλιμάκωση κατά τη διάρκεια της νύχτας και των Σαββατοκύριακων:

image: hjacobs/kube-downscaler:20.4.3
args:
  - --interval=30
  # не отключать компоненты инфраструктуры
  - --exclude-namespaces=kube-system,infra
  # не отключать kube-downscaler, а также оставить Postgres Operator, чтобы исключенными БД можно было управлять
  - --exclude-deployments=kube-downscaler,postgres-operator
  - --default-uptime=Mon-Fri 08:00-20:00 Europe/Berlin
  - --include-resources=deployments,statefulsets,stacks,cronjobs
  - --deployment-time-annotation=deployment-time

Ακολουθεί ένα γράφημα για την κλιμάκωση των κόμβων εργασίας συμπλέγματος τα Σαββατοκύριακα:

Εξοικονομήστε κόστος στο cloud Kubernetes στο AWS

Η μείωση από ~13 σε 4 κόμβους εργαζομένων σίγουρα κάνει μια αξιοσημείωτη διαφορά στον λογαριασμό AWS σας.

Τι γίνεται όμως αν χρειαστεί να δουλέψω κατά τη διάρκεια της «διακοπής λειτουργίας» του συμπλέγματος; Ορισμένες αναπτύξεις μπορούν να εξαιρεθούν οριστικά από την κλιμάκωση προσθέτοντας το downscaler/exclude: true σχολιασμός. Οι αναπτύξεις μπορούν να εξαιρεθούν προσωρινά χρησιμοποιώντας τον σχολιασμό μείωσης κλίμακας/εξαίρεση-μέχρι σχολιασμού με απόλυτη χρονική σήμανση στη μορφή ΕΕΕΕ-ΜΜ-ΗΗ ΩΩ:ΜΛ (UTC). Εάν είναι απαραίτητο, ολόκληρο το σύμπλεγμα μπορεί να μειωθεί, αναπτύσσοντας μια ομάδα με τον σχολιασμό downscaler/force-uptime, για παράδειγμα, εκκινώντας το nginx blank:

kubectl run scale-up --image=nginx
kubectl annotate deploy scale-up janitor/ttl=1h # удалить развертывание через час
kubectl annotate pod $(kubectl get pod -l run=scale-up -o jsonpath="{.items[0].metadata.name}") downscaler/force-uptime=true

Βλέπω README kube-downscaler, εάν ενδιαφέρεστε για οδηγίες ανάπτυξης και πρόσθετες επιλογές.

Χρησιμοποιήστε οριζόντια αυτόματη κλιμάκωση

Πολλές εφαρμογές/υπηρεσίες αντιμετωπίζουν ένα δυναμικό μοτίβο φόρτωσης: μερικές φορές οι μονάδες τους είναι αδρανείς και μερικές φορές λειτουργούν με πλήρη χωρητικότητα. Η λειτουργία ενός μόνιμου στόλου λοβών για την αντιμετώπιση του μέγιστου φορτίου αιχμής δεν είναι οικονομική. Το Kubernetes υποστηρίζει οριζόντια αυτόματη κλιμάκωση σε έναν πόρο HorizontalPodAutoscaler (HPA). Η χρήση της CPU είναι συχνά ένας καλός δείκτης για την κλιμάκωση:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        averageUtilization: 100
        type: Utilization

Η Zalando έχει δημιουργήσει ένα στοιχείο για να συνδέει εύκολα προσαρμοσμένες μετρήσεις για κλιμάκωση: Προσαρμογέας Kube Metrics (kube-metrics-adapter) είναι ένας γενικός προσαρμογέας μετρήσεων για το Kubernetes που μπορεί να συλλέγει και να εξυπηρετεί προσαρμοσμένες και εξωτερικές μετρήσεις για οριζόντια αυτόματη κλιμάκωση ομάδων. Υποστηρίζει κλιμάκωση με βάση τις μετρήσεις του Prometheus, τις ουρές SQS και άλλες ρυθμίσεις. Για παράδειγμα, για να κλιμακώσετε την ανάπτυξή σας σε μια προσαρμοσμένη μέτρηση που αντιπροσωπεύεται από την ίδια την εφαρμογή ως JSON στο /metrics, χρησιμοποιήστε:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
  annotations:
    # metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
    metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps"
    metric-config.pods.requests-per-second.json-path/path: /metrics
    metric-config.pods.requests-per-second.json-path/port: "9090"
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: requests-per-second
      target:
        averageValue: 1k
        type: AverageValue

Η διαμόρφωση της οριζόντιας αυτόματης κλιμάκωσης με HPA θα πρέπει να είναι μία από τις προεπιλεγμένες ενέργειες για τη βελτίωση της αποτελεσματικότητας για υπηρεσίες χωρίς ιθαγένεια. Το Spotify έχει μια παρουσίαση με την εμπειρία και τις συστάσεις του για το HPA: κλιμακώστε τις αναπτύξεις σας, όχι το πορτοφόλι σας.

Μειώστε τις υπερκρατήσεις πόρων

Οι φόρτοι εργασίας του Kubernetes καθορίζουν τις ανάγκες τους σε CPU/μνήμη μέσω "αιτημάτων πόρων". Οι πόροι της CPU μετρώνται σε εικονικούς πυρήνες ή πιο συχνά σε "millicores", για παράδειγμα 500m συνεπάγεται 50% vCPU. Οι πόροι μνήμης μετρώνται σε byte και μπορούν να χρησιμοποιηθούν κοινά επιθήματα, όπως 500Mi, που σημαίνει 500 megabyte. Τα αιτήματα πόρων "κλειδώνουν" χωρητικότητα σε κόμβους εργαζομένων, πράγμα που σημαίνει ότι ένα pod με αίτημα CPU 1000m σε έναν κόμβο με 4 vCPU θα αφήσει μόνο 3 vCPU διαθέσιμες σε άλλα pods. [1]

Χαλαρή (υπερβολική ρεζέρβα) είναι η διαφορά μεταξύ των ζητούμενων πόρων και της πραγματικής χρήσης. Για παράδειγμα, ένα pod που ζητά 2 GiB μνήμης αλλά χρησιμοποιεί μόνο 200 MiB έχει ~1,8 GiB "υπερβάλλουσα" μνήμη. Το υπερβολικό κοστίζει. Μπορεί κανείς να υπολογίσει χονδρικά ότι 1 GiB πλεονάζουσας μνήμης κοστίζει ~ 10$ το μήνα. [2]

Αναφορά πόρων Kubernetes (kube-resource-report) εμφανίζει τα πλεονάζοντα αποθέματα και μπορεί να σας βοηθήσει να προσδιορίσετε τις δυνατότητες εξοικονόμησης:

Εξοικονομήστε κόστος στο cloud Kubernetes στο AWS

Αναφορά πόρων Kubernetes δείχνει την περίσσεια που συγκεντρώνεται κατά εφαρμογή και εντολή. Αυτό σας επιτρέπει να βρείτε μέρη όπου οι απαιτήσεις πόρων μπορούν να μειωθούν. Η αναφορά HTML που δημιουργήθηκε παρέχει μόνο ένα στιγμιότυπο της χρήσης πόρων. Θα πρέπει να εξετάσετε τη χρήση της CPU/μνήμης με την πάροδο του χρόνου για να προσδιορίσετε επαρκείς αιτήσεις πόρων. Ακολουθεί ένα γράφημα Grafana για μια "τυπική" υπηρεσία με μεγάλη CPU: όλα τα pods χρησιμοποιούν σημαντικά λιγότερους από τους 3 πυρήνες CPU που ζητήθηκαν:

Εξοικονομήστε κόστος στο cloud Kubernetes στο AWS

Η μείωση του αιτήματος CPU από 3000m σε ~400m απελευθερώνει πόρους για άλλους φόρτους εργασίας και επιτρέπει στο σύμπλεγμα να είναι μικρότερο.

"Η μέση χρήση CPU των παρουσιών EC2 συχνά αιωρείται στο μονοψήφιο ποσοστό", γράφει ο Corey Quinn. Ενώ για EC2 Η εκτίμηση του σωστού μεγέθους μπορεί να είναι μια κακή απόφασηΗ αλλαγή ορισμένων ερωτημάτων πόρων Kubernetes σε ένα αρχείο YAML είναι εύκολη και μπορεί να αποφέρει τεράστια εξοικονόμηση πόρων.

Θέλουμε όμως πραγματικά οι άνθρωποι να αλλάζουν τιμές στα αρχεία YAML; Όχι, οι μηχανές μπορούν να το κάνουν πολύ καλύτερα! Kubernetes Vertical Pod Autoscaler (VPA) κάνει ακριβώς αυτό: προσαρμόζει τα αιτήματα πόρων και τους περιορισμούς ανάλογα με τον φόρτο εργασίας. Ακολουθεί ένα παράδειγμα γραφήματος των αιτημάτων CPU του Prometheus (λεπτή μπλε γραμμή) προσαρμοσμένα από το VPA με την πάροδο του χρόνου:

Εξοικονομήστε κόστος στο cloud Kubernetes στο AWS

Το Zalando χρησιμοποιεί VPA σε όλα τα cluster του για στοιχεία υποδομής. Οι μη κρίσιμες εφαρμογές μπορούν επίσης να χρησιμοποιούν VPA.

Goldilocks από το Fairwind είναι ένα εργαλείο που δημιουργεί ένα VPA για κάθε ανάπτυξη σε έναν χώρο ονομάτων και στη συνέχεια εμφανίζει μια πρόταση VPA στον πίνακα εργαλείων του. Μπορεί να βοηθήσει τους προγραμματιστές να ορίσουν τα σωστά αιτήματα CPU/μνήμης για τις εφαρμογές τους:

Εξοικονομήστε κόστος στο cloud Kubernetes στο AWS

Έγραψα ένα μικρό ανάρτηση ιστολογίου σχετικά με το VPA το 2019 και πρόσφατα σε Η Κοινότητα τελικών χρηστών CNCF συζήτησε το ζήτημα της VPA.

Χρήση EC2 Spot Instances

Τελευταίο αλλά εξίσου σημαντικό, το κόστος AWS EC2 μπορεί να μειωθεί χρησιμοποιώντας στιγμιότυπα Spot ως κόμβους εργαζομένων Kubernetes [3]. Τα σποτ διατίθενται με έκπτωση έως και 90% σε σύγκριση με τις τιμές κατ' απαίτηση. Η εκτέλεση του Kubernetes στο EC2 Spot είναι ένας καλός συνδυασμός: πρέπει να καθορίσετε πολλούς διαφορετικούς τύπους παρουσιών για μεγαλύτερη διαθεσιμότητα, που σημαίνει ότι μπορείτε να αποκτήσετε μεγαλύτερο κόμβο για την ίδια ή χαμηλότερη τιμή και η αυξημένη χωρητικότητα μπορεί να χρησιμοποιηθεί από φόρτους εργασίας Kubernetes με κοντέινερ.

Πώς να εκτελέσετε το Kubernetes στο EC2 Spot; Υπάρχουν πολλές επιλογές: χρησιμοποιήστε μια υπηρεσία τρίτου μέρους όπως το SpotInst (τώρα ονομάζεται "Spot", μην με ρωτήσετε γιατί) ή απλώς προσθέστε μια Spot AutoScalingGroup (ASG) στο σύμπλεγμα σας. Για παράδειγμα, εδώ είναι ένα απόσπασμα CloudFormation για ένα Spot ASG "βελτιστοποιημένο για χωρητικότητα" με πολλούς τύπους παρουσιών:

MySpotAutoScalingGroup:
 Properties:
   HealthCheckGracePeriod: 300
   HealthCheckType: EC2
   MixedInstancesPolicy:
     InstancesDistribution:
       OnDemandPercentageAboveBaseCapacity: 0
       SpotAllocationStrategy: capacity-optimized
     LaunchTemplate:
       LaunchTemplateSpecification:
         LaunchTemplateId: !Ref LaunchTemplate
         Version: !GetAtt LaunchTemplate.LatestVersionNumber
       Overrides:
         - InstanceType: "m4.2xlarge"
         - InstanceType: "m4.4xlarge"
         - InstanceType: "m5.2xlarge"
         - InstanceType: "m5.4xlarge"
         - InstanceType: "r4.2xlarge"
         - InstanceType: "r4.4xlarge"
   LaunchTemplate:
     LaunchTemplateId: !Ref LaunchTemplate
     Version: !GetAtt LaunchTemplate.LatestVersionNumber
   MinSize: 0
   MaxSize: 100
   Tags:
   - Key: k8s.io/cluster-autoscaler/node-template/label/aws.amazon.com/spot
     PropagateAtLaunch: true
     Value: "true"

Μερικές σημειώσεις σχετικά με τη χρήση του Spot με το Kubernetes:

  • Πρέπει να χειριστείτε τους τερματισμούς Spot, για παράδειγμα με τη συγχώνευση του κόμβου όταν η παρουσία σταματά
  • Zalando χρησιμοποιεί πιρούνι επίσημη αυτόματη κλιμάκωση συμπλέγματος με προτεραιότητες συγκέντρωσης κόμβων
  • Σημειακοί κόμβοι μπορεί να αναγκαστεί αποδεχτείτε «εγγραφές» φόρτου εργασίας για εκτέλεση στο Spot

Περίληψη

Ελπίζω να βρείτε μερικά από τα εργαλεία που παρουσιάζονται χρήσιμα για τη μείωση του λογαριασμού σας στο cloud. Μπορείτε επίσης να βρείτε τα περισσότερα από τα περιεχόμενα του άρθρου στη διεύθυνση η ομιλία μου στο DevOps Gathering 2019 στο YouTube και σε διαφάνειες.

Ποιες είναι οι βέλτιστες πρακτικές σας για την εξοικονόμηση κόστους στο cloud στο Kubernetes; Παρακαλώ ενημερώστε με στο Twitter (@try_except_).

[1] Στην πραγματικότητα, λιγότερο από 3 vCPU θα παραμείνουν χρησιμοποιήσιμα καθώς η απόδοση του κόμβου μειώνεται από τους δεσμευμένους πόρους του συστήματος. Το Kubernetes κάνει διάκριση μεταξύ φυσικής χωρητικότητας κόμβου και "παρεχόμενων" πόρων (Κατανομή κόμβου).

[2] Παράδειγμα υπολογισμού: ένα στιγμιότυπο m5.large με μνήμη 8 GiB είναι ~$84 ​​ανά μήνα (eu-central-1, On-Demand), δηλ. Ο αποκλεισμός του κόμβου 1/8 είναι περίπου ~10$/μήνα.

[3] Υπάρχουν πολλοί περισσότεροι τρόποι για να μειώσετε τον λογαριασμό EC2, όπως Δεσμευμένες περιπτώσεις, Πρόγραμμα Αποταμίευσης κ.λπ. - Δεν θα καλύψω αυτά τα θέματα εδώ, αλλά θα πρέπει οπωσδήποτε να τα εξετάσετε!

Μάθετε περισσότερα για το μάθημα.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο