K8S服务暴露介绍
首先简要了解一下K8S中提供的暴露服务的三种方式
- LoadBlancer
该方式是kubernetes深度结合云平台的一个组件。当集群运行在云厂商提供的云平台上时,常用该方式对外暴露服务(收费)。
- NodePort
通过在集群的每个NodePort上暴露端口,访问指定端口即可访问到指定服务。一般使用这种方式时,都是选择固定端口,但服务一多就容易产生冲突或者不方便管理的情况。
-
Ingress(方式)
-
Ingress Controller
Ingress Controller 实质上可以理解为是个监视器,Ingress Controller 通过不断地跟 kubernetes API 打交道,实时的感知后端 service、pod 等变化,比如新增和减少 pod,service 增加与减少等;当得到这些变化信息后,Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,达到服务发现的作用
-
Ingress(资源清单)
Ingress 简单理解就是个规则定义;比如说某个域名对应某个 service,即当某个域名的请求进来时转发给某个 service;这个规则将与 Ingress Controller 结合,然后 Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡
服务访问流程图如下(具体查看官方文档,本文底下有链接):
使用
安装步骤大概分为以下:
- 安装Ingress Controller Pod
- 部署服务并对外暴露
- 部署ingress
安装Ingress Controller Pod
注意:
-
国内无法下载官方Ingress Controller部署文件,且无法通过helm进行下载,所以下载三方部署文件。
-
其次容器镜像也无法下载,需要使用三方镜像源。
- 默认下载的deploy部署文件是LoadBlancer进行服务暴露(需要云厂商支持),所以需要更改配置文件使用NodePort方式。
下载deploy文件
# 下载对应的yml
$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml
# 替换镜像地址(国内无法下载)
$ sed -i 's@k8s.gcr.io/ingress-nginx/controller:v1.1.1\(.*\)@duangx/ingress-nginx-controller:v1.1.@' deploy.yaml
$ sed -i 's@k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1\(.*\)$@duangx/kube-webhook-certgen:v1.1.1@' deploy.yaml
# 修改yml文件名
$ mv deploy.yaml ingress-nginx.yaml
修改deploy文件
配置ingress controller以NodePort的形式暴露,使其能通过域名+端口访问,再通过指定后缀名的方式访问到具体服务。例如http://test.wlhiot.com:30080/test,访问http://test.wlhiot.com:30080其实是访问ingress controller。
$ vim ingress-nginx.yaml # 搜索LoadBalancer的资源清单,将其注释。替换成NodePort
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
appProtocol: http
nodePort: 30080
- name: https
port: 443
protocol: TCP
targetPort: https
appProtocol: https
nodePort: 30443
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
部署
$ kubectl apply -f ingress-nginx.yaml # 运行过程中出现报错可查看是否是因为镜像问题造成
$ kubectl get all -n ingress-nginx # 查看部署情况
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create--1-v4hbn 0/1 Completed 0 18h
pod/ingress-nginx-admission-patch--1-xkxbz 0/1 Completed 2 18h
pod/ingress-nginx-controller-69d84f9c5f-dl28r 1/1 Running 0 18h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller NodePort 10.254.21.242 <none> 80:30080/TCP,443:30443/TCP 18h
service/ingress-nginx-controller-admission ClusterIP 10.254.202.85 <none> 443/TCP 18h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 18h
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-69d84f9c5f 1 1 1 18h
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 17s 18h
job.batch/ingress-nginx-admission-patch 1/1 34s 18h
$ kubectl delete -f ingress-nginx.yaml # 卸载
使用NGINX测试
$ kubectl create ns test # 创建命名空间
$ kubectl create deployment test-ingress --image=nginx -n test # 在test命名空间创建nginx
$ kubectl expose deployment test-ingress --port=80 --target-port=80 --type=NodePort -n test # 暴漏端口
$ kubectl apply -f test-ingress.yml
$ kubectl get pod -o wide -n test
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-ingress-5c4bb6ff8-t4ml5 1/1 Running 0 21h 10.20.7.215 k8s-node07 <none> <none>
$ kubectl exec -it -n test test-ingress-5c4bb6ff8-t4ml5 -- /bin/bash
root@test-ingress-5c4bb6ff8-t4ml5:/# echo "test-nginx" > /usr/share/nginx/html/index.html
$ kubectl get svc -o wide -n test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
test-ingress NodePort 10.254.147.162 <none> 80:32117/TCP 21h app=test-ingress
$ curl 192.168.254.23:32117 # 192.168.254.23为master地址
test-nginx
修改本地解析
解析这块有点知识点,虽然test.wlhiot.com在公网上确实是有这么一个域名且能访问。但是DNS的解析顺序是先从本地查找,若查找不到再通过域名服务器/etc/resolv.conf进行查找。
所以当在本机添加test.wlhiot.com的条目后,再通过该域名访问它优先解析成192.168.254.23。
关于DNS解析可查看http://www.dhr2333.cn/article/2022/7/1/38.html
C:\Windows\System32\drivers\etc/hosts # Windows,因为我是在windows中进行访问服务
/etc/hosts # Linux
192.168.254.23 ebox.test.wlhiot.com # [master的IP地址] [自定义域名]
部署Ingress
$ vim test-ingress.yml # 创建ingress服务
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
namespace: test
spec:
ingressClassName: nginx
rules:
- host: ebox.test.wlhiot.com # 自定义域名
http:
paths:
- pathType: Prefix
path: / # 后缀
backend:
service:
name: test-ingress # 上面创建的服务名 svc
port:
number: 80
$ curl ebox.test.wlhiot.com:30080 # [自定义域名]:[ingress-controller的NodePort]/[后缀]
实现效果
参考资料:
- 官方文档:https://kubernetes.io/zh-cn/docs/concepts/overview/what-is-kubernetes/
- ingress介绍:http://t.zoukankan.com/wjoyxt-p-10025214.html
- ingress-nginx-controller安装:https://blog.csdn.net/Hello_worId/article/details/123602379