Bu kapsamlı ingress rehberinde, Kubernetes üzerinde Nginx ingress controller‘ı adım adım nasıl kuracağınız, nasıl kullanacağınız ve nasıl yapılandıracağınızı öğreneceksiniz.

Nginx Ingress Controller Nedir?

Nginx Ingress Controller, Kubernetes’in karmaşıklığını azaltan ve trafik yönlendirme süreçlerini optimize eden bir araçtır. Kubernetes ortamında HTTP ve HTTPS trafiğini yönlendirmek için kullanılan Nginx Ingress Controller, esnek yapılandırma seçenekleri ve yüksek performansıyla öne çıkar. Bu controller, Ingress kaynaklarını kullanarak gelen istekleri izler ve belirli kurallara göre işler. SSL/TLS desteğiyle güvenli iletişim kanalları sağlar ve yüksek kullanılabilirlik için tasarlanmıştır. Yüksek performansıyla bilinen Nginx, uygulamalarınızın sorunsuz çalışmasını sağlar. Nginx Ingress Controller, trafik yönlendirme ihtiyaçlarınızı karşılamak ve dış dünyaya açılmak için ideal bir çözümdür.

Kurulum Hazırlıkları

2 adet Ingress Controller vardır.

  1. Nginx ingress controller by kubernetes community
  2. Nginx ingress controller by Nginx Inc

Biz bu rehberde Kubernetes community’sinin yayınladığı ingress controller’ı kullanacağız.

Gereksinimler

  1. Kubernetes Cluster
  2. Kubectl yüklenmiş ve Service Account’a login olunmuş Shell veya Command Prompt
  3. Bağlı olduğunuz Kubernetes Cluster’a admin yetkisi
  4. Ingress Controller LoadBalancer IP’sini işaret edecek geçerli bir domain. (İsteğe bağlı)

Bu kurulumu Google Cloud üzerinde deniyorsanız, cluster rollerini etkinleştirmek için hesabınıza yönetici izinlerini aşağıdaki komutla verebilirsiniz.

ACCOUNT=$(gcloud info --format='value(config.account)')
kubectl create clusterrolebinding owner-cluster-admin-binding \
    --clusterrole cluster-admin \
    --user $ACCOUNT

Nginx Ingress Controller Kubernetes Manifest’leri

Bu yazıda kullanılan tüm kubernetes manifestleri Resmi Kubernetes Nginx Github reposundan alınmıştır. Repoyu clone’layabilirsiniz ve rehberi takip ederek doğrudan aşamaları uygulayabilirsiniz.

git clone https://github.com/techiescamp/nginx-ingress-controller

İlk olarak, YAML manifestlerini kullanarak Nginx Controller’ı deploy ederek ilişkili tüm Kubernetes nesnelerini kavrayacağız. Kavradıktan sonra, diğer kurulum seçeneği olan Helm chart’ı kullanarakta Ingress Controller’ı ayağa kaldıracağız.

Not: Tüm Nginx ingress controller nesnelerini ve birbirleriyle nasıl ilişkili olduklarını anlamak istiyorsanız, nesneleri repodan ayrı ayrı oluşturmanızı öneririm. Nasıl çalıştığını öğrendikten sonra, deploy için tek bir manifest ya da helm chart kullanabilirsiniz.

Tüm nesneleri tek seferde deploy etmek istiyorsanız, clone’ladığınız repoyu terminal’de açın ve ilgili klasörün içerisine girin. Daha sonra aşağıdaki komutu çalıştırın.

kubectl apply -f .

1. Yöntem: Adım Adım Kurulum Aşamaları

Namespace Oluşturma

Tüm Nginx Controller nesnelerini ingress-nginx namespace’i üzerinde dağıtacağız. Aşağıdaki komutla namespace’i oluşturabilirsiniz.

kubectl create ns ingress-nginx

Admission Controller Roles & Service Account Oluşturma

Gerekli izinlere sahip ve ingress-nginx-admission service account’una bağlanan bir Role ve ClusterRole’a ihtiyacımız var.

admission-service-account.yaml adında bir dosya oluşturun ve aşağıdaki içerikleri dosya içerisine yapıştırın.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-admission
  namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  annotations:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-admission
  namespace: ingress-nginx
rules:
- apiGroups:
  - ""
  resources:
  - secrets
  verbs:
  - get
  - create

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-admission
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
  name: ingress-nginx-admission
  namespace: ingress-nginx


---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-admission
rules:
- apiGroups:
  - admissionregistration.k8s.io
  resources:
  - validatingwebhookconfigurations
  verbs:
  - get
  - update

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-admission
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
  name: ingress-nginx-admission
  namespace: ingress-nginx

İlgili dosyayı deploy edelim.

kubectl apply -f admission-service-account.yaml 

Validating Webhook Configuration’u Oluşturma

validating-webhook.yaml adında dosya oluşturup içerisine aşağıdakileri yapıştıralım.

---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-admission
webhooks:
- admissionReviewVersions:
  - v1
  clientConfig:
    service:
      name: ingress-nginx-controller-admission
      namespace: ingress-nginx
      path: /networking/v1/ingresses
  failurePolicy: Fail
  matchPolicy: Equivalent
  name: validate.nginx.ingress.kubernetes.io
  rules:
  - apiGroups:
    - networking.k8s.io
    apiVersions:
    - v1
    operations:
    - CREATE
    - UPDATE
    resources:
    - ingresses
  sideEffects: None

Daha sonra ilgili manifest’i deploy edelim.

kubectl apply -f validating-webhook.yaml

Webhook Certificate’i Güncellemek İçin Job’ları Deploy Edelim

ValidatingWebhookConfiguration sadece HTTPS üzerinde çalışır. Bu nedenle CA bundle’a ihtiyacımız var. Bu rehberde kube-webhook-certgen kullanarak CA bundle sertifikamızı oluşturup job içerisinde kullanacağız. Oluşturduğumuz CA sertifikalarını ingress-nginx-admission adlı secret içerisinde barındıracağız.

İkinci Job’da ValidatingWebhookConfiguration nesnesini CA bundle ile patch’leyeceğiz.

jobs.yaml adında bir dosya oluşturup aşağıdakileri içerisine yapıştıralım.

---
apiVersion: batch/v1
kind: Job
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-admission-create
  namespace: ingress-nginx
spec:
  template:
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx
      name: ingress-nginx-admission-create
    spec:
      containers:
      - args:
        - create
        - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
        - --namespace=$(POD_NAMESPACE)
        - --secret-name=ingress-nginx-admission
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231011-8b53cabe0
        imagePullPolicy: IfNotPresent
        name: create
        securityContext:
          allowPrivilegeEscalation: false
      nodeSelector:
        kubernetes.io/os: linux
      restartPolicy: OnFailure
      securityContext:
        runAsNonRoot: true
        runAsUser: 2000
      serviceAccountName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-admission-patch
  namespace: ingress-nginx
spec:
  template:
    metadata:
      labels:
        app.kubernetes.io/component: admission-webhook
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx
      name: ingress-nginx-admission-patch
    spec:
      containers:
      - args:
        - patch
        - --webhook-name=ingress-nginx-admission
        - --namespace=$(POD_NAMESPACE)
        - --patch-mutating=false
        - --secret-name=ingress-nginx-admission
        - --patch-failure-policy=Fail
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231011-8b53cabe0
        imagePullPolicy: IfNotPresent
        name: patch
        securityContext:
          allowPrivilegeEscalation: false
      nodeSelector:
        kubernetes.io/os: linux
      restartPolicy: OnFailure
      securityContext:
        runAsNonRoot: true
        runAsUser: 2000
      serviceAccountName: ingress-nginx-admission

Aşağıdaki komutla ilgili job’ımızı create edelim.

kubectl apply -f jobs.yaml

Aşağıdaki komutla job’ların create edildiğini teyit edelim.

kubectl get jobs -n ingress-nginx

Daha sonra ValidatingWebhookConfiguration objemizi describe edip CA bundle’ımızın oluştuğunu görebiliriz.

kubectl describe ValidatingWebhookConfiguration ingress-nginx-admission
image 1

Ingress Controller Roles & Service Account Oluşturma

