Service
K8s 中 service定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略——通常称为微服务。这一组 Pod 能够被 Service
访问到,通常是通过 Label Selector
SVC 原理:
Service能够提供负载均衡的能力,但是在使用上有以下限制:
只提供4层负载均衡能力,而没有7层功能,但有时候我们需要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的
Service类型
Service在k8s中有以下4中类型:
- ClusterIp:默认类型,自动分屏一个仅Cluster内部可以访问的虚拟IP;
- NodePort:在ClusterIP基础上为service在每台机器上绑定一个端口,这样就可以通过
NodeIP:NodePort
来访问服务; - LoadBalancer:在NodePort的基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到
NodeIP:NodePort
; - ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,k8s版本要求 ≥1.7。
SVC依赖组件:
VIP 和 Service 代理
为什么不用Round-Robin DNS负载均衡?
答:因为DNS缓存,无法及时更新。
代理模式的分类
-
userSpace 代理模式
-
IPtables 代理模式
-
ipvs 代理模式
- rr:轮询调度
- lc:最小连接数
- dh:目标哈希
- sh:源哈希
- sed:最短期望延迟
- nq:不排队调度
注意:ipvs模式嘉定在运行 kube-proxy 之前在节点上都已经安装了 IPVS 内核模块。当kube-proxy以ipvs代理模式启动时,kube-proxy将验证节点上是否安装了 IPVS 模块,如果未安装,则kube-proxy将回退到iptables代理模式。
ClusterIP
Headless Service
# 查询
$ dig -t A SVC_Name.default.svc.cluster.local. @PodIp
NodePort
nodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由kube-proxy进一步分发给对应的pod。
# 查询
$ iptables -t nat -nvL
KUBE-NODEPORTS
LoadBalancer
loadBalancer 和 nodePort 其实是同一种方式。区别自安于loadBalancer比NodePort多了一步,就是可以调用cloud provider去创建LB来向节点导流。
需要额外付费,不推荐!
ExternalName
Ingress
github地址:https://github.com/kubernetes/ingress-nginx
官方网站:https://kubernetes.github.io/ingress-nginx/
访问方式:
原理:
部署 Ingress-Nginx
访问官网——Deployment。
# 下载 mandatory.yaml
$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
# 查看镜像地址
$ cat mandatory.yaml |grep image
# 为了加速部署:先下载镜像到本地
$ docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
# 上传至本地镜像仓库
$ docker tag quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 hub.adaixuezhang.cn/library/nginx-ingress-controller:v1
$ docker push hub.adaixuezhang.cn/library/nginx-ingress-controller:v1
# 修改mandatory.yaml中镜像地址为本地镜像
$ vim mandatory.yaml
image: hub.adaixuezhang.cn/library/nginx-ingress-controller:v1
# 部署 ingress-nginx pod
$ kubectl apply -f mandatory.yaml
$ kubectl -n ingress-nginx get pod
# 部署 ingress-nginx Service
$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
$ kubectl apply -f service-nodeport.yaml
$ kubectl -n ingress-nginx get svc
Ingress HTTP 代理访问
deployment、Service、Ingress Yaml文件。
注意:Deployment中apiVersion从k8s 1.16开始统一使用 apps/v1
,参考 。
ingress.http.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: hub.adaixuezhang.cn/library/myapp:v1
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: test.adaixuezhang.cn
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
Tips:
-
apps/v1 版 Deployment.spec.template.spec:
- 不支持 imagePullPolicy
- 必须包含字段:selector
-
Ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
创建:
$ kubectl apply -f ingress.http.yaml
Nginx 进行 https配置
创建证书:
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
# 如果使用付费证书,在此直接将tls.key、tls.crt 换为自己的证书
$ 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:
- test.adaixuezhang.cn
secretName: tls-secret
rules:
- hosts: test.adaixuezhang.cn
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
Nginx 进行 BasicAuth
基于httpd认证:
$ yum install -y httpd
$ htpasswd -c auth username
$ kubectl create secret generic basic-auth --from-file=auth
yaml:
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:
- hosts: test.adaixuezhang.cn
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
Nginx 进行重写
配置位置:annotations
字段说明:
名称 | 描述 | 值 |
---|---|---|
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上定义的路径是否使用正则表达式 | 布尔 |
eg:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: http://test01.adaixuezhang.cn:32432/hostname.html
spec:
rules:
- hosts: test02.adaixuezhang.cn
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80