k8s svc详解
一、k8s svc详解[*]先容了pod之间怎么通讯的,可以通过ClusterIP,dns,pod ip直接通讯
[*]dns比力风趣 web-svc.default.svc.cluster.local
[*]pod对外提供服务就必要NodePort,LoadBalance
[*]如果还对七层有要求的话,就必要ingress
1、为什么必要这个svc呢?
[*]核心缘故起因
[*]pod的ip不固定,pod重启,重新调理后ip会厘革
[*]如果没有svc,就必要直接访问pod的ip,但是pod的ip一但厘革的,全部依赖这个设置的都必要重新设置,在生产情况中是不可继续的
[*]办理了核心的题目
[*]稳固的网络入口,提供了一个假造的ip(clusterip)和dns名称,就是不必要管后端pod的厘革了
[*]实现了负载均衡,svc主动的将流量转发到后端的pod,无需设置额外的负载均衡器
[*]服务发现,集群内的其他组件可以通过dns直接访问
1、svc的设置
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDI0LmNuYmxvZ3MuY29tL2Jsb2cvMzMzMjMyMi8yMDI2MDMvMzMzMjMyMi0yMDI2MDMzMTE4MjgwMTA3OS0xNTc4MjY1OTQ3LnBuZw==
[*]也是通过标签关联一组pod
创建一个nginx,svc
# kubectl create deployment web1 --image=nginx --dry-run=client -o yaml > web1.yml
# 查看pod的ip地址
# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web1-8fd498dd-klfrx 1/1 Running 0 6m17s 10.246.73.146 node <none> <none>
web1-8fd498dd-nch98 1/1 Running 0 6m17s 10.244.59.197 master02 <none> <none>
# kubectl expose deployment web1 --port=80 --target-port=80 --type=ClusterIP
service/web1 exposed
# kubectl describe svc web1
Name: web1
Namespace: default
Labels: app=web1# 选择的标签
Annotations: <none>
Selector: app=web1
Type: ClusterIP
IP Family Policy:SingleStack
IP Families: IPv4
IP: 10.110.146.0
IPs: 10.110.146.0
Port: <unset>80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.59.197:80,10.246.73.146:80# 关联上带app=web1的pod了
Session Affinity:None
Events: <none>
# svc下面还有一个endpoints关联pod
# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 192.168.50.20:6443,192.168.50.21:6443 7d5h
web1 10.244.59.197:80,10.246.73.146:80 2m4s
# pod被删除了,这个ip也会变化,也会被endpoints重新记录新的pod的ip
# kubectl delete pod web1-8fd498dd-klfrx
pod "web1-8fd498dd-klfrx" deleted
# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 192.168.50.20:6443,192.168.50.21:6443 7d5h
web1 10.244.59.197:80,10.246.73.145:80 3m28s访问
# 集群内部访问clusterip 就能访问到pod提供的业务了,发现是轮询的,实现了负载均衡的效果
# curl 10.110.146.0
456
# curl 10.110.146.0
123
[*]集群外貌是不能通过clusterip访问的,必要借助其他的nodeport等等
2、kube-proxy详解
1、kube-proxy是什么
[*]在每一个节点上必须跑的一个署理步调,专门负责实现svc的网络转发本领(集群内部的调理员+规则设置员)
svc是一个设置,不会自己转发流量,kube-proxy才是干活的人
[*]监听svc和endpoint的厘革,知道哪些svc对应哪些pod的ip
[*]在节点上设置网络规则,ipvs和iptables规则
[*]实现服务访问和负载均衡的,当访问svc ip时,将流量转发到后端的pod上
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDI0LmNuYmxvZ3MuY29tL2Jsb2cvMzMzMjMyMi8yMDI2MDQvMzMzMjMyMi0yMDI2MDQwMTA5NDUxMjU2MS0xNzM4NjI3OTYwLnBuZw==
[*]修改kube-proxy的模式为iptables
有一个存储kube-proxy的设置文件为configmap,修改后,删除全部pod,设置就会更新过来
# kubectl edit cm -n kube-system kube-proxy
mode: iptables
# 删除kube-proxy关联的pod
# kubectl delete pods -n kube-system -l k8s-app=kube-proxy
pod "kube-proxy-95mlq" deleted
pod "kube-proxy-svx52" deleted
pod "kube-proxy-tzts4" deleted
# 会重新创建出来,配置也被更新了
# kubectl get pod -n kube-system -l k8s-app=kube-proxy
NAME READY STATUS RESTARTS AGE
kube-proxy-bs4rg 1/1 Running 0 5s
kube-proxy-kzknc 1/1 Running 0 4s
kube-proxy-zq975 1/1 Running 0 4s
# 查看日志,发现使用了iptables规则
# kubectl logs -n kube-system kube-proxy-bs4rg
I0401 07:39:33.514227 1 node.go:163] Successfully retrieved node IP: 192.168.50.22
I0401 07:39:33.514303 1 server_others.go:138] "Detected node IP" address="192.168.50.22"
I0401 07:39:33.532944 1 server_others.go:206] "Using iptables Proxier"
# 查看iptables规则
# iptables -t nat -L -n | grep 10.110.237.145
KUBE-SVC-CWMY3MEVXVILAFTHtcp--0.0.0.0/0 10.110.237.145 /* default/v1 cluster IP */ tcp dpt:80
KUBE-MARK-MASQtcp-- !10.240.0.0/12 10.110.237.145 /* default/v1 cluster IP */ tcp dpt:802、kube-proxy和svc的区别
[*]关系是,svc是访问的入口,kube-proxy是实现这个入口转发本领的节点署理进程
[*]svc是提供稳固的假造ip,端口和负载均衡入口,通过标签选择一组pod,自己是不处置惩罚流量的
[*]kube-proxy每个节点上运行的进程,监听svc和endpoints厘革,在节点上设置ipvs/iptables规则,实现流量转发和负载均衡,是svc的实验者
[*]svc和kube-proxy共同利用
[*]svc界说访问的计谋,端口,稳固的入口
[*]kube-proxy,实现这些svc界说的计谋,实现流量转发的本领
[*]没有svc,不知道怎么访问
[*]没有kube-proxy,有svc,但是没有现实的流量转发本领,也访问不到
3、服务发现
[*]就是pod之间通过这些来举行通讯
[*]服务发现流程,就是pod访问别的一个pod的场景
[*]容器内部举行dns剖析,指向了core-dns
[*]core-dns查询当地的缓存,找到对应的svc
[*]得到应用的ip
[*]发送哀求到该ip
[*]kube-proxy的iptables/ipvs规则
[*]转发到后端的pod
1、clusterip
[*]是svc的默认范例,为svc分配一个集群内部专用的假造ip,只能在集群内部举行访问
[*]这个ip网段,在创建k8s集群的时间,可以指定的,差别的网段,底层是买通的
[*]是一个假造网卡,没有实体的网卡绑定
[*]仅存在iptables/ipvs规则中,通过kube-proxy实现流量的转发
[*]等完成后,将kube-proxy模式改为iptables,就能看到iptables规则了
继续看我们上面完成的实验
# type的类型是clusterip
# 虚拟ip为10.110.146.0
# 监听的端口是80的 这个ip和端口都是虚拟出来的
# kubectl get svc web1
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web1 ClusterIP 10.110.146.0 <none> 80/TCP 17m
# 访问这个虚拟ip就能访问pod了
# 查看ipvs规则
# ipvsadm -ln
# 关联的pod的ip
TCP10.110.146.0:80 rr
-> 10.244.59.197:80 Masq 1 0 0
-> 10.246.73.145:80 Masq 1 0 02、dns方式
[*]集群内里有core-dns这个pod,这个就是集群pod内部的dns服务器
[*]CoreDNS 的 DNS 纪录完全泉源于 Service(以及 Pod、Endpoint 等资源):
[*]为什么必要呢?
[*]svc的假造ip难记
[*]一个服务多个端口的时间难以区分
[*]跨ns的时间调用困难,必要知道对方的clusterip
[*]可以直接通过域名的方式来举行访问,差别名称空间下面也可以举行访问
[*]就不必要关系clusterip的厘革,由于删除clusterip的话,ip地点会变动
[*]core-dns为每一个创建的svc主动天生一个唯一的域名,也就是dns纪录,每一个svc都在上面举行注册了,一个域名剖析器
[*]域名的格式为 svcname.nsname.svc.cluster.local
[*]服务名称.名称空间.范例.集群域
[*]kube-dns已经没有被维护了,大多数利用的是core-dns
1、检察集群dns
检察集群dns
# 查看集群dns 10.96.0.10
# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 7d5h
# pod里面的dns也是10.96.0.10
root@web1-8fd498dd-nch98:/# cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
# 查看core-dns,集群现在就是这2个pod在提供dns服务
# kubectl get pod -n kube-system-o wide | grep dns
coredns-665d974787-46d59 1/1 Running 11 7d6h
coredns-665d974787-s564k 1/1 Running 11 7d6h
[*]上面不是说kube-dns没有被维护了,为什么照旧利用kube-dns呢?
[*]转发到kube-dns,末了照旧转发到core-dns的pod了
[*]照旧在利用core-dns
# 查看kube-dns的详细信息
# kubectl describe svc -n kube-system kube-dns| grep -i endpoints
Endpoints: 10.255.112.164:53,10.255.112.165:53
Endpoints: 10.255.112.164:53,10.255.112.165:53
Endpoints: 10.255.112.164:9153,10.255.112.165:9153
# 发现转发到后端的pod是core-dns
# kubectl get pod -n kube-system-o wide | grep dns
coredns-665d974787-46d59 1/1 Running 11 7d6h 10.255.112.164 master01 <none> <none>
coredns-665d974787-s564k 1/1 Running 11 7d6h 10.255.112.165 master01 <none> <none>2、pod之间通过域名来访问
[*]域名剖析同一个名称空间下
# 我们上面创建了一个web1 svc,关联了2个pod
# 因此创建一个临时容器测试一下
# kubectl run b1 --image=busybox --rm -ti -- sh
/ # wget web1# 直接访问web1服务,不需要知道web1的svc的ip地址,因为有dns记录,会自动的解析
Connecting to web1 (10.110.146.0:80)
saving to 'index.html'
index.html 100% |**********************************| 40:00:00 ETA
'index.html' saved
/ # cat index.html
123
# busybox会自己去找dns,然后解析这个web1的ip,从而实现访问,就是在访问clusterip,从而获取提供的服务
[*]域名剖析不在同一个名称空间下面
# 在test空间下,创建一个pod,测试能不能解析default下的svc
# kubectl run b1 --image=busybox --namespace test--rm -ti -- sh
# 直接解析svc,没有成功
/ # wget web1
wget: bad address 'web1'
# 添加一个defaul空间,就能解析成功
/ # wget web1.default
Connecting to web1.default (10.110.146.0:80)
saving to 'index.html'
index.html 100% |**********************************| 40:00:00 ETA
'index.html' saved
# 这个是dns的地址
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search test.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
[*]尚有一个题目,pod可以访问差别空间下的pod,直接利用ip访问
/ # ping 10.246.73.145
PING 10.246.73.145 (10.246.73.145): 56 data bytes
64 bytes from 10.246.73.145: seq=0 ttl=63 time=0.093 ms
[*]这是是由于不必要dns剖析,直接走的calico网络,pod网络是扁平化的
[*]无论pod在哪一个ns,ip段都是互通的
[*]没有ns的网络隔离(除非利用网络计谋,上一篇博客讲了的)
[*]coredns的设置
# kubectl get configmaps -n kube-system coredns -o yaml
apiVersion: v1
data:
Corefile: |
.:53 {# 监听所有dns的请求
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure # 允许pod ip解析pod的名称
fallthrough in-addr.arpa ip6.arpa
ttl 30# dns记录缓存30s
}
prometheus :9153
forward . /etc/resolv.conf {# 非集群域名(baidu.com0)转发到上游的dns,也就是宿主机配置的dns
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
kind: ConfigMap
metadata:
creationTimestamp: "2026-03-24T04:41:18Z"
name: coredns
namespace: kube-system
resourceVersion: "302"
uid: 9281803b-4bfe-4a36-8796-ef60d870e8013、无头的clusterip
[*]也就是svc没有clusterip的ip地点
[*]实用的场景,三个pod,一个主mysql,2个都是备mysql,只要主继续哀求,由于clusterip是轮询的,以是不可,必要headless clsuterip
[*]连合这个dns,statefulset(有序的) 常连合一起利用,为每一个pod分配一个唯一的域名,如许就能指定访问一个pod,不会轮询了
[*]在这种情况下可以通过访问pod的域名来实现访问,其他情况下都是通过访问svc实现对pod的访问
# cat ds.yml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
clusterIP: None # 为none就是没有clusterip
selector:
app: d1
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: StatefulSet# sts的控制器
metadata:
creationTimestamp: null
labels:
app: d1
name: d1
spec:
replicas: 2
selector:
matchLabels:
app: d1
serviceName: "nginx"# 指定服务,这个服务关联一组pod,dns为每一个这样的pod分配唯一的域名,因为没有clusterip,所以这样
template:
metadata:
creationTimestamp: null
labels:
app: d1
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
# 创建一个测试容器
# kubectl run b1 --image=busybox --rm -ti -- sh
# 解析这个nginx svc 返回的是一组pod的域名和ip
/ # nslookup nginx
Server: 10.96.0.10
Address: 10.96.0.10:53
** server can't find nginx.cluster.local: NXDOMAIN
Name: nginx.default.svc.cluster.local
Address: 10.246.73.150
Name: nginx.default.svc.cluster.local
Address: 10.244.59.198
# 可以单独访问指定的pod
/ # ping d1-0.nginx.default.svc.cluster.local
PING d1-0.nginx.default.svc.cluster.local (10.246.73.150): 56 data bytes
64 bytes from 10.246.73.150: seq=0 ttl=63 time=0.054 ms4、core-dns和svc的关系
[*]图自己修改一劣等一下
[*]就是在集群中创建一个svc,kueb-proxy会天生ipvs规则大概iptables规则
[*]然后这个core-dns监听svc,会纪录在内里,并有dns纪录
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDI0LmNuYmxvZ3MuY29tL2Jsb2cvMzMzMjMyMi8yMDI2MDMvMzMzMjMyMi0yMDI2MDMzMTEzMTQwNDk2Ny0xNzI5MDI4NzMyLnBuZw==
[*]pod通过域名访问
[*]起首找自己的dns,也就是core-dns
[*]通过这个dns找到了这个域名对应的ip
[*]然后访问这个pod即可,内核照旧kube-proxy实现的
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDI0LmNuYmxvZ3MuY29tL2Jsb2cvMzMzMjMyMi8yMDI2MDMvMzMzMjMyMi0yMDI2MDMzMTEzMjIwMzQ3OC0xMDk1OTkwNzY1LnBuZw==
Service 提供稳定的访问入口(IP + 端口) 餐厅的实体店面
CoreDNS 提供服务名到 IP 的映射 餐厅的地图导航
kube-proxy 实现流量的负载均衡和转发 餐厅的服务员和调度3、变量的方式
4、NodePort
[*]之前的clusterip是集群内部举行访问的,集群外貌就不可了
[*]nodeport就是做一个端口映射的,访问物理主机+映射到主机的端口就能访问到集群内部的服务了
[*]创建出来后,每个物理主机都有这个端口,因此每一个主机+映射的端口就能访问
[*]默认天生一个3w以上的端口
[*]寻常的svc利用ipvs全节点转发,kube-proxy在全部节点都创建了ipvs转发规则
[*]为什么全部节点都能访问呢?
[*]缘故起因就是这个externalTrafficPolicy: Cluster这个参数, 全部节点都能转发
[*]这个是控制外部流量怎么访问集群
[*]尚有一个local就是只有当地有pod,才气被访问,背面ingress 会详细讲授的,就是为什么其他节点没有ingress pod就访问不到了?
[*]核心就是添加一个ipvs规则大概iptables规则
[*]nodeport访问流程
[*]先访问主机ip+端口
[*]转发到svc的ip+端口
[*]kube-proxy通过ipvs规则,转发到后端的关联的pod,从而实现访问
kubectl expose deployment web1 --name nginx-svc --port 80 --target-port 80 --type NodePort
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d6h
nginx-svc NodePort 10.109.165.192 <none> 80:30108/TCP 49s
web1 ClusterIP 10.110.146.0 <none> 80/TCP 93m
# 所有节点都有这个映射的端口
# netstat -pant|grep 30108
tcp 0 0 0.0.0.0:30108 0.0.0.0:* LISTEN 2315/kube-proxy
curl 192.168.50.20:30108
curl 192.168.50.21:30108
curl 192.168.50.22:30108
# 查看ipvs信息
ipvsadm -ln
TCP10.255.112.128:30108 rr
-> 10.244.59.199:80 Masq 1 0 0
-> 10.246.73.152:80 Masq 1 0 0 5、ingress(最常用的)
[*]上面的几种方式都是四层,基于ip和端口的
[*]ingress是基于七层的
[*]让用户通过一个域名/ip,访问集群内里多个差别的svc
[*]是一个七层的路由,可以或许根据域名和url路径转发
1、核心组件
[*]ingress资源
[*]访问a.com 转发给svc1
[*]访问b.com/api 转发到svc2
[*]ingress controller
[*]是真正干活的步调(nginx-ingress)
[*]监听全部ingress规则(自己编写的ingress规则)
[*]主动天生设置并见效,就是天生nginx.conf文件,翻译成这个
[*]吸收外部真实流量
2、工作流程
[*]用于输入域名,访问ingress的外部ip/域名
[*]流量到达ingress-controller这个pod
[*]默认监听是80/443
[*]一样寻常是nodeport
[*]根据ingress规则匹配
[*]域名是谁
[*]url路径是谁
[*]转发到哪一个svc
[*]转发到svc和关联的pod上
[*]末了照旧靠的ipvs转发到对应的pod
3、安装ingress
[*]https://github.com/kubernetes/ingress-nginx
[*]https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.6.4/deploy/static/provider/cloud/deploy.yaml
[*]上面这个文件,路径在deploy/static/下面
# 将里面三个镜像可以改成华为的
kubectl apply -f ingress.yml
# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-dqrkj 0/1 Completed 0 65s
ingress-nginx-admission-patch-pjbf5 0/1 Completed 0 65s
ingress-nginx-controller-8478d55789-f4444 1/1 Running 0 65s
# 查看svc
# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.103.125.75 <pending> 80:32162/TCP,443:30717/TCP 70s
ingress-nginx-controller-admission ClusterIP 10.111.38.80 <none> 443/TCP 70s
# 将这个ingress-nginx-controller改成nodeport
# 直接修改配置文件即可
# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.103.125.75 <none> 80:32162/TCP,443:30717/TCP 3m46s
ingress-nginx-controller-admission ClusterIP 10.111.38.80 <none> 443/TCP 3m46s4、界说ingress规则
[*]实验图
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDI0LmNuYmxvZ3MuY29tL2Jsb2cvMzMzMjMyMi8yMDI2MDMvMzMzMjMyMi0yMDI2MDMzMTIyMTIxNTYzOC0xNDU5NDIzNjE2LnBuZw==
[*]ingress实验流程就是
[*]访问节点ip+32162,这个svc,根据这个ipvs规则(创建了一个svc,kube-proxy会主动创建一个ipvs规则),转发到ingress-nginx-controller这个pod
[*]根据这ingress这个规则,转发到提供服务的svc
[*]根据这个ipvs规则转发到后端的pod
# class为nginx
# kubectl get ingressclasses.networking.k8s.io
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 11m
# cat in.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
spec:
ingressClassName: nginx # 需要定义class规则,对一组ingress
rules:
- host: www.meme1.com
http:
paths:
- path: / # 直接匹配根路径
pathType: Prefix# 前缀匹配
backend:
service:
name: svcn1 # 转发到svcn1的80端口,从而转发到后端的pod
port:
number: 80
- host: www.meme2.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svcn2
port:
number: 80
# 创建svcn1和svcn2
# cat web1.yml
apiVersion: v1
kind: Service
metadata:
name: svcn1
spec:
type: NodePort
selector:
app: svcn1
ports:
- port: 80
targetPort: 80
nodePort: 32222
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: svcn1
name: web1
spec:
replicas: 1
selector:
matchLabels:
app: svcn1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: svcn1
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
resources: {}
# kubectl get pod
NAME READY STATUS RESTARTS AGE
web1-5b7f5548b-vx9vt 1/1 Running 0 23m
web2-d86c55fbf-2mm2b 1/1 Running 0 21m
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d8h
svcn1 NodePort 10.101.227.56 <none> 80:32222/TCP 23m
svcn2 NodePort 10.108.20.222 <none> 80:32223/TCP 22m# 部署ingress规则
# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
my-app-ingress nginx www.meme1.com,www.meme2.com 10.103.125.75 80 21m
# 已经做好了映射了
# kubectl describe ingress
Name: my-app-ingress
Labels: <none>
Namespace: default
Address: 10.103.125.75
Default backend:default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host PathBackends
---- ------------
www.meme1.com
/ svcn1:80 (10.246.73.160:80)
www.meme2.com
/ svcn2:80 (10.246.73.159:80)
Annotations: <none>
Events:
Type ReasonAge From Message
---- ---------- ---- -------
NormalSync 21m (x2 over 21m)nginx-ingress-controllerScheduled for sync5、客户端欣赏器测试和细节
# curl -H "Host: www.meme1.com" http://192.168.50.22:32162
meme1.com
# curl -H "Host: www.meme2.com" http://192.168.50.22:32162
meme2
# 只能访问22才能访问到,原因就是20,21节点上面没有这个ingress-nginx这个pod
# 访问20:32162 没有这个pod,进不去,也没有这ipvs
# 21一样
# 因此将这个副本数变成3个即可
# kubectl scale deployment ingress-nginx-controller -n ingress-nginx --replicas=3
# 就能访问了,也有这个ipvs规则了
[*]上面的实验,为什么21,20的32162不能访问呢?
[*]缘故起因就是ingress-nginx这个svc中的externalTrafficPolicy: Local 是这个模式
[*]这个模式下,当地有ingresss pod ,该节点的ipvs才有后端,能访问
[*]当地没有ingress pod ,该节点的ipvs没有后端,访问拒绝
[*]摆设3个ingrees pod 后,一个在master02上,一个在node上
[*]这2个节点都能访问到,master01上有污点,以是不能摆设,也就没有ipvs后端,也就访问不到了
[*]总结一下
[*]由于ingress的svc是local,这个节点上有这个ingress的pod,才气实现访问节点(有ingress的节点)+端谈锋气访问到,其他节点上没有这个ingress的pod,就访问不到,有ingress pod的节点就有转发到ingree pod的规则
[*]这个nodeport的svc不能实现跨节点的通讯
[*]改成externalTrafficPolicy: cluster就能访问到了,这个就是无论节点上有没有这个ingress pod,都能访问,就天生了ipvs规则,到这个ingress pod的规则
[*]上面不通,除了摆设多个ingrees pod 外,尚有一种方式就是将loacl改成cluster,如许不管其他节点有没有ingress pod 都能访问到了
# kubectl edit svc -n ingress-nginx ingress-nginx-controller
externalTrafficPolicy: Cluster
# 修改后,ipvs规则就有了,对应的是3个ingress pod ,因为流量必须经过这个ingrees pod 然后根据这个ingress规则实现转发
TCP192.168.50.20:32162 rr
-> 10.244.59.201:80 Masq 1 0 0
-> 10.246.73.162:80 Masq 1 0 0
-> 10.246.73.163:80 Masq 1 0 1 6、ingress规则详细设置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
namespace: default
annotations:
# 最重要的注解(rewrite、限流、超时都在这里)
nginx.ingress.kubernetes.io/rewrite-target: /# 路径重写,/api/v1 转发到 / 就是只访问根目录
spec:
# 指定 Ingress 控制器(必须写)
ingressClassName: nginx
# 路由规则(核心!)
rules:
- host: www.meme1.com # 访问域名
http:# 因为是七层的,所以是http访问
paths:
- path: / # URL 路径
pathType: Prefix# 匹配类型
backend:# 将符合上面的规则转发到哪一个svc上
service:
name: svcn1 # 转发到哪个 Service
port:
number: 80# Service 端口
- host: www.meme2.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svcn2
port:
number: 80
[*]pathType详解
[*]Prefix 前缀匹配,/匹配全部的,/api 匹配/api/,/api/v1, /api/user
[*]Exact 准确匹配,必须完全一样即可, /api 不匹配/api/
[*]只必要访问根目次 添加一个表明即可
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /7、ingress进阶实验
[*]同一个域名差别的路径转发到差别的服务
[*]访问a.com/v1 跳转到v1服务
[*]访问a.com/v2 跳转到v2 服务
# cat in1.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-1
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: "nginx"
rules:
- host: "a.com"
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: v1
port:
number: 80
- host: "a.com"
http:
paths:
- path: /v2# a.com/v2 由于是nginx的配置(这个配置会翻译成nginx的配置)
# a.com/v2 会跳转到 /usr/share/nginx/html/v1/index.html 这个页面
pathType: Prefix
backend:
service:
name: v2
port:
number: 80
#kubectl describe ingress ingress-1
Name: ingress-1
Labels: <none>
Namespace: default
Address: 10.103.125.75
Default backend:default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host PathBackends
---- ------------
a.com
/v1 v1:80 (10.246.73.166:80)
a.com
/v2 v2:80 (10.246.73.167:80)
Annotations:nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type ReasonAge From Message
---- ---------- ---- -------
NormalSync 11m (x4 over 29m)nginx-ingress-controllerScheduled for sync
NormalSync 11m (x4 over 29m)nginx-ingress-controllerScheduled for sync
NormalSync 11m (x4 over 29m)nginx-ingress-controllerScheduled for sync
[*]客户端测试
# curl -H "Host: a.com" http://192.168.50.22:32162/v1
v1
# curl -H "Host: a.com" http://192.168.50.22:32162/v2
v2
[*]ingress 只负责转发,不负责修改路径
[*]第一种在pod内里创建v2,v1目次,存放网页文件
[*]第二种,路径重写,跳转到/目次即可
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /8、ingress总结
[*]负责路径的转发,这个设置会翻译成nginx的设置,雷同的,不会修改路径
[*]这个访问路径必须真实存在,才气访问到
6、LoadBalance
1、loadbalance是什么呢?
[*]之前学过的nodeport,必要袒露端口,3w以上的,不方便,访问必要加上端口
[*]loadbalance直接分配一个公网ip,直接对外提供服务
[*]lb=nodeport + 云厂商的外部负载均衡器
[*]由于我没有公网ip,因此必要下载一个插件,模拟一下即可
# 这个external-ip 这个就是公网ip地址,没有指定,就是none
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15d2、下载插件文件
# wget https://raw.githubusercontent.com/metallb/metallb/v0.13.9/config/manifests/metallb-native.yaml
# kubectl apply -f metallb-native.yaml
# kubectl get pod -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-7967ffcf8-h29sm 1/1 Running 0 6m15s
speaker-btw9v 1/1 Running 0 6m15s
speaker-lt2h6 1/1 Running 0 6m15s
speaker-rvslq 1/1 Running 0 6m15s3、创建地点池和绑定
# 安装一个网络计算工具
yum -y install sipcalc
# sipcalc 192.168.50.100/24
- - 0
Host address - 192.168.50.100
Host address (decimal) - 3232248420
Host address (hex) - C0A83264
Network address - 192.168.50.0
Network mask - 255.255.255.0
Network mask (bits) - 24
Network mask (hex) - FFFFFF00
Broadcast address - 192.168.50.255
Cisco wildcard - 0.0.0.255
Addresses in network - 256
Network range - 192.168.50.0 - 192.168.50.255
Usable range - 192.168.50.1 - 192.168.50.254
[*]创建存储池和实例绑定存储池
# 创建地址池
# cat pools.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 192.168.50.200-192.168.50.220
# 创建实例绑定地址池
# cat l2.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb-system
spec:
ipAddressPools:
- first-pool
# kubectl get ipaddresspools.metallb.io-n metallb-system
NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
first-pool true false ["192.168.50.200-192.168.50.220"]4、创建svc
# 因为是LoadBalancer,所以会自动的分配外部ip地址,从之前创建的地址池中分配一个地址
# 如果是对外提供的,就需要使用公网ip
# 还会创建一个nodeport端口
# kubectl expose deployment nginx --name svc666 --port 80 --target-port 80 --type LoadBalancer
service/svc666 exposed
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d
svc666 LoadBalancer 10.99.233.85 192.168.50.200 80:31439/TCP 3s
# 直接访问ip即可,但是这个80端口如果换成其他的81,就需要加上端口了5、lb访问原理
[*]直接访问公网ip地点
[*]哀求到达集群节点的nodeport端口
[*]根据haproxy实现的ipvs规则转发到后端的pod
[*]Nginx pod 相应
[*]公网ip+NodePort
6、lb访问
# 直接访问这个模拟出来的公网ip地址就能访问到后端关联的pod
# 不需要添加端口
# 如果购买了域名的话,可以使用域名访问
# curl 192.168.50.200# 等价于 :80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</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
nginx.org.<br/>
Commercial support is available at
nginx.com.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>7、实验
[*]wordpress和mysql
[*]mysql和wordpress内部通讯,dns大概clusteripwordpress访问mysql-svc就能访问到mysql
[*]外部访问wordpress,利用nodeport
1、创建mysql的pod和svc
# kubectl run db --image=mysql --image-pull-policy=IfNotPresent --dry-run=client -o yaml > db.yml
# cat db.yml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: db
name: db
spec:
nodeName: node# 指定调度在node节点上
containers:
- image: mysql
imagePullPolicy: IfNotPresent
name: db
resources: {}
env:
- name: "MYSQL_ROOT_PASSWORD"# 添加环境变量
value: "123"
- name: "MYSQL_DATABASE"
value: "wordpress"
dnsPolicy: ClusterFirst
restartPolicy: Always
# kubectl expose pod db --type ClusterIP --port=3306 --target-port 3306--name db-svc --dry-run=client -o yaml > db-svc.yml
# cat db-svc.yml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
run: db
name: db-svc
spec:
ports:
- port: 3306
protocol: TCP
targetPort: 3306
selector:
run: db
type: ClusterIP
# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/db 1/1 Running 0 8m31s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/db-svc ClusterIP 10.101.1.39 <none> 3306/TCP 5m50s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15d集群内部访问
# 可以直接通过ClusterIP进行访问对应的pod
# mysql -uroot -p123 -h 10.101.1.39
# 访问svc就能访问到对应的pod2、创建wordpress和svc
kubectl run web-wordpress --image=wordpress --image-pull-policy=IfNotPresent --dry-run=client -o yaml > web.yml
# cat web.yml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: web-wordpress
name: web-wordpress
spec:
nodeName: master02
containers:
- image: wordpress
imagePullPolicy: IfNotPresent
name: web-wordpress
resources: {}
env:
- name: "WORDPRESS_DB_HOST"# 连接后端数据的地址,这里使用的是svc,也可以使用svc的dns地址,这样svc的ip变化后,也不受影响,db-svc.default.svc.cluster.local
value: "10.101.1.39"
- name: "WORDPRESS_DB_USER"# 数据库的用户
value: "root"
- name: "WORDPRESS_DB_PASSWORD"# 数据库的密码
value: "123"
- name: "WORDPRESS_DB_NAME"# 使用哪一个数据库
value: "wordpress"
dnsPolicy: ClusterFirst
kubectl expose pod web-wordpress --type NodePort --port 80 --target-port 80 --name web-svc --dry-run=client -o yaml > web-svc.yml
# kubectl get pod
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 19m
web-wordpress 1/1 Running 0 6m8s
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db-svc ClusterIP 10.101.1.39 <none> 3306/TCP 17m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15d
web-svc NodePort 10.98.68.65 <none> 80:31366/TCP 4m20s
[*]欣赏器访问
192.168.50.20:31366
[*]这个实验实现了什么呢?
[*]pod与pod之间的通讯,可以通过ip,svc(svc对应后端的pod),大概svc的dns通讯
[*]这个wordpress的svc利用的是NodePort,对外提供服务的
svc中nodeport核心参数
字段管谁的流量可选项作用externalTrafficPolicy外部流量(你 curl 节点 IP)Cluster / Local控制外部访问要不要跨节点internalTrafficPolicy内部流量(Pod 访问 Service)Cluster / Local控制内部访问要不要跨节点
页:
[1]