nodeport类型的服务通过每个节点上暴露的ip和端口路由到ClusterIP服务,所以可从外部访问。
在具有ClusterIP服务的前提下,集群的每个节点在同一个端口上公开同一个服务。用户可以在任何:NodePort 地址上访问服务。
将type设置为NodePort,Kubernetes主机会从配置的范围中(默认 30000~32767)分配一个端口;若不为nodePort指定端口,集群会选择一个随机的端口。
1、deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubia-deployment
labels:
app: kubia
namespace: ycloans-repayment-namespace
spec:
replicas: 3
selector:
matchLabels:
app: kubia
template:
metadata:
labels:
app: kubia
spec:
containers:
- name: kubia
image: yegang5211/kubia
ports:
- containerPort: 8080
# 对工作负载进行容器资源限制,容器对服务和节点性能影响非常大。
# 根据不同业务类型,并配合监控进行动态调配,以寻求一个合理值。
# 如果namespace设置配额将强制namespace中的所有工作负载在每个容器中都必须设置requests和limits, 否则Pod将无法进行调配。
# ------------------------------------------------
resources:
limits:
memory: 20Mi
cpu: 100m
requests: #Pod的memory requests为100 MiB且CPU requests为100 millicores
memory: 10Mi
cpu: 100m
2、Service,服务类型type定义为NodePort
apiVersion: v1
kind: Service
metadata:
name: kubia-service
namespace: ycloans-repayment-namespace
spec:
selector:
app: kubia
type: NodePort
ports:
- name: http
nodePort: 30226
port: 8080
protocol: TCP
targetPort: 8080
3、查看
kubectl get nodes -o wide -n ycloans-repayment-namespace
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
minikube Ready control-plane,master 11h v1.23.3 192.168.49.2 Ubuntu 20.04.2 LTS 4.18.0-348.7.1.el8_5.x86_64 docker://20.10.12
minikube kubectl -- get all -o wide -n ycloans-repayment-namespace
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/kubia-deployment-56fb7d8f76-b5l9x 1/1 Running 0 9h 172.17.0.8 minikube
pod/kubia-deployment-56fb7d8f76-m9mnl 1/1 Running 0 13m 172.17.0.7 minikube
pod/kubia-deployment-56fb7d8f76-p9fw6 1/1 Running 0 24m 172.17.0.6 minikube
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubia-service NodePort 10.106.110.217 8080:30226/TCP 10h app=kubia
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/kubia-deployment 3/3 3 3 10h kubia yegang5211/kubia app=kubia
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/kubia-deployment-56fb7d8f76 3 3 3 10h kubia yegang5211/kubia app=kubia,pod-template-hash=56fb7d8f76
replicaset.apps/kubia-deployment-f689966bb 0 0 0 10h kubia yegang5211/kubia app=kubia,pod-template-hash=f689966bb
1、pod公开了8080端口,可通过 kubectl exec
2、Service是NodePort类型的,所以提供一个了节点端口,这样通过30226就可以访问Service管辖的Pod了,例如进入容器内部:curl http://localhost:30226
3、多次请求分别调用了不同的Pod应用程序,说明已经实现了负载均衡,例如外部访问:curl http://192.168.49.2:30226
LoadBalancer只为服务提供一个负载均衡器(三四层),而Ingress只需要一个公网IP就能为许多服务提供访问(七层)。当客户端向Ingress发送Http请求时,Ingress会根据请求的主机名和路径决定请求转发到哪个服务上。
ingress controller:将新加入的ingress转化成nginx的配置文件并使之生效 ingress服务:nginx配置文件的抽象概念,每添加一个新的服务只需写一个新的yaml文件即可
1、ingress controller与kubernetes api交互,动态感知集群中ingress规则变化
2、按照自定义的规则:哪个域名对应哪个service,生成一段nginx配置
3、将配置写到运行着一个nginx、名为nginx-ingress-control的pod里,文件路径/etc/nginx.conf
4、然后reload一下使配置生效,以此达到域名分配置和动态更新
1、动态配置服务:如果按照传统方式, 当新增加一个服务时, 我们可能需要在流量入口加一个反向代理指向我们新的k8s服务. 而如果用了Ingress, 只需要配置好这个服务, 当服务启动时, 会自动注册到Ingress的中, 不需要而外的操作
2、减少不必要的端口暴露:除了Ingress自身服务可能需要映射出去, 其他服务都不要用NodePort方式
创建Deployment/Service/Ingress资源
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubia-deployment
labels:
app: kubia
namespace: ycloans-repayment-namespace
spec:
replicas: 2
selector:
matchLabels:
app: kubia
template:
metadata:
labels:
app: kubia
spec:
containers:
- name: kubia
image: yegang5211/kubia
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
# ------------------------------------------------
# 对工作负载进行容器资源限制,包括 limits 和 releases 至关重要, 器对服务和节点性能影响非常大。
# 如何设置这两个值,应根据不同业务类型,并配合如上所讲的监控进行动态调配,以寻求一个合理值。
# 设置名称空间配额将强制名称空间中的所有工作负载在每个容器中都必须设置requests和limits, 否则 Pod 将无法进行调配。
# ------------------------------------------------
resources:
limits:
memory: 20Mi
cpu: 100m
requests: # Pod 的 memory requests 为 100 MiB 且 CPU requests 为 100 millicores
memory: 10Mi
cpu: 100m
---
apiVersion: v1
kind: Service
metadata:
name: kubia-service
namespace: ycloans-repayment-namespace
spec:
selector:
app: kubia
type: NodePort
ports:
- name: http
port: 80 # 服务集群IP端口
protocol: TCP
targetPort: 8080 # 背后Pod的目标端口号
nodePort: 30226 # 通过集群节点的30226端口可以访问该服务
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kubia-ingress # 应用路由对应 Kubernetes Ingress对象,工作负载编辑器为其使用与 Deployment 相同的名字 web-nginx
namespace: ycloans-repayment-namespace
spec:
ingressClassName: my-ingress-controller # 通过指定ingressClassName ,为指定的服务创建Ingress
rules:
- host: kubia.freedom.com # 在云虚拟机上添加hosts配置,这样就可以通过 http://kubia.freedom.com:30222 访问后台的Pod了。
http:
paths:
- backend:
service:
name: kubia-service # 指定后端的 Service 为之前创建的 kubia-service
port:
number: 80
path: /kubia
pathType: Prefix
验证一下
curl http://kubia.freedom.com:30222/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
外部客户端如何通过负载均衡器和Ingress控制器访问到pod?
1、pod对外开放了8080端口,可通过 kubectl exec
curl http://localhost:8080
你已经命中了 kubia-deployment-56fb7d8f76-b5l9x [2022:05:02:07:15:28]
2、service资源创建后会分配一个虚拟地址:
kubectl get svc -n ycloans-repayment-namespace
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubia-service NodePort 10.105.172.105 80:30226/TCP 8m38s
这个10.105.172.105就是kubia-service在集群中的唯一访问地址。我们进入任意一个Pod,然后通过服务地址和端口号,就可以访问该集群下的Pod了。
curl http://podip:<端口号>
3、Service是NodePort类型的,此处公开的端口就是30226,这样通就可以访问Service纳管的Pod了。例如:
容器内:curl http://localhost:30226
节点内:curl http://节点ip:30226
4、对于集群外的客户端,首先对kubia.freedom.com 执行DNS查找,返回了Ingredd控制器的IP。客户端然后向Ingress控制器发送HTTP请求,并在报文的host指定kubia.freedom.com。控制器从该头部确定客户端尝试访问哪个服务,通过与该服务关联的Endpoint对象查看 Pod IP,并将客户端的请求转发给其中一个pod。