溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

kubernetes系列教程(三)kubernetes快速入

發(fā)布時間:2020-03-01 11:44:15 來源:網(wǎng)絡 閱讀:318 作者:liuhaiping123 欄目:云計算

寫在前面

kubernetes中涉及很多概念,包含云生態(tài)社區(qū)中各類技術(shù),學習成本比較高,k8s中通常以編寫yaml文件完成資源的部署,對于較多入門的人來說是個較高的門坎,本文以命令行的形式代理大家快速入門,俯瞰kubernetes核心概念,快速入門。

1. 基礎(chǔ)概念

1.1 集群與節(jié)點

kubernetes是一個開源的容器引擎管理平臺,實現(xiàn)容器化應用的自動化部署,任務調(diào)度,彈性伸縮,負載均衡等功能,cluster是由master和node兩種角色組成,其中master負責管理集群,master節(jié)點由kube-apiserver,kube-controller-manager,kube-scheduler,etcd角色組成,node節(jié)點運行實際的應用,由Container Runtime,kubelet和kube-proxy組成,其中Container Runtime可能是Docker,rke,containerd,node節(jié)點可由物理機或者虛擬機組成。

kubernetes系列教程(三)kubernetes快速入

1、查看master組件角色

[root@node-1 ~]# kubectl get componentstatuses 
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   

2、 查看node節(jié)點列表

[root@node-1 ~]# kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
node-1   Ready    master   26h   v1.14.1
node-2   Ready    <none>   26h   v1.14.1
node-3   Ready    <none>   26h   v1.14.1

3、查看node節(jié)點詳情

[root@node-1 ~]# kubectl describe node node-3
Name:               node-3
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64。#標簽和Annotations
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=node-3
                    kubernetes.io/os=linux
Annotations:        flannel.alpha.coreos.com/backend-data: {"VtepMAC":"22:f8:75:bb:da:4e"}
                    flannel.alpha.coreos.com/backend-type: vxlan
                    flannel.alpha.coreos.com/kube-subnet-manager: true
                    flannel.alpha.coreos.com/public-ip: 10.254.100.103
                    kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Sat, 10 Aug 2019 17:50:00 +0800
Taints:             <none>
Unschedulable:      false。#是否禁用調(diào)度,cordon命令控制的標識位。
Conditions:     #資源調(diào)度能力,MemoryPressure內(nèi)存是否有壓力(即內(nèi)存不足)
                #DiskPressure磁盤壓力
                #PIDPressure磁盤壓力
                #Ready,是否就緒,表明節(jié)點是否處于正常工作狀態(tài),表示資源充足+相關(guān)進程狀態(tài)正常
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  MemoryPressure   False   Sun, 11 Aug 2019 20:32:07 +0800   Sat, 10 Aug 2019 17:50:00 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Sun, 11 Aug 2019 20:32:07 +0800   Sat, 10 Aug 2019 17:50:00 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Sun, 11 Aug 2019 20:32:07 +0800   Sat, 10 Aug 2019 17:50:00 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Sun, 11 Aug 2019 20:32:07 +0800   Sat, 10 Aug 2019 18:04:20 +0800   KubeletReady                 kubelet is posting ready status
Addresses:     #地址和主機名
  InternalIP:  10.254.100.103
  Hostname:    node-3
Capacity:      #容器的資源容量
 cpu:                2
 ephemeral-storage:  51473868Ki
 hugepages-2Mi:      0
 memory:             3880524Ki
 pods:               110
Allocatable:    #已分配資源情況
 cpu:                2
 ephemeral-storage:  47438316671
 hugepages-2Mi:      0
 memory:             3778124Ki
 pods:               110
System Info:     #系統(tǒng)信息,如內(nèi)核版本,操作系統(tǒng)版本,cpu架構(gòu),node節(jié)點軟件版本
 Machine ID:                 0ea734564f9a4e2881b866b82d679dfc
 System UUID:                D98ECAB1-2D9E-41CC-9A5E-51A44DC5BB97
 Boot ID:                    6ec81f5b-cb05-4322-b47a-a8e046d9bf79
 Kernel Version:             3.10.0-957.el7.x86_64
 OS Image:                   CentOS Linux 7 (Core)
 Operating System:           linux
 Architecture:               amd64
 Container Runtime Version:  docker://18.3.1 .     #Container Runtime為docker,版本為18.3.1
 Kubelet Version:            v1.14.1               #kubelet版本
 Kube-Proxy Version:         v1.14.1               #kube-proxy版本
PodCIDR:                     10.244.2.0/24         #pod使用的網(wǎng)絡
Non-terminated Pods:         (4 in total)。        #下面是每個pod資源占用情況
  Namespace                  Name                           CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                  ----                           ------------  ----------  ---------------  -------------  ---
  kube-system                coredns-fb8b8dccf-hrqm8        100m (5%)     0 (0%)      70Mi (1%)        170Mi (4%)     26h
  kube-system                coredns-fb8b8dccf-qwwks        100m (5%)     0 (0%)      70Mi (1%)        170Mi (4%)     26h
  kube-system                kube-flannel-ds-amd64-zzm2g    100m (5%)     100m (5%)   50Mi (1%)        50Mi (1%)      26h
  kube-system                kube-proxy-x8zqh               0 (0%)        0 (0%)      0 (0%)           0 (0%)         26h
