Blog AWS Indonesia
Mengekspos Aplikasi Kubernetes, Bagian 2: AWS Load Balancer Controller
Perkenalan
Seri Mengekspos Aplikasi Kubernetes berfokus pada cara untuk mengekspos aplikasi yang berjalan di Kubernetes cluster untuk akses eksternal.
Di Bagian 1 dari seri ini, kami telah membahas tipe resource Service dan Ingress yang menentukan dua cara untuk mengontrol traffic masuk dalam Kubernetes cluster. Kita membahas penanganan tipe resource ini melalui Service dan Ingress controller, diikuti dengan gambaran umum kelebihan dan kekurangan beberapa varian implementasi controller.
Dalam posting ini, Bagian 2, kami memberikan gambaran umum tentang implementasi open-source AWS dari ingress controller, AWS Load Balancer Controller. Kita mendemonstrasikan pengaturan, konfigurasi, kemungkinan use case, dan limitasi controller.
Bagian 3 didedikasikan untuk memberi panduan serupa tentang implementasi open-source tambahan dari Ingress controller, NGINX Ingress Controller, dan beberapa cara yang berbeda dari implementasi AWS.
Gambaran Umum AWS Load Balancer Controller
Di Bagian 1 dari seri ini, kita berfokus pada dua pendekatan untuk mengekspos aplikasi Kubernetes: external load balancer yang merouting traffic langsung ke Pod aplikasi dan in-cluster reverse proxy yang berfungsi sebagai entry-point utama untuk aplikasi dan merouting traffic ke Pod.
AWS Load Balancer Controller mewakili pendekatan pertama, yang kami tunjukkan secara skematis dalam diagram berikut:
Perhatikan bahwa AWS Load Balancer Controller juga berisi Service Controller. Kita akan melihat contoh penggunaannya di Bagian 3 dari seri ini.
Dalam diagram di bawah ini, kita melihat proses langkah demi langkah untuk mengekspos aplikasi di belakang Ingress:
alb-ingress-controller
mengawasi Ingress events.- Sebuah ALB dikelola untuk setiap Ingress object. Itu dibuat, dikonfigurasi, dan dihapus sesuai kebutuhan.
- Target Groups dibuat, dengan mode
instance
(ServiceA dan ServiceB) atauip
(ServiceC). - ALB listeners dibuat dan dikonfigurasi.
- Aturan dikonfigurasi untuk meneruskan traffic dari listeners ke target groups.
Di Bagian 1, kami menjabarkan manfaat outsourcing pekerjaan ke load balancing service yang managed, highly available, dan dapat discaling seperti AWS Load Balancer. Dalam posting ini (Bagian 2), kami akan memandu pengaturan, konfigurasi, dan contoh kode yang mengilustrasikan penggunaan AWS Load Balancer Controller.
Panduan
Prasyarat
1. Dapatkan Akses ke Akun AWS
Anda akan memerlukan akun AWS dan kemampuan untuk berkomunikasi dengannya dari terminal Anda, menggunakan AWS Command Line Interface (AWS CLI) dan tool serupa.
Dalam contoh kode di bawah ini, kita akan menemukan beberapa token yang tidak dapat diberikan nilai sintetis (misalnya, yang mengacu pada ID akun atau Region AWS). Ini harus diganti dengan nilai yang sesuai dengan environment Anda.
2. Buat AWS Load Balancer Identity and Access Management (AWS IAM) Policy
Buat AWSLoadBalancerControllerIAMPolicy
menggunakan instruksi berikut (hanya #2 dan #3) yang mengatur IAM Roles for Service Accounts guna memberikan permission bagi controller.
Perhatikan bahwa pendaftaran OIDC IAM Provider dan pembuatan service account AWS Load Balancer Controller dilakukan secara otomatis oleh eksctl
berdasarkan konfigurasi di bawah ini dan tidak perlu ditangani secara eksplisit.
3. Membuat Cluster
Kita menggunakan eksctl untuk membuat Amazon EKS cluster, yang selain membuat cluster itu sendiri, juga membuat dan mengonfigurasi network resource yang diperlukan: sebuah virtual private cloud (VPC), subnet, dan security group (lihat di sini untuk instruksi instalasi).
File konfigurasi eksctl
berikut mendefinisikan cluster Amazon EKS dan pengaturannya:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: aws-load-balancer-controller-walkthrough
region: ${AWS_REGION}
version: '1.23'
iam:
withOIDC: true
serviceAccounts:
- metadata:
name: aws-load-balancer-controller
namespace: kube-system
attachPolicyARNs:
- arn:aws:iam::${AWS_ACCOUNT}:policy/AWSLoadBalancerControllerIAMPolicy
managedNodeGroups:
- name: main-ng
instanceType: m5.large
desiredCapacity: 1
privateNetworking: true
Masukkan kode di atas dalam file config.yml
.
Verifikasi keberadaan environment variables berikut: AWS_REGION
dan AWS_ACCOUNT
dan buat cluster:
envsubst < config.yml | eksctl create cluster -f -
Perhatikan bahwa panduan ini menggunakan platform Amazon EKS versi eks.3
untuk Kubernetes versi 1.23.
Untuk singkatnya, konfigurasi di atas tidak mempertimbangkan banyak aspek penyediaan dan manajemen cluster Kubernetes seperti security dan monitoring. Untuk informasi selengkapnya dan praktik terbaik, lihat dokumentasi Amazon EKS dan eksctl.
Verifikasi bahwa cluster aktif dan berjalan:
kubectl get nodes
kubectl get pods -A
Perintah di atas harus mengembalikan satu node Amazon EKS dan empat Pod yang sedang berjalan.
4. Instalasi Helm
Kita menggunakan Helm, package manager populer untuk Kubernetes, untuk menginstal dan mengonfigurasi controller. Ikuti petunjuk instalasi Helm di sini.
Menginstal AWS Load Balancer Controller
1. Menginstal CustomResourceDefinitions (CRD)
Perintah berikut menginstal Custom Resource Definitions yang diperlukan agar controller berfungsi:
kubectl apply -k \
"github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"
2. Instalasi Controller menggunakan Helm
Perhatikan bahwa kami menggunakan service account yang dibuat secara otomatis oleh eksctl.
helm repo add eks https://aws.github.io/eks-charts
helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \
--namespace kube-system \
--set clusterName=aws-load-balancer-controller-walkthrough \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
kubectl -n kube-system rollout status deployment aws-load-balancer-controller
kubectl get deployment -n kube-system aws-load-balancer-controller
Mendeploy Testing Service
1. Membuat Namespace untuk Service
kubectl create namespace apps
2. Membuat Manifest File untuk Service
Tempatkan kode berikut dalam file service.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${SERVICE_NAME}
namespace: ${NS}
labels:
app.kubernetes.io/name: ${SERVICE_NAME}
spec:
selector:
matchLabels:
app.kubernetes.io/name: ${SERVICE_NAME}
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: ${SERVICE_NAME}
spec:
terminationGracePeriodSeconds: 0
containers:
- name: ${SERVICE_NAME}
image: hashicorp/http-echo
imagePullPolicy: IfNotPresent
args:
- -listen=:3000
- -text=${SERVICE_NAME}
ports:
- name: app-port
containerPort: 3000
resources:
requests:
cpu: 0.125
memory: 50Mi
---
apiVersion: v1
kind: Service
metadata:
name: ${SERVICE_NAME}
namespace: ${NS}
labels:
app.kubernetes.io/name: ${SERVICE_NAME}
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: ${SERVICE_NAME}
ports:
- name: svc-port
port: 80
targetPort: app-port
protocol: TCP
Service di atas, berdasarkan http-echo container image, yang menjawab permintaan apa pun dengan nama Service tersebut, sebagaimana didefinisikan di atas oleh token ${SERVICE_NAME}
. Kami juga mendefinisikan replika tunggal agar tidak rumit.
3. Deploy dan Verifikasi Service
Jalankan perintah berikut (kami akan menggunakan Service ini di seluruh posting):
SERVICE_NAME=first NS=apps envsubst < service.yml | kubectl apply -f -
SERVICE_NAME=second NS=apps envsubst < service.yml | kubectl apply -f -
SERVICE_NAME=third NS=apps envsubst < service.yml | kubectl apply -f -
SERVICE_NAME=fourth NS=apps envsubst < service.yml | kubectl apply -f -
SERVICE_NAME=error NS=apps envsubst < service.yml | kubectl apply -f -
Verifikasi bahwa semua resource terdeploy:
kubectl get pod,svc -n apps
Hal ini seharusnya menghasilkan output yang mirip dengan yang berikut:
Deploy Ingress Sederhana
1. Buat Manifest File untuk Ingress
Salin kode berikut ke dalam file ingress.yml
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ${NS}-ingress
namespace: ${NS}
annotations:
alb.ingress.kubernetes.io/load-balancer-name: ${NS}-ingress
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /first
pathType: Prefix
backend:
service:
name: first
port:
name: svc-port
- path: /second
pathType: Prefix
backend:
service:
name: second
port:
name: svc-port
Untuk gambaran singkat tentang Ingress, Anda dapat merujuk ke Bagian 1 dari seri ini atau menjelajahi spesifikasi dan ikhtisar lengkap dalam dokumentasi resmi Kubernetes.
Kode di atas melakukan beberapa hal yang memberikan informasi tambahan untuk AWS Load Balancer Controller:
- kita tetapkan
ingressClassName
kealb
, yang menunjukkan kepada controller untuk menangani Ingress resource ini - kita mendefinisikan, melalui anotasi:
- Nama load balancer yang akan dibuat controller
- tipe target load balancer menjadi
ip
(yaitu, Pod itu sendiri terdaftar sebagai target) - load balancer untuk berhubungan dengan internet
- health check path
Sebelum Kubernetes 1.19, Anda juga dapat mendefinisikan Ingress class melalui anotasi Ingress dengan format kubernetes.io/ingress.class: alb
, yang sejak itu sudah tidak digunakan lagi. Anotasi tersebut masih beroperasi, tetapi ingressClassName
lebih diutamakan daripada itu.
Lihat di sini untuk daftar lengkap anotasi yang tersedia.
2. Deploy Ingress Resource
Jalankan:
NS=apps envsubst < ingress.yml | kubectl apply -f -
Setelah beberapa saat, kita dapat melihat status Ingress resource yang disebarkan (kita mengganti ID dan Region dengan placeholder):
kubectl get ingress -n apps
Yang akan menghasilkan hasil yang mirip dengan ini:
Simpan URL Application Load Balancer:
export ALB_URL=$(kubectl get -n apps ingress/apps-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
Setelah beberapa menit, load balancer tersedia dan kita dapat mengirim requests:
curl ${ALB_URL}/first
curl ${ALB_URL}/second
Hasil ini menunjukkan bahwa Service dan Ingress berfungsi dengan baik:
AWS Load Balancer Controller tersedia, seperti halnya untuk Ingress resource, Application Load Balancer dengan nama apps-ingress, yang menentukan konfigurasi listeners rule (dan target group dengan targetnya):
Praktik terbaik untuk AWS Application Load Balancer Controller mengharuskan kita mengonfigurasinya dengan setidaknya dua public subnets dan dua private subnets di seluruh availability zone. Node-node cluster Amazon EKS kita berada di private subnets, sementara public subnets digunakan untuk menyediakan internal resource yang memungkinkan load balancer merouting traffic ke IP di private subnets.
Controller dapat secara otomatis menemukan subnet ini berdasarkan tag mereka:
kubernetes.io/role/elb
dengan nilai 1 atau''
untuk public subnet, dankubernetes.io/role/internal-elb
dengan nilai 1 atau''
untuk private subnet
Kita tidak perlu secara eksplisit membuat tag ini, karena eksctl
, yang kita gunakan untuk membuat cluster, melakukannya secara otomatis. Kita juga dapat secara eksplisit menetapkan subnet yang relevan menggunakan anotasi alb.ingress.kubernetes.io/subnets
.
Jika Anda membuka salah satu Target Groups di atas, Anda akan melihat target terdaftar dan Pod port dan konfigurasi health check milik target, sebagaimana didefinisikan oleh anotasi
alb.ingress.kubernetes.io/healthcheck-path
dalam definisi Ingress di atas, tercermin dalam target group tersedia. Controller juga telah memperbarui security group cluster untuk memungkinkan traffic dari node load balancer ke Pod kita.
Anda mungkin telah memperhatikan dalam konfigurasi listener di atas, bahwa untuk permintaan yang tidak merouting ke salah satu jalur tertentu, ada rule default, catch-all yang mengembalikan respons tetap 404.
Anda dapat mengonfigurasi ini lebih lanjut melalui anotasi tambahan atau Anda dapat secara eksplisit menentukan default backend melalui konfigurasi Ingress.
Default Backend
1. Update Ingress
Tambahkan konfigurasi defaultBackend
ke fileingress.yml
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ${NS}-ingress
namespace: ${NS}
annotations:
alb.ingress.kubernetes.io/load-balancer-name: ${NS}-ingress
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
ingressClassName: alb
defaultBackend:
service:
name: error
port:
name: svc-port
rules:
- http:
paths:
- path: /first
pathType: Prefix
backend:
service:
name: first
port:
name: svc-port
- path: /second
pathType: Prefix
backend:
service:
name: second
port:
name: svc-port
2. Deploy Ingress yang telah diupdate
NS=apps envsubst < ingress.yml | kubectl apply -f -
Setelah beberapa saat, konfigurasi listener rules dari Application Load Balancer diperbaharui sebagaimana mestinya:
Menjalankan perintah berikut akan memverifikasi konfigurasi listener rules:
curl ${ALB_URL}
curl ${ALB_URL}/first
curl ${ALB_URL}/first/something
curl ${ALB_URL}/second
curl ${ALB_URL}/third
curl ${ALB_URL}/something
Ini akan menghasilkan output:
Routing berbasis Hostname
Dalam definisi Ingress di atas, kita tidak menentukan pengaturan host
apa pun untuk rule apa pun, yang berarti bahwa request apa pun dengan nilai Host
header apa pun yang dikirim ke Application Load Balancer akan cocok dengan rule ini.
Kita dapat menggabungkan routing berbasis path dan host dalam definisi Ingress.
1. Mengubah Definisi Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ${NS}-ingress
namespace: ${NS}
annotations:
alb.ingress.kubernetes.io/load-balancer-name: ${NS}-ingress
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
ingressClassName: alb
defaultBackend:
service:
name: error
port:
name: svc-port
rules:
- host: a.example.com
http:
paths:
- path: /first
pathType: Prefix
backend:
service:
name: first
port:
name: svc-port
- path: /second
pathType: Prefix
backend:
service:
name: second
port:
name: svc-port
- host: '*.example.com'
http:
paths:
- path: /third
pathType: Prefix
backend:
service:
name: third
port:
name: svc-port
- path: /fourth
pathType: Prefix
backend:
service:
name: fourth
port:
name: svc-port
Kami menggunakan wildcard untuk merouting semua permintaan selain dari a.example.com
ke yang ditentukan di bawah *.example.com
(lihat di sini untuk pertimbangan wildcard tambahan).
2. Deploy Ingress yang diperbaharui
NS=apps envsubst < ingress.yml | kubectl apply -f -
Konfigurasi load balancer telah diperbaharui seperti yang diharapkan:
Kita dapat menguji pengaturan menggunakan curl
(perhatikan domain yang salah pada permintaan kedua):
curl ${ALB_URL}/first -H 'Host: a.example.com'
curl ${ALB_URL}/first -H 'Host: a.example.net'
curl ${ALB_URL}/third -H 'Host: b.example.com'
curl ${ALB_URL}/fourth -H 'Host: c.example.com'
Hasil yang diharapkan adalah:
Dalam setup production, kita tentu saja akan mengarahkan DNS records untuk subdomain di atas ke DNS name dari ALB.
Perhatikan bahwa mulai saat ini dan seterusnya, contoh kode hanya untuk tujuan ilustrasi dan bukan merupakan bagian dari panduan. Anda dapat mendeploynya sesuai keinginan dan melihat efeknya.
Lebih dari Satu Ingress Resource
Sejauh ini, kita telah berurusan dengan satu Ingress resource menggunakan ALB untuk merouting traffic ke Service backend di namespace yang sama. Bagaimana jika kita membutuhkan beberapa Ingress resource, yang tersebar di banyak namespaces? Apakah kita harus menyediakan ALB untuk masing-masing dari mereka?
Jawabannya adalah TIDAK.
Kita dapat mengonfigurasi beberapa Ingress resource untuk ditangani di bawah load balancer yang sama. Ini dilakukan dengan menggunakan anotasi alb.ingress.kubernetes.io/group.name yang memiliki nilai yang sama untuk semua Ingress resource. Kita juga dapat mengontrol urutan penggabungan dengan menambahkan anotasi alb.ingress.kubernetes.io/group.order.
Salah satu kasus penggunaan yang mungkin untuk konsolidasi semacam itu adalah untuk mengurangi ketergantungan antara tim dan masing-masing yang bertanggung jawab atas subset dari Service, sambil tetap dapat menggunakan load balancer yang disediakan secara terpusat yang sama.
Misalnya, perhatikan Ingress resource berikut (diringkas untuk kejelasan):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: apps-ingress
namespace: apps
annotations:
alb.ingress.kubernetes.io/load-balancer-name: apps-ingress
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/healthcheck-path: /healthz
alb.ingress.kubernetes.io/group.name: common-ingress-group
spec:
ingressClassName: alb
defaultBackend:
service:
name: error
port:
name: svc-port
rules:
- host: a.example.com
...
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ops-ingress
namespace: ops
annotations:
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/group.name: common-ingress-group
alb.ingress.kubernetes.io/group.order: '10'
spec:
ingressClassName: alb
rules:
- host: a.example.com
...
- host: b.example.com
...
Mereka akan digabungkan di bawah load balancer yang sama:
Urutan yang kita definisikan untuk Ingress resource kedua adalah 10
, yang lebih tinggi (dan dengan demikian memiliki prioritas lebih rendah) daripada urutan default 0
untuk resource Ingress pertama. Oleh karena itu rute untuk a.example.com dari Ingress kedua lebih rendah pada daftar rule (lihat /first
menunjuk ke first.apps
Service dalam rule #1 dan ke Servicethird.ops
dalam rule #3).
Perhatikan bahwa kita perlu mendefinisikan target-type
pada kedua Ingress resource dan kita hanya dapat menentukan backend default sekali.
IngressClass
Properti ingressClassName
di semua definisi Ingress resource di atas adalah referensi ke IngressClass
resource di seluruh cluster. Memang, alb
adalah nilai default untuk nilai konfigurasi ingressClass
controller, dan terinstal bersama controller.
Ini mengacu pada definisi yang mirip dengan yang berikut:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb
...
spec:
controller: ingress.k8s.aws/alb
Kita dapat mendefinisikan Ingress class kita sendiri dengan cara yang sama.
Default IngressClass
Selain dapat mereferensikan IngressClass
dari dalam Ingress resource, kita juga dapat mendefinisikan IngressClass
default dan menghilangkan kebutuhan untuk melakukannya sama sekali. Ini dapat dilakukan dengan menambahkan anotasi ingressclass.kubernetes.io/is-default-class
ke definisi IngressClass
:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb
annotations:
ingressclass.kubernetes.io/is-default-class: true
...
spec:
controller: ingress.k8s.aws/alb
Semua Ingress resource yang tidak mereferensikan IngressClass
apa pun ditangani oleh controller yang ditentukan dalam controller yang diajukan di atas.
IngressClassParams
Di antara Custom Resource Definitions yang kita instal bersama dengan controller, ada IngressClassParams
. Tujuannya adalah untuk meneruskan parameter tambahan ke controller, dengan beberapa parameter yang sebelumnya ditangani melalui anotasi. Bahkan, kita dapat memindahkan anotasi grup dan skema ke dalamnya juga. Selain itu, kita dapat menentukan namespaceSelector
yang mengontrol Ingress resource mana, berdasarkan namespace mereka, yang diizinkan untuk menggunakan IngressClassParams
tertentu:
apiVersion: elbv2.k8s.aws/v1beta1
kind: IngressClassParams
metadata:
name: alb-ingress-class-params
...
spec:
namespaceSelector:
matchLabels:
team: some-team
group:
name: common-ingress-group
scheme: internet-facing
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb
....
spec:
controller: ingress.k8s.aws/alb
parameters:
apiGroup: elbv2.k8s.aws
kind: IngressClassParams
name: alb-ingress-class-params
Membatasi Cakupan Controller
Saat kita mendeploy AWS Load Balancer Controller di awal panduan, kita tidak secara eksplisit membatasi Ingress dan Service resource mana yang akan ditanganinya.
Sebagai alternatif, controller dapat dibatasi untuk melihat Ingress dan Service resource dari namespace tertentu.
helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=aws-load-balancer-controller-walkthrough \
--set serviceAccount.create=false \
--set watchNamespace=apps \
--set serviceAccount.name=aws-load-balancer-controller
AWS Load Balancer Controller dapat melihat namespace tertentu dengan memberikan nilai konfigurasi watchNamespace
atau melihat semua namespace dengan menghilangkannya. Saat ini, tidak ada opsi untuk melihat beberapa namespace tertentu.
Lebih dari Satu Instance AWS Load Balancer Controller
Mengingat kemampuan di atas untuk membatasi controller ke namespace tertentu, mungkin masuk akal untuk menerapkan lebih dari satu instance AWS Load Balancer Controller, masing-masing terbatas pada namespace tertentu dan dengan konfigurasi yang berbeda. Saat ini, AWS Load Balancer Controller tidak mendukung lebih dari satu instance, tetapi Anda dapat melacak masalah berikut untuk melihat perkembangannya.
Pembersihan
Untuk menghapus resource yang Anda buat selama panduan, Anda dapat menjalankan hal berikut:
NS=apps envsubst < ingress.yml | kubectl delete -f -
helm uninstall -n kube-system aws-load-balancer-controller
envsubst < config.yml | eksctl delete cluster -f -
aws iam delete-policy --policy-arn arn:aws:iam::${AWS_ACCOUNT}:policy/AWSLoadBalancerControllerIAMPolicy
Kesimpulan
AWS Load Balancer Controller mengurangi kompleksitas operasional dengan memindahkan penanganan traffic masuk ke layanan terkelola yang Highly Available dan dapat scaling secara elastis, yaitu AWS Application Load Balancer. AWS Load Balancer Controller menerjemahkan Ingress resource ke dalam pembuatan dan konfigurasi load balancer, menyediakan aplikasi dengan kemampuan untuk mengontrol semua aspek ingress traffic tersebut, independen dari proses penyediaan infrastruktur.
Karena menyediakan Service controller serta ingress controller, AWS Load Balancer Controller adalah solusi lengkap untuk mengekspos aplikasi Kubernetes ke traffic eksternal.
Artikel ini diterjemahkan dari artikel asli berjudul “Exposing Kubernetes Applications, Part 2: AWS Load Balancer Controller” yang ditulis oleh Dmitry Notels dan Tsahi Duek.