一、Service的概念
1、kubenrnets的service定义了这样一种抽象:一个pod的逻辑分组,一种可以访问他们的策略--通常别称为微服务。这一组pod能够被service访问到,通常是通过label selector
2、service能够提供负载负载均衡能力,但是在使用上有一下限制:
1)只能提供4层负载均衡能力,而没有七层功能,但是我们可以通过更多的匹配规则来请求转发,这点上4层负载均衡是不支持的
二、service的类型
1)ClusterIp:默认类型,自动分配一个仅cluster内部可以访问的虚拟IP地址
2)NodePort:在clusterip的基础上为Service在每台机器上绑定一个端口,这样就可以通过<NodeIp>:nodeport来访问服务
3)LoadBalancer:在nodeport的基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到<nodeip>:nodeport
4)ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用没有任何类型的代理被创建,这只有kubernetes1.7或者更高版本的kube-dns才支持
在kubenetes集群中,每个Node运行一个kube-proxy进程。kube-proxy负责service实现了一种Vip(虚拟ip)的形式。而不是ExternalName的形似。但并不是默认的运行模式。从k8s1.2起,默认就是iptables代理,在k8s-1.8-beta.0,添加了ipvs代理
在k8ds1.4版本中开始默认使用ipvs代理
在k8s1.0版本,service是四层(tcp/udp overip)概念。在k8s1.1版本,新增了ingressAPI(beta版),用来表示七层(http)服务
clusterip主要在每个node节点使用ipvs,将发向clusterip对应端口的数据,转发到kube-proxy中,然后kube-proxy自己内部有实现负载均衡的办法,并可以查询到这个service下对应pod的地址和端口,进而把数据转发给对应的pod的地址和端口
为了实现上图的功能,主要需要一下几个组件的协同工作:
1)apiserver用户通过kubectl命令向apiserver发送创建service的命令,apiserver接收到请求后将数据存储到etcd中
2)kube-proxy k8s的每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的ipvs规则中
3)ipvs使用nat将virtualip的流量转至endpoint中
有时不需要或者不想要负载均衡,以及单独的Serviceip。遇到这种情况,可以通过指定Clusterip(spec.clusterIP)的值为None,来创建headless server。这类Service并不会分配Clusterip,kubectl-proxy不会处理他们,而且平台也不会为他们进行父子均衡和路由
三、部署ingress-nginx(http)
namespace.yaml: 创建一个独立的命名空间 ingress-nginx
configmap.yaml: 提供configmap可以在线更行nginx的配置
default-backend.yaml: 提供一个缺省的后台错误页面 404
rbac.yaml:创建对应的role rolebinding 用于rbac
tcp-services-configmap.yaml: 修改L4负载均衡配置的configmap
udp-services-configmap.yaml: 修改L4负载均衡配置的configmap
with-rbac.yaml: 有应用rbac的nginx-ingress-controller组件
service-nodeport.yaml: 指定nginx的80端口和443端口
[root@k8s-master1 ingress-nginx]# cd /usr/local/ingress-nginx/
[root@k8s-master1 ingress-nginx]# kubectl create -f namespace.yaml
[root@k8s-master1 ingress-nginx]# kubectl delete -f ./
注:pod的标签需要和svc的选择器一致,ingress的servicename要和service的svc的名字一致
[root@k8s-master1 ~]# vim ingress.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
template:
metadata:
labels:
name : nginx
spec:
containers:
- name: nginx
image: nginx
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: www.benet.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
[root@k8s-master1 ~]# kubectl create -f ingress.yaml
[root@k8s-master1 ~]# kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
nginx-test www.benet.com 80 74m
[root@k8s-master1 /]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 16d
nginx-svc ClusterIP 10.0.0.210 <none> 80/TCP 5h8m
[root@k8s-master1 ~]# kubectl get pod,svc -o wide -n ingress-nginx
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/default-http-backend-6cdd6c64f8-6jj26 1/1 Running 0 11m 172.18.0.2 192.168.100.40 <none> <none>
pod/nginx-ingress-controller-589b9b8c9d-8cl57 1/1 Running 0 11m 172.18.0.4 192.168.100.40 <none> <none>
[root@lb1 /]# vim /var/named/benet.com.zone
www A 192.168.100.40
[root@k8s-master1 ~]# kubectl get svc -o wide -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
default-http-backend ClusterIP 10.0.0.218 <none> 80/TCP 13m app=default-http-backend
ingress-nginx NodePort 10.0.0.21 <none> 80:45473/TCP,443:49863/TCP 13m app=ingress-nginx
http://www.benet.com:45473/
四、部署ingress-nginx(https)
[root@k8s-master1 https]# yum -y install openssl-1.0.2k-8.el7.x86_64
[root@k8s-master1 https]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2018 -keyout nginx.key -out nginx.crt -subj "/CN=nginxsvc/0=nginxsvc"
[root@k8s-master1 https]# kubectl create secret tls nginx-secret --key nginx.key --cert nginx.crt
[root@k8s-master1 https]# vim nginx.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-https
spec:
tls:
- host:
secretName: nginx-secret
rules:
- host: nginx.benet.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
[root@k8s-master1 https]# kubectl apply -f nginx.yaml
[root@k8s-master1 https]# kubectl get svc -o wide -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
default-http-backend ClusterIP 10.0.0.218 <none> 80/TCP 4h10m app=default-http-backend
ingress-nginx NodePort 10.0.0.21 <none> 80:45473/TCP,443:49863/TCP 4h10m app=ingress-nginx
https://nginx.benet.com:49863/
五、部署ingress-nginx(BasicAuth)
[root@k8s-master1 https]# yum -y install httpd-tools-2.4.6-67.el7.centos.x86_64
[root@k8s-master1 https]# htpasswd -c auth bob
[root@k8s-master1 https]# kubectl create secret generic basic-auth --from-file=auth
[root@k8s-master1 https]# vim basicauth.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx-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 !!!'
spec:
rules:
- host: auth.benet.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
[root@k8s-master1 https]# kubectl create -f basicauth.yaml
http://auth.benet.com:45473/
六、部署ingress-nginx(rewrite)
名称 描述 值
nginx.ingress.kubernetes.io/rewrite-target 必须重定向流量的目标URI 串
nginx.ingress.kubernetes.io/ssl-redirect 指示位置部分是否仅可访问SSL(当Ingress包含证书时布redirect默认为True) 布尔
nginx.ingress.kubernetes.io/force-ssl-redirect 即使Ingress未启用TLS,也强制重定向到HTTPS 布尔
nginx.ingress.kubernetes.io/app-root 定义Controller必须重定向的应用程序根,如果它在/上root下文中 串
nginx.ingress.kubernetes.io/use-regex 指示Ingress上定义的路径是否使用正则表达式 布尔
[root@k8s-master1 https]# vim rewrite.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx-rewrite
annotations:
nginx.ingress.kubernetes.io/rewrite-target: http://auth.benet.com:45473
spec:
rules:
- host: aaa.benet.com
http:
paths:
- path: /
backend:
serviceName: niiginx-svc #随便写
servicePort: 80
[root@k8s-master1 https]# kubectl create -f rewrite.yam
http://aaa.benet.com:45473/