Allocated resources:   #已分配資源情況
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                300m (15%)  100m (5%)
  memory             190Mi (5%)  390Mi (10%)
  ephemeral-storage  0 (0%)      0 (0%)
Events:              <none>

1.2 容器與應用

kubernetes是容器編排引擎,其負責容器的調(diào)度,管理和容器的運行,但kubernetes調(diào)度最小單位并非是container,而是pod,pod中可包含多個container,通常集群中不會直接運行pod,而是通過各種控制器如Deployments,ReplicaSets,DaemonSets的方式運行,為啥?因為控制器能夠保證pod狀態(tài)的一致性,正如官方所描述的一樣“make sure the current state match to the desire state”,確保當前狀態(tài)和預期的一致,簡單來說就是pod異常了,控制器會在其他節(jié)點重建,確保集群當前運行的pod和預期設(shè)定的一致。

kubernetes系列教程(三)kubernetes快速入

  • Container,容器是一種輕量化的虛擬化技術(shù),通過將應用封裝在鏡像中,實現(xiàn)便捷部署,應用分發(fā)。
  • Pod,kubernetes中最小的調(diào)度單位,封裝容器,包含一個pause容器和應用容器,容器之間共享相同的命名空間,網(wǎng)絡,存儲,共享進程。
  • Deployments,部署組也稱應用,嚴格上來說是無狀態(tài)化應用,另外一種由狀態(tài)化應用是StatefulSets,Deployments是一種控制器,可以控制應用的副本數(shù)replicas,通過kube-controller-manager中的Deployments Controller實現(xiàn)副本數(shù)狀態(tài)的控制。

1.3 服務訪問

kubernetes中pod是實際運行的載體,pod依附于node中,node可能會出現(xiàn)故障,kubernetes的控制器如replicasets會在其他node上重新拉起一個pod,新的pod會分配一個新的IP;再者,應用部署時會包含多個副本replicas,如同個應用deployments部署了3個pod副本,pod相當于后端的Real Server,如何實現(xiàn)這三個應用訪問呢?對于這種情況,我們一般會在Real Server前面加一個負載均衡Load Balancer,service就是pod的負載均衡調(diào)度器,service將動態(tài)的pod抽象為一個服務,應用程序直接訪問service即可,service會自動將請求轉(zhuǎn)發(fā)到后端的pod。負責service轉(zhuǎn)發(fā)規(guī)則有兩種機制:iptables和ipvs,iptables通過設(shè)置DNAT等規(guī)則實現(xiàn)負載均衡,ipvs通過ipvsadm設(shè)置轉(zhuǎn)發(fā)規(guī)。

kubernetes系列教程(三)kubernetes快速入

根據(jù)服務不同的訪問方式,service分為如下幾種類型:ClusterIP,NodePort,LoadBalancer和_ExternalName,可通過type設(shè)置。

  • ClusterIP,集群內(nèi)部互訪,與DNS結(jié)合實現(xiàn)集群內(nèi)部的服務發(fā)現(xiàn);
  • NodePort,通過NAT將每個node節(jié)點暴露一個端口實現(xiàn)外部訪問;
  • LoadBalancer,實現(xiàn)云廠商外部接入方式的接口,需要依賴云服務提供商實現(xiàn)具體技術(shù)細節(jié),如騰訊云實現(xiàn)與CLB集成;
  • ExternalName,通過服務名字暴露服務名,當前可由ingress實現(xiàn),將外部的請求以域名轉(zhuǎn)發(fā)的形式轉(zhuǎn)發(fā)到集群,需要依附具體的外部實現(xiàn),如nginx,traefik,各大云計算廠商實現(xiàn)接入細節(jié)。

    pod是動態(tài)變化的,ip地址可能會變化(如node故障),副本數(shù)可能會變化,如應用擴展scale up,應用鎖容scale down等,service如何識別到pod的動態(tài)變化呢?答案是labels,通過labels自動會過濾出某個應用的Endpoints,當pod變化時會自動更新Endpoints,不同的應用會有由不同的label組成。labels相關(guān)可以參考下https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/

kubernetes系列教程(三)kubernetes快速入

2. 創(chuàng)建應用

我們開始部署一個應用即deployments,kubernetes中包含各種workload如無狀態(tài)話的Deployments,有狀態(tài)化的StatefulSets,守護進程的DaemonSets,美中workload對應不同的應用場景,我們先以Deployments為例入門,其他workload均以此類似,一般而言,在kubernetes中部署應用均以yaml文件方式部署,對于初學者而言,編寫yaml文件太冗長,不適合初學,我們先kubectl命令行方式實現(xiàn)API的接入。

1、部署nginx應用,部署三個副本

[root@node-1 ~]# kubectl run nginx-app-demo --image=nginx:1.7.9 --port=80 --replicas=3 
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx-app-demo created

2、查看應用列表,可以看到當前pod的狀態(tài)均已正常,Ready是當前狀態(tài),AVAILABLE是目標狀態(tài)

[root@node-1 ~]# kubectl get deployments
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
nginx-app-demo   3/3     3            3           72s

3、查看應用的詳細信息,如下我們可以知道Deployments是通過ReplicaSets控制副本數(shù)的,由Replicaset控制pod數(shù)

