k8s學習筆記--資源清單-控制器-service
- 資源清單格式
- 資源清單的常用命令
- 通過定義清單檔案建立 Pod
- Init 容器
- 檢測探針 - 就緒檢測
- 檢測探針 - 存活檢測
- 啟動、退出動作
- 什麼是控制器
- 控制器型別
- ReplicationController 和 ReplicaSet
- Deployment
- DaemonSet
- Job
- CronJob
- StatefulSet
- HPA
- RS 與 RC 與 Deployment 關聯
- RS 與 Deployment 的關聯
- Deployment
- 更新 Deployment
- Deployment 更新策略
- Rollover(多個rollout並行)
- 回退 Deployment
- 清理 Policy
- 什麼是 DaemonSet
- Job
- CronJob Spec
- CronJob
- CronJob Spec
- CrondJob 本身的一些限制
- Service 的概念
- 核心迭代
- Service 的型別
- ClusterIP
- Headless 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 上執行
glusterd
、ceph
- 在每個 Node 上執行日誌收集 daemon,例如
fluentd
、logstash
- 在每個 Node 上執行監控 daemon,例如 Prometheus Node Exporter、
collectd
、Datadog 代理、New Relic 代理,或 Gangliagmond
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 上執行
glusterd
、ceph
- 在每個 Node 上執行日誌收集 daemon,例如
fluentd
、logstash
- 在每個 Node 上執行監控 daemon,例如 Prometheus Node Exporter、
collectd
、Datadog 代理、New Relic 代理,或 Gangliagmond
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的個數,預設為1spec.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的個數,預設為1spec.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
(預設):允許併發執行 JobForbid
:禁止併發執行,如果前一個還沒有完成,則直接跳過下一個Replace
:取消當前正在執行的 Job,用一個新的來替換
注意,當前策略只能應用於同一個 Cron Job 建立的 Job。如果存在多個 Cron Job,它們建立的 Job 之間總是允許併發執行。
-
.spec.suspend
:掛起,該欄位也是可選的。如果設定為true
,後續所有執行都會被掛起。它對已經開始執行的 Job 不起作用。預設值為false
。 -
.spec.successfulJobsHistoryLimit
和.spec.failedJobsHistoryLimit
:歷史限制,是可選的欄位。它們指定了可以保留多少完成和失敗的 Job。預設情況下,它們分別設定為3
和1
。設定限制的值為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