Kubernetes etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Kubernetes etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

17 Kasım 2021 Çarşamba

Kubernetes Operator

Giriş
Açıklaması şöyle. Custom Resource ve Custom Controller kavramı vardır
The basic idea of a Kubernetes Operator is to extend the Kubernetes’s level-driven reconciliation loop and API set towards running stateful application workloads natively on Kubernetes. A Kubernetes Operator consists of Kubernetes Custom Resource(s) / API(s) and Kubernetes Custom Controller(s). 
Açıklaması şöyle. 
An Operator is packaged as a container image and is deployed in a Kubernetes cluster using Kubernetes YAMLs. 
Custom Resource Nedir?
Açıklaması şöyle. 
The Custom Resources represent an API that takes declarative inputs on the workload being abstracted and the Custom Controller implements corresponding actions on the workload. Kubernetes Operators are typically implemented in a standard programming language (Golang, Python, Java, etc.).
Açıklaması şöyle. Yani veri tabanı gibi şeyler Custom Resource oluyor
Once deployed, new Custom Resources (e.g. Mysql, Cassandra, etc.) are available to the end users similar to built-in Resources (e.g. Pod, Service, etc.). This allows them to orchestrate their application workflows more effectively leveraging additional Custom Resources.
Custom Resource, Kubernetes'e CRD metaPI kullanılarak tanıtılır. Açıklaması şöyle. 
In order for the Custom Resources to be recognized in a cluster, they need to be first registered in the cluster using Kubernetes’s meta API of ‘Custom Resource Definition (CRD)’. The CRD itself is a Kubernetes resource.
Helm ile kullanmak
Helm ile kullanmak için bazı maddeler şöyle
- Register Custom Resource Definitions in Helm chart (and not in Operator code)
- Make sure Custom Resource Definitions are getting installed prior to the Operator deployment
- Define Custom Resource validation rules in CRD YAML
- Use values.yaml or ConfigMaps for Operator configurables
- Add Platform-as-Code annotations to enable easy discovery and consumption of Operator’s Custom Resources
Örnek - Vitess
Şöyle yaparız
git clone git@github.com:vitessio/vitess.git
cd vitess/examples/operator

kubectl apply -f operator.yaml

7 Kasım 2021 Pazar

Kubernetes ConfigMap - Gizli Olmayan Veri

Giriş
ConfigMap içinde non-confidential yani gizli olmayan veri saklanır. Eğer gizli veri (password, token, key gibi) saklanacaksa Secret kullanılır

Pod içinde kullanırken
envFrom başlığı altında configMapRef şeklinde kullanılır
envFrom başlığı altında secretRef şeklinde kullanılır

Örnek
Şöyle yaparız
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
  - name: nginx
    image: nginx
    envFrom:
    - configMapRef:
        name: testconfigmap
ConfigMap yaratmak
ConfigMap yaratmak için 2 tane yöntem var
1. ConfigMap yaml dosyası tanımlanır
2. Komut satırında "kubectl create configmap ..." yapılır

1. Dosya Tanımlama
kind olarak ConfigMap verilir ve data bölümünde key-value değerleri tanımlanır

Örnek
Şöyle yaparız
apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb
data:
  database-name: microservices
Örnek
Şöyle yaparız
apiVersion: v1
kind: ConfigMap
metadata:
  name: geared-marsupi-configmap
data:
  myvalue: "Hello World"
  drink: coffee
2. Komut Satırı
Örnek
configmap yaratmak için şöyle yaparız
#Create ConfigMap
kubectl create configmap testconfigmap --from-literal=TestKey1=TestValue1 
--from-literal=TestKey2=TestValue2 kubectl create configmap testconfigmap --from-file=/opt/test_file #Test kubectl get configmaps kubectl describe configmaps kubectl describe configmap testconfigmap
komut satırından kullanmak istersek iki seçenek var. Açıklaması şöyle
1. Use the contents of an entire directory with kubectl create configmap my-config --from-file=./my/dir/path/
2. Use the contents of a file or specific set of files with kubectl create configmap my-config --from-file=./my/file.txt

31 Ekim 2021 Pazar

Kubernetes Container Lifecycle Events

Lifecycle Hook
İki tane lifecycle hook var. Açıklaması şöyle
PostStart: This hook is executed right after a container is created. However, the hook might be invoked after the container's ENTRYPOINT is executed. The hook handler must not accept any parameters.

PreStop: This hook is executed immediately before a container is terminated due to any reason, such as resource contention, liveness probe failure, etc. You cannot pass any parameters to the handler, and the container will be terminated irrespective of the outcome of the handler.
Lifecycle Hook Handlers
Hook'a iki çeşit handler takabiliriz. Açıklaması şöyle
There are two types of handlers that you can attach to a lifecycle hook:

exec: It executes the specified command in the container's main process. The command is executed in parallel with the container's ENTRYPOINT instruction. If the hook takes too long or fails, the kubelet process will restart the container.

httpGet or tcpSocket: It sends an HTTP request or establishes a TCP socket connection against a specific endpoint on the container. Unlike the exec, which is executed by the container, this handler is executed by the kubelet process.
Örnek - postStart
Şöyle yaparız
apiVersion: v1
kind: Pod
metadata:
  name: sidecar-container-demo
spec:
  containers:
    - image: busybox
      command: ["/bin/sh"]
      args:
        [
          "-c",
          "while true; do echo echo $(date -u) 'Written by busybox sidecar container' >> /var/log/index.html; sleep 5;done",
        ]
      name: sidecar-container
      resources: {}
      volumeMounts:
        - name: var-logs
          mountPath: /var/log
      lifecycle:
        postStart:
          httpGet:
            path: /index.html
            port: 80
            host: localhost
            scheme: HTTP
    - image: nginx
      name: main-container
      resources: {}
      ports:
        - containerPort: 80
      volumeMounts:
        - name: var-logs
          mountPath: /usr/share/nginx/html
  dnsPolicy: Default
  volumes:
    - name: var-logs
      emptyDir: {}
Örnek - preStop
Şöyle yaparız
apiVersion: v1
kind: Pod
metadata:
  name: prestop-demo
spec:
  containers:
    - image: nginx
      name: nginx-container
      resources: {}
      ports:
        - containerPort: 80
      lifecycle:
        preStop:
          exec:
            command:
              - sh
              - -c
              - echo "Stopping container now...">/proc/1/fd/1 && nginx -s stop
  dnsPolicy: Default

12 Ekim 2021 Salı

Kubernetes Probe'ları

Giriş
Kubernetes uygulamanın sağlıklı, hazır ve başladığını anlamak için 3 tane probe kullanır. Bunlar şöyle
liveness probe
readiness probe
startup probe
Açıklaması şöyle
Kubernetes has built-in probes for determining whether or not a Pod is alive and ready to serve incoming requests. This is known as the Health Check pattern, which is is supported in Quarkus using the SmallRye Health extension. The SmallRye Health extension is an implementation of the MicroProfile Health specification. 

Spring Boot applications can use the Kubernetes probes included in the Spring Boot Actuator starter; however, the Spring Boot Actuator only provides the endpoints and doesn't generate the necessary configuration or the required Kubernetes manifests. They will need to be created manually.

8 Ekim 2021 Cuma

Kubernetes Ingress Service

Giriş
Açıklaması şöyle. OpenShift terminolojisinde Ingress yerine Route kelimesi kullanılıyor.
Ingress is actually NOT a type of service. Instead, it sits in front of multiple services and act as a “smart router” or entrypoint into your cluster.
Şeklen şöyle. Burada ingress olarak nginx kullanılıyor.


Örnek
Şöyle yaparız
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
   ingress.kubernetes.io/rewrite-target: /
 name: web-ingress
spec:
  rules:
  - host: kubernetes.foo.bar
    http:
      paths:
      - backend:
          serviceName: appsvc
          servicePort: 80
        path: /app
Daha sonra /etc/nginx.conf şöyle yaparız
server {
    server_name kubernetes.foo.bar;
    ...
}

17 Eylül 2021 Cuma

Kubernetes Deployment İçin Volumes

Giriş
Çeşitli volume tipleri var.
1. emptyDir
2. PersistentVolume
gibi

emptyDir
Şu cümleler önemli
emptyDir are volumes that get created empty when a Pod is created.
Deleting a Pod deletes all its emptyDirs.
emptyDir are meant for temporary working disk space.

