天天看點

K8S(二)-建立一個pod應用

 Pod是可以建立和管理Kubernetes計算的最小可部署單元。pod可以了解為容器的外殼,給容器做了一層抽象封裝。一個Pod代表着叢集中運作的一個程序,每個pod都有一個唯一的ip。

一個pod類似一個豌豆莢,包含一個或多個容器(通常是docker),這多個容器間共享IPC、Network和UTC,和存儲卷,存儲卷不再屬于容器,而屬于pod。

Pod分為兩類:

  1. 自主式Pod
  2. 控制器管理的Pod  使pod成為有生命周期的對象
  • ReplicationController
  • ReplicaSet    replicaset不直接使用,它有一個聲明式更新的控制器--deployment來負責管理,但是deployment隻能管理無狀态的
  • Deployment   管理無狀态的,使用最多的
  • StatefulSet    管理有狀态的
  • DaemonSet 
  • Job, Ctonjob

 Deployment為Pod和ReplicaSet提供了一個聲明式定義(declarative)方法,用來替代以前的ReplicationController來友善的管理應用。典型的應用場景包括:

  • 定義Deployment來建立Pod和ReplicaSet
  • 滾動更新和復原應用
  • 擴容和縮容
  • 暫停和繼續Deployment

使用deployment建立一個pod應用

kubectl  run -h  檢視run指令的用法

master01 # kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1  --record
              控制器名稱      容器鏡像           容器的端口  pod的數量   在Deployment revision中可以檢視到執行的曆史指令      

檢視

# kubectl get deployment -o wide   #檢視deployment控制器      
  NAME         READY UP-TO-DATE AVAILABLE AGE   CONTAINERS   IMAGES            SELECTOR
  nginx-deploy 1/1    1         1        2m38s  nginx-deploy nginx:1.14-alpine run=nginx-deploy
[master01 ]# kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
nginx-deploy-55d8d67cf-kckf9   1/1     Running   0          2m55s   10.244.1.2   node01   <none>           <none>
可以看到pod已經運作在一個工作節點上, 這裡的ip是cni0橋的ip
      
[node01] # ifconfig
cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.244.1.1  netmask 255.255.255.0  broadcast 0.0.0.0 
# curl 10.244.1.2  可以通路到nginx。在叢集中間的任意一個節點都可以通路到pod      

 在叢集内部任意的節點可以通路pod 。叢集外部無法直接通路pod

 删除pods     檢視會看到自動起來另一個,因為 replicas個數為1,控制器會另外再啟動一個pod

# kubectl delete pod nginx-deploy-55d8d67cf-kckf9
pod "nginx-deploy-55d8d67cf-kckf9" deleted
# kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
nginx-deploy-55d8d67cf-lf5xb   1/1     Running   0          2m55s   10.244.1.3   node01   <none>           <none>      

 會看到容器已經被重建了,且pod的ip發生變化了。

service 

service是一個抽象概念,定義了一個服務的多個pod邏輯合集和通路pod的政策,一般把service稱為微服務。

舉個例子:a服務運作3個pod,b服務怎麼通路a服務的pod,pod的ip都不是持久化的重新開機之後就會有變化。

這時候b服務可以通路跟a服務綁定的service,service資訊是固定的提前告訴b就行了,service通過Label Selector跟a服務的pod綁定,無論a的pod如何變化對b來說都是透明的。

 用戶端的請求到service,由service代理至後端的pod。service并不是一個具體的應用程式,而是相當于一條ipvs或iptables規則。

kubectl  expose  -h  檢視指令的用法

kubectl expose (-f FILENAME | TYPE NAME)  [--port=port]  [--protocol=TCP|UDP|SCTP]  [--target-port=number-or-name]  [--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]

建立service 

# kubectl expose deployment nginx-deploy --name=nginx80 --port=80 --target-port=80 --protocol=TCP
                                         service_name  service_port  pod_port
service/nginx exposed      

檢視service

# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE     SELECTOR
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          26d     <none>
nginx80      ClusterIP   10.105.125.134   <none>        80/TCP           118s    run=nginx-deploy
# curl 10.105.125.134:80  在叢集内部節點上可以通路到pod      

 在叢集節點可以使用 service_ip:service_port 通路pod。  node通路 -> service_ip:service_port -> pod_ip:pod:port。

  在pod用戶端可以通過 service_name:service_port 通路到pod,這依賴于coredns解析

[master01 ] # cat /etc/resolv.conf

nameserver 114.114.114.114       # 節點上的dns伺服器不是指向的coredns的位址,是以無法直接通過server_name:service_port 通路pod

# kubectl get svc -n kube-system   #可以看到coredns的位址
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   6d3h       

在pod用戶端通路

# kubectl run client --image=busybox --replicas=1 -it --restart=Never

