Kubernetes实现Ingress服务发布
Ingress原理在K8S中,暴露一个http服务一般有两种方式,一是通过Service暴露端口的方式让外部以及集群内部的node来访问到http相关页面内容,二是通过Ingress负载均衡的方式,将由外部网络域名访问通过Ingress的Nginx节点反代到后端指定Service下的Pod节点中的http服务。Service的模式结构如下: service ->...
Ingress原理
在K8S中,暴露一个http服务一般有两种方式,一是通过Service暴露端口的方式让外部以及集群内部的node来访问到http相关页面内容,二是通过Ingress负载均衡的方式,将由外部网络域名访问通过Ingress的Nginx节点反代到后端指定Service下的Pod节点中的http服务。
Service的模式结构如下:
service -> label selector -> pods
31217 -> app1 selector -> app1 1234
31218 -> app2 selector -> app2 3456
31218 -> app2 selector -> app2 4567
访问流程:
【PREROUTING链】 -m comment --comment "kubernetes service portals" -j KUBE-SERVICES 【KUBE-SERVICES链】 -d 10.16.0.10/32 -p udp -m comment --comment "kube-system/kube-dns:dns cluster IP" -m udp --dport 53 -j KUBE-SVC-TCOU7JCQXEZGVUNU 【KUBE-SVC-TCOU7JCQXEZGVUNU链】 -m comment --comment "kube-system/kube-dns:dns" -j KUBE-SEP-L5MHPWJPDKD7XIFG 【KUBE-SEP-L5MHPWJPDKD7XIFG链】 -p udp -m comment --comment "kube-system/kube-dns:dns" -m udp -j DNAT --to-destination 10.0.0.46:53
注意:目前有三种访问方式
①名称空间,通过kube-proxy
②iptables,不需要直接通过kube-proxy所以效率更高
③通过ipvs进行,效率是最高的
目前默认使用的是②
用户通过访问由service层生成的ClusterIP以及随机端口,访问到由该service指定的唯一标志label,指向内部挑选出来的Pod节点
向service ip 10.16.0.10:53发送udp请求,查找路由表,把数据包转发给网桥docker0,在数据包进入docker0网桥时,数据包经过
PREROUTING链,然后跳至KUBE-SERVICES链,KUBE-SERVICES链中一条匹配此数据包的规则,跳至KUBE-SVC-*链KUBE-SVC-*
不做任何操作,跳至KUBE-SEP-*链KUBE-SEP-*里对此数据包作了DNAT到10.0.0.46:53,其中10.0.0.46即为kube-dns的pod ip
查找与10.0.0.46匹配的路由,转发数据包到flannel.1,再交由flanneld进程进行封装转发出去。
Ingress模式结构如下:
ingress -> service -> label selector -> pods
www.app1.com -> app1-service -> app1 selector -> app1 1234
80 -> www.app2.com -> app2-service -> app2 selector -> app2 3456
www.app3.com -> app3-service -> app3 selector -> app3 4567
Ingress负载均衡由三种组件组成
①Nginx
②Ingress Controller
③Ingress
Nginx用于对外提供访问,内部记录了由Ingress Controller向kube-apiserver拿到的实时的service的endpoint到nginx配置文件中,
关联的Service下的Pod节点的IP,端口信息,让Nginx在访问域名时能够反代到指定Service下属的Pod节点上。Ingress则是用于在
Nginx中生成虚拟主机的配置端,如指定Service下属的Pod节点的upstream上下文等配置信息。
Ingress负载均衡实现
基于http:
部署Ingress基本环境
Master节点上配置
官方文档:https://github.com/kubernetes/ingress-nginx/tree/master/deploy
下载yaml文件
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/default-backend.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/tcp-services-configmap.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/udp-services-configmap.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/rbac.yaml | kubectl apply -f -
namespace.yaml:创建一个网络名称空间供Ingress使用
default-backend.yaml:创建一个在Nginx默认的虚拟主机配置。
tcp-services-configmap.yaml:使得Nginx能代理tcp,存放tcp四层负载均衡配置。
udp-services-configmap.yaml:使得Nginx能代理udp,存放udp四层负载均衡配置。
rbac.yaml:启用rbac角色,将角色绑定到指定的 ServiceAccount。
启用Ingress配置的yaml,default-backend.yaml需要更改镜像为国内镜像
# kubectl create -f namespace.yaml
# kubectl create -f default-backend.yaml
# kubectl create -f tcp-services-configmap.yaml
# kubectl create -f udp-services-configmap.yaml
# kubectl create -f rbac.yaml
创建nginx,Ingress-controller
编辑yaml文件
[root@node-1 ingress]# cat deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
annotations:
prometheus.io/port: '10254'
prometheus.io/scrape: 'true'
spec:
serviceAccountName: nginx-ingress-serviceaccount
hostNetwork: true
containers:
- name: nginx-ingress-controller
image: lizhenliang/nginx-ingress-controller:0.9.0
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
# - --annotations-prefix=nginx.ingress.kubernetes.io
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
启用nginx-ingress-controller:kubectl create -f deployment.yaml
查看:
创建ingress配置文件,用于定义Ingress中需要的关联Service,在这里我创建两个web服务,nginx与apache
# kubectl run --image=nginx:1.10 nginx --replicas=1 #定义deployment
# kubectl expose deployment nginx --port=80 #定义service,暴露端口
# kubectl run --image=httpd httpd --replicas=1
# kubectl expose deployment httpd --port=80
指定Ingress中需要关联的service
[root@node-1 ingress]# cat ingress-test.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: http-test
spec:
rules:
- host: nginx-wjq.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
- host: httpd-wjq.com
http:
paths:
- backend:
serviceName: httpd
servicePort: 80
#kubectl create -f ingress-test.yaml
这个时候查看nginx-ingress-controller的pod就会发现Ingress组件已经自动同步了相关的虚拟主机配置,ingress-controller去获取到了Service后端的Pod
一下是创建了nginx,httpd的service后,自动同步到nginx中的配置
同步了httpd-wjq.com域名的虚拟主机在nginx中
同步了nginx-wjq.com域名的虚拟主机在nginx中
查看ingress-controller在哪个pod主机上,就可以通过那个主机对外的物理IP访问到Nginx从而访问到对应域名service的Pod应用
可以配置ingress-controller在两个node物理主机上,修改replicas为2
[root@node-1 ingress]# kubectl edit deployment nginx-ingress-controller -n ingress-nginx -o yaml
浏览器访问
需要在本地物理机的host文件中添加域名解析
192.168.175.130 nginx-wjq.com
192.168.175.130 httpd-wjq.com
基于https:
创建密钥对:
使用cfssl创建私人CA
# cfssl print-defaults csr > ca-csr.json ##创建默认的csr json文件
修改ca-csr.json
[root@node-1 https]# cat ca-csr.json
{
"CN": "wujunqi", ##CA名称
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "shenzhen",
"ST": "shenzhen"
}
]
}
创建私人CA参数,有效期之类的,默认是一年,无需修改
# cfssl print-defaults config > ca-config.json
生成CA密钥对:
# cfssl gencert --initca ca-csr.json | cfssljson -bare ca
创建出ca.pem以及ca-key.pem
再根据两个密钥对创建出针对于域名的相关密钥证书
在创建一个证书请求文件,针对于某一访问域名
# cfssl print-defaults csr > server-csr.json
# cat server-csr.json
[root@node-1 https]# cat server-csr.json
{
"CN": "www.wujunqi.com",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "shenzhen",
"ST": "shenzhen"
}
]
}
由私人CA针对该证书请求文件创建对应的密钥对
# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem --config=ca-config.json --prefile=www server-csr.json | cfssljson -bare server
至此,需要的密钥创建完成
创建在集群中使用的TLS
# kubectl create secret tls wujunqi-https --key server-key.pem --cert server.pem
查看tls
# kubectl get secret
创建Ingress使用TLS进行访问,指定Service,让ingress-controller关联到Service后端的Pod
[root@node-1 ingress]# cat https.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: https-test
spec:
tls:
- hosts:
- www.wujunqi.com
secretName: wujunqi-https
rules:
- host: www.wujunqi.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
创建Ingress:
# kubectl create -f https.yaml
查看Ingress:
这时候就可以进行访问了,将物理主机的host文件中添加域名解析
192.168.175.130 www.wujunqi.com
转载于:https://blog.51cto.com/12480612/2298456
更多推荐
所有评论(0)