Örnek
Şöyle yaparız
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dune-quote-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dune-quote-service
  template:
    metadata:
      labels:
        app: dune-quote-service
    spec:
      containers:
        - image: gamussa/reactive-quote-service:0.0.3
          imagePullPolicy: Always
          name: dune-quote-service
          ports:
            - containerPort: 9001
          env:
            ...
            - name: GRPC_SERVER_SECURITY_CERTIFICATECHAIN
              value: "file:/mnt/grpc-cert-chain/server.crt"
            - name: GRPC_SERVER_SECURITY_PRIVATEKEY
              value: "file:/mnt/grpc-pk/server.key"
          volumeMounts:
            - mountPath: /mnt/grpc-cert-chain
              name: grpc-cert-chain
            - mountPath: /mnt/grpc-pk
              name: grpc-pk
      volumes:
        - name: grpc-cert-chain
          secret:
            secretName: grpc-cert-chain
        - name: grpc-pk
          secret:
            secretName: grpc-pk
Örnek - sadece tmp Dizini Hakkı
Açıklaması şöyle
Applications running in a containerized environment seldom write data, as that practically goes against the logic of having an immutable system. However, at times, it may be needed for caching or temporary swapping/processing of files. Hence, to provide this functionality to the developer, we can mount an emptyDir as an ephemeral volume which is lost once the container is killed.

With this in place, we can also add another security context attribute called “readOnlyRootFilesystem” and set it as true, since the application running inside the container no longer needs to write anywhere on the file-system other than the ‘tmp’ directory.
Şöyle yaparız
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: springbootmaven
  name: springbootmaven
  namespace: boot
spec:
  replicas: 1
  selector:
    matchLabels:
      app: springbootmaven
  template:
    metadata:
      labels:
        app: springbootmaven
    spec:
      securityContext:
        fsGroup: 1337
        runAsNonRoot: true
        runAsUser: 1337
      containers:
      - image: salecharohit/springbootmaven
        name: springbootmaven
        ports:
        - containerPort: 8080
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          privileged: false
          runAsUser: 1337
          capabilities:
            drop: ["SETUID", "SETGID"]
        volumeMounts:
        - mountPath: /tmp
          name: tmp
      serviceAccountName: ""
      automountServiceAccountToken: false
      volumes:
      - emptyDir: {}
        name: tmp

16 Eylül 2021 Perşembe

Kubernetes Servis Nedir?

Giriş
Açıklaması şöyle. Dış dünyaya açılan yüzümüz diye düşünebiliriz.
A Service enables network access to a set of Pods in Kubernetes.

Services select Pods based on their labels. When a network request is made to the service, it selects all Pods in the cluster matching the service's selector, chooses one of them, and forwards the network request to it.
Service ve Deployment Farkı Nedir?
Açıklaması şöyle.
A deployment is responsible for keeping a set of pods running.
A service is responsible for enabling network access to a set of pods.
Servis Tipleri Nedir?
Açıklaması şöyle
The type property in the Service's spec determines how the service is exposed to the network. It changes where a Service is able to be accessed from. The possible types are ClusterIP, NodePort, and LoadBalancer

- ClusterIP – The default value. The service is only accessible from within the Kubernetes cluster – you can’t make requests to your Pods from outside the cluster!

- NodePort – This makes the service accessible on a static port on each Node in the cluster. This means that the service can handle requests that originate from outside the cluster.

- LoadBalancer – The service becomes accessible externally through a cloud provider's load balancer functionality. GCP, AWS, Azure, and OpenStack offer this functionality. The cloud provider will create a load balancer, which then automatically routes requests to your Kubernetes Service
servisleri görmek için kubectl get services kullanılır

ClusterIP Service yazısına bakabilirsiniz
LoadBalanceService yazısına bakabilirsiniz
IngressService yazısına bakabilirsiniz


Kubernetes Pod Nedir?

Giriş
Pod, Kubernetes mimarisinde Kubernetes Node'un bir parçası. Kısaca container'ları çalıştırır deyebiliriz.

Açıklaması şöyle. Aslında bir pod birden fazla docker container çalıştırabilir. Açıklaması şöyle
The primary reason that Pods can have multiple containers is to support helper applications that assist a primary application. Typical examples of helper applications are data pullers, data pushers, and proxies. Helper and primary applications often need to communicate with each other. Typically this is done through a shared filesystem, as shown in this exercise, or through the loopback network interface, localhost. An example of this pattern is a web server along with a helper program that polls a Git repository for new updates. 
Ancak bu tavsiye edilmediği için pod = container gibi düşünülebilir.
The containers are called as ‘Pod’ in Kubernetes terms. So a single Kubernetes node can have multiple containers.
Pod örneğin bir servis olabilir.
Kubernetes Servis Nedir? yazısına bakabilirsiniz

