Bildiğimiz gibi Kubernetes içerisinde bir ingress controller’a, tek bir IP adresi üzerinden trafiği route edebilmek ve TLS termination işlemleri için ihtiyaç duymaktayız.
Günümüzde bu tarz işlemler için çeşitli Service Mesh teknolojileri tercih ediliyor olsada, sistemin türüne ve boyutuna göre bazı durumlarda da Nginx gibi bir ingress controller’a ihtiyaç duymaktayız. Örneğin, sistem fazla kompleks değilse veya Kubernetes cluster’ı içerisinde bir Windows node kullanıyorsak.
Sidecar proxy’ler problem olabiliyor.
Bu makale kapsamında ise Azure Kubernetes Service (AKS) üzerinde, dışarıya public olarak expose olmayan, internal bir nginx ingress controller’ı (open-source olan) nasıl kullanabiliriz konusuna değinmeye çalışacağım.
Gereksinimler:
- Güncel bir Azure CLI
- Azure Kubernetes Service
- Helm 3 CLI
NOT: AKS kurulumu ile ilgili adımları, buradan takip edebilirsiniz.
Nginx Ingress Controller’ının Kurulumu
AKS cluster’ı içerisinde nginx controller’ının kurulum işlemini gerçekleştirebilmek için, aşağıdaki komut satırından yararlanacağız.
kubectl create namespace ingress-private
helm install my-ingress stable/nginx-ingress \
--namespace=ingress-private \
--set rbac.create=true \
--set controller.service.loadBalancerIP="10.240.2.2" \
--set controller.replicaCount=2 \
--set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
--set defaultBackend.nodeSelector."beta\.kubernetes\.io\/os"=linux \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"="true"
Burada dikkat etmemiz gereken bir kaç nokta bulunmaktadır.
- Eğer AKS cluster’ı içerisinde RBAC enable değilse, “false” olarak set etmemiz gerekmektedir.
- Ingress controller’ı dynamic bir public IP ile oluşturmamak için load balancer IP adresi olarak, virtual network içerisinden kullanılmayan bir internal IP adresi sağlamamız gerekmektedir.
- Ardından internal bir load balancer olacağını belirtebilmek için, service.beta.kubernetes.io/azure-load-balancer-internal: “true” annotation’ını eklememiz gerekmektedir.
- Ayrıca nginx ingress controller‘ın ve nginx ingress default backend‘inin “linux” node’u üzerinde scheduled edilmesi gerekmektedir. Bu sebeple gerekli node selector tanımlamalarının “linux” olarak yapılması gerekmektedir.
Şimdi komut satırını çalıştıralım ve nginx ingress controller’ının “EXTERNAL-IP” adresi alma işlemini aşağıdaki gibi bekleyelim.
kubectl get svc -n ingress-private -w
Helm Chart’n Oluşturulması
AKS cluster’ına örnek bir uygulama deploy edebilmek ve ardından test edebilmek için, aşağıdaki gibi “mytodoapp-api” adında bir helm chart oluşturalım.
helm create mytodoapp-api
Ardından chart’ın içindeki “values.yaml” dosyasını açalım ve aşağıdaki gibi güncelleyelim.
# Default values for mytodoapp-api.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: mytodotestregistry.azurecr.io/mytodoapp-api:01
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name:
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: true
annotations: {
kubernetes.io/ingress.class: "nginx",
nginx.ingress.kubernetes.io/rewrite-target: /$1
}
hosts:
- host:
paths:
- /mytodoapp-api/?(.*)
tls: []
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector:
beta.kubernetes.io/os: windows
tolerations: []
affinity: {}
Ben “image.repository” bölümünde, örnek gerçekleştirebilmek için içerisinde ASP.NET Framework Web API projesi içeren bir windows container image’i kullanacağımı belirttim. Ardından “nodeSelector” bölümünde ise, bu pod’un “windows” olan node içerisinde scheduled edilebilmesi için gerekli olan tanımlamayı yaptım.
Burada önemli olan asıl nokta ise, “ingress” ayarları. Nginx’in otomatik olarak ingress’i bulabilmesi için, kubernetes.io/ingress.class: “nginx” annotation’ını eklememiz gerekmektedir. Ayrıca path forwarding için de, “rewrite-target” annotation’ı.
Annotation’ları ekledikten sonra ise “paths” kısmında, uygulamanın yönlendirilmesini istediğimiz path’i belirtiyoruz.
Şimdi aşağıdaki gibi oluşturmuş olduğumuz bu chart’ı deploy edelim.
helm install mytodoapp-api mytodoapp-api
Test Edelim
Şimdi test işlemini gerçekleştirebilmek için nginx ingress controller‘ın “80” port’unu, local “8080” port’una aşağıdaki gibi yönlendirelim.
kubectl port-forward svc/my-ingress-nginx-ingress-controller -n ingress-private 8080:80
Ardından path yönlendirmesini test edebilmek için, helm içerisinde örnek API için belirlemiş olduğumuz path’e aşağıdaki gibi bir request atalım.
Yukarıda gördüğümüz gibi nginx ingress controller, ilgili request’i tanımlamış olduğumuz API‘a yönlendirme işlemini gerçekleştirmiştir.
Referanslar
https://docs.microsoft.com/en-us/azure/aks/ingress-internal-ip?WT.mc_id=DT-MVP-5003382
https://github.com/helm/charts/tree/master/stable/nginx-ingress