Cluster üzerinde uygulama dağıtımını adımlarını örnekler ile ele alalım, kubectl create deployment komutu ile bir imajın replicasını deployment ederiz. Burada kullanılan hello-world containeri Google Container registry üzerinden alınmaktadır.
kubectl create deployment hello-world --image=gcr.io/google-samples/hello-app:1.0
root@k8s-c1-cp1:~# kubectl create deployment hello-world --image=gcr.io/google-samples/hello-app:1.0 deployment.apps/hello-world created root@k8s-c1-cp1:~#
Bir tane de Cluster tarafından yönetilmeyen “bare” pod deploy edelim,
kubectl run hello-world-pod --image=gcr.io/google-samples/hello-app:1.0
root@k8s-c1-cp1:~# kubectl run hello-world-pod --image=gcr.io/google-samples/hello-app:1.0 pod/hello-world-pod created root@k8s-c1-cp1:~#
Deploymentin tek bir kopya oluşturduğunu görelim ve ayrıca bu bare imajın oluşturulup, oluşturulmadığını da teyit edelim, iki adet pod görmeliyiz.. Cluster tarafından yönetilen pod, uniqe bir tanıma sahiptir. Bare pod ise basit şekilde öylece ismi yazacaktır.
root@k8s-c1-cp1:~# kubectl get pods NAME READY STATUS RESTARTS AGE hello-world-5457b44555-7knkk 1/1 Running 0 2m17s hello-world-pod 1/1 Running 0 68s root@k8s-c1-cp1:~#
root@k8s-c1-cp1:~# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-world-5457b44555-7knkk 1/1 Running 0 3m20s 192.168.131.14 c1-node2 <none> <none> hello-world-pod 1/1 Running 0 2m11s 192.168.206.80 c1-node3 <none> <none> root@k8s-c1-cp1:~#
Kubernetesin container orchestrator olduğunu ve nodlarda containerlar başlatıldığını unutmayalım. Node üzerine ssh ile bağlanıp birde node üzerinden testlerimizi yapalım.
Containerd üzerinde çalışan konteynırların listelesini almak için crictl kullanılır.
https://kubernetes.io/docs/tasks/debug-application-cluster/crictl
sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps
root@c1-node1:~# sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID 4a4b0da73a559 7a71aca7b60fc 10 hours ago Running calico-node 0 6180625bb78e5 e076d3ae0e85d 2025ac44bb2b3 10 hours ago Running kube-proxy 0 1ab276b0f7b87 root@c1-node1:~#
Docker da ise bildiğiniz üzere docker ps kullanılır.
docker ps
Tekrardan Control-plane noduna giriş yapalım,
Uygulamalarımızda bir şeyler ters gitti ve podumuzda başlamıyor. Bu sorunu giderme için loglarımızı incelememiz gerekmektedir. Bu işlem için,
kubectl logs hello-world-pod
Podun içerisinde bir işlem başlatmak için ise exec prosesi çalıştırılmalıdır.
kubectl exec -it hello-world-pod -- /bin/sh
root@k8s-c1-cp1:~# kubectl exec -it hello-world-pod -- /bin/sh / # hostname hello-world-pod / # ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 4: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1480 qdisc noqueue state UP link/ether 52:e5:c4:62:f5:25 brd ff:ff:ff:ff:ff:ff inet 192.168.206.80/32 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::50e5:c4ff:fe62:f525/64 scope link valid_lft forever preferred_lft forever / # exit root@k8s-c1-cp1:~#
İlk kubectl bizim yürüttüğümüz konuşlandırmayı oluşturdu, yaptığımız işlem ile ilk deployment bizim için oluşturuldu. Deploymentlar ReplicaSetlerden oluşturulur.
kubectl describe deployment hello-world | more
root@k8s-c1-cp1:~# kubectl describe deployment hello-world | more Name: hello-world Namespace: default CreationTimestamp: Wed, 16 Mar 2022 18:34:43 +0000 Labels: app=hello-world Annotations: deployment.kubernetes.io/revision: 1 Selector: app=hello-world Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=hello-world Containers: hello-app: Image: gcr.io/google-samples/hello-app:1.0 Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: hello-world-5457b44555 (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set hello-world-5457b44555 to 1 root@k8s-c1-cp1:~#
ReplicaSetler podları oluşturur. Çıktıyı kontrol edelim, Name, Controlled By, Replicas, Pod Template ve Events bilgilerini aşağıdaki komut ile kontrol edebiliriz.
root@k8s-c1-cp1:~# kubectl describe replicaset hello-world | more Name: hello-world-5457b44555 Namespace: default Selector: app=hello-world,pod-template-hash=5457b44555 Labels: app=hello-world pod-template-hash=5457b44555 Annotations: deployment.kubernetes.io/desired-replicas: 1 deployment.kubernetes.io/max-replicas: 2 deployment.kubernetes.io/revision: 1 Controlled By: Deployment/hello-world Replicas: 1 current / 1 desired Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: app=hello-world pod-template-hash=5457b44555 Containers: hello-app: Image: gcr.io/google-samples/hello-app:1.0 Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 24m replicaset-controller Created pod: hello-world-5457b44555-7knkk root@k8s-c1-cp1:~#
Name, Node, Status, Controlled By, IPs, Contaners, ve Event bilgilerini ise aşağıdaki şekilde kontrol ederiz.
root@k8s-c1-cp1:~# kubectl describe pod hello-world-5457b44555-7knkk | more Name: hello-world-5457b44555-7knkk Namespace: default Priority: 0 Node: c1-node2/172.22.17.202 Start Time: Wed, 16 Mar 2022 18:34:43 +0000 Labels: app=hello-world pod-template-hash=5457b44555 Annotations: cni.projectcalico.org/containerID: 333ff93c30077116ff804570ea18a4d53cbe4c9a941994c57bcb8a843a78e29a cni.projectcalico.org/podIP: 192.168.131.14/32 cni.projectcalico.org/podIPs: 192.168.131.14/32 Status: Running IP: 192.168.131.14 IPs: IP: 192.168.131.14 Controlled By: ReplicaSet/hello-world-5457b44555 Containers: hello-app: Container ID: containerd://95b88dabfb92a432df219639d3078508fd25dcb849948589406aab10d8a45713 Image: gcr.io/google-samples/hello-app:1.0 Image ID: gcr.io/google-samples/hello-app@sha256:88b205d7995332e10e836514fbfd59ecaf8976fc15060cd66e85cdcebe7fb356 Port: <none> Host Port: <none> State: Running Started: Wed, 16 Mar 2022 18:34:44 +0000 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-r5p8g (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-r5p8g: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 30m default-scheduler Successfully assigned default/hello-world-5457b44555-7knkk to c1-node2 Normal Pulled 30m kubelet Container image "gcr.io/google-samples/hello-app:1.0" already present on machine Normal Created 30m kubelet Created container hello-app Normal Started 30m kubelet Started container hello-app root@k8s-c1-cp1:~#
Deploymentı, servis olarak gösterelim. Podumuzda 8080 üzerinde çalışan bir uygulamaya bağlanarak hizmetimizi 80 numaralı portumuzdan yayımlayalım.
Port – Internal CLuster port, Servis portudur. Cluster kaynağında bu port bilgisini göstereceğiz.
TargetPort – Podun servis portudur, uygulamamızın.
kubectl expose deployment hello-world \ --port=80 \ --target-port=8080
root@k8s-c1-cp1:~# kubectl expose deployment hello-world \ --port=80 \ --target-port=8080 service/hello-world exposed root@k8s-c1-cp1:~#
Cluster-IP ve Portları kontrol edelim. Bu servise Clusterin içinden erişeceğimiz IP bilgisi yansıyacaktır.
root@k8s-c1-cp1:~# kubectl get service hello-world NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world ClusterIP 10.104.148.127 <none> 80/TCP 16s root@k8s-c1-cp1:~#
Describe ile servisimiz hakkında detaylı bilgi alamızı sağlayalım. Endpoints IP:Port ile eşleşen her pod bilgisini gösterir. Şuan tek bir tane gösterilmektedir çünkü replika sayısı bir olarak tanımlıdır. Artırma işlemini gerçekleştirip kontrol ettiğimizde daha fazla Endpoint eklenecektir.
root@k8s-c1-cp1:~# kubectl describe service hello-world Name: hello-world Namespace: default Labels: app=hello-world Annotations: <none> Selector: app=hello-world Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.104.148.127 IPs: 10.104.148.127 Port: <unset> 80/TCP TargetPort: 8080/TCP Endpoints: 192.168.131.14:8080 Session Affinity: None Events: <none> root@k8s-c1-cp1:~#
Cluster içinde bulunan servise erişelim,
curl http://$SERVCIEIP:$PORT
root@k8s-c1-cp1:~# curl http://192.168.131.14:8080 Hello, world! Version: 1.0.0 Hostname: hello-world-5457b44555-7knkk root@k8s-c1-cp1:~#
Sorun giderme için yararlı olan bir poda doğrudan erişelim,
kubectl get endpoints hello-world curl http://$ENDPOINT:$TARGETORT
Deploymentlarımız için yaml veya json çıktısı oluşturmak için kubectl kullanımı, Bu işlem runtime bilgilerini ve yapılandırma yönetimi için faydalı olabilecek bilgileri içerir,
root@k8s-c1-cp1:~# kubectl get deployment hello-world -o yaml | more apiVersion: apps/v1 kind: Deployment metadata: annotations: deployment.kubernetes.io/revision: "1" creationTimestamp: "2022-03-16T18:34:43Z" generation: 1 labels: app: hello-world name: hello-world namespace: default resourceVersion: "56133" uid: d57c4b44-2194-41b9-9034-6f330605f0a9 spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: hello-world strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: hello-world spec: containers: - image: gcr.io/google-samples/hello-app:1.0 imagePullPolicy: IfNotPresent name: hello-app resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 status: availableReplicas: 1 conditions: - lastTransitionTime: "2022-03-16T18:34:44Z" lastUpdateTime: "2022-03-16T18:34:44Z" message: Deployment has minimum availability. reason: MinimumReplicasAvailable status: "True" type: Available - lastTransitionTime: "2022-03-16T18:34:43Z" lastUpdateTime: "2022-03-16T18:34:44Z" message: ReplicaSet "hello-world-5457b44555" has successfully progressed. reason: NewReplicaSetAvailable status: "True" type: Progressing observedGeneration: 1 readyReplicas: 1 replicas: 1 updatedReplicas: 1 root@k8s-c1-cp1:~#
root@k8s-c1-cp1:~# kubectl get deployment hello-world -o json | more { "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "annotations": { "deployment.kubernetes.io/revision": "1" }, "creationTimestamp": "2022-03-16T18:34:43Z", "generation": 1, "labels": { "app": "hello-world" }, "name": "hello-world", "namespace": "default", "resourceVersion": "56133", "uid": "d57c4b44-2194-41b9-9034-6f330605f0a9" }, "spec": { "progressDeadlineSeconds": 600, "replicas": 1, "revisionHistoryLimit": 10, "selector": { "matchLabels": { "app": "hello-world" } }, "strategy": { "rollingUpdate": { "maxSurge": "25%", "maxUnavailable": "25%" }, "type": "RollingUpdate" }, "template": { "metadata": { "creationTimestamp": null, "labels": { "app": "hello-world" } }, "spec": { "containers": [ { "image": "gcr.io/google-samples/hello-app:1.0", "imagePullPolicy": "IfNotPresent", "name": "hello-app", "resources": {}, "terminationMessagePath": "/dev/termination-log", "terminationMessagePolicy": "File" } ], "dnsPolicy": "ClusterFirst", "restartPolicy": "Always", "schedulerName": "default-scheduler", "securityContext": {}, "terminationGracePeriodSeconds": 30 } } }, "status": { "availableReplicas": 1, "conditions": [ { "lastTransitionTime": "2022-03-16T18:34:44Z", "lastUpdateTime": "2022-03-16T18:34:44Z", "message": "Deployment has minimum availability.", "reason": "MinimumReplicasAvailable", "status": "True", "type": "Available" }, { "lastTransitionTime": "2022-03-16T18:34:43Z", "lastUpdateTime": "2022-03-16T18:34:44Z", "message": "ReplicaSet \"hello-world-5457b44555\" has successfully progressed.", "reason": "NewReplicaSetAvailable", "status": "True", "type": "Progressing" } ], "observedGeneration": 1, "readyReplicas": 1, "replicas": 1, "updatedReplicas": 1 } } root@k8s-c1-cp1:~#
Deployment, replicaset ve podlarımızı silelim, Cluster tarafından yönetilmeyen bare türü podumuzu manuel silmemiz gerekmektedir,
kubectl get all kubectl delete service hello-world kubectl delete deployment hello-world kubectl delete pod hello-world-pod kubectl get all
root@k8s-c1-cp1:~# kubectl get all NAME READY STATUS RESTARTS AGE pod/hello-world-5457b44555-7knkk 1/1 Running 0 43m pod/hello-world-pod 1/1 Running 0 42m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/hello-world ClusterIP 10.104.148.127 <none> 80/TCP 9m16s service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/hello-world 1/1 1 1 43m NAME DESIRED CURRENT READY AGE replicaset.apps/hello-world-5457b44555 1 1 1 43m root@k8s-c1-cp1:~# kubectl delete service hello-world service "hello-world" deleted root@k8s-c1-cp1:~# kubectl delete deployment hello-world deployment.apps "hello-world" deleted root@k8s-c1-cp1:~# kubectl delete pod hello-world-pod pod "hello-world-pod" deleted root@k8s-c1-cp1:~# kubectl get all NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10h root@k8s-c1-cp1:~#
Devamını bir sonraki yazımızda devam edelim,