Örnek
Buradaki şekilde aynı Pod içinde çalışan farklı container'lar görülebilir.

13 Eylül 2021 Pazartesi

Kubernetes Configuration Examples

Giriş
Konfigürasyon için iki yöntem var
1. Environment variable
2. ConfigMap
Her iki yöntem de Pod, Service veya herhangi bir başka Kubernetes kind için kullanılabilir.

1. Environment variable
env başlığı altında
- name + value 
- name + valueFrom + configMapKeyRef
- name + valueFrom + secretKeyRef
şeklinde kullanılır

Örnek
Şöyle yaparız
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
  - name: nginx
    image: nginx
    env:
    - name: DB_NAME
      value: MyDB
    - name: DB_URL
      valueFrom:
        configMapKeyRef:
          name: config-url
          key: db_url
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: config-passwd
          key: db_password
2. ConfigMap
Kubernetes ConfigMap yazısına taşıdım

23 Ağustos 2021 Pazartesi

Kubernetes ve DNS

Giriş
Açıklaması şöyle
You can set up a DNS service for your Kubernetes cluster using an add-on.

We all know how DNS works in the case of the internet. Every website has a unique address a.k.a domain (for e.g. www.amazon.com). A similar approach is applied in the case of service discovery in Kubernetes. DNS server watches the Kubernetes for new services and creates a set of DNS records for each one. If DNS has been enabled throughout your cluster then all Pods should automatically be able to resolve services by their DNS name.

For instance, in our case, the DNS service and control plane (Kubernetes control panel) acting together create a DNS record of shoppingcart-service.dev-ns . Pods in the dev-ns the namespace should be able to find the service by doing a name lookup for shoppingcart-service

Kubernetes provides the concept of namespaces to segregate different concerns. For instances, you can have different namespaces for dev, test and prodenvironments.
Headless Service
Açıklaması şöyle
Luckily, Kubernetes allows clients to discover pod IPs through DNS lookups. Usually, when you perform a DNS lookup for a service, the DNS server returns a single IP — the service’s cluster IP. But if you tell Kubernetes you don’t need a cluster IP for your service (you do this by setting the clusterIP field to None in the service specification ), the DNS server will return the pod IPs instead of the single service IP. Instead of returning a single DNS A record, the DNS server will return multiple A records for the service, each pointing to the IP of an individual pod backing the service at that moment. Clients can therefore do a simple DNS A record lookup and get the IPs of all the pods that are part of the service. The client can then use that information to connect to one, many, or all of them.

Setting the clusterIP field in a service spec to None makes the service headless, as Kubernetes won’t assign it a cluster IP through which clients could connect to the pods backing it.
Örnek
Şöyle yaparız
apiVersion: v1
kind: Service
metadata:
  name: grpc-server-service
spec:
  clusterIP: None
  selector:
    app: grpc-server
  ports:
    - port: 80
      targetPort: 8001

23 Şubat 2021 Salı

Kubernetes Autoscaler

Giriş
Kubernetes için 3 tane autoscaler var. Bunlar şöyle
1. Horizontal Pod Autoscaler : Pod sayınını ölçeklendirir
2. Vertical Pod Autoscaler : İşlemci ve belleği ölçeklendirir
3. Cluster Autoscaler : Cluster'a node eklemeyi ölçeklendirir
Cluster Autoscaler
Eğer cluster'da yeni pod için kaynak yoksa, horizontal autocaler zaten işe yaramaz.

Horizontal Pod Autoscaler
Kaç tane POD'un çalışması gerektiğine karar veren bileşenin ismi "Horizontal Pod Autoscaler". CPU ve bellek kullanımına bakarak bir formül çalıştırır. Açıklaması şöyle.
Kubernetes’ Horizontal Pod Autoscaler (HPA) automatically scales the application workload by scaling the number of Pods in deployment (or replication controller, replica set, stateful set), based on observed metrics like CPU utilization, memory consumption, or with custom metrics provided by the application. 

HPA uses the following simple algorithms to determine the scaling decision, and it can scale the deployment within the defined minimum and the maximum number of replicas. 

desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
Örnek - CPU
Şöyle yaparız
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: hello-world
  namespace: default
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: hello-world
  targetCPUUtilizationPercentage: 50

Scale To Zero
Şu anda sıfır POD'a indirmek desteklenmiyor. Açıklaması şöyle.
Kubernetes’ default HPA is based on CPU utilization and desiredReplicas never go lower than 1, where CPU utilization cannot be zero for a running Pod. This is the same behavior for memory consumption-based autoscaling, where you cannot achieve scale to zero. However, it is possible to scale into zero replicas if you ignore CPU and memory utilization and consider other metrics to determine whether the application is idle. For example, a workload that only consumes and processes a queue can scale to zero if we can take queue length as a metric and the queue is empty for a given period of time. Of course, there should be other factors to consider like lower latency sensitivity and fast bootup time (warm-up time) of the workload to have a smooth user experience. 

But, the current Kubernetes current stable release (v1.19) does not support scale to zero, and you can find discussions to support this in the Kubernetes enhancements gitrepo.

8 Şubat 2021 Pazartesi

Kubernetes ClusterIP Service - Servise Sadece Cluster İçindeki Pod/Servisler Erişebilir

Giriş
Diğer Servisler arasındaki fark şöyle. Yani NodePort ve LoadBalancer servisi cluster dışına açar, ancak ClusterIP açmaz.
ClusterIP: Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. This is the default ServiceType

NodePort: Exposes the service on each Node’s IP at a static port (the NodePort). A ClusterIP service, to which the NodePort service will route, is automatically created. You’ll be able to contact the NodePort service, from outside the cluster, by requesting <NodeIP>:<NodePort>.

LoadBalancer: Exposes the service externally using a cloud provider’s load balancer. NodePort and ClusterIP services, to which the external load balancer will route, are automatically created.
servisleri görmek için kubectl get services kullanılır. Sorgularsak çıktı olarak şuna benzer bir şey alırız
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP          58d
mongodb             ClusterIP   10.105.147.168   <none>        27017/TCP        6s
springbootmongodb   NodePort    10.108.143.94    <none>        8080:31636/TCP   16m
kind : Service 
type: ClusterIP
şeklinde kullanılır. type: ClusterIP yazmak zorunlu değildir, çünkü varsayılan servis tipi budur

Örnek - ClusterIP
Şeklen şöyle

Deployment şöyle
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grpc-server
  labels:
    app: grpc-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: grpc-server
  template:
    metadata:
      labels:
        app: grpc-server
    spec:
      containers:
        - name: grpc-server
          image: techdozo/grpc-lb-server:1.0.0
Service şöyle
apiVersion: v1
kind: Service metadata: name: grpc-server-service spec: type: ClusterIP selector: app: grpc-server ports: - port: 80 targetPort: 8001
Bu servise erişmek isteyen bir başka kod şöyle yapar
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grpc-client
  labels:
    app: grpc-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grpc-client
  template:
    metadata:
      labels:
        app: grpc-client
    spec:
      containers:
        - name: grpc-client
          image: techdozo/grpc-lb-client:1.0.0
          env:
            - name: SERVER_HOST
              value: grpc-server-service:80
Açıklaması şöyle
The SERVER_HOST environment variable point to the DNS of the service grpc-server-service.

Örnek - ClusterIP
Deployment için şöyle yaparız. Burada  webcenter/activemq isimli registry'den activemq eğer zaten indirilmemişse, indiriliyor.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: queue
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: queue
    spec:
      containers:
      - name: web
        image: webcenter/activemq:5.14.3
        imagePullPolicy: IfNotPresent
        ports:
          - containerPort: 61616
        resources:
          limits:
            memory: 512Mi
Önüne bir servis için şöyle yaparız
apiVersion: v1
kind: Service
metadata:
  name: queue
spec:
  ports:
  - port: 61616 
    targetPort: 61616
  selector:
    app: queue
Açıklaması şöyle
- you created a load balancer that exposes port 61616
- the incoming traffic is distributed to all Pods (see deployment above) that has a label of type app: queue
- the targetPort is the port exposed by the Pods

Kubernetes Pod File

Örnek
Şöyle yaparız
apiVersion: v1
kind: Pod                                            # 1
metadata:
  name: sa-frontend                                  # 2