/ # cat /etc/resolv.conf

nameserver 10.96.0.10

search default.svc.cluster.local svc.cluster.local cluster.local

/ # wget -O - -q http://nginx80      可以通路到  #  pod用戶端可以通過 server_name:server_ip 通路到pod 

在node可以通過dig解析

# dig    nginx80.default.svc.cluster.local.   @10.96.0.10

              svc的域名                                  coredns的clusterip

 kubectl describe svc nginx80    檢視service詳細資訊

K8S(二)-建立一個pod應用
  • selector    标簽選擇器
  • endpoints可以看到後端pod資源

pod被删除掉之後會建立一個新pod,通路nginx:80依然能通路到,因為service通過selector标簽選擇器跟pod建立了綁定,service可以為pod提供固定通路端點。

# kubectl get pods --show-labels   # 檢視标簽

NAME READY STATUS RESTARTS AGE LABELS

client 1/1 Running 0 19m run=client

nginx-deploy-54d6d94f75-b2kxf 1/1 Running 0 165m pod-template-hash=54d6d94f75,run=nginx-deploy

實踐:

建立兩個pod

# kubectl run myapp --image=ikubernetes/myapp:v1 --replicas=2
# kubectl get deployment  -w    # -w 監控deployment狀态      
# kubectl get pods -o wide       
K8S(二)-建立一個pod應用

建立一個service

# kubectl expose deployment myapp --port=8000 --target-port=80      

檢視svc

# kubectl describe svc myapp
Name:              myapp
Namespace:         default
Labels:            run=myapp
Annotations:       <none>
Selector:          run=myapp
Type:              ClusterIP
IP:                10.99.71.37       
Port:              <unset>  8000/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.35:80,10.244.1.36:80  #service後端的兩個pod
Session Affinity:  None
Events:            <none>      

 建立一個pod用戶端通路 service_name:service_port,可以看到service是随機的将請求分發到後端的兩個pod的

# kubectl run client --image=busybox -it 

/ # wget -O - -q http://myapp:8000/hostname.html

K8S(二)-建立一個pod應用

動态擴容縮容

  kubectl scale --replicas=5 deployment  nginx-deploy     # replicas指定pod數即可擴容縮容

更新鏡像

 将鏡像更新為1.16-alpine:

# kubectl set image deployment nginx-deploy nginx-deploy=nginx:1.16-alpine  --record
deployment.extensions/nginx-deploy image updated      

另開一個視窗監控更新過程:

# kubectl get pod -w

K8S(二)-建立一個pod應用

  更新完成後檢視:

# kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
nginx-deploy-56457775df-ptx9f   1/1     Running   0          2m25s

# kubectl get deployment -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS     IMAGES              SELECTOR
nginx-deploy   1/1     1            1           23d   nginx-deploy   nginx:1.16-alpine   run=nginx-deploy      

# kubectl describe pod nginx-deploy-56457775df-ptx9f

K8S(二)-建立一個pod應用

復原操作

# kubectl rollout undo deployment/nginx-deploy

deployment.extensions/nginx-deploy rolled back

--to-revision 參數可以指定回退的版本

# kubectl rollout undo deploy/nginx-deploy --to-revision=1

# kubectl rollout history deployment/nginx-deploy     #檢視曆史版本

K8S(二)-建立一個pod應用

這裡CHANGE-CAUSE顯示為空是因為操作deployment的時候沒有加--record。如果加上應該顯示:

K8S(二)-建立一個pod應用

外部用戶端通路pod

k8s中的三種網絡:

Node Network: 與外部網絡接口

Service Network:又叫叢集網絡,與pod不在一個網段,隻存在于iptables或ipvs規則中,是虛拟的

Pod Network: 節點當中pod的内部網絡

K8S(二)-建立一個pod應用

如果端口暴露類型為NodePort,那麼外部用戶端可以通過叢集内任意一台主機ip加暴露的端口進行通路

1. #  kubectl edit svc myapp   修改service的type為NodePort

  ClusterIP: 預設類型,自動配置設定一個僅叢集内部可以通路的虛拟IP

  NodePort: 在ClusterIP基礎上為Service在每台機器上綁定一個端口,這樣就可以通過  NodeIP:NodePort 來通路該服務

2. 也可以在建立service時指定type

 kubectl expose deployment nginx-deploy  --name=nginx   --port=80 --target-port=80 --

type

=NodePort

 # kubectl get svc -o wide

NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        26d   <none>
nginx80      NodePort    10.105.125.134   <none>        80:32441/TCP   35m   run=nginx-deploy      

使用叢集外用戶端通路,需要使用叢集任意一個節點的IP位址加上暴露的端口号

K8S(二)-建立一個pod應用

繼續閱讀