KUBERNETES Kubernetes hem beyan temelli yapılandırmayı hem de otomasyonu kolaylaştıran, container iş yüklerini ve hizmetleri yönetmek için oluşturulmuş, taşınabilir ve genişletilebilir açık kaynaklı bir platformdur. Kubernetes Komponentleri kub-apiserver Kubernetes control plane’in en önemli bileşeni ve giriş noktasıdır. Tüm diğer komponent ve node bileşenlerinin direkt iletişim kurabildiği tek komponenttir. etcd Etcd tüm cluster verisi, metadata bilgileri ve Kubernetes’de oluşturulan tüm objelerin bilgilerinin tutulduğu anahtar-değer “key-value” veri deposudur. kube-scheduler Yeni oluşturulan ya da bir node ataması yapılmış Pod’ları izler ve üzerinde çalışacakları uygun bir node seçer. kube-controller-manager Mantıksal olarak, her controller ayrı bir süreçtir, ancak karmaşıklığı azaltmak için hepsi tek bir binary olarak derlenmiştir ve tek bir process olarak çalışır. Clusterın mevcut durumu ile istenilen durumdan farklı durumda kubeapi ile etc’de saklanan bilgiler kontorl edilerek örneğin node eğer çalışamaz haldeyse pod’ları başka bir node’da oluşturur, günceller ayağa kaldırır farkı yok eder durumu eşitler. Controller Managerdan bazıları: Node Controller Job Controller Service Account & Token Controller Endpoints Controller Kubernetes Cluster kubelet Cluster’daki her node çalışan bir agent’tır. Pod içerisinde tanımlanan containerların çalıştırılmasını sağlar. Kubelet çeşitli mekanizmalar aracılığıyla sağlanan bir dizi Pod tanımı alır ve bu Pod tanımında belirtilen containerların çalışır durumda ve sağlıklı olmasını sağlar. kube-proxy kube-proxy, nodelar üstünde ağ kurallarını yönetir. Bu ağ kuralları,(TCP/IP, UDP) cluster’ın içindeki veya dışındaki ağ oturumlarından Pod’larınızla ağ iletişimine izin verir. Kubectl-Config - kubectl aracı bağlanacağı Kubernetes cluster bilgilerine config dosyaları aracılığıyla erişir. Config dosyasının içerisinde Kubernetes cluster bağlantı bilgilerini ve oraya bağlanırken kullanmak istediğimiz kullanıcıları belirtiriz. Daha sonra bu bağlantı bilgileri ve kullanıcıları ve ek olarak namespace bilgilerini de oluşturarak context’ler yaratırız. Kubectl varsayılan olarak $HOME/.kube/ altındaki config isimli dosyaya bakar. Kubectl varsayılan olarak $HOME/.kube/ altındaki config dosyasına bakar ama bunun KUBECONFIG environment variable değerini değiştirerek güncelleyebiliriz. kubectl config get-contexts: kubectl’in baktığı config dosyasında bulunan contextleri izleyebiliriz. bu komuttan sonra çıkan sonuçlarda yanında yıldız olan (current context) yani kullanılan contexti gösterir yada kubectl config get-contexts komutu ile geçerli/kullanılan context’i gösterir. kubectl config use-contexts [context-adi]: Bu komut başka bir context’e geçmek istediğiniz zaman kullanılır. kubectl cluster-info: Üzerinde çalıştığımız kubernetes cluster ile ilgili temel bilgi öğreneceğimiz komuttur. kubectl get pods -n kube-system: Kubectl podsları -n opsiyonu belirtilerek kube-system isimli namespace’de getirir. kubectl get pods -A: Sistemde çalışan tüm namespaceleri listeler. kubectl get pods -A -o wide: Sistemde çalışan tüm namespaceleri listeler ve -o wide ile geniş çıktıda listeler. Kubernetes Objeleri Kubernetes üzerinde deploy ettiğimiz, çalıştırdığımız, koşturduğumuz şeylere kubernetes objeleri deriz. Kubernetes üzerinde herşey bir API objesidir. Kubernetes tarafında ki en küçük obje pod’dur. İçerisinde bir veya birden fazla container bulunduran en temel objedir. Fakat genellikle 1 pod içinde bir container çalıştırılır. Her pod eşşiz bir UID’si vardır. ve eşsiz bir IP’ye sahiptir. Imperative yöntemle pod oluşturma; $ kubectl run "pod_ismi" --image="image_ismi" --restart=Never Ör: kubectl run firstpod --image=nginx --restart=Never Bir objenin ayrıntılı özelliklerini görmek: $ kubectl describe "obje_tipi" "obje_ismi" Ör: kubectl describe pods firstpod Bir pod objesinin loglarını görüntüleme. (-f opsiyonu çıktıya yapışmanızı ve anlık olarak üretilen logları görmenizi sağlar); $ kubectl logs "pod_ismi" Ör: kubectl logs firstpod Ör: kubectl logs -f firstpod Pod'da komut çalıştırma. (Eğer pod içerisinde birden fazla container varsa -c "container_ismi" opsiyonu ile komutun çalıştırılması istenilen container belirtilebilir); $ kubectl exec "pod_ismi" -- "komut" Ör: kubectl exec firstpod -- printenv Ör: kubectl exec firstpod -c container1 --printenv Pod'a shell bağlantısı oluşturma. (Eğer pod içerisinde birden fazla container varsa -c "container_ismi" opsiyonu ile komutun çalıştırılması istenilen container b $ kubectl exec -it "pod_ismi" -- "shell_konumu-yada-komutu" Ör: kubectl exec -it firstpod -- /bin/sh Ör: kubectl exec -it firstpod -c container1 -- /bin/sh Bir Kubernetes objesini silme. $ kubectl delete "obje_tipi" "obje_ismi" Ör: kubectl delete pods firstpod POD YAML kubectl apply -f [pod1.yml]: Bu yöntemle düzenleme yaptığımız yaml dosyası okunarak deklaratif yöntemle pod ayağa kaldırılır. Yaml içerisinde bir değişiklik yapıldıktan sonra tekrar apply diyerek değişiklik uygulanır. kubectl edit pods [podadı]: Edit komutu herhangi bir kubernetes objesi üzerinde bir düzenleme yapmak için kullanılır. Kubernetes clusterdan bu objenin güncel halini yaml formatında çeker ve sistemde varsayılan text editör üzerinde açar ve yaml dosyasını düzenlemeye izin verir ve pod’a uygular. Fakat prod üzerinde bunu çok uygulanmaz. POD YAŞAM DÖNGÜSÜ Çoklu container pod uygulama kubectl exec -it multicontainer -c webcontainer -- /bin/sh : Bu komut ile multicontainer podu içerisinde ki webcontainer container’ının shelline bağlanıyoruz. kubectl port-forward pod/[podadı] 8080:80 Bu komut ile publish etmek istediğiniz pod’u port-forward ile localde belirttiğiniz portta publish edebiliyoruz. **kubernetes uzak sunucudan kendi locale tünel bağlantı oluşturmak ssh -L 8080:localhost:8080 root@10.0.71.99 ile uzak sunucumuza bağlandıktan sonra localhost:8080 portundan uzak sunucunun localine tünel bağlantı oluştururuz. Init Container Bir pod içerisinde birden fazla container yaratılmasına izin verir. Pod’un yaşam döngüsü kadar çalışmaz. Pod tanımına init container tanımlarsak ilk önce init container çalışır. Görevini yapar tekrar kapanır. App container çalışır. Uygulamamızın bağımlı olduğu bir uygulama/servis olduğu durumda kullanır. - Uygulama container başlatılmadan önce ilk olarak init container çalışır. - Init container yapması gereken işlemleri tamamlar ve kapanır. Uygulama container init container kapatıldıktan sonra çalışmaya başlar. Init container işlemlerini tamamlamadan uygulama container başlatılmaz. kubectl apply -f podinitcontainer.yaml kubectl apply -f service1.yaml Daha sonra service1.yaml dosyamızda myservice adında bir service oluşturuyoruz. init container bu service’i çözümlediği zaman kapanıp appcontainer ayağa kalkacak. kubectl logs -f initcontainerpod -c initcontainer ile myservice adındaki service çözümlenirse initcontainer kapatılır. app container oluşturulur. LABEL & SELECTOR kubectl get pods -l "app" --show-labels Komutuyla podları listelerken -l ile label’e göre arama yap deriz. Sonrasında “app” anahtarına(key) atanmış podları belirtiriz. kubectl get pods -l "app=firstapp,tier=frontend" --show-labels Bu şekilde anahtar karşısına değer ve virgülden sonra başka bir key=value ile aramaları daha da özelleştirebiliriz. Burada virgül(,) “ve” anlamına gelir. kubectl get pods -l "app=firstapp,tier!=frontend" --show-labels Bu aramada tier!=frontend dersek frontend anahtarına eşit olmayan sonuçları getirir. kubectl label pods pod9 app=thirdapp Bu komut ile pod’umuza ekstra label ekleyebiliriz. kubectl label pods [podismi] app- İstediğimiz bir label’ı silmek istersek komuttaki gibi yazıp sonuna - işaretini koyuyoruz. Bu o anahtar ve değeri silmesi anlamına gelir. kubectl label --overwrite pods [podadı] team=team4 Bu şekilde --overwrite komutu ile varolan bir pod içindeki labelda güncelleme işlemini gerçekleştirebiliriz. kubectl label pods --all foo=bar Bu komutla tüm podlara label ataması yapabiliriz. nodeSelector label’i ile objeler arası ilişkiler kurabiliriz. Bu örnekte olduğu gibi podumuzun hangi node üzerinde çalışacağını belirtiriz. Örn hddtype = ssd dediğimizde ssd diskine sahip bir node üzerinde çalışması gerektiğiniz belirttik. Bunun sonucunda pod cluster içinde ssd olan bir disk yoksa başlatılmayacak pending aşamadında bekleyecektir. Annotation Bu özellikle aynı label’da olduğu gibi podlara metadata eklemesi yapabiliriz. kubectl annotate pods [podadı] key=value Şeklinde var olan bir pod’umuz üzerine yeni bir annotation ekleyebiliriz. kubectl annotate pods [podadı] key- komutu ile ise eklediğimiz annotation’u silebiliriz. NAMESPACE Varsayılan olarak bir namespace belirtilmediği sürece tüm podlar default namespace altında oluşturulur. kubectl get pods --namespace kube-system Cluster içinde var olan podlarda belirli bir namespace içindeki podları listelemek için kullanılır. Namespace oluşturabilmek için hem imperative (komut ile) hem declarative (yaml) ile gerçekleştirebiliriz. Imperative yöntemle namespace oluşturmak: kubectl create namepace [namepace] Declarative yöntemle namespace oluşturmak: oluşturduğumuz namespace üzerindeki podları listelemek için; kubectl get pods -n [namespaceadı] Çalışmalarımızda her seferinde namespace belirtmek yerine, default olarak isteğimiz namespace’i seçmek için; kubectl config set-context --current --namespace=[namespaceadı] ile çalışmak istediğimiz namespace’i seçmiş oluruz. Oluşturduğumuz namespace’i silmek için; kubectl delete namespaces [namespaceadı] DEPLOYMENT Bir deployment’da istenen durumu tanımlarsınız ve Deployment Controller mevcut durumu(current state) istenilen durum(desired state) ile karşılaştırıp gerekli aksiyonları alır. Imperative Yöntemle Deployment kubectl create deployment [deploymentadı] --image=nginx:latest --replicas=2 Deployment içerisinde değişiklik yapmak için set komutu kubectl set image deployment/[deploymentadı] nginx=httpd Deployment ile pod sayısınıda ayarlayabiliriz. kubectl set deployment [deploymentadı] --replicas=5 Deployment silme kubectl delete deployments [deploymentadı] Declarative Yöntemle Deployment deploymenttemplate.yaml podexample.yaml deployment için yaml oluştururken sağda bulunan pod yaml dosyasında metadata kısmından sonra ki gibi özellikleri alıp deployment yaml dosyamızda template altına atarız. name kısmını sileriz. selector kısmı her deployment yaml’da yer alır. bu örnekte deployment’ın yöneteceği podlar app: frontend podları olacağını belirtiyoruz. template kısmında ise yeni yaratılacak podlara bu label’ı ekleriz ki seçme işlemi tamamlansın. Deployment’ta en az bir tane selector olmalı aynı label’lar template kısmında bulunmalı. Bu deployment yaml’ı ayağa kaldırmak için; kubectl apply -f deploymenttemplate.yaml ReplicaSet Bir ReplicaSet’in amacı, herhangi bir replica Pod setini sürdürmektedir. Bu nedenle, genellikle belirli sayıda özdeş Pod’un kullanılabilirliğini garanti etmek için kullanılır. Güncellediğimiz deployment’ı geri almak istersek yeni oluşan replicaset bir önceki replicaset’e geçer. Güncellediğimiz deployment’ı ilk baştaki deployment’a geri dönmek için; kubectl rollout undo deployment [deploymentadı] Belirlenen revizyona geri dönmebilmek için; kubectl rollout undo deployment [deploymentadı] --to-revision=2 Varsayılan olarak deployment’ta RollingUpdate seçilidir. Rollout & Rollback rollout history deployment [deploymentpodadı] :Bu sayede oluşturmuş olduğumuz yeni objenin geçmişini görebiliriz. rollout history deployment [deploymentpodadı] --revision=2 :Bu sayede listede bulunan ikinci revizyonda gösterilir. Rollout durumunu görmek için; kubectl rollout status deployment [deploymentadı] -w KUBERNETES AĞ ALTYAPISI - - Kubernetes kurulumda pod’lara ip dağıtılması için bir ip adres aralığı ya da kubernetes terminolojisinde bilinen adıyla --pod-network-cidr belirlenir. Kubernetes’de her pod bu cidr bloğundan atanacak bir unique(eşsiz) ip adresine sahip olur. Aynı cluster içerisindeki tüm podlar varsayılan olarak birbirleriyle herhangi bir kısıtlama olmadan ve NAT yani Network Address Translation olmadan haberleşebilirler. Kubernetes clusterlar node’lar birbirleriyle haberleşmek için CNI network pluginine ihtiyaç duyarlar. Bunlardan en çok kullanılanı Calico’dur. Bu sayede bu pluginler podların ip adresi atanması, ip table kuralları düzenlenmesi, nodelar arasında pod cidr bloğunun natsız çalışması için overlay bloğunun oluşmasını sağlar. SERVICE ClusterIP Service NodePortService LoadBalancerService Imperative Olarak Service Oluşturma kubectl expose deployment [deploymentadı] --type=ClusterIP --name=[deploymentadı] LIVENESS PROBE Kubelet, bir containerın ne zaman yeniden başlatılacağını bilmek için liveness probe kullanır. Örneğin, liveness probe, bir uygulamanın çalıştığı ancak ilerleme sağlayamadığı bir kilitlenmeyi yakalayabilir. Böyle bir durumda bir container’ı yeniden başlatmak, hatalara rağmen uygulamayı daha kullanılabilir hale getirmeye yardımcı olabilir. READINESS PROBE Kubelet, bir containerın ne zaman trafiği kabul etmeye hazır olduğunu bilmek için readiness probleları kullanır. Bir pod, tüm containerlar hazır olduğunda hazır kabul edilir. Readiness probe sayesinde bir Pod hazır olana kadar service arkasına eklenmez. Pod tanımlarında termitaionGracePeriodSeconds anahtarı bulunur ve varsayılan değeri 30 sn’dir. Bunun anlamı eğer pod’un yaptığı bir işlem varsa bunu belirtilen süre(30sn) içerisinde tamamla ve kendini kapat sinyali gönderir. Resource Limits Burada resources kısmında request bu pod’un kullanacağı minimum sistem kaynağı miktarını gösterir. limits kısmı ise bu container’ın maksimum kullanacağı sistem kaynağı miktarını ifade eder. CPU için örn: 250m ile 0.25 aynı ifade demektir. Bu sayede eğer memory kısmı limitten fazla memory tüketmek isterse sistem OOMKiled durumuna geçer ve pod’u restart eder. Environment Variable Environment variable’da belirttiğimiz değişkenler belirttiğimiz kısımlara gelerek kullanılabilir. KUBERNETES 102 Volume Ephemeral(Geçici) Volume: Geçici Volume verileri fiziksel olarak başka bir konumda tutmaya sağlar. emptyDir volume ilk olarak bir pod bir node’a atandığında oluşturulur ve bu Pod o node’da çalıştığı sürece var olur. Adından da anlaşılacağı üzere, emptyDir birimi başlangıcta boştur. Pod içindeki tüm containerlar, emptyDir volume’deki aynı dosyaları okuyabilir ve yazabilir, ancak bu birim her kapsayıcıda aynı veya farklı yollarla mount edilebilir. Bir Pod herhangi bir nedenlebir node’dan silindiğinde, emptyDir içindeki veriler de kalıcı olarak silinir. hostPath: Bir hostPath volume, worker node dosya sisteminden Pod’unuza bir dosya veya dizini bağlayabilme imkanı verir. Bu çoğu Pod’un ihtiyac duyacağı bir şey değildir, ancak bazı uygulamalar için güçlü bir kaçış kapısı sunar. SECRET Kubernetes Secret, parolalar, Oauth token ve ssh anahtarları gibi hassas bilgileri depolamanıza ve yönetmenize olanak tanır. Gizli bilgileri bir secret içinde saklamak, onu bir container imajına koymantan daha güvenli ve esnektir. secret create kubectl create secret generic myscret2 --from-literal=db_server=db.example.com -from-literal=db_username=admin --from-literal=P@ssw0rd! imperative yöntemle secret oluşturduğumuzda yaml içindeki type=Opaque kısmı burada generic olarak geçiyor. --from-literal ile ise stringData bilgilerini ekleyebiliriz. Eğer bulunduğu klasör içindeki bir dosyadan data değerlerini okutmak isterseniz --from-file attribute kullanırız; kubectl secret create generic mysecret3 --from-file=db_server=server.txt --fromfile=db_username=username.txt --from-file=db_password=password.txt Tüm attributeları eğer bir dosya içerisinden çekmek istersek bu dosyayı .json formatında hazırlamalıyız Bu json dosyasıda işlem yaptığımız klasör içinde yer almalıdır. kubectl create secret generic mysecret4 --from-file=config.json Bu sayede secret-vol isminde bir secret oluşturuyoruz. Bu volume mysecret3 isimli bir secrettan oluşssun. Sonrasında bunu container içinde bir folder’a mount ediyoruz. Bu pod oluştuğunda kubernetes bu secret’ı mouthPath’te belirttiğimiz(/secret) klasörün altına oluşturacak. Bu path’in altında ise anahtar ile atadığımız değerler olacak. -----------------------------------------------------Burada ise env anahtarı ile environment variable tanımlıyoruz. Burada değerleri yaml dosyasının içine yazmak yerine secrettan okutuyoruz. ---------------------------------------------------------------------------------- Bu durumda ise yine environment variable olarak tanımlıyoruz fakat tek tek tanımlamak yerine gidip mysecret3 isimli secret’a bak onun içindeki tüm değerleri environment variable olarak atamasını tanımlıyoruz. ConfigMap Gizli olmayan verileri anahtar/değer eşlenikleri olarak depolamak için kullanılan bir API nesnesidir. Podlar, ConfigMap’i environment variable, komut satırı argümanları veya bir volume olarak bağlanan yapılandırma dosyaları olarak kullanılabilir. Secretlarla birebir aynıdır. Farkı gizli olmayan bilgileri tutmak için kullanılır. Imperative Yöntemle Oluşturma kubectl create configmap myconfigmap --from-literal=background=blue --fromfile=a.txt Declarative Yöntemle Oluşturma kubctl apply -f configmap.yaml kubectl exec -it configmappod -- prinenv Node Affinity Pod’larımızın uygun worker nodelar üzerinde çalışmasını sağlayabilen ve node selectorden daha fazla opsiyon sağlayan özelliktir. Node’lara atanan etiketlere göre podunuzun hangi node üstünde schedule edilmeye uygun olduğunu kısıtlamanıza olanak tanır. Tain & Toleration Taint, bir node üzerinde çalışan pod'ların kabul edilmesini engelleyen bir işaretçidir. Tolerations ise, pod'ların belirli bir Taint'e sahip node'lar üzerinde çalışmasını sağlayan bir yöntemdir. Bir node'a Taint eklemek, o node üzerinde çalışan pod'ların sadece belirli tolerasyonlara sahip pod'lar tarafından çalıştırılmasını sağlar. Taints, özellikle belirli bir node'un sadece belirli pod'lar tarafından kullanılmasını gerektiği durumlarda kullanılır. Taint eklemek için kubectl taint node worker1 platform=production:NoSchedule Tain kaldırmak için kubectl taint node worker1 platform- DaemonSet Tüm (veya bazı) nodeların bir Pod’un bir kopyasını çalıştırmasını sağlar. Cluster’a yeni node eklendikçe, onlara Podlar eklenir. Clusterdan node kaldırıldığında, bu podlar da kaldırılır. Bir DaemonSet’in silinmesi, oluşturulduğu Pod’ları da temizleyecektir. Persistent Volume ve Persisten Volume Claim Cluster dışında tutulabilen ve çeşitli türde depolama ünitelerinin üzerinde oluşturabildiğimiz ve pod yaşam süresinden daha uzun süre saklamamız gereken verileri saklamamıza imkan veren verilere persisten volume denir. Container Storage Interface(CSI) CSI kubernetesin storage altyapısının nasıl ayarlanması gerektiğini belirten bir standarttır. Üçüncü taraf depolama sağlayıcıları, CSI kullanarak, çekirdek kubernetes koduna dokunmak zorunda kalmadan Kubernetes’te yeni depolama sistemlerini açığa çıkaran eklentiler yazabilme imkanına kavuştu. Persisten volume tanımında persistenVolumeReclaimPolicy seçeneği ile işi bitip kullanma bırakıldak sonra bu volume’e ne olacağını belirtiyoruz. Retain seçeneği seçilirse; Bu persistent volume kullanıldaktan sonra olduğu gibi kalır. Recycyle seçeği ile volume ile işimiz bittiğinde volume silinmiyor fakat içindeki tüm dosyalar siliniyor. Tekrar boş bir volume ile başka podlarda kullanıyoruz. Delete ile volume ile işimiz bittiğinde volume’ü tamamen siler. Persistent volume’ü bir pod’a bağlamak için Persistent Volume Claim tipinde bir obje daha oluşturmalıyız. PVC bize işimize yarayan bir PV’yi seçmemizi sağlar. StatefulSet Job Bir job objesi, bir veya daha fazla pod oluşturur ve belirli bir sayıda pod başarıyla sonlandırılana kadar pod yürütmeyi yeniden denemeye devam eder. Job belirtilen sayıda pod’un başarıyla tamamlanma durumunu izler. Belirtilen sayıda başarılı tamamlamaya ulaşıldığında, Job tamamlanır. Bir Job’un silinmesi, oluşturduğu podları temizleyecektir. Bu yaml ile pi sayısısının 2000 sayısı listelenecek listelendikten sonra pod duracak bu aynı anda 2 pod’da olacak. 10 tane pod oluşacak eğer 5 kere denemeden sonra running olmazsa hata logu verecek veya 100sn’den sonra oluşmazsa hata logu bascak. CronJob Eğer bu job işlemlerini manuel tetiklemekten ziyade hergün belirli bir dk saatte çalışmasını otomatize etmek isteseydik. Bunun için cronjob kullanacağız. Bu yaml içerinde schedule kısmına istediğimiz saati dk veya saniyeyi yazarız. Görüntülemek için: kubectl get cronjobs.batch Silmek için: kubectl delete cronjobs.batch [cronjobadı] Role Based Access Control Rol tabanlı erişim denetimi (RBAC), kuruluşunuzdaki bireysel kullanıcıların rollerine dayalı olarak bilgisayar veya ağ kaynaklarına erişimi düzenleme yöntemidir. RBAC yetkilendirmesi, yetkilendirme kararlarını yönlendirmek için rbac.authorization.k8s.is API grubunu kullanır ve Kubernetes API aracılığıyla ilkeleri dinamik olarak tanır. Ingress Ingress controller, L7 Application Loadbalancer kavramının Kubernetes spesifikasyonlarına göre çalışan ve Kubernetes’e deploy ederek kullanabildiğimiz türüdür. Nginx, Haproxy, Traefik en bilinen ingress controller uygulamalarıdır. - Genellikle HTTP olmak üzere bir clusterdaki servislere yöneten bir API nesnesidir. Yük dengeleme, SSL sonlandırması ve path-name tabanlı yönlendirme özelliklerini destekler. Application Load Balancing yapabilmek için, SSN Terminating yapabilmek için, Path Base Routing yapabilmek için bir Ingress Controller kurmalıyız. kubectl drain Worker node'lardan bir tanesinin üzerindeki tüm podları tahliye edin ve ardından yeni pod schedule edilememesini sağlayın. $ nodedrain=$(kubectl get no -o jsonpath="{.items[3].metadata.name}") $ kubectl drain $nodedrain --ignore-daemonsets --delete-emptydir-data --force $ kubectl cordon $nodedrain drain komutu ve sonrasında belirtilen node o node üzerindeki podların o sunucudan başka bir sunucuya gönderilmesini ve orada çalışmasını sağlar. Kubectl cordon ile podların yeniden o node üzerinde yeniden schedule edilmesini engeller. NETWORK POLICY TEMEL KUBERNETES NETWOERK KURALLARI Her pod’un kendine ait bir unique ID si olması gerekiyor. Bütün podlar birbirleri arasında NAT olmadan haberleşebilmeleri gerekiyor. Bütün podlar diğer podlarlarla varsayılan olarak haberleşebilmeleri gerekiyor. Podlar bulundukları virtual machine’in (worker node’un) erişebildiği her yere erişebilmesi gerekiyor. Network Policy oluştururken ilk olarak kind kısmına ne oluşturacağımızı yazarız. Metadata kısmındaisim ve namespace belirleriz. Spec kısmında podSelector ile hangi pod’a uygulayacağımızı seçeriz. Policy içerisinde bir policyType belirleriz. -Ingress -> selector ile seçtiğimiz podlara, içeriye doğru gelen istekler demek -Egress -> Selector ile seçtiğimiz podlardan dış dünyaya doğru, yani dışarıya doğru giden ayarları belirler. Ingress anahtarı açıp from ile ayarları belirleriz. ipBlock ile bizim belirlediğimiz podlara hangi ip blokları ve ports kısmında belirlediğimiz port üzerinden izin vermesini belirlediğimiz ip block’unu belirleriz. Except: kısmı ise gelmesini istemediğimiz block’u belirleriz. Namespace üzerindeki labeller üzerinden tanımlayabiliriz. Oluşturduğumuz network policyi git yukardaki belirtiğimiz labeldaki podlara atamasını yap ve bu podlara team: b isimli label’a sahip namespacedeki bütün podlar 80 portu üzerinden erişebilsin. Son olarak kullanabileceğimiz seçim şekli direk pod üzerinden app: frontend seçerek yapabiliriz. Ayrıca port kısmının altına endport yaparsak port aralığıda tanımlayabiliriz. Egress: Bu kısımda belirttiğimiz ipblock’una port 80 üzerinden sadece erişebilsin onun dışında hiç bir yere erişim izni olmasın. Aynı poda birden fazla policy ataması yapabiliriz. Helm Helm bizlere kubernetes üzerinde paket yüklememizi sağlar. Bir paket yöneticisidir. Uygulamalarımızı bir paket haline getirmemizi ve bu paketleri tek bir komut ile kubernetes üzerine yüklememizi sağlar. Helm’de kubernetes üzerine yükleyebildiğiniz uygulamanın paketlenmiş haline CHART deriz. Biz bu chart’ı alıp kubernetes clusterımız üzerine yüklersek bunada release deriz. Repository ise bu helm chartların bir arada tutulduğu yerdir. ArtifactHUB ise oluşturulan helm chartları yada paketleri aratabiliceğimiz bir arama motoru gibi düşünebiliriz. MONITORING – Prometheus Cluster’ın durumu, Objelerin durumu, Nodeların durumu, Uygulamaların Logları’nı Prometheus stack ile ilk 3 maddeyi monitoring edebiliriz. Uygulamaların loglarını ELK Stack ile nasıl toplayabiliceğimizi(aggregate) göreceğiz. Prometheus bir metrik altyapısı ve sunucusu diyebiliriz. Prometheus pull-base çalışır.Yani biz bunu kurduğumuz zaman cluster üzerine prometheus gidip bu metrikleri toplar. Kurulum: Prometheus’da görselleştirme sağlamak için Grafana kullanabiliriz. Kurulum aşamasında birden fazla ayrı kurmamız gereken değişkenler olduğu için prometheus-community adında bir topluluğun oluşturduğu kube-prometheus-stack helm-charts ile kolay kurulum yapabiliyoruz. k8sfundamentals/monitoring bu adrestende ulaşabiliriz. İlk olarak monitoring adında bir namespace oluşturuyoruz. $ kubectl create namespace monitoring Daha sonra helm ile repoyu çekip update edip en sonunda kube-prometheus-stack’i clusterımıza yüklüyoruz. $ helm repo add prometheus-community https://prometheuscommunity.github.io/helm-charts $ helm repo update $ helm install kubeprostack --namespace monitoring prometheuscommunity/kube-prometheus-stack Prometheus’u kontrol ediyoruz. $ kubectl --namespace monitoring port-forward svc/kubeprostack-kubepromethe-prometheus 9090 Port forward sonrası ssh ile tünel oluştutup prometheusa bağlanabiliriz. Sonrasında queryleri çalıştırmak istersek aşağıdaki gibi işlemler yapabiliriz. queries: Şu ana kadar oluşturulmuş tüm podlar: kube_pod_created Namespace'e göre dağılım ^^:count by (namespace) (kube_pod_created) Mevcut çalışan podlar: sum by (namespace) (kube_pod_info) Ready durumunda olmayan podlar "namespace'e göre dağılım": sum by (namespace) (kube_pod_status_ready{condition="false"}) Alert manager kontrol et kubectl --namespace monitoring port-forward svc/kubeprostack-kube-promethealertmanager 9093 Grafana'a bağlan kubectl --namespace monitoring port-forward svc/kubeprostack-grafana 8080:80 username: admin password: prom-operator kubectl get secret kubeprostack-grafana -n monitoring -o jsonpath="{.data.admin-password}" | base64 --decode ; echo Grafana Dashboards: https://grafana.com/grafana/dashboards/ ELK STACK Uygulamaların loglarını kontrol eder ve onları monitoring olarak izlettirir. Elasticsearch logların toplandığı ve kaydedildiği yerdir. Logları toplamak için ise Logstash’i kullanırız. Diğer log toplama uygulaması ise fluentd’dir. Kibana görselleştirmeyi sağlar. Kurulum Cloud Log oluşturacak pod'u çalıştır $ kubectl apply -f testpod.yaml efk isimli yeni bir namespace oluştur $ kubectl create namespace efk elastichsearch deploy et $ helm repo add elastic https://helm.elastic.co $ helm repo update $ helm install elasticsearch elastic/elasticsearch --namespace efk rollout'un bitmesini bekle $ kubectl rollout status sts/elasticsearch-master --namespace=efk Waiting for 3 pods to be ready... Waiting for 2 pods to be ready... Waiting for 1 pods to be ready... partitioned roll out complete: 3 new pods have been updated... Elasticsearch'un düzgün çalıştığını kontrol et. $ kubectl port-forward svc/elasticsearch-master 9200:9200 --namespace=efk $ curl http://localhost:9200/_cluster/state?pretty { "cluster_name" : "elasticsearch", "cluster_uuid" : "7cqcefAkTkuk7jJAjRaNSw", "version" : 17, "state_uuid" : "vsAEUSmVTlyFl5PLHIdcfw", "master_node" : "tMwUfjTjR_OYKAZMRn57ig", "blocks" : { }, "nodes" : { "tMwUfjTjR_OYKAZMRn57ig" : { "name" : "elasticsearch-master-0", "ephemeral_id" : "747I-N1jQOCTvWQFnMyvpA", ... Fluentd deploy et $ kubectl apply -f fluentd.yaml kibana deploy et $ helm install kibana elastic/kibana --set env.ELASTICSEARCH_URL=http://elasticsearch-master:9200 --namespace efk Fluentd ve kibana deploymentlarının tamamlanmasını bekle Kibana service'sini expose et kubectl port-forward service/kibana-kibana -n efk 5601:5601 Kibana'da index oluştur ve sorgulamayı dene