spec:                                                # 3
  containers:
    - image: rinormaloku/sentiment-analysis-frontend # 4
      name: sa-frontend                              # 5
      ports:
        - containerPort: 80                          # 6
Açıklaması şöyle
1. Kind: specifies the kind of the Kubernetes Resource that we want to create. In our case, a Pod.
2. Name: defines the name for the resource. We named it sa-frontend.
3. Spec is the object that defines the desired state for the resource. The most important property of a Pods Spec is the Array of containers.
4. Image is the container image we want to start in this pod.
5. Name is the unique name for a container in a pod.
6. Container Port:is the port at which the container is listening. This is just an indicator for the reader (dropping the port doesn’t restrict access).

13 Kasım 2020 Cuma

Kubernetes Deployment File

Giri
Bazı notlarım şöyle

Deployment Nedir?
Açıklaması şöyle. Kaç tane Pod istediğimizi belirtiriz.
Although pods are the basic unit of computation in Kubernetes, they are not typically directly launched on a cluster. Instead, pods are usually managed by one more layer of abstraction: the deployment.
A deployment’s primary purpose is to declare how many replicas of a pod should be running at a time. When a deployment is added to the cluster, it will automatically spin up the requested number of pods, and then monitor them. If a pod dies, the deployment will automatically re-create it.
Pod ve Service Registry
Açıklaması şöyle
“Service” in Kubernetes serves the purpose of service discovery. If I deploy service with the name as name:shoppingcart-service and selector as app:shoppingcart-service-pod , all the pods having this as a label will be considered as a set of available pods for the shoppingcart-service .

The controller for the service selector continuously scans for pods that match its selector app:shoppingcart-service and then post any updates to an endpoint object also named shoppingcart-service. Kubernetes assigns this endpoint an IP address. The service is also associated with a DNS name.

Kubernetes provides in-built health check options, where it keeps a check on the health of all the available pods. If a pod is found unhealthy, it deregisters it from the list of service pods.
Örnek
Şöyle yaparız
apiVersion: extensions/v1beta1
kind: Deployment                                          # 1
metadata:
  name: sa-frontend
spec:
  selector:                                               # 2
    matchLabels:
      app: sa-frontend  
  replicas: 2                                             # 3
  minReadySeconds: 15
  strategy:
    type: RollingUpdate                                   # 4
    rollingUpdate: 
      maxUnavailable: 1                                   # 5
      maxSurge: 1                                         # 6
  template:                                               # 7
    metadata:
      labels:
        app: sa-frontend                                  # 8
    spec:
      containers:
        - image: rinormaloku/sentiment-analysis-frontend
          imagePullPolicy: Always                         # 9
          name: sa-frontend
          ports:
            - containerPort: 80
Açıklaması şöyle
1. Kind: A deployment.
2. Selector: Pods matching the selector will be taken under the management of this deployment.
3. Replicas is a property of the deployments Spec object that defines how many pods we want to run. So only 2.
4. Type specifies the strategy used in this deployment when moving from the current version to the next. The strategy RollingUpdate ensures Zero Downtime deployments.
5. MaxUnavailable is a property of the RollingUpdate object that specifies the maximum unavailable pods allowed (compared to the desired state) when doing a rolling update. For our deployment which has 2 replicas this means that after terminating one Pod, we would still have one pod running, this way keeping our application accessible.
6. MaxSurge is another property of the RollingUpdate object that defines the maximum amount of pods added to a deployment (compared to the desired state). For our deployment, this means that when moving to a new version we can add one pod, which adds up to 3 pods at the same time.
7. Template: specifies the pod template that the Deployment will use to create new pods. Most likely the resemblance with Pods struck you immediately.
8. app: sa-frontend the label to use for the pods created by this template.
9. ImagePullPolicy when set to Always, it will pull the container images on each redeployment.
Deployment Örnekleri
metadata/name Alanı
Kubernetes tarafından kullanılan deployment ismini belirtir
Örnek
Şöyle olsun
apiVersion : apps/v1
kind: Deployment
metadata:
  name: simple-app-deployment
...
Şöyle yaparız
kb get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
simple-app-deployment 2/2 2 2 2m23s
spec/replicas Alanı
ReplicaSet Nedir

