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


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

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

 

Pod分為兩類:

  1. 自主式Pod
  2. 控制器管理的Pod 
    • ReplicationController
    • ReplicaSet
    • Deployment   管理無狀態的
    • StatefulSet    管理有狀態的
    • Job, Ctonjob

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

  • 定義Deployment來創建Pod和ReplicaSet
  • 滾動升級和回滾應用
  • 擴容和縮容
  • 暫停和繼續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_ip 訪問到pod,這依賴於coredns解析

[master01 ] # cat /etc/resolv.conf

nameserver 114.114.114.114       # 節點上的dns服務器不是指向的coredns的地址,所以無法直接通過server_name:service_ip 訪問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 

 

 kubectl describe svc nginx80    查看service詳細信息

 

  • 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 

 

創建一個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

  

動態擴容縮容

  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

  升級完成后查看:

# 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

  

回滾操作

# 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     #查看歷史版本

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

 

外部客戶端訪問pod

k8s中的三種網絡:

Node Network: 與外部網絡接口
Service Network:又叫集群網絡,與pod不在一個網段,只存在於iptables或ipvs規則中,是虛擬的
Pod Network: 節點當中pod的內部網絡,可以ping通

如果端口暴露類型為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地址加上暴露的端口號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM