💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
推荐:Linux运维老纪的首页,持续学习,不断总结,共同进步,活到老学到老
导航剑指大厂系列:全面总结 运维核心技术:系统基础、数据库、网路技术、系统安全、自动化运维、容器技术、监控工具、脚本编程、云服务等。
常用运维工具系列:常用的运维开发工具, zabbix、nagios、docker、k8s、puppet、ansible等
数据库系列:详细总结了常用数据库 mysql、Redis、MongoDB、oracle 技术点,以及工作中遇到的 mysql 问题等
懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
一篇文章精通K8S的统一访问入口-Service
1、Service是什么?
-
背景:每个Pod具有IP地址,当使用Deployment控制器时,Pod的IP地址往往动态变化。
-
解决方法:通过Service可以获得稳定的IP地址,且在Service的生命周期有效,与Pod的IP地址变化与否无关。
-
实质:Service本质就是一个LB负载均衡器
2.Service存在的意义![](https://i-blog.csdnimg.cn/direct/a608c661c5984fd88bef05bcd9774c5d.png)
3.Pod与Service的关系![](https://i-blog.csdnimg.cn/direct/a7ff24fc2f474ed78c6b7ba44764e60a.png)
4.Service定义和创建![](https://i-blog.csdnimg.cn/direct/4d81f6d41df04a4b9de4a3807bffabef.png)
5.创建Nginx
[root@k8s-master ~]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
查看刚刚部署的Nginx服务标签
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-6799fc88d8-s5rnz 1/1 Running 0 24d app=nginx,pod-template-hash=6799fc88d8
nginx-deployment-66b6c48dd5-hxv7h 1/1 Running 0 70s app=nginx,pod-template-hash=66b6c48dd5
nginx-deployment-66b6c48dd5-jjkk4 1/1 Running 0 70s app=nginx,pod-template-hash=66b6c48dd5
nginx-deployment-66b6c48dd5-tsgvb 1/1 Running 0 70s app=nginx,pod-template-hash=66b6c48dd5
查看当前namespace(default)下有哪些svc
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24d
nginx NodePort 10.108.41.4 <none> 80:31434/TCP 24d
定义并创建Service
[root@k8s-node2 ~]# vim service.yaml
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
ports:
- port: 80 # Service端口
protocol: TCP # 协议
targetPort: 80 # 容器端口(程序启动端口,比如django默认是8000端口)
selector:
app: nginx # 指定关联Pod的标签(上面已经查到了,app=nginx)
type: ClusterIP # 服务类型
创建svc
[root@k8s-master ~]# kubectl apply -f service.yaml
通过Service访问Nginx集群
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24d
nginx NodePort 10.108.41.4 <none> 80:31434/TCP 24d
web ClusterIP 10.105.53.183 <none> 80/TCP 2m40s
[root@k8s-master ~]# curl 10.105.53.183 # 可以通过web的地址访问后面三个nginx集群
[root@k8s-master ~]# kubectl delete svc web2 # 可以删除其中一个
Service三种常用类型
-
ClusterIP
:集群内部使用 -
NodePort
:对外暴露应用(集群外) -
LoadBalancer
:对外暴露应用,适用公有云
ClusterIP(VIP)
NodePort
部署并测试
[root@k8s-master ~]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
查看nginx服务的标签
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-6799fc88d8-s5rnz 1/1 Running 0 24d app=nginx,pod-template-hash=6799fc88d8
nginx-deployment-66b6c48dd5-hxv7h 1/1 Running 0 70s app=nginx,pod-template-hash=66b6c48dd5
nginx-deployment-66b6c48dd5-jjkk4 1/1 Running 0 70s app=nginx,pod-template-hash=66b6c48dd5
nginx-deployment-66b6c48dd5-tsgvb 1/1 Running 0 70s app=nginx,pod-template-hash=66b6c48dd5
使用NodePort创建svc
[root@k8s-node2 ~]# vim service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: web-nodeport
namespace: default
spec:
ports:
- port: 80 # Service端口
protocol: TCP # 协议
targetPort: 80 # 容器端口(程序启动端口,比如django默认是8000端口)
nodePort: 30706 # 指定NodePort监听的外网端口
selector:
app: nginx # 指定关联Pod的标签(上面已经查到了,app=nginx)
type: NodePort # 服务类型(只需要把服务类型修改成NodePort即可)
创建svc
[root@k8s-master ~]# kubectl apply -f service-nodeport.yaml
访问
-
访问地址:<任意NodeIP>:NodePort
-
端口范围:30000-32767
NodePort弊端
LoadBalancer
LB说明
-
负责均衡器有哪些:nginx、LVS、haproxy
-
私有云:SLB、ELB
配置LB
-
直接找一个nginx配置反向代理即可
stream {
log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
access_log /var/log/nginx/django-access.log main;
upstream django-apiserver {
server 192.168.56.62:30706;
server 192.168.56.63:30706;
}
server {
listen 88;
proxy_pass django-apiserver;
}
}
注意:生产最好使用云厂商的ELB或者SLB
Service二种特殊类型
-
ExternalName:引用集群外的服务
-
Headless:允许Pod通过其主机名被访问
ExternalName Service
ExternalName Service说明:
ExternalName
Service 是一种特殊类型的 Service,它不分配 ClusterIP,也不选择 Pods。相反,它允许你通过 Kubernetes Service 来引用外部的服务,比如一个托管在集群外的数据库或任何其他服务。
使用场景:
-
引用集群外的服务。
-
简化对外部服务的引用,不需要修改应用程序配置。
操作步骤:
-
创建一个
ExternalName
类型的 Service YAML 文件,指定type: ExternalName
和externalName
字段。 -
应用该 YAML 文件来创建 Service。
apiVersion: v1
kind: Service
metadata:
name: external-db-service
spec:
type: ExternalName
externalName: my.database.com
ports:
- port: 5432
实现效果:
-
当你创建了上述 Service 后,Kubernetes 会创建一个 DNS 记录,使得
external-db-service.default.svc.cluster.local
解析到my.database.com
。 -
集群内的 Pod 可以通过这个 DNS 名称和端口号
5432
来访问外部的数据库服务。
ExternalName Service 优缺点:
优点:
-
简化外部服务引用:不需要修改应用程序的配置即可引用外部服务。
-
集成外部服务:可以无缝地将外部服务集成到Kubernetes集群的服务发现机制中。
-
灵活性:可以引用任何可通过DNS解析的服务,不限于特定的服务类型或协议。
缺点:
-
依赖外部服务:如果外部服务不可用,那么通过
ExternalName
Service 访问它也会失败。 -
没有负载均衡:不提供内置的负载均衡功能,所有流量直接转发到外部服务。
-
安全性:如果外部服务需要特定的安全措施,可能需要额外的配置。
Headless Service
Headless Service说明:
Headless Service
是一种不分配 ClusterIP 的 Service,它允许每个 Pod 通过其主机名直接被访问。
使用场景:
-
当你不需要 Kubernetes 来管理负载均衡和路由时。
-
当你想要直接控制 Pod 的访问方式时。
操作步骤:
-
创建一个 Service YAML 文件,不要指定
clusterIP: None
(默认就是 None)。 -
应用该 YAML 文件来创建 Service。
apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
# 注意这里不指定 clusterIP
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: 8080
实现效果:
-
创建 Service 后,Kubernetes 会为每个匹配的 Pod 创建一个 DNS 记录。
-
Pod 可以通过
<pod-name>.headless-service.default.svc.cluster.local
来访问同一 Service 下的其他 Pod。 -
这种方式不提供负载均衡,直接通过 DNS 解析到具体的 Pod。
Headless Service 优缺点:
优点:
-
直接访问:允许直接通过Pod的主机名访问,无需通过负载均衡器。
-
简单性:不需要Kubernetes进行流量管理和负载均衡,简化了网络架构。
-
适用于无状态服务:对于不需要负载均衡的无状态服务,Headless Service是一个轻量级的选择。
缺点:
-
没有负载均衡:不提供负载均衡,可能导致某些Pod过载而其他Pod空闲。
-
管理复杂性:需要手动管理Pod的访问和负载分配,增加了运维的复杂性。
-
扩展性问题:当服务需要水平扩展时,手动管理Pod的访问可能会变得不切实际。