Açıklaması şöyle. spec/replicas altında belirtilir
Bir poddan kaç tane olacağını replicaset ile belirtiyoruz. İstediğiniz anda bir pod’u kesintisiz bir şekilde scale edebilir yada azaltabiliriz.
Örnek
Şöyle yaparız
apiVersion: apps/v1
kind: Deployment
metadata:
  name: springbootmongodb
  labels:
    app: springbootmongodb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: springbootmongodb
  template:
    metadata:
      labels:
        app: springbootmongodb
    spec:
      containers:
      - name: springbootmongodb
        image: mytest/springbootmongodb
      - name: mongo
        image: mongo
Pod ile Docker imajını eşleştirmek için 
deployment tanımındaki spec/template/metadata/labels/app ile 
kind:Service tanımındaki spec/selector/app
alanları kullanılır
Örnek
Şöyle yaparız. Deployment alanında kullanılacak container belirtiliyor. imaj ismi marounbassam/hello-spring
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: hello-world
        visualize: "true"
    spec:
      containers:
      - name: hello-world-pod
        image: marounbassam/hello-spring
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  labels:
    visualize: "true"
  name: hello-world-service
spec:
  selector:
    app: hello-world
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
  type: ClusterIP
İki tane pod elde ederiz
+---------------------+
| hello-world-service |
|                     |
|    10.15.242.210    |
+---------O-----------+
          |
          +-------------O--------------------------O
                        |                          |
              +---------O-----------+    +---------O-----------+
              |        pod 1        |    |        pod 2        |
              |                     |    |                     |
              |     hello-world     |    |     hello-world     |
              +---------------------+    +---------------------+
containers
Açıklaması şöyle
describes the container’s specification like the name, the image and the exposed port.
containers/livenessProbe
Açıklaması şöyle
Among its many components, the Kubelet ensures that the containers are running and replaced with a healthy instance, anytime it goes down. This is detected using two properties:

- Liveness Check: An endpoint indicating that the application is available. The Kubelet uses liveness probes to know when to restart a container.
- Readiness Check: The Kubelet uses readiness probes to know when a container is ready to start accepting traffic.
Örnek
Şöyle yaparız
apiVersion: apps/v1 
kind: Deployment
...
        livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 5
        readinessProbe:  
            httpGet:
              path: /actuator/health/readiness
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5
containers/imagePullPolicy Alanı
Açıklaması şöyle.
The default pull policy is IfNotPresent which causes the kubelet to skip pulling an image if it already exists. If you would like to always force a pull, set it to Always
Açıklaması şöyle.
This option comes in handy if you deploy your application too often (Typical use case is CI/CD).
Örnek
Şöyle yaparız. Burada  webcenter/activemq isimli registry'den activemq eğer zaten indirilmemişse, indiriliyor.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: queue
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: queue
    spec:
      containers:
      - name: web
        image: webcenter/activemq:5.14.3
        imagePullPolicy: IfNotPresent
        ports:
          - containerPort: 61616
        resources:
          limits:
            memory: 512Mi
Örnek
Şöylee yaparız
apiVersion: v1
kind: Pod
metadata:
  name: demo
spec:
  containers:
    - name: image-name
      image: my-image:0.0.1
      imagePullPolicy: Always # <<--here
containers/readinessProbe
Örnek
Şöyle yaparız
apiVersion: v1
kind: Namespace
metadata:
  name: demo-ns
---
apiVersion: v1
kind: Pod
metadata:
  name: worker
  namespace: demo-ns
  labels:
    app: nine-to-five
spec:
  containers:
    - name: nine-to-five
      image: nine-to-five:1.0.0
      ports:
        - name: health-check
          containerPort: 5000
          hostPort: 5000
      readinessProbe:
        tcpSocket:
          port: health-check
        initialDelaySeconds: 5
        failureThreshold: 2
        timeoutSeconds: 3
        periodSeconds: 10
      livenessProbe:
        tcpSocket:
          port: health-check
        initialDelaySeconds: 15
        failureThreshold: 2
        timeoutSeconds: 3
        periodSeconds: 20
containers/resources
Şöyle yaparız
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world2-deployment
  labels:
    app: hello-world2
spec:
  selector:
    matchLabels:
      app: hello-world2
  replicas: 2
  template:
    metadata:
      labels:
        app: hello-world2
    spec:
      containers:
      - name: hello-world2
        image: bhargavshah86/kube-test:v0.1
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 256Mi
            cpu: "250m"
          requests:
            memory: 128Mi
            cpu: "80m"