第六章 Kubernetes网络
1、Service 控制器
在 Kubernetes (K8S) 中,Service 控制器 是一个关键组件,负责管理 Kubernetes 服务的生命周期和实现其功能。Service 控制器确保服务能够正确地将流量路由到后端 Pod,并处理服务的负载均衡和 DNS 解析。
1.1 Service存在的意义
Service 引入主要是解决Pod的动态变化,提供统一访问入口:
- 定义一组Pod的访问策略(负载均衡)
- Pod的生存周期是短暂的动态的,在重建或增加的情况下,Service为了防止Pod失联,动态感知Pod的变化获取最新的IP,找到提供同一个服务的Pod(服务发现)
Service 控制器的主要职责包括:
- 负载均衡: 将流量分发到后端 Pod
- DNS 解析: 提供 DNS 名称解析,使得服务可以通过名称被其他服务或应用访问
- IP 管理: 确保 Service 拥有一个稳定的 IP 地址
- 健康检查: 监控后端 Pod 的健康状态,确保流量只被发送到健康的 Pod
1.2 Pod与Service的关系
Service 通过标签选择器(Label Selector)来选择一组 Pod。标签选择器定义了一组键值对,Service 会根据这些键值对来匹配具有相应标签的 Pod。
- Service 通过 标签 关联一组Pod(selector)
- Service 为一组Pod提供负载均衡能力
1.3 Service定义与创建
前提:之前创建Service是基于Deployment控制器,如:kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
- Kubectl expose 基于已有的Deployment创建service
- kubectl create service 可以直接创建service,不需要基于Deployment
1)创建service:
- 命令:kubectl create service --tcp=port:port
kubectl create service clusterip web --tcp=80:80
2)生成YAML:
kubectl create service clusterip web --tcp=80:80 --dry-run=client -o yaml > clusterip-web.yaml
3)定义 service:
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: ClusterIP # 服务类型
ports:
- name: 80-80
port: 80 # Service端口,统一的内部访问端口
protocol: TCP # 协议
targetPort: 80 # 容器端口(应用程序监听端口)
selector:
app: web # 指定关联Pod的标签
4)查看 service:
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web ClusterIP 10.110.27.138 <none> 80/TCP 6s
测试:Cluster IP类型 Service 内部集群访问
# 由于是直接创建的Service,没有相关的Pod进行关联
[root@k8s-master-1-71 ~]# kubectl get ep
NAME ENDPOINTS AGE
web <none> 10s //相关endpoints为空
# 需创建标签相同的Pod与Service进行关联
[root@k8s-master-1-71 ~]# kubectl run web --image=nginx
[root@k8s-master-1-71 ~]# kubectl label pods web app=web --overwrite //定义标签(--overwrite覆盖)
[root@k8s-master-1-71 ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
web 1/1 Running 0 13m app=web,run=web
[root@k8s-master-1-71 ~]# kubectl get ep
NAME ENDPOINTS AGE
web 10.244.114.31:80 5m59s //相关endpoints已关联Pod
# 将web作为后端,再创建一个bs作为前端进行测试
[root@k8s-master-1-71 ~]# kubectl run bs --image=busybox -- sleep 24h
[root@k8s-master-1-71 ~]# kubectl exec -it bs -- sh
/ # wget 10.110.27.138:80 //访问并下载web svc的默认首页
/ # cat index.html
<title>Welcome to nginx!</title>
注意:由于镜像是周期性方式存在的,没有相关执行进程将会一直不断拉取镜像重启,而在创建busybox类似镜像时,需要通过加 sleep进行Hold住。
多端口Service定义:
对于某些服务,需要公开多个端口, Service也需要配置多个端口定义,通过端口名称区分。例如https服务:
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: ClusterIP
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80 //需转发80端口
- name: https
port: 443
protocol: TCP
targetPort: 443 //需转发443端口
selector:
app: web
示例:
# 创建多镜像Pod,注意标签
[root@k8s-master-1-71 ~]# kubectl apply -f pod-mutil.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: pod-mutil
name: pod-mutil
spec:
containers:
- image: nginx
name: web
- image: tomcat:6
name: api
[root@k8s-master-1-71 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-mutil 2/2 Running 0 14m 10.244.114.33 k8s-node2-1-73 <none> <none>
# 创建多端口Service,注意标签
[root@k8s-master-1-71 ~]# kubectl apply -f clusterip-mutil.yaml
apiVersion: v1
kind: Service
metadata:
name: clusterip-mutil
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
- name: 88-8080
port: 88
protocol: TCP
targetPort: 8080
selector:
run: pod-mutil //指定Pod的Labels标签
type: ClusterIP
[root@k8s-master-1-71 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
clusterip-mutil ClusterIP 10.111.231.50 <none> 80/TCP,88/TCP 4m34s
[root@k8s-master-1-71 ~]# kubectl get ep
NAME ENDPOINTS AGE
clusterip-mutil 10.244.114.33:8080,10.244.114.33:80 23m
# 通过bs作为前端进行测试
[root@k8s-master-1-71 ~]# kubectl exec -it bs -- sh
/ # wget 10.111.231.50:80 -O web-index.html
/ # cat web-index.html
<title>Welcome to nginx!</title>
/ # wget 10.111.231.50:88 -O tomcat-index.html
/ # cat tomcat-index.html
<a href="http://tomcat.apache.org/">
1.4 Service 三种类型
类型 |
描述 |
备注 |
Clusterlp |
集群内部使用 (Pod) |
仅集群内部访问,适用于内部服务发现和通信 |
NodePort |
对外暴露应用 (浏览器) |
通过节点端口从集群外部访问,适用于简单的外部访问需求 |
LoadBalancer |
对外暴露应用,适用公有云 |
通过云提供商的负载均衡器从集群外部访问,适用于生产环境和高可用性需求 |
注意:选择哪种 Service 类型取决于您的具体需求和部署环境。
1.4.1 ClusterIP
ClusterIP 是 Kubernetes 中默认的 Service 类型。它为 Service 分配一个仅在集群内部可访问的虚拟 IP 地址。这意味着只有集群内部的 Pod 和组件可以通过这个 IP 地址访问 Service。
特点:
- 仅集群内部访问:Service 只能在集群内部访问,不会暴露在集群外部。
- 负载均衡:Kubernetes 会自动在后端 Pod 之间进行负载均衡。
- 简单的内部通信:适用于集群内部的服务发现和通信。
使用场景:
- 当您只需要在集群内部访问服务时。
- 用于内部微服务之间的通信。
默认创建,会分配一个稳定的IP地址,即VIP(VirtualIP),只能在k8s集群内部进行访问,用于内部维护使用。示例配置:
apiVersion: v1
kind: Service
metadata:
name: my-clusterip-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
1.4.2 NodePort
NodePort 通过在每个节点上打开一个特定的端口(称为 NodePort),将外部流量转发到 Service。NodePort 允许外部流量通过节点的 IP 地址和 NodePort 访问 Service。
特点:
- 外部访问:通过节点的 IP 地址和 NodePort 可以从集群外部访问 Service。
- 固定端口:NodePort 的范围通常是 30000-32767,但可以通过配置修改。
- 简单配置:适用于需要简单外部访问的场景。
- 访问地址:<任意NodeIP>:<NodePort>
- 默认端口范围:30000 - 32767
使用场景:
- 当您需要从集群外部访问服务,但没有负载均衡器时。
- 适用于简单的开发和测试环境。