[root@node-1 ~]# kubectl describe deployments nginx-app-demo 
Name:                   nginx-app-demo     #應用名稱
Namespace:              default            #命名空間
CreationTimestamp:      Sun, 11 Aug 2019 21:52:32 +0800
Labels:                 run=nginx-app-demo #labels,很重要,后續(xù)service通過labels實現(xiàn)訪問
Annotations:            deployment.kubernetes.io/revision: 1 #滾動升級版本號
Selector:               run=nginx-app-demo #labels的選擇器selector
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable #副本控制器
StrategyType:           RollingUpdate     #升級策略為RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge #RollingUpdate升級策略,即最大不超過25%的pod
Pod Template:   #容器應用模版,包含鏡像,port,存儲等
  Labels:  run=nginx-app-demo
  Containers:
   nginx-app-demo:
    Image:        nginx:1.7.9
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:  #當前狀態(tài)
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-app-demo-7bdfd97dcd (3/3 replicas created) #ReplicaSets控制器名稱
Events:  #運行事件
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  3m24s  deployment-controller  Scaled up replica set nginx-app-demo-7bdfd97dcd to 3

4、查看replicasets情況,通過查看可知replicasets副本控制器生成了三個pod

1. 查看replicasets列表
  [root@node-1 ~]# kubectl get replicasets
NAME                        DESIRED   CURRENT   READY   AGE
nginx-app-demo-7bdfd97dcd   3         3         3       9m9s

2. 查看replicasets詳情
[root@node-1 ~]# kubectl describe replicasets nginx-app-demo-7bdfd97dcd 
Name:           nginx-app-demo-7bdfd97dcd
Namespace:      default
Selector:       pod-template-hash=7bdfd97dcd,run=nginx-app-demo
Labels:         pod-template-hash=7bdfd97dcd #labels,增加了一個hash的label識別replicasets
                run=nginx-app-demo
Annotations:    deployment.kubernetes.io/desired-replicas: 3 #滾動升級的信息,副本樹,最大數(shù),應用版本
                deployment.kubernetes.io/max-replicas: 4
                deployment.kubernetes.io/revision: 1
Controlled By:  Deployment/nginx-app-demo #副本的父控制,為nginx-app-demo這個Deployments
Replicas:       3 current / 3 desired
Pods Status:    3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:  #容器模板,繼承于deployments
  Labels:  pod-template-hash=7bdfd97dcd
           run=nginx-app-demo
  Containers:
   nginx-app-demo:
    Image:        nginx:1.7.9
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events: #事件日志,生成了三個不同的pod
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  9m25s  replicaset-controller  Created pod: nginx-app-demo-7bdfd97dcd-hsrft
  Normal  SuccessfulCreate  9m25s  replicaset-controller  Created pod: nginx-app-demo-7bdfd97dcd-qtbzd
  Normal  SuccessfulCreate  9m25s  replicaset-controller  Created pod: nginx-app-demo-7bdfd97dcd-7t72x

5、查看pod的情況,實際應用部署的載體,pod中部署了一個nginx的容器并分配了一個ip,可通過該ip直接訪問應用

1. 查看pod的列表,和replicasets生成的名稱一致
[root@node-1 ~]# kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
nginx-app-demo-7bdfd97dcd-7t72x   1/1     Running   0          13m
nginx-app-demo-7bdfd97dcd-hsrft   1/1     Running   0          13m
nginx-app-demo-7bdfd97dcd-qtbzd   1/1     Running   0          13m

查看pod的詳情
[root@node-1 ~]# kubectl describe pods nginx-app-demo-7bdfd97dcd-7t72x 
Name:               nginx-app-demo-7bdfd97dcd-7t72x
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               node-3/10.254.100.103
Start Time:         Sun, 11 Aug 2019 21:52:32 +0800
Labels:             pod-template-hash=7bdfd97dcd  #labels名稱
                    run=nginx-app-demo
Annotations:        <none>
Status:             Running
IP:                 10.244.2.4 #pod的ip地址
Controlled By:      ReplicaSet/nginx-app-demo-7bdfd97dcd #副本控制器為replicasets
Containers:   #容器的信息,包括容器id,鏡像,丟按扣,狀態(tài),環(huán)境變量等信息
  nginx-app-demo:
    Container ID:   docker://5a0e5560583c5929e9768487cef43b045af4c6d3b7b927d9daf181cb28867766
    Image:          nginx:1.7.9
    Image ID:       docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sun, 11 Aug 2019 21:52:40 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-txhkc (ro)
Conditions: #容器的狀態(tài)條件
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:    #容器卷
  default-token-txhkc:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-txhkc
    Optional:    false
QoS Class:       BestEffort #QOS類型
Node-Selectors:  <none> #污點類型
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:  #事件狀態(tài),拉鏡像,啟動容器
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  14m   default-scheduler  Successfully assigned default/nginx-app-demo-7bdfd97dcd-7t72x to node-3
  Normal  Pulling    14m   kubelet, node-3    Pulling image "nginx:1.7.9"
  Normal  Pulled     14m   kubelet, node-3    Successfully pulled image "nginx:1.7.9"
  Normal  Created    14m   kubelet, node-3    Created container nginx-app-demo
  Normal  Started    14m   kubelet, node-3    Started container nginx-app-demo

3. 訪問應用