ingress-service-account.yaml adında dosya oluşturup aşağıdakileri içerisine yapıştırın.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx
  namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx
  namespace: ingress-nginx
rules:
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - configmaps
  - pods
  - secrets
  - endpoints
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses/status
  verbs:
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - ingressclasses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resourceNames:
  - ingress-controller-leader
  resources:
  - configmaps
  verbs:
  - get
  - update
- apiGroups:
  - ""
  resources:
  - configmaps
  verbs:
  - create
- apiGroups:
  - ""
  resources:
  - events
  verbs:
  - create
  - patch

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx
subjects:
- kind: ServiceAccount
  name: ingress-nginx
  namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx
rules:
- apiGroups:
  - ""
  resources:
  - configmaps
  - endpoints
  - nodes
  - pods
  - secrets
  - namespaces
  verbs:
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - events
  verbs:
  - create
  - patch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses/status
  verbs:
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - ingressclasses
  verbs:
  - get
  - list
  - watch

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx
subjects:
- kind: ServiceAccount
  name: ingress-nginx
  namespace: ingress-nginx

Daha sonra aşağıdaki komutla ilgili manifestimizi deploy edelim.

kubectl apply -f ingress-service-account.yaml

Configmap Oluşturma

Bu Configmap ile Nginx ayarlarını özelleştirebilirsiniz. Örneğin Custom header veya bir çok nginx ayarını değiştirebilirsiniz.

Bu adresten (official community documentation) tüm desteklenen configuration’lara ulaşabilirsiniz.

configmap.yaml adında dosya oluşturup içeriğine aşağıdakileri yapıştıralım.

---
apiVersion: v1
data:
  allow-snippet-annotations: "true"
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-controller
  namespace: ingress-nginx

Aşağıdaki komutla configmap’i dağıtalım.

kubectl apply -f configmap.yaml

Ingress Controller & Admission Controller Servislerini Oluşturma

services.yaml dosyasını oluşturup içeriğine aşağıdakileri yapıştıralım.

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  externalTrafficPolicy: Local
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-controller-admission
  namespace: ingress-nginx
spec:
  ports:
  - appProtocol: https
    name: https-webhook
    port: 443
    targetPort: webhook
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: ClusterIP

Daha sonra aşağıdaki komutla servisi create edelim.

kubectl apply -f services.yaml

ingress-nginx-controller servisi, deploy ettiğiniz ilgili cloud platformunda bir LoadBalancer oluşturur. Aşağıdaki komutu kullanarak LoadBalancer IP/DNS’sini alabilirsiniz.

kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller

Not: Her bulut sağlayıcısı için, statik IP adresini ve diğer yapılandırmaları LoadBalancer ile eşlemek için kullanabileceğiniz belirli annotation’lar vardır. GCP ek annotation’larına buradan ve AWS annotation’larına buradan göz atabilirsiniz.

IngressClass Oluşturma

ingressclass.yaml adında bir dosya oluşturup içerisine aşağıdakileri ekleyelim.

---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: nginx
spec:
  controller: k8s.io/ingress-nginx

Daha sonra ilgili dosyayı deploy edelim.

kubectl apply -f ingressclass.yaml

Komut sonucunda nginx adında bir ingress oluşacaktır. Oluşturduğumuz Ingress objelerinde bu ingressClassName‘i kullanmamız gerekiyor.

Ingress Controller Deployment Oluşturma

deployment.yaml adında dosya oluşturup içerisine aşağıdakileri ekleyelim.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  minReadySeconds: 0
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/component: controller
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/name: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx
    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
        - --election-id=ingress-controller-leader
        - --controller-class=k8s.io/ingress-nginx
        - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
        - --validating-webhook=:8443
        - --validating-webhook-certificate=/usr/local/certificates/cert
        - --validating-webhook-key=/usr/local/certificates/key
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: LD_PRELOAD
          value: /usr/local/lib/libmimalloc.so
        image: registry.k8s.io/ingress-nginx/controller:v1.9.5
        imagePullPolicy: IfNotPresent
        lifecycle:
          preStop:
            exec:
              command:
              - /wait-shutdown
        livenessProbe:
          failureThreshold: 5
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: controller
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        - containerPort: 8443
          name: webhook
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
          requests:
            cpu: 100m
            memory: 90Mi
        securityContext:
          allowPrivilegeEscalation: true
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - ALL
          runAsUser: 101
        volumeMounts:
        - mountPath: /usr/local/certificates/
          name: webhook-cert
          readOnly: true
      dnsPolicy: ClusterFirst
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: ingress-nginx
      terminationGracePeriodSeconds: 300
      volumes:
      - name: webhook-cert
        secret:
          secretName: ingress-nginx-admission

