1. 程式人生 > 其它 >k8s學習筆記--資源清單-控制器-service

k8s學習筆記--資源清單-控制器-service

目錄

資源清單格式

apiVersion: group/apiversion  # 如果沒有給定 group 名稱,那麼預設為 core,可以使用 kubectl api-versions # 獲取當前 k8s 版本上所有的 apiVersion 版本資訊( 每個版本可能不同 )
kind:       #資源類別
metadata:  #資源元資料
   name
   namespace
   lables
   annotations   # 主要目的是方便使用者閱讀查詢
spec: # 期望的狀態(disired state)
status:# 當前狀態,本欄位有 Kubernetes 自身維護,使用者不能去定義

資源清單的常用命令

獲取 apiversion 版本資訊

[root@k8s-master01 ~]# kubectl api-versions 
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
......(以下省略)

獲取資源的 apiVersion 版本資訊

[root@k8s-master01 ~]# kubectl explain pod
KIND:     Pod
VERSION:  v1
.....(以下省略)

[root@k8s-master01 ~]# kubectl explain Ingress
KIND:     Ingress
VERSION:  extensions/v1beta1

獲取欄位設定幫助文件

[root@k8s-master01 ~]# kubectl explain pod
KIND:     Pod
VERSION:  v1

DESCRIPTION:
     Pod is a collection of containers that can run on a host. This resource is
     created by clients and scheduled onto hosts.

FIELDS:
   apiVersion    <string>
     ........
     ........

欄位配置格式

apiVersion <string>          #表示字串型別
metadata <Object>            #表示需要巢狀多層欄位
labels <map[string]string>   #表示由k:v組成的對映
finalizers <[]string>        #表示字串列表
ownerReferences <[]Object>   #表示物件列表
hostPID <boolean>            #布林型別
priority <integer>           #整型
name <string> -required-     #如果型別後面接 -required-,表示為必填欄位

通過定義清單檔案建立 Pod

apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-1
    image: harbor.hongfu.com/library/myapp:v1
  - name: busybox-1
    image: harbor.hongfu.com/library/busybox:v1
    command:
    - "/bin/sh"
    - "-c"
    - "sleep 3600"
kubectl get pod xx.xx.xx -o yaml  
<!--使用 -o 引數 加 yaml,可以將資源的配置以 yaml的格式輸出出來,也可以使用json,輸出為json格式--> 

Init 容器

init 模板
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image:  harbor.hongfu.com/library/busybox:v1
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image:  harbor.hongfu.com/library/busybox:v1
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: harbor.hongfu.com/library/busybox:v1
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
---
kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377

檢測探針 - 就緒檢測

readinessProbe-httpget
apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget-pod
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: wangyanglinux/myapp:v1
    imagePullPolicy: IfNotPresent
    readinessProbe:
      httpGet:
        port: 80
        path: /index1.html
      initialDelaySeconds: 1
      periodSeconds: 3

檢測探針 - 存活檢測

livenessProbe-exec
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-pod
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: harbor.hongfu.com/library/busybox:v1
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep
3600"]
    livenessProbe:
      exec:
        command: ["test","-e","/tmp/live"]
      initialDelaySeconds: 1
      periodSeconds: 3
livenessProbe-httpget
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: harbor.hongfu.com/library/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 3
livenessProbe-tcp
apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: harbor.hongfu.com/library/myapp:v1
    livenessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 80
        

啟動、退出動作

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: harbor.hongfu.com/library/myapp:v1
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
      preStop:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the poststop handler > /usr/share/message"]

什麼是控制器

Kubernetes 中內建了很多 controller(控制器),這些相當於一個狀態機,用來控制 Pod 的具體狀態和行為

控制器型別

  • ReplicationController 和 ReplicaSet
  • Deployment
  • DaemonSet
  • StateFulSet
  • Job/CronJob
  • Horizontal Pod Autoscaling

