07 . Kubernetes之Service
- 2020 年 7 月 2 日
- 筆記
- Kubernetes
kubernetes有三種網路
1. Node Network
2. Pod Network
3. Cluster Network
Service-網路代理模式
**userspce: 1.1-
**三種代理模式
1.1版本使用的userspace,性能低,因為用戶請求先要到內核空間,然後到主機用戶空間Kube-Proxy,由kube-proxy封裝報文再返回到內核空間,再到iptables分發.
2.iptables
1.10版本就開始使用iptables,因為他直接工作在內核,性能相比之前提升了很多,他是基於四層的轉發,不會經過用戶層kube-proxy,直接調度給相關的Pod
3.ipvs
1.11版本默認ipvs,如果沒激活降級為iptables
1.8版本增加了ipvs為了能最大的發揮轉發的性能,client請求到達了直接調度給Pod網路地址範圍.
Service類型
類型
ExternalName: # 把集群外部服務引入到集群內部直接使用
ClusterIP: # 默認,僅用於集群內部通訊,如果要接入外部需要NodePort;
NodePort:
LoadBalancer: # 表示我們把kubernetes集群部署在虛擬機上,虛擬機工作在雲環境上,雲環境支援LBAAS,負載均衡一鍵調用.
資源記錄
SVC_NAME,NS_NAME,DOMAIN,LTD
svc.cluster.local
redis.default.svc.cluster.local
Example1.使用清單創建SVC
cat pod-service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
selector:
app: myapp
release: canary
clusterIP: 10.96.122.10
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30000
cat pod-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
kubectl describe svc redis
kubectl get endpoints
使用集群外的機器訪問看下什麼效果
while true; do curl 172.19.0.26:30000/hostname.html ; sleep 2;done
myapp-deploy-7d574d56c7-2tsdx
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-2tsdx
kubectl patch svc redis -p '{"spec":{"sessionAffinity":"ClientIP"}}'
# sessionAffinity,讓同一個客戶端IP訪問固定的一個Pod
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-hcw8s
kubectl patch svc redis -p '{"spec":{"sessionAffinity":"None"}}'
# 修改成默認值None
myapp-deploy-7d574d56c7-2tsdx
myapp-deploy-7d574d56c7-2tsdx
myapp-deploy-7d574d56c7-hcw8s
myapp-deploy-7d574d56c7-2tsdx
myapp-deploy-7d574d56c7-2tsdx
myapp-deploy-7d574d56c7-hcw8s
# Service到Pod是有一個中間層,Endpoints,他也是一個標準Kubernetes對象,地址加埠,關聯到後端的Pod
創建一個無頭IP
cat pod-svc-head.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
namespace: default
spec:
selector:
app: myapp
release: canary
clusterIP: "None"
ports:
- port: 80
targetPort: 80
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d17h
myapp-svc ClusterIP None <none> 80/TCP 8m16s
使用清單定義Service服務代理
Example
cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 443
# 通過svc的ClusterIP地址加上埠就能訪問此處app指定的服務
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29h
my-service ClusterIP 10.96.87.66 <none> 80/TCP,443/TCP 61s
kubectl get endpoints my-service
NAME ENDPOINTS AGE
my-service <none> 3m25s
因為匹配不到MyApp標籤的Pod,我們去修改下my-service裡面標籤為已有Pod的標籤
kubectl edit svc/my-service
28 selector:
29 app: nginx
30 sessionAffinity: None
31 type: ClusterIP
# 然後我們去查看service後面有不有代理的Pod
kubectl get ep
kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.78.7:6443 29h
my-service 10.244.2.11:80,10.244.3.13:80,10.244.3.14:80 + 3 more... 6m37s
nginx-service <none>
# 接下來訪問svc裡面的IP+埠即可
服務發現(環境變數與KubeDNS)
環境變數
當一個Pod運行在Node,kubelet會為每個容器添加一組環境變數,Pod容器中程式就可以使用這些環境變數發現Service。這些環境變數格式如下:
(SVCNAME)_SERVICE_HOST
(SVCNAME)_SERVICE_PORT
其中服務名和埠名轉為大寫,連字元轉換為下劃線.
限制
# 1. Pod和Service的創建順序是由要求的,Service必須在Pod創建之前被創建,否則環境變數不會設置到Pod上.
# 2. Pod只能獲取同個NameSpace中的Service環境變數.
DNS
DNS服務監視Kubernetes API,為每一個Service創建DNS記錄用於域名解析,這樣Pod中可以通過DNS域名獲取Service的訪問地址.
Example1
我們先創建一個busybox的pod
cat busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
kubectl exec -it busybox /bin/sh
/ # env |head -6
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
MY_SERVICE_PORT_443_TCP_ADDR=10.96.87.66
MY_SERVICE_PORT_80_TCP=tcp://10.96.87.66:80
HOSTNAME=busybox
SHLVL=1
# 我們每創建一個Pod都會在env裡面創建這些環境變數
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29h
my-service ClusterIP 10.96.87.66 <none> 80/TCP,443/TCP 22m
nginx-service ClusterIP 10.96.60.189 <none> 8080/TCP 24m
[root@master ~]# kubectl exec -it busybox /bin/sh
/ # echo ${MY_SERVICE_SERVICE_HOST_PORT}
10.96.87.66
# 我們可以通過一些變數獲取相應的值
# 但是我們要先創建service,後面的Pod才能獲取service那些環境變數.
Example2(DNS)
DNS可以拋去上面的那種Pod先後創建順序限制
//github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/deployments/kube-dns.yaml
# 到這個網址下載yaml文件創建kube-dns
# 注意修改配置文件的clusterIP: 通過ps -ef |grep kubelet查看
# 注意配置文件是要訪問外國源的,注意換成中國源.