Daha sonra ilgili dosyayı deploy edelim.

kubectl apply -f deployment.yaml

Deploy’un başarılı bir şekilde çalıştığından emin olmak için aşağıdaki komutla kontrol edebiliriz.

kubectl get pods -n ingress-nginx

Ingress Controller Deployment Kontrolü

Service tarafından oluşturulan LoadBalancer endpointini kullanarak ingress controller deployunu kontrol edebilirsiniz.

Nginx Ingress Controller‘ın varsayılan bir endpoint’i vardır. Gelen istek bir ingress’ten gelmiyorsa, varsayılan olarak default backend endpoint’e gider.

Default backend’i kullanarak controller’ı doğrulayacağız. Loadbalancer endpoint’inizi bulun ve tarayıcıdan erişmeyi deneyin. Aşağıdaki gibi 404 hatası almalısınız.

image 2

Şimdi aşağıdaki gibi curl kullanarak /healthz url’sine erişmeyi deneyin. 200 yanıtını almalısınız. <LOAD-BALANCER-ENDPOINT> kısmını Loadbalancer endpoint’iniz ile değiştirin.

curl http://<LOAD-BALANCER-ENDPOINT>/healthz
image 3

2. Yöntem: Tek Komutla Helm ile Nginx Ingress Controller Kurulumu

Helm kullanıyorsanız community helm chart’ını kullanarak ingress controller‘ı kurabilirsiniz.

NOT: ValidatingWebhookConfiguration, value.yaml’de varsayılan olarak devre dışıdır.

Aşağıdaki Helm Chart komutunu çalıştırın. Eğer ilgili namespace yoksa, ingress-nginx adında bir namespace yaratacaktır.

helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace

Helm release’ini kontrol edelim.

helm list -n ingress-nginx

Eğer cluster’dan Ingress Controller’ı kaldırmak isterseniz aşağıdaki komutu kullanabilirsiniz.

helm uninstall ingress-nginx -n ingress-nginx

Alanı Adını Nginx Ingress LoadBalancer IP’sine Eşleme

Ingress’in birincil hedefi Kubernetes üzerinde çalışan service’ler harici trafik almaktır. İdeal olarak projelerde DNS, Ingress Controller LoadBalancer IP’sine eşlenir.

Single DNS Mapping

Tek bir domain’i doğrudan A kaydı olarak LoadBalancer IP’sine eşleyebilirsiniz. Bunu kullanarak Ingress Controller için yalnızca bir alan adına ve birden çok path-based trafik yönlendirmesine sahip olabilirsiniz.

Örneğin;

www.sezer.in --> Loadbalancer IP

Bu modeli kullanarak path-based yönlendirmeye de sahip olabilirsiniz.

Örneğin;

http://www.sezer.in/app1
http://www.sezer.in/app2
http://www.sezer.in/app1/api
http://www.sezer.in/app2/api

Wildcard DNS Mapping

LoadBalancer’a wildcard bir DNS eşlerseniz Ingress yoluyla dinamik DNS endpointlerine sahip olabilirsiniz.

DNS kayıtlarına wildcard karakterini (*) ekledikten sonra, Ingress objesinde gerekli DNS’i belirtmeniz gerekir; Nginx Ingress Controller, onu gerekli service endpoint’ine yönlendirmeyle ilgilenir.

Örneğin;

*.sezer.in --> Loadbalancer IP
*.apps.sezer.in --> Loadbalancer IP 

Bu şekilde, tek bir Ingress Controller aracılığıyla birden fazla dinamik subdomain’e sahip olabilirsiniz ve her DNS, kendi path-based yönlendirmesine sahip olabilir.

Örneğin;

#URL_1

http://demo1.sezer.in/api
http://demo1.sezer.in/api/v1
http://demo1.sezer.in/api/v2

#uygulamaya özel spesifik url'ler

http://grafana.apps.sezer.in
http://prometheus.apps.sezer.in

#URL_2

http://demo2.apps.sezer.in/api
http://demo2.apps.sezer.in/api/v1
http://demo2.apps.sezer.in/api/v2

Demo Uygulama Deploy’u

Ingress’i test etmek için bir demo uygulaması deploy edeceğiz ve buna bir ClusterIP service’i ekleyeceğiz. Bu uygulamaya Ingress olmadan yalnızca Cluster içinden erişilebilecektir.

Adım 1: dev adında bir namespace oluşturalım

kubectl create namespace dev

Adım 2: hello-app.yaml adında bir dosya oluşturup aşağıdakileri içerisine yapıştıralım.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
  namespace: dev
spec:
  selector:
    matchLabels:
      app: hello
  replicas: 2
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"

Adım 3: Oluşturduğumuz dosyayı deploy edelim

kubectl create -f hello-app.yaml

Adım 4: Deployment durumunu kontrol edelim.

kubectl get deployments -n dev

Adım 5: hello-app-service.yaml adında dosya oluşturup aşağıdakileri içerisine yapıştıralım.

apiVersion: v1
kind: Service
metadata:
  name: hello-service
  namespace: dev
  labels:
    app: hello
spec:
  type: ClusterIP
  selector:
    app: hello
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP

Adım 6: Oluşturduğumuz dosyayı kubectl ile cluster’da create edelim

kubectl create -f hello-app-service.yaml

Demo Uygulama İçin Ingress Objesini Oluşturma

Şimdi hello-app uygulamamıza DNS kullanarak erişmek için bir Ingress Objesi oluşturalım. Ingress objesi bir dizi yönlendirme kuralından başka bir şey değildir.

Ingress objesinin Nginx Controller’a nasıl bağlandığını merak ediyorsanız; Ingress Controller, kuralları kontrol etmek için Ingress API’sine bağlanır ve nginx.conf dosyasını buna göre günceller.

Adım 1: ingress.yaml adında dosya oluşturalım

Adım 2: Aşağıdaki uyarıya göre değişiklikleri yapıp manifest kodlarını oluşturduğumuz dosyanın içerisine yapıştıralım.

demo.apps.sezer.in adresini alan adınızla değiştirin. Ayrıca, hello-app uygulaması dev namespace’inde çalıştığı için bu ingress objesini dev namespace’inde oluşturuyoruz.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: dev
spec:
  ingressClassName: nginx
  rules:
  - host: "demo.apps.sezer.in"
    http:
      paths:
        - pathType: Prefix
          path: "/"
          backend:
            service:
              name: hello-service
              port:
                number: 80

Adım 3: Oluşturduğumuz dosyayı kubectl aracılığı ile create ettirelim.

kubectl create -f ingress.yaml

Adım 4: Oluşturduğumuz Ingress’i describe edip configuration’u inceleyelim.

kubectl describe ingress  -n dev

Artık demo.apps.sezer.in domainine erişmeye çalışırsam, aşağıdaki gibi hello-app uygulamasına erişebileceğim. (Alan adınızla değiştirmelisiniz)

image 4

Tarayıcınızda https hatasıyla karşılaşabilirsiniz. Bu durumda Ingress endpoint’ini doğrulamak için curl komutunu kullanabilirsiniz.

curl demo.apps.sezer.in

Nginx Ingress ile Birlikte TLS Kullanımı

Her ingress objenizi TLS sertifikanızla yapılandırabilirsiniz. TLS, ingress controller seviyesinde sonlanır.

Aşağıdaki resimde ingress TLS yapılandırmasını bulabilirsiniz. TLS sertifikasının secret object olarak kubernetes’e eklenmesi gerekir.

nginx ingress controller

Ayrıca ilgilenirseniz bu bağlantıdan MetalLB kurulumu için yazdığım bir diğer yazıya da göz gezdirebilirsiniz.