ReplicationController 和 ReplicaSet

ReplicationController(RC)用來確保容器應用的副本數始終保持在使用者定義的副本數,即如果有容器異常退出,會自動建立新的 Pod 來替代;而如果異常多出來的容器也會自動回收;

在新版本的 Kubernetes 中建議使用 ReplicaSet 來取代 ReplicationController 。ReplicaSet 跟ReplicationController 沒有本質的不同,只是名字不一樣,並且 ReplicaSet 支援集合式的 selector;

Deployment

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

  • 定義 Deployment 來建立 Pod 和 ReplicaSet
  • 滾動升級和回滾應用
  • 擴容和縮容
  • 暫停和繼續 Deployment

DaemonSet

DaemonSet 確保全部(或者一些)Node 上執行一個 Pod 的副本。當有 Node 加入叢集時,也會為他們新增一個 Pod 。當有 Node 從叢集移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它建立的所有 Pod

使用 DaemonSet 的一些典型用法:

  • 執行叢集儲存 daemon,例如在每個 Node 上執行 glusterdceph
  • 在每個 Node 上執行日誌收集 daemon,例如fluentdlogstash
  • 在每個 Node 上執行監控 daemon,例如 Prometheus Node Exportercollectd、Datadog 代理、New Relic 代理,或 Ganglia gmond

Job

Job 負責批處理任務,即僅執行一次的任務,它保證批處理任務的一個或多個 Pod 成功結束

CronJob

Cron Job 管理基於時間的 Job,即:

  • 在給定時間點只執行一次
  • 週期性地在給定時間點執行

使用前提條件:當前使用的 Kubernetes 叢集,版本 >= 1.8(對 CronJob)。對於先前版本的叢集,版本 < 1.8,啟動 API Server時,通過傳遞選項 --runtime-config=batch/v2alpha1=true 可以開啟 batch/v2alpha1 API

典型的用法如下所示:

  • 在給定的時間點排程 Job 執行
  • 建立週期性執行的 Job,例如:資料庫備份、傳送郵件

StatefulSet

StatefulSet 作為 Controller 為 Pod 提供唯一的標識。它可以保證部署和 scale 的順序

StatefulSet是為了解決有狀態服務的問題(對應Deployments和ReplicaSets是為無狀態服務而設計),其應用場景包括:

  • 穩定的持久化儲存,即Pod重新排程後還是能訪問到相同的持久化資料,基於PVC來實現
  • 穩定的網路標誌,即Pod重新排程後其PodName和HostName不變,基於Headless Service(即沒有Cluster IP的Service)來實現
  • 有序部署,有序擴充套件,即Pod是有順序的,在部署或者擴充套件的時候要依據定義的順序依次依次進行(即從0到N-1,在下一個Pod執行之前所有之前的Pod必須都是Running和Ready狀態),基於init containers來實現
  • 有序收縮,有序刪除(即從N-1到0)

HPA

應用的資源使用率通常都有高峰和低谷的時候,如何削峰填谷,提高叢集的整體資源利用率,讓 service 中的Pod個數自動調整呢?這就有賴於 HPA (Horizontal Pod Autoscaling)了,顧名思義,使 Pod 水平自動縮放


typora-root-url: Png


RS 與 RC 與 Deployment 關聯

RC (ReplicationController )主要的作用就是用來確保容器應用的副本數始終保持在使用者定義的副本數 。即如果有容器異常退出,會自動建立新的Pod來替代;而如果異常多出來的容器也會自動回收

Kubernetes 官方建議使用 RS(ReplicaSet ) 替代 RC (ReplicationController ) 進行部署,RS 跟 RC 沒有本質的不同,只是名字不一樣,並且 RS 支援集合式的 selector

RC 控制器

apiVersion: v1
kind: ReplicationController
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: php-redis
        image: wangyanglinux/myapp:v1
        env:
        - name: GET_HOSTS_FROM
          value: dns
          name: zhangsan
          value: "123"
        ports:
        - containerPort: 80

RS 控制器

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: myapp
        image: wangyanglinux/myapp:v1
        env:
        - name: GET_HOSTS_FROM
          value: dns
        ports:
        - containerPort: 80

selector.matchExpressions

rs 在標籤選擇器上,除了可以定義鍵值對的選擇形式,還支援 matchExpressions 欄位,可以提供多種選擇。
目前支援的操作包括:

  • In:label 的值在某個列表中
  • NotIn:label 的值不在某個列表中
  • Exists:某個 label 存在
  • DoesNotExist:某個 label 不存在
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: rs-demo
spec:
  selector:
    matchExpressions:
      - key: app
        operator: Exists
  template:
    metadata:
      labels:
        app: spring-k8s
    spec:
      containers:
        - name: rs-c1
          image: wangyanglinux/myapp:v1
          ports:
            - containerPort: 80
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: rs-demo
spec:
  selector:
    matchExpressions:
      - key: app
        operator: In
        values:
        - spring-k8s
        - hahahah
  template:
    metadata:
      labels:
        app: sg-k8s
    spec:
      containers:
        - name: rs-c1
          image: wangyanglinux/myapp:v1
          ports:
            - containerPort: 80

RS 與 Deployment 的關聯

Deployment

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

  • 定義Deployment來建立Pod和ReplicaSet
  • 滾動升級和回滾應用
  • 擴容和縮容
  • 暫停和繼續Deployment

Ⅰ、部署一個簡單的 Nginx 應用

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: wangyanglinux/myapp:v1
        ports:
        - containerPort: 80
kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml --record
## --record引數可以記錄命令,我們可以很方便的檢視每次 revision 的變化

Ⅱ、擴容

kubectl scale deployment nginx-deployment --replicas 10

Ⅲ、如果叢集支援 horizontal pod autoscaling 的話,還可以為Deployment設定自動擴充套件

kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80

Ⅳ、更新映象也比較簡單

kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

Ⅴ、回滾

kubectl rollout undo deployment/nginx-deployment

更新 Deployment

假如我們現在想要讓 nginx pod 使用nginx:1.9.1的映象來代替原來的nginx:1.7.9的映象

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment "nginx-deployment" image updated

可以使用edit命令來編輯 Deployment

$ kubectl edit deployment/nginx-deployment
deployment "nginx-deployment" edited

檢視 rollout 的狀態

$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out

檢視歷史 RS

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-1564180365   3         3         0       6s
nginx-deployment-2035384211   0         0         0       36s

Deployment 更新策略

Deployment 可以保證在升級時只有一定數量的 Pod 是 down 的。預設的,它會確保至少有比期望的Pod數量少一個是up狀態(最多一個不可用)

Deployment 同時也可以確保只創建出超過期望數量的一定數量的 Pod。預設的,它會確保最多比期望的Pod數量多一個的 Pod 是 up 的(最多1個 surge )

未來的 Kuberentes 版本中,將從1-1變成25%-25%

$ kubectl describe deployments

更新策略宣告

kubectl explain deploy.spec.strategy.type

  • Recreate
  • rollingUpdate
    • maxSurge:指定超出副本數有幾個,兩種方式:1、指定數量 2、百分比
    • maxUnavailable : 最多有幾個不可用
kubectl patch deployment  nginx-deployment -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'

金絲雀部署

$ kubectl set image deploy  nginx-deployment nginx=wangyanglinux/myapp:v2 && kubectl rollout pause deploy  nginx-deployment

$ kubectl rollout resume deploy  nginx-deployment

Rollover(多個rollout並行)

假如您建立了一個有5個niginx:1.7.9 replica的 Deployment,但是當還只有3個nginx:1.7.9的 replica 創建出來的時候您就開始更新含有5個nginx:1.9.1 replica 的 Deployment。在這種情況下,Deployment 會立即殺掉已建立的3個nginx:1.7.9的 Pod,並開始建立nginx:1.9.1的 Pod。它不會等到所有的5個nginx:1.7.9的 Pod 都建立完成後才開始改變航道

回退 Deployment

kubectl set image deployment/nginx-deployment nginx=nginx:1.91
kubectl rollout status deployments nginx-deployment
kubectl get pods
kubectl rollout history deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment --to-revision=2   ## 可以使用 --revision引數指定某個歷史版本
kubectl rollout pause deployment/nginx-deployment    ## 暫停 deployment 的更新

您可以用kubectl rollout status命令檢視 Deployment 是否完成。如果 rollout 成功完成,kubectl rollout status將返回一個0值的 Exit Code

$ kubectl rollout status deploy/nginx
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx" successfully rolled out
$ echo $?
0

清理 Policy

您可以通過設定.spec.revisonHistoryLimit項來指定 deployment 最多保留多少 revision 歷史記錄。預設的會保留所有的 revision;如果將該項設定為0,Deployment 就不允許回退了

什麼是 DaemonSet

DaemonSet 確保全部(或者一些)Node 上執行一個 Pod 的副本。當有 Node 加入叢集時,也會為他們新增一個 Pod 。當有 Node 從叢集移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它建立的所有 Pod

使用 DaemonSet 的一些典型用法:

  • 執行叢集儲存 daemon,例如在每個 Node 上執行 glusterdceph
  • 在每個 Node 上執行日誌收集 daemon,例如fluentdlogstash
  • 在每個 Node 上執行監控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: deamonset-example
  labels:
    app: daemonset
spec:
  selector:
    matchLabels:
      name: deamonset-example
  template:
    metadata:
      labels:
        name: deamonset-example
    spec:
      containers:
      - name: daemonset-example
        image: wangyanglinux/myapp:v1

Job

Job 負責批處理任務,即僅執行一次的任務,它保證批處理任務的一個或多個 Pod 成功結束

特殊說明
  • spec.template格式同Pod
  • RestartPolicy僅支援Never或OnFailure
  • 單個Pod時,預設Pod成功執行後Job即結束
  • .spec.completions標誌Job結束需要成功執行的Pod個數,預設為1
  • .spec.parallelism標誌並行執行的Pod的個數,預設為1
  • spec.activeDeadlineSeconds標誌失敗Pod的重試最大時間,超過這個時間不會繼續重試

Example

求 π 值

演算法:馬青公式

π/4=4arctan1/5-arctan1/239

這個公式由英國天文學教授 約翰·馬青 於 1706 年發現。他利用這個公式計算到了 100 位的圓周率。馬青公式每計算一項可以得到 1.4 位的 十進位制精度。因為它的計算過程中被乘數和被除數都不大於長整數,所以可以很容易地在計算機上程式設計實現

# -*- coding: utf-8 -*-
from __future__ import division
# 匯入時間模組
import time
# 計算當前時間
time1=time.time()
# 演算法根據馬青公式計算圓周率 #
number = 1000
# 多計算10位,防止尾數取捨的影響
number1 = number+10
# 算到小數點後number1位
b = 10**number1
# 求含4/5的首項
x1 = b*4//5
# 求含1/239的首項
x2 = b // -239
# 求第一大項
he = x1+x2
#設定下面迴圈的終點,即共計算n項
number *= 2
#迴圈初值=3,末值2n,步長=2
for i in xrange(3,number,2):
  # 求每個含1/5的項及符號
  x1 //= -25
  # 求每個含1/239的項及符號
  x2 //= -57121
  # 求兩項之和
  x = (x1+x2) // i
  # 求總和
  he += x
# 求出π
pai = he*4
#舍掉後十位
pai //= 10**10
# 輸出圓周率π的值
paistring=str(pai)
result=paistring[0]+str('.')+paistring[1:len(paistring)]
print result
time2=time.time()
print u'Total time:' + str(time2 - time1) + 's'
FROM hub.c.163.com/public/python:2.7
ADD ./main.py /root
CMD /usr/bin/python /root/main.py
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    metadata:
      name: pi
    spec:
      containers:
      - name: pi
        image: maqing:v1
      restartPolicy: Never

CronJob Spec

  • spec.template 格式同 Pod
  • RestartPolicy僅支援Never或OnFailure
  • 單個Pod時,預設Pod成功執行後Job即結束
  • .spec.completions標誌Job結束需要成功執行的Pod個數,預設為1
  • .spec.parallelism標誌並行執行的Pod的個數,預設為1
  • spec.activeDeadlineSeconds標誌失敗Pod的重試最大時間,超過這個時間不會繼續重試

CronJob

Cron Job 管理基於時間的 Job,即:

  • 在給定時間點只執行一次
  • 週期性地在給定時間點執行

使用條件:當前使用的 Kubernetes 叢集,版本 >= 1.8(對 CronJob)

典型的用法如下所示:

  • 在給定的時間點排程 Job 執行
  • 建立週期性執行的 Job,例如:資料庫備份、傳送郵件

CronJob Spec

  • .spec.schedule:排程,必需欄位,指定任務執行週期,格式同 Cron

  • .spec.jobTemplate:Job 模板,必需欄位,指定需要執行的任務,格式同 Job

  • .spec.startingDeadlineSeconds :啟動 Job 的期限(秒級別),該欄位是可選的。如果因為任何原因而錯過了被排程的時間,那麼錯過執行時間的 Job 將被認為是失敗的。如果沒有指定,則沒有期限

  • .spec.concurrencyPolicy:併發策略,該欄位也是可選的。它指定了如何處理被 Cron Job 建立的 Job 的併發執行。只允許指定下面策略中的一種:

    • Allow(預設):允許併發執行 Job
    • Forbid:禁止併發執行,如果前一個還沒有完成,則直接跳過下一個
    • Replace:取消當前正在執行的 Job,用一個新的來替換

    注意,當前策略只能應用於同一個 Cron Job 建立的 Job。如果存在多個 Cron Job,它們建立的 Job 之間總是允許併發執行。

  • .spec.suspend :掛起,該欄位也是可選的。如果設定為 true,後續所有執行都會被掛起。它對已經開始執行的 Job 不起作用。預設值為 false

  • .spec.successfulJobsHistoryLimit.spec.failedJobsHistoryLimit :歷史限制,是可選的欄位。它們指定了可以保留多少完成和失敗的 Job。預設情況下,它們分別設定為 31。設定限制的值為 0,相關型別的 Job 完成後將不會被保留。

Example

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
$ kubectl get cronjob
NAME      SCHEDULE      SUSPEND   ACTIVE    LAST-SCHEDULE
hello     */1 * * * *   False     0         <none>
$ kubectl get jobs
NAME               DESIRED   SUCCESSFUL   AGE
hello-1202039034   1         1            49s

$ pods=$(kubectl get pods --selector=job-name=hello-1202039034 --output=jsonpath={.items..metadata.name})

$ kubectl logs $pods
Mon Aug 29 21:34:09 UTC 2016
Hello from the Kubernetes cluster

# 注意,刪除 cronjob 的時候不會自動刪除 job,這些 job 可以用 kubectl delete job 來刪除
$ kubectl delete cronjob hello
cronjob "hello" deleted

CrondJob 本身的一些限制

建立 Job 操作應該是 冪等的

目錄

    Service 的概念

    Kubernetes Service 定義了這樣一種抽象:一個 Pod 的邏輯分組,一種可以訪問它們的策略 —— 通常稱為微服務。 這一組 Pod 能夠被 Service 訪問到,通常是通過 Label Selector

    核心迭代

    在 Kubernetes 叢集中,每個 Node 執行一個 kube-proxy 程序。kube-proxy 負責為 Service 實現了一種 VIP(虛擬 IP)的形式,而不是 ExternalName 的形式。 在 Kubernetes v1.0 版本,代理完全在 userspace。在 Kubernetes v1.1 版本,新增了 iptables 代理,但並不是預設的執行模式。 從 Kubernetes v1.2 起,預設就是 iptables 代理。 在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理

    在 Kubernetes 1.14 版本開始預設使用 ipvs 代理

    在 Kubernetes v1.0 版本,Service 是 “4層”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 Ingress API(beta 版),用來表示 “7層”(HTTP)服務

    Ⅰ、userspace 代理模式

    Ⅱ、iptables 代理模式

    Ⅲ、ipvs 代理模式

    限制

    Service能夠提供負載均衡的能力,但是在使用上有以下限制:

    • 只提供 4 層負載均衡能力,而沒有 7 層功能,但有時我們可能需要更多的匹配規則來轉發請求,這點上 4 層負載均衡是不支援的

    Service 的型別

    • ClusterIp:預設型別,自動分配一個僅 Cluster 內部可以訪問的虛擬 IP
    • NodePort:在 ClusterIP 基礎上為 Service 在每臺機器上繫結一個埠,這樣就可以通過 : NodePort 來訪問該服務
    • LoadBalancer:在 NodePort 的基礎上,藉助 cloud provider 建立一個外部負載均衡器,並將請求轉發到: NodePort
    • ExternalName:把叢集外部的服務引入到叢集內部來,在叢集內部直接使用。沒有任何型別代理被建立,這隻有 kubernetes 1.7 或更高版本的 kube-dns 才支援

    ClusterIP

    **為了實現圖上的功能,主要需要以下幾個元件的協同工作: **

    • apiserver:使用者通過 kubectl 命令向 apiserver 傳送建立 service 的命令,apiserver 接收到請求後將資料儲存到 etcd 中
    • kube-proxy:kubernetes 的每個節點中都有一個叫做 kube-porxy 的程序,這個程序負責感知service,pod 的變化,並將變化的資訊寫入本地的 ipvs 規則中
    • ipvs:基於核心的鉤子函式機制實現負載

    建立 myapp-deploy.yaml 檔案

    [root@master manifests]# vim myapp-deploy.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp-deploy
      namespace: default
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: myapp
          release: stabel
      template:
        metadata:
          labels:
            app: myapp
            release: stabel
            env: test
        spec:
          containers:
          - name: myapp
            image: wangyanglinux/myapp:v2
            imagePullPolicy: IfNotPresent
            ports:
            - name: http
              containerPort: 80
    

    建立 Service 資訊

    [root@master manifests]# vim myapp-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp
      namespace: default
    spec:
      type: ClusterIP
      selector:
        app: myapp
        release: stabel
      ports:
      - name: http
        port: 80
        targetPort: 80
    

    Headless Service

    有時不需要或不想要負載均衡,以及單獨的 Service IP 。遇到這種情況,可以通過指定 Cluster IP ( spec.clusterIP ) 的值為 “ None ” 來建立 Headless Service 。這類 Service 並不會分配 Cluster IP, kube-proxy 不會處理它們,而且平臺也不會為它們進行負載均衡和路由

    # yum -y install bind-utils
    [root@k8s-master mainfests]# vim myapp-svc-headless.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp-headless
      namespace: default
    spec:
      selector:
        app: myapp
      clusterIP: "None"
      ports: 
      - port: 80
        targetPort: 80
        
    [root@k8s-master mainfests]# dig -t A myapp-headless.default.svc.cluster.local. @10.96.0.10
    

    NodePort

    [root@master manifests]# vim myapp-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp
      namespace: default
    spec:
      type: NodePort
      selector:
        app: myapp
        release: stabel
      ports:
      - name: http
        port: 80
        targetPort: 80
    

    LoadBalancer

    loadBalancer 和 nodePort 其實是同一種方式。區別在於 loadBalancer 比 nodePort 多了一步,就是可以呼叫 cloud provider 去建立 LB 來向節點導流

    ExternalName

    這種型別的 Service 通過返回 CNAME 和它的值,可以將服務對映到 externalName 欄位的內容( 例如:hub.hongfu.com )。ExternalName Service 是 Service 的特例,它沒有 selector,也沒有定義任何的埠和 Endpoint。相反的,對於執行在叢集外部的服務,它通過返回該外部服務的別名這種方式來提供服務

    kind: Service
    apiVersion: v1
    metadata:
      name: my-service-1
      namespace: default
    spec:
      type: ExternalName
      externalName: hub.hongfu.com
    

    當查詢主機 my-service.defalut.svc.cluster.local ( SVC_NAME.NAMESPACE.svc.cluster.local )時,叢集的 DNS 服務將返回一個值 my.database.example.com 的 CNAME 記錄。訪問這個服務的工作方式和其他的相同,唯一不同的是重定向發生在 DNS 層,而且不會進行代理或轉發


    typora-root-url: Png


    資料資訊

    Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx

    Ingress-Nginx 官方網站:https://kubernetes.github.io/ingress-nginx/

    部署 Ingress-Nginx

    $ kubectl  apply -f mandatory.yaml
    $ kubectl  apply -f service-nodeport.yaml
    

    Ingress HTTP 代理訪問

    deployment、Service、Ingress Yaml 檔案
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: nginx-dm
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            name: nginx
        spec:
          containers:
            - name: nginx
              image: wangyanglinux/myapp:v1
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc
    spec:
      ports:
        - port: 80
          targetPort: 80
          protocol: TCP
      selector:
        name: nginx
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: nginx-test
    spec:
      rules:
        - host: www1.hongfu.com
          http:
            paths:
            - path: /
              backend:
                serviceName: nginx-svc
                servicePort: 80
    

    Ingress HTTPS 代理訪問

    建立證書,以及 cert 儲存方式
    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
    kubectl create secret tls tls-secret --key tls.key --cert tls.crt
    
    deployment、Service、Ingress Yaml 檔案
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: nginx-test
    spec:
      tls:
        - hosts:
          - foo.bar.com
          secretName: tls-secret
      rules:
        - host: foo.bar.com
          http:
            paths:
            - path: /
              backend:
                serviceName: nginx-svc
                servicePort: 80
    

    Nginx 進行 BasicAuth

    yum -y install httpd
    htpasswd -c auth foo
    kubectl create secret generic basic-auth --from-file=auth
    
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress-with-auth
      annotations:
        nginx.ingress.kubernetes.io/auth-type: basic
        nginx.ingress.kubernetes.io/auth-secret: basic-auth
        nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
    spec:
      rules:
      - host: foo2.bar.com
        http:
          paths:
          - path: /
            backend:
              serviceName: nginx-svc
              servicePort: 80
    

    Nginx 進行重寫

    名稱 描述
    nginx.ingress.kubernetes.io/rewrite-target 必須重定向流量的目標URI
    nginx.ingress.kubernetes.io/ssl-redirect 指示位置部分是否僅可訪問SSL(當Ingress包含證書時預設為True) 布林
    nginx.ingress.kubernetes.io/force-ssl-redirect 即使Ingress未啟用TLS,也強制重定向到HTTPS 布林
    nginx.ingress.kubernetes.io/app-root 定義Controller必須重定向的應用程式根,如果它在'/'上下文中
    nginx.ingress.kubernetes.io/use-regex 指示Ingress上定義的路徑是否使用正則表示式 布林
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: nginx-test
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: http://foo.bar.com:31795/hostname.html
    spec:
      rules:
      - host: foo10.bar.com
        http:
          paths:
          - path: /
            backend:
              serviceName: nginx-svc
              servicePort: 80