架构图:
访问流程:
网络连通原理:
ip netns add ns1 #添加网络名称空间
ls /var/run/netns #查看所有网络名词空间
ip netns #查看所有网络名词空间
# Linux 将所有的进程都分配到 root network namespace,以使得进程可以访问外部网络
# Kubernetes 为每一个 Pod 都创建了一个 network namespace
2、跨节点
3、Pod-To-Service
1、Pod To Service
2、Service-To-Pod
4、Internet-To-Service
2、Internet-To-Pod(LoadBalancer – Layer4)
3、Internet-To-Pod(Ingress-- Layer7)
Service:
只需要访问这个Service,Service还会基于Pod的探针机制,(ReadinessProbe:就绪探针)完成Pod的自动剔除和线上工作。
Service 即使是无头服务,别人pod不能用ip访问,但是可以用service名当成域名访问。
Service的名字还能当成域名被pod解析
将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
service中的type可选值:
ClusterIP: 通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType
NodePort: 通过每个节点上的 IP 和静态端口( NodePort )暴露服务。 NodePort 服务会路
由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口> ,你可以从集群的外部访问
一个 NodePort 服务。
LoadBalancer: 使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由
到自动创建的 NodePort 服务和 ClusterIP 服务上。
ExternalName: 通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容
(例如, foo.bar.example.com )。 无需创建任何类型代理。
Service 创建完成后,会对应一组EndPoint。可以kubectl get ep 进行查看
type有四种,每种对应不同服务发现机制
Servvice可以利用Pod的就绪探针机制,只负载就绪了的Pod。自动剔除没有就绪的Pod
ClusterIP:
apiVersion: v1
kind: Service
metadata:
name: cluster-service-test
namespace: default
spec:
selector:
app: canary-nginx
# clusterIP: 10.96.88.99
#clusterIP: None # 不要给这个svc分配ip。headless service无头服务配合有状态副本集StatefulSet
type: ClusterIP # ClusterIP,ExternalName, NodePort, and LoadBalancer
## ClusterIP:指,当前Service在集群内可以被所有人发现,默认给这个service分配一个集群内的网络
## podcidr: Pod的子网范围 svccidr:Service的子网范围
ports:
- name: abc
port: 80 # 访问当前service 的 80
targetPort: 80 ## 派发到Pod的8080
# ports:
# - name: abc
# port: 80 ## 访问当前service 的 80
# targetPort: 8080 ## 派发到Pod的8080
# - name: redis
# port: 99
# targetPort: 6379
NodePort:
apiVersion: v1
kind: Service
metadata:
name: cluster-service-222
namespace: default
spec:
selector:
app: canary-nginx
type: NodePort # 每一台机器都为这个service随机分配一个指定的端口
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
# nodePort: 不指定默认会在 30000-32765这个范围内随机分配
nodePort: 31110
#查看机器端口号:
netstat -lnpt | grep 31110
创建无Selector的Service:
我们可以创建Service不指定Selector
然后手动创建EndPoint,指定一组Pod地址。
此场景用于我们负载均衡其他中间件场景。
创建Service:
# 无selector的svc
apiVersion: v1
kind: Service
metadata:
name: cluster-service-no-selector
namespace: default
spec:
## 不选中Pod而在下面手动定义可以访问的EndPoint
type: ClusterIP
ports:
- name: abc
port: 80 # 访问当前service 的 80
targetPort: 80 ## 派发到Pod的 80
### 场景:Pod要访问 MySQL。 MySQL单独部署到很多机器,每次记ip麻烦
### 集群内创建一个Service,实时的可以剔除EP信息。反向代理集群外的东西。
创建Endpoints:挂载service
apiVersion: v1
kind: Endpoints
metadata:
name: cluster-service-no-selector ## 和service同名
namespace: default
subsets:
- addresses:
- ip: 192.168.179.37 # 挂载你想访问的中间件ip
- ip: 192.168.179.36 # 挂载你想访问的中间件ip
- ip: 220.181.38.251 # 挂载你想访问的中间件ip
ports:
- name: abc ## ep和service要是一样的
port: 80
protocol: TCP
原理:kube-proxy 在负责这个事情
场景:Pod要访问 MySQL。 MySQL单独部署到很多机器,每次记ip麻 烦
集群内创建一个Service,实时的可以剔除EP信息。反向代理集群外的东西
ExternalName:
apiVersion: v1
kind: Service
metadata:
name: my-service-05
namespace: default
spec:
type: ExternalName
externalName: baidu.com
#无selector 自己写EP,只能写域名,web服务,注意跨域问题
- 其他的Pod可以通过访问这个service而访问其他的域名服务
- 但是需要注意目标服务的跨域问题
LoadBalancer: 对外的负载均衡器
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/name: load-balancer-example
name: my-service
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app.kubernetes.io/name: load-balancer-example
type: LoadBalancer # 负载均衡,开放给云平台实现,阿里云,百度云
扩展 - externalIP:
在 Service 的定义中, externalIPs
可以和任何类型的 .spec.type
一通使用。在下面的例子中,客户端可通过 80.11.12.10:80
(externalIP:port) 访问my-service
apiVersion: v1
kind: Service
metadata:
name: my-service-externalip
spec:
selector:
app: canary-nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
externalIPs: ### 定义只有externalIPs指定的地址才可以访问这个service
- 10.170.0.111 ### 集群内的ip都不行?
扩展 - Pod的DNS:
apiVersion: v1
kind: Service
metadata:
name: default-subdomain
spec:
selector:
name: busybox
clusterIP: None
ports:
- name: foo # 实际上不需要指定端口号
port: 1234
targetPort: 1234
---
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
hostname: busybox-1
subdomain: default-subdomain
## 指定必须和svc名称一样,才可以 podName.subdomain.名称空间.svc.cluster.local访问。否则访问不同指定Pod
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
---
apiVersion: v1
kind: Pod
metadata:
name: busybox2
labels:
name: busybox
spec:
hostname: busybox-2 ### 每个Pod指定主机名
subdomain: default-subdomain ## subdomain等于sevrice的名
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
- 访问 busybox-1.default-subdomain.default.
svc.cluster.local
可以访问到busybox-1。 - 访问Service
- 同名称空间
- ping service-name 即可
- 不同名称空间
- ping service-name.namespace 即可
- 同名称空间
- 访问Pod
- 同名称空间
- ping pod-host-name.service-name 即可
- 不同名称空间
- ping pod-host-name.service-name.namespace 即可
- 同名称空间
busybox-1.default-subdomain.default**
Pod的hostName.service的名.名称空间的名
想要使用域名访问的模式,必须加Service网络的名字