kubernetes為每個pod都分配了一個ip地址,可通過該地址直接訪問應用,相當于訪問RS,但一個應用是一個整體,由多個副本數(shù)組成,需要依賴于service來實現(xiàn)應用的負載均衡,service我們探討ClusterIP和NodePort的訪問方式。

3.1 訪問Pod IP

1、設(shè)置pod的內(nèi)容,為了方便區(qū)分,我們將三個pod的nginx站點內(nèi)容設(shè)置為不同,以觀察負載均衡的效果

查看pod列表
[root@node-1 ~]# kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
nginx-app-demo-7bdfd97dcd-7t72x   1/1     Running   0          28m
nginx-app-demo-7bdfd97dcd-hsrft   1/1     Running   0          28m
nginx-app-demo-7bdfd97dcd-qtbzd   1/1     Running   0          28m

進入pod容器中
[root@node-1 ~]# kubectl exec -it nginx-app-demo-7bdfd97dcd-7t72x /bin/bash

設(shè)置站點內(nèi)容
[root@nginx-app-demo-7bdfd97dcd-7t72x:/# echo "web1" >/usr/share/nginx/html/index.html

以此類推設(shè)置另外兩個pod的內(nèi)容為web2和web3
[root@nginx-app-demo-7bdfd97dcd-hsrft:/# echo web2 >/usr/share/nginx/html/index.html
[root@nginx-app-demo-7bdfd97dcd-qtbzd:/# echo web3 >/usr/share/nginx/html/index.html

2、獲取pod的ip地址,如何快速獲取pod的ip地址呢,可以通過-o wide參數(shù)顯示更多的內(nèi)容,會包含pod所屬node和ip

[root@node-1 ~]# kubectl get pods -o wide 
NAME                              READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
nginx-app-demo-7bdfd97dcd-7t72x   1/1     Running   0          34m   10.244.2.4   node-3   <none>           <none>
nginx-app-demo-7bdfd97dcd-hsrft   1/1     Running   0          34m   10.244.1.2   node-2   <none>           <none>
nginx-app-demo-7bdfd97dcd-qtbzd   1/1     Running   0          34m   10.244.1.3   node-2   <none>           <none>

3、訪問pod的ip,查看站點內(nèi)容,不同的pod站點內(nèi)容和上述步驟設(shè)置一致。

[root@node-1 ~]# curl http://10.244.2.4
web1
[root@node-1 ~]# curl http://10.244.1.2
web2
[root@node-1 ~]# curl http://10.244.1.3
web3

3.2 ClusterIP訪問

通過pod的ip直接訪問應用,對于單個pod的應用可以實現(xiàn),對于多個副本replicas的應用則不符合要求,需要通過service來實現(xiàn)負載均衡,service需要設(shè)置不同的type,默認為ClusterIP即集群內(nèi)部訪問,如下通過expose子命令將服務暴露到service。

1、暴露service,其中port表示代理監(jiān)聽端口,target-port代表是容器的端口,type設(shè)置的是service的類型

[root@node-1 ~]# kubectl expose deployment nginx-app-demo --name nginx-service-demo \
--port=80 \
--protocol=TCP \
--target-port=80 \
--type ClusterIP 
service/nginx-service-demo exposed

2、查看service的詳情,可以看到service通過labels選擇器selector自動將pod的ip生成endpoints

查看service列表,顯示有兩個,kubernetes為默認集群創(chuàng)建的service
[root@node-1 ~]# kubectl get services
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes           ClusterIP   10.96.0.1    <none>        443/TCP   29h
nginx-service-demo   ClusterIP   10.102.1.1   <none>        80/TCP    2m54s

查看service詳情,可以看到Labels的Seletor和前面Deployments設(shè)置一致,Endpoints將pod組成一個列表
[root@node-1 ~]# kubectl describe services nginx-service-demo 
Name:              nginx-service-demo   #名稱
Namespace:         default              #命名空間
Labels:            run=nginx-app-demo   #標簽名稱
Annotations:       <none>
Selector:          run=nginx-app-demo   #標簽選擇器
Type:              ClusterIP            #service類型為ClusterIP
IP:                10.102.1.1           #服務的ip,即vip,集群內(nèi)部會自動分配一個
Port:              <unset>  80/TCP      #服務端口,即ClusterIP對外訪問的端口
TargetPort:        80/TCP               #容器端口
Endpoints:         10.244.1.2:80,10.244.1.3:80,10.244.2.4:80 #訪問地址列表
Session Affinity:  None                 #負載均衡調(diào)度算法
Events:            <none>

3、訪問service的地址,可以訪問的內(nèi)容可知,service自動實現(xiàn)了pods的負載均衡,調(diào)度策略為輪詢,為何?因為service默認的調(diào)度策略Session Affinity為None,即是輪訓,可以設(shè)置為ClientIP,實現(xiàn)會話保持,相同客戶端IP的請求會調(diào)度到相同的pod上。

[root@node-1 ~]# curl http://10.102.1.1
web3
[root@node-1 ~]# curl http://10.102.1.1
web1
[root@node-1 ~]# curl http://10.102.1.1
web2
[root@node-1 ~]# curl http://10.102.1.1

4、ClusterIP原理深入剖析,service后端實現(xiàn)有兩種機制:iptables和ipvs,環(huán)境安裝采用iptables,iptables通過nat的鏈生成訪問規(guī)則,KUBE-SVC-R5Y5DZHD7Q6DDTFZ為入站DNAT轉(zhuǎn)發(fā)規(guī)則,KUBE-MARK-MASQ為出站轉(zhuǎn)發(fā)

[root@node-1 ~]# iptables -t nat -L -n
Chain KUBE-SERVICES (2 references)
target     prot opt source               destination         
KUBE-MARK-MASQ  tcp  -- !10.244.0.0/16        10.102.1.1           /* default/nginx-service-demo: cluster IP */ tcp dpt:80
KUBE-SVC-R5Y5DZHD7Q6DDTFZ  tcp  --  0.0.0.0/0            10.102.1.1           /* default/nginx-service-demo: cluster IP */ tcp dpt:80

出站:KUBE-MARK-MASQ源地址段不是10.244.0.0/16訪問10.102.1.1的目標端口80時,將請求轉(zhuǎn)發(fā)給KUBE-MARK-MASQ鏈
入站:KUBE-SVC-R5Y5DZHD7Q6DDTFZ任意原地址訪問目標10.102.1.1的目標端口80時將請求轉(zhuǎn)發(fā)給KUBE-SVC-R5Y5DZHD7Q6DDTFZ鏈

5、查看入站請求規(guī)則,入站請求規(guī)則將會映射到不同的鏈,不同鏈將會轉(zhuǎn)發(fā)到不同pod的ip上。

1. 查看入站規(guī)則KUBE-SVC-R5Y5DZHD7Q6DDTFZ,請求將轉(zhuǎn)發(fā)至三條鏈
[root@node-1 ~]# iptables -t nat -L KUBE-SVC-R5Y5DZHD7Q6DDTFZ -n
Chain KUBE-SVC-R5Y5DZHD7Q6DDTFZ (1 references)
target     prot opt source               destination         
KUBE-SEP-DSWLUQNR4UPH24AX  all  --  0.0.0.0/0            0.0.0.0/0            statistic mode random probability 0.33332999982
KUBE-SEP-56SLMGHHOILJT36K  all  --  0.0.0.0/0            0.0.0.0/0            statistic mode random probability 0.50000000000
KUBE-SEP-K6G4Z74HQYF6X7SI  all  --  0.0.0.0/0            0.0.0.0/0 

2. 查看實際轉(zhuǎn)發(fā)的三條鏈的規(guī)則,實際映射到不同的pod的ip地址上
[root@node-1 ~]# iptables -t nat -L KUBE-SEP-DSWLUQNR4UPH24AX  -n
Chain KUBE-SEP-DSWLUQNR4UPH24AX (1 references)
target     prot opt source               destination         
KUBE-MARK-MASQ  all  --  10.244.1.2           0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp to:10.244.1.2:80

[root@node-1 ~]# iptables -t nat -L KUBE-SEP-56SLMGHHOILJT36K  -n
Chain KUBE-SEP-56SLMGHHOILJT36K (1 references)
target     prot opt source               destination         
KUBE-MARK-MASQ  all  --  10.244.1.3           0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp to:10.244.1.3:80

[root@node-1 ~]# iptables -t nat -L KUBE-SEP-K6G4Z74HQYF6X7SI   -n
Chain KUBE-SEP-K6G4Z74HQYF6X7SI (1 references)
target     prot opt source               destination         
KUBE-MARK-MASQ  all  --  10.244.2.4           0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp to:10.244.2.4:80     

3.3 NodePort訪問

Service通過ClusterIP只能提供集群內(nèi)部的應用訪問,外部無法直接訪問應用,如果需要外部訪問有如下幾種方式:NodePort,LoadBalancer和Ingress,其中LoadBalancer需要由云服務提供商實現(xiàn),Ingress需要安裝單獨的Ingress Controller,日常測試可以通過NodePort的方式實現(xiàn),NodePort可以將node的某個端口暴露給外部網(wǎng)絡訪問。

1、修改type的類型由ClusterIP修改為NodePort類型(或者重新創(chuàng)建,指定type的類型為NodePort)

1. 通過patch修改type的類型
[root@node-1 ~]# kubectl patch services nginx-service-demo -p '{"spec":{"type": "NodePort"}}'
service/nginx-service-demo patched

2. 確認yaml文件配置,分配了一個NodePort端口,即每個node上都會監(jiān)聽該端口
[root@node-1 ~]# kubectl get services nginx-service-demo -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2019-08-11T14:35:59Z"
  labels:
    run: nginx-app-demo
  name: nginx-service-demo
  namespace: default
  resourceVersion: "157676"
  selfLink: /api/v1/namespaces/default/services/nginx-service-demo
  uid: 55e29b78-bc45-11e9-b073-525400490421
spec:
  clusterIP: 10.102.1.1
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 32416 #自動分配了一個NodePort端口
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx-app-demo
  sessionAffinity: None
  type: NodePort #類型修改為NodePort
status:
  loadBalancer: {}

3. 查看service列表,可以知道service的type已經(jīng)修改為NodePort,同時還保留ClusterIP的訪問IP
[root@node-1 ~]# kubectl get services
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes           ClusterIP   10.96.0.1    <none>        443/TCP        30h
nginx-service-demo   NodePort    10.102.1.1   <none>        80:32416/TCP   68m

2、通過NodePort訪問應用程序,每個node的地址相當于vip,可以實現(xiàn)相同的負載均衡效果,同時CluserIP功能依可用

1. NodePort的負載均衡
[root@node-1 ~]# curl http://node-1:32416
web1
[root@node-1 ~]# curl http://node-2:32416
web1
[root@node-1 ~]# curl http://node-3:32416
web1
[root@node-1 ~]# curl http://node-3:32416
web3
[root@node-1 ~]# curl http://node-3:32416
web2

2. ClusterIP的負載均衡
[root@node-1 ~]# curl http://10.102.1.1
web2
[root@node-1 ~]# curl http://10.102.1.1
web1
[root@node-1 ~]# curl http://10.102.1.1
web1
[root@node-1 ~]# curl http://10.102.1.1
web3

3、NodePort轉(zhuǎn)發(fā)原理,每個node上通過kube-proxy監(jiān)聽NodePort的端口,由后端的iptables實現(xiàn)端口的轉(zhuǎn)發(fā)

1. NodePort監(jiān)聽端口
[root@node-1 ~]# netstat -antupl |grep 32416
tcp6       0      0 :::32416                :::*                    LISTEN      32052/kube-proxy 

2. 查看nat表的轉(zhuǎn)發(fā)規(guī)則,有兩條規(guī)則KUBE-MARK-MASQ出口和KUBE-SVC-R5Y5DZHD7Q6DDTFZ入站方向。
Chain KUBE-NODEPORTS (1 references)
target     prot opt source               destination         
KUBE-MARK-MASQ  tcp  --  0.0.0.0/0            0.0.0.0/0            /* default/nginx-service-demo: */ tcp dpt:32416
KUBE-SVC-R5Y5DZHD7Q6DDTFZ  tcp  --  0.0.0.0/0            0.0.0.0/0            /* default/nginx-service-demo: */ tcp dpt:32416

3. 查看入站的請求規(guī)則鏈KUBE-SVC-R5Y5DZHD7Q6DDTFZ 
[root@node-1 ~]# iptables -t nat -L KUBE-SVC-R5Y5DZHD7Q6DDTFZ  -n
Chain KUBE-SVC-R5Y5DZHD7Q6DDTFZ (2 references)
target     prot opt source               destination         
KUBE-SEP-DSWLUQNR4UPH24AX  all  --  0.0.0.0/0            0.0.0.0/0            statistic mode random probability 0.33332999982
KUBE-SEP-56SLMGHHOILJT36K  all  --  0.0.0.0/0            0.0.0.0/0            statistic mode random probability 0.50000000000
KUBE-SEP-K6G4Z74HQYF6X7SI  all  --  0.0.0.0/0            0.0.0.0/0          

4. 繼續(xù)查看轉(zhuǎn)發(fā)鏈,包含有DNAT轉(zhuǎn)發(fā)和KUBE-MARK-MASQ和出站返回的規(guī)則
[root@node-1 ~]# iptables -t nat -L KUBE-SEP-DSWLUQNR4UPH24AX  -n
Chain KUBE-SEP-DSWLUQNR4UPH24AX (1 references)
target     prot opt source               destination         
KUBE-MARK-MASQ  all  --  10.244.1.2           0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp to:10.244.1.2:80

[root@node-1 ~]# iptables -t nat -L KUBE-SEP-56SLMGHHOILJT36K  -n
Chain KUBE-SEP-56SLMGHHOILJT36K (1 references)
target     prot opt source               destination         
KUBE-MARK-MASQ  all  --  10.244.1.3           0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp to:10.244.1.3:80

[root@node-1 ~]# iptables -t nat -L KUBE-SEP-K6G4Z74HQYF6X7SI   -n
Chain KUBE-SEP-K6G4Z74HQYF6X7SI (1 references)
target     prot opt source               destination         
KUBE-MARK-MASQ  all  --  10.244.2.4           0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp to:10.244.2.4:80

4. 擴展應用

當應用程序的負載比較高無法滿足應用請求時,一般我們會通過擴展RS的數(shù)量來實現(xiàn),在kubernetes中,擴展RS實際上通過擴展副本數(shù)replicas來實現(xiàn),擴展RS非常便利,快速實現(xiàn)彈性伸縮。kubernets能提供兩種方式的伸縮能力:1. 手動伸縮能力scale up和scale down,2. 動態(tài)的彈性伸縮horizontalpodautoscalers,基于CPU的利用率實現(xiàn)自動的彈性伸縮,需要依賴與監(jiān)控組件如metrics server,當前未實現(xiàn),后續(xù)再做深入探討,本文以手動的scale的方式擴展應用的副本數(shù)。

1、手動擴展副本數(shù)

[root@node-1 ~]# kubectl scale  --replicas=4 deployment nginx-app-demo 
deployment.extensions/nginx-app-demo scaled

2、查看副本擴展情況,deployments自動部署一個應用

[root@node-1 ~]# kubectl get deployments
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
nginx-app-demo   4/4     4            4           133m

3、此時service的情況會怎樣呢?查看service詳情,新擴展的pod會自動更新到service的endpoints中,自動服務發(fā)現(xiàn)

查看service詳情
[root@node-1 ~]# kubectl describe services nginx-service-demo 
Name:                     nginx-service-demo
Namespace:                default
Labels:                   run=nginx-app-demo
Annotations:              <none>
Selector:                 run=nginx-app-demo
Type:                     NodePort
IP:                       10.102.1.1
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  32416/TCP
Endpoints:                10.244.1.2:80,10.244.1.3:80,10.244.2.4:80 + 1 more...#地址已自動加入
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

查看endpioints詳情
[root@node-1 ~]# kubectl describe endpoints nginx-service-demo  
Name:         nginx-service-demo
Namespace:    default
Labels:       run=nginx-app-demo
Annotations:  endpoints.kubernetes.io/last-change-trigger-time: 2019-08-11T16:04:56Z
Subsets:
  Addresses:          10.244.1.2,10.244.1.3,10.244.2.4,10.244.2.5
  NotReadyAddresses:  <none>
  Ports:
    Name     Port  Protocol
    ----     ----  --------
    <unset>  80    TCP

Events:  <none>

4、測試,將新加入的pod站點內(nèi)容設(shè)置為web4,參考前面的設(shè)置方法,測試service的ip,查看負載均衡效果

[root@node-1 ~]# curl http://10.102.1.1
web4
[root@node-1 ~]# curl http://10.102.1.1
web4
[root@node-1 ~]# curl http://10.102.1.1
web2
[root@node-1 ~]# curl http://10.102.1.1
web3
[root@node-1 ~]# curl http://10.102.1.1
web1
[root@node-1 ~]# curl http://10.102.1.1
web2
[root@node-1 ~]# curl http://10.102.1.1
web1

由此可知,彈性伸縮會自動自動加入到service中實現(xiàn)服務自動發(fā)現(xiàn)和負載均衡,應用的擴展相比于傳統(tǒng)應用快速非常多。

5. 滾動升級

在kubernetes中更新應用程序時可以將應用程序打包到鏡像中,然后更新應用程序的鏡像以實現(xiàn)升級。默認Deployments的升級策略為RollingUpdate,其每次會更新應用中的25%的pod,新建新的pod逐個替換,防止應用程序在升級過程中不可用。同時,如果應用程序升級過程中失敗,還可以通過回滾的方式將應用程序回滾到之前的狀態(tài),回滾時通過replicasets的方式實現(xiàn)。

1、更換nginx的鏡像,將應用升級至最新版本,打開另外一個窗口使用kubectl get pods -w觀察升級過程

[root@node-1 ~]# kubectl set image deployments/nginx-app-demo nginx-app-demo=nginx:latest
deployment.extensions/nginx-app-demo image updated

2、觀察升級過程,通過查看可知,升級過程中是通過新建+刪除的方式逐個替換pod的方式

[root@node-1 ~]# kubectl get pods -w
NAME                              READY   STATUS    RESTARTS   AGE
nginx-app-demo-7bdfd97dcd-7t72x   1/1     Running   0          145m
nginx-app-demo-7bdfd97dcd-hsrft   1/1     Running   0          145m
nginx-app-demo-7bdfd97dcd-j6lgd   1/1     Running   0          12m
nginx-app-demo-7bdfd97dcd-qtbzd   1/1     Running   0          145m
nginx-app-demo-5cc8746f96-xsxz4   0/1     Pending   0          0s #新建一個pod
nginx-app-demo-5cc8746f96-xsxz4   0/1     Pending   0          0s
nginx-app-demo-7bdfd97dcd-j6lgd   1/1     Terminating   0          14m #刪除舊的pod,替換
nginx-app-demo-5cc8746f96-xsxz4   0/1     ContainerCreating   0          0s
nginx-app-demo-5cc8746f96-s49nv   0/1     Pending             0          0s #新建第二個pod
nginx-app-demo-5cc8746f96-s49nv   0/1     Pending             0          0s
nginx-app-demo-5cc8746f96-s49nv   0/1     ContainerCreating   0          0s
nginx-app-demo-7bdfd97dcd-j6lgd   0/1     Terminating         0          14m #更換第二個pod
nginx-app-demo-5cc8746f96-s49nv   1/1     Running             0          7s
nginx-app-demo-7bdfd97dcd-qtbzd   1/1     Terminating         0          146m
nginx-app-demo-5cc8746f96-txjqh   0/1     Pending             0          0s
nginx-app-demo-5cc8746f96-txjqh   0/1     Pending             0          0s
nginx-app-demo-5cc8746f96-txjqh   0/1     ContainerCreating   0          0s
nginx-app-demo-7bdfd97dcd-j6lgd   0/1     Terminating         0          14m
nginx-app-demo-7bdfd97dcd-j6lgd   0/1     Terminating         0          14m
nginx-app-demo-5cc8746f96-xsxz4   1/1     Running             0          9s
nginx-app-demo-5cc8746f96-txjqh   1/1     Running             0          1s
nginx-app-demo-7bdfd97dcd-hsrft   1/1     Terminating         0          146m
nginx-app-demo-7bdfd97dcd-qtbzd   0/1     Terminating         0          146m
nginx-app-demo-5cc8746f96-rcpmw   0/1     Pending             0          0s
nginx-app-demo-5cc8746f96-rcpmw   0/1     Pending             0          0s
nginx-app-demo-5cc8746f96-rcpmw   0/1     ContainerCreating   0          0s
nginx-app-demo-7bdfd97dcd-7t72x   1/1     Terminating         0          146m
nginx-app-demo-7bdfd97dcd-7t72x   0/1     Terminating         0          147m
nginx-app-demo-7bdfd97dcd-hsrft   0/1     Terminating         0          147m
nginx-app-demo-7bdfd97dcd-hsrft   0/1     Terminating         0          147m
nginx-app-demo-5cc8746f96-rcpmw   1/1     Running             0          2s
nginx-app-demo-7bdfd97dcd-7t72x   0/1     Terminating         0          147m
nginx-app-demo-7bdfd97dcd-7t72x   0/1     Terminating         0          147m
nginx-app-demo-7bdfd97dcd-hsrft   0/1     Terminating         0          147m
nginx-app-demo-7bdfd97dcd-hsrft   0/1     Terminating         0          147m
nginx-app-demo-7bdfd97dcd-qtbzd   0/1     Terminating         0          147m
nginx-app-demo-7bdfd97dcd-qtbzd   0/1     Terminating         0          147m

3、再次查看deployments的詳情可知道,deployments已經(jīng)更換了新的replicasets,原來的replicasets的版本為1,可用于回滾。

[root@node-1 ~]# kubectl describe deployments nginx-app-demo 
Name:                   nginx-app-demo
Namespace:              default
CreationTimestamp:      Sun, 11 Aug 2019 21:52:32 +0800
Labels:                 run=nginx-app-demo
Annotations:            deployment.kubernetes.io/revision: 2 #新的版本號,用于回滾
Selector:               run=nginx-app-demo
Replicas:               4 desired | 4 updated | 4 total | 4 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=nginx-app-demo
  Containers:
   nginx-app-demo:
    Image:        nginx:latest
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-app-demo-5cc8746f96 (4/4 replicas created) #新的replicaset,實際是替換新的replicasets
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  19m    deployment-controller  Scaled up replica set nginx-app-demo-7bdfd97dcd to 4
  Normal  ScalingReplicaSet  4m51s  deployment-controller  Scaled up replica set nginx-app-demo-5cc8746f96 to 1
  Normal  ScalingReplicaSet  4m51s  deployment-controller  Scaled down replica set nginx-app-demo-7bdfd97dcd to 3
  Normal  ScalingReplicaSet  4m51s  deployment-controller  Scaled up replica set nginx-app-demo-5cc8746f96 to 2
  Normal  ScalingReplicaSet  4m43s  deployment-controller  Scaled down replica set nginx-app-demo-7bdfd97dcd to 2
  Normal  ScalingReplicaSet  4m43s  deployment-controller  Scaled up replica set nginx-app-demo-5cc8746f96 to 3
  Normal  ScalingReplicaSet  4m42s  deployment-controller  Scaled down replica set nginx-app-demo-7bdfd97dcd to 1
  Normal  ScalingReplicaSet  4m42s  deployment-controller  Scaled up replica set nginx-app-demo-5cc8746f96 to 4
  Normal  ScalingReplicaSet  4m42s  deployment-controller  Scaled down replica set nginx-app-demo-7bdfd97dcd to 0

4、查看滾動升級的版本,可以看到有兩個版本,分別對應的兩個不同的replicasets

[root@node-1 ~]# kubectl rollout history deployment nginx-app-demo 
deployment.extensions/nginx-app-demo 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

查看replicasets列表,舊的包含pod為0
[root@node-1 ~]# kubectl get replicasets
NAME                        DESIRED   CURRENT   READY   AGE
nginx-app-demo-5cc8746f96   4         4         4       9m2s
nginx-app-demo-7bdfd97dcd   0         0         0       155m

5、測試應用的升級情況,發(fā)現(xiàn)nginx已經(jīng)升級到最新nginx/1.17.2版本

[root@node-1 ~]# curl -I http://10.102.1.1
HTTP/1.1 200 OK
Server: nginx/1.17.2 #nginx版本信息
Date: Sun, 11 Aug 2019 16:30:03 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 23 Jul 2019 11:45:37 GMT
Connection: keep-alive
ETag: "5d36f361-264"
Accept-Ranges: bytes

6、回滾到舊的版本

[root@node-1 ~]# kubectl rollout undo deployment nginx-app-demo --to-revision=1
deployment.extensions/nginx-app-demo rolled back

再次測應用,已經(jīng)回滾到舊版本。
[root@node-1 ~]# curl -I http://10.102.1.1
HTTP/1.1 200 OK
Server: nginx/1.7.9
Date: Sun, 11 Aug 2019 16:34:33 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 23 Dec 2014 16:25:09 GMT
Connection: keep-alive
ETag: "54999765-264"
Accept-Ranges: bytes

寫在最后:本文以命令行的方式實踐探索kubernetes中涉及的最重要的幾個概念:應用部署,負載均衡,彈性伸縮和滾動升級,并以命令行的形式實際操作,讀者可以參照文檔實現(xiàn)快速入門,后續(xù)會大部分以yaml文件的形式部署和kubernets交互。

參考文檔

基礎(chǔ)概念:https://kubernetes.io/docs/tutorials/kubernetes-basics/

部署應用:https://kubernetes.io/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/

訪問應用:https://kubernetes.io/docs/tutorials/kubernetes-basics/explore/explore-intro/

外部訪問:https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/

訪問應用:https://kubernetes.io/docs/tutorials/kubernetes-basics/scale/scale-intro/

滾動升級:https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/


當你的才華撐不起你的野心時,你就應該靜下心來學習

返回kubernetes系列教程目錄

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI