1. Service
-
Service可以看作是一組提供相同服務的Pod對外的訪問接口。藉助Service,應用可以方便地實現服務發現和負載均衡
-
service默認只支持4層負載均衡能力,沒有7層功能。(可以通過Ingress實現)
-
service的類型:
- ClusterIP:默認值,k8s系統給service自動分配的虛擬IP,只能在集羣內部訪問
- NodePort:將Service通過指定的Node上的端口暴露給外部,訪問任意一個
- NodeIP:nodePort都將路由到ClusterIP
- LoadBalancer:在 NodePort 的基礎上,藉助 cloud provider 創建一個外部的負載均衡器,並將請求轉發到 :NodePort,此模式只能在雲服務器上使用
- ExternalName:將服務通過 DNS CNAME 記錄方式轉發到指定的域名(通過spec.externlName 設定)
-
Service 是由 kube-proxy 組件,加上 iptables 來共同實現的
-
kube-proxy 通過 iptables 處理 Service 的過程,需要在宿主機上設置相當多的iptables 規則,如果宿主機有大量的Pod,不斷刷新iptables規則,會消耗大量的CPU資源
-
IPVS模式的service,可以使K8s集羣支持更多量級的Pod
1.1 開啓kube-proxy的ipvs模式
所有節點安裝ipvsadm
yum install -y ipvsadm
修改IPVS模式
kubectl edit cm kube-proxy -n kube-system
更新kube-proxy pod
kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
注意: IPVS模式下,kube-proxy會在service創建後,在宿主機上添加一個虛擬網卡: kube-ipvs0,並分配service IP
ifconfig kube-ipvs0
###
若還沒有ifconfig命令,安裝net-tools.x86_64
###
查看屬性
kube-proxy通過linux的IPVS模塊,以rr輪詢方式調度service中的Pod
Flannel vxlan模式跨主機通信原理
創建service:(ClusterIP方式)
vim service-test.yaml
kubectl create -f service-test.yaml
kubectl describe service web-service
Kubernetes 提供了一個 DNS 插件 Service
kubectl get services kube-dns --namespace=kube-system
kubectl run test --image=reg.harbor.com/library/busybox -it
###
nslookup web-service
###
Headless Service “無頭服務”
- Headless Service不需要分配一個VIP,而是直接以DNS記錄的方式解析出被代理Pod的IP地址
- 域名格式:(namespace).svc.cluster.local
Headless Service 示例
kubectl create -f service.yaml
kubectl get services
yum install -y bind-utils-9.9.4-72.el7.x86_64
dig -t A nginx-svc.default.svc.cluster.local @10.96.0.10
Pod滾動更新後,依然可以解析
kubectl delete pod --all
dig -t A nginx-svc.default.svc.cluster.local @10.96.0.10
創建service:(NodePort方式)
vim service-example.yaml
kubectl create -f service-example.yaml
kubectl get services my-nginx
外部訪問 Service 的第二種方式,適用於公有云上的 Kubernetes 服務。這時候,你可以指定一個 LoadBalancer 類型的Service
vim lb-service.yaml
在service提交後,Kubernetes就會調用 CloudProvider 在公有云上爲你創建一個負載均衡服務,並且把被代理的 Pod 的 IP地址配置給負載均衡服務做後端
從外部訪問的第三種方式叫做ExternalName
vim ex-service.yaml
kubectl create -f ex-service.yaml
dig -t A my-service.default.svc.cluster.local @10.96.0.10
service允許爲其分配一個公有IP
vim ex-service.yaml
kubectl create -f ex-service.yaml
kubectl get services ex-service
1.2 ingress-nginx
- 一種全局的、爲了代理不同後端 Service 而設置的負載均衡服務,就是 Kubernetes 裏的Ingress 服務
- Ingress由兩部分組成:Ingress controller和Ingress服務
- Ingress Controller 會根據你定義的 Ingress 對象,提供對應的代理能力。業界常用的各種反向代理項目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已經爲Kubernetes 專門維護了對應的 Ingress Controller
官網: https://kubernetes.github.io/ingress-nginx/
應用ingress controller定義文件
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
應用ingress-service定義文件
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
kubectl -n ingress-nginx get pod
kubectl -n ingress-nginx get services
創建ingress服務
vim ingress.yaml
kubectl apply -f ingress.yaml
kubectl get ingresses
用DaemonSet結合nodeselector來部署ingress-controller到特定的node上,然後使用HostNetwork直接把該pod與宿主機node的網絡打通,直接使用宿主機的80/433端口就能訪問服務
- 優點是整個請求鏈路最簡單,性能相對NodePort模式更好
- 缺點是由於直接利用宿主機節點的網絡和端口,一個node只能部署一個ingress-controller pod
- 比較適合大併發的生產環境使用
修改ingress controller部署文件
vim mandatory.yaml ##我已經將需要的鏡像下載上傳到harbor倉庫,所以這裏使用harbor倉庫
設置ingress controller節點的標籤
kubectl label nodes server6 type=ingress
應用更新配置
kubectl -n ingress-nginx delete deployments.apps nginx-ingress-controller
kubectl apply -f mandatory.yaml
Ingress TLS 配置
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
vim ingress-https.yaml
Ingress 認證配置
yum install -y httpd-tools
htpasswd -c auth dsd
kubectl create secret generic basic-auth --from-file=auth
vim ingress-auth.yaml
kubectl create -f ingress-auth.yaml
Ingress地址重寫
vim ingress-rewrite.yaml
kubectl apply -f ingress-rewrite.yaml
annotations參數