背景
在上一篇博文中,我们讲述了如何在Linux环境搭建kubernetes集群。但是部署应用的方式仍然存在着一些问题,例如:
- 每次只能访问一个Pod,没有负载均衡,不会自动转发到不同的Pod。
- 访问时需要端口转发。
- Pod重新创建后IP变了,名称也会改变。
因此我们通过Service来解决这些问题,以便我们更好地部署应用。
实现
Service相对于kubernetes原生的应用部署方式有如下优点:
- Service通过label关联对象的Pod。
- Service生命周期不跟Pod绑定,不会因为Pod重新创建而改变IP。
- 提供了负载均衡功能,自动转发流程到不同的Pod。
- 可对集群外部提供访问端口。
- 集群内部可通过服务名字访问。
创建Service
创建Service
,要注意通过标签与test-k8s
跟对应的Pod关联上。
service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: ClusterIP
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
新建service.yaml文件:
vim service.yaml
部署Service
删除原有部署
可使用如下命令查看已部署的服务:
kubectl get all
删除已部署的服务:
kubectl delete all --all
部署pod
新建或修改app.yaml
文件:
vim app.yaml
app.yaml
文件内容:
要注意本文中的
app.yaml
不同于上一篇的yaml
文件,对比上一篇的yaml
文件,增加了labels
标签,用于与service关联服务。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test-k8s
# 部署名字
name: test-k8s
spec:
replicas: 5
# 用来查找关联的 Pod,所有标签都匹配才行
selector:
matchLabels:
app: test-k8s
# 定义 Pod 相关数据
template:
metadata:
labels:
app: test-k8s
spec:
# 定义容器,可以多个
containers:
- name: test-k8s # 容器名字
image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
部署pod命令:
kubectl apply -f app.yaml
部署Service
部署Service:
kubectl apply -f service.yaml
service的其它操作
查看service详情
kubectl describe svc test-k8s
进入pod内部访问service服务
进入pod内部:
# 注意行末的bash与双横杠之间有一个空格
kubectl exec -it test-k8s-664bdc5c58-54rxt -- bash
注:
- 如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):
kubectl port-forward service/test-k8s 8888:8080
对外暴露服务
上面我们是通过端口转发的方式可以在外面访问到集群里的服务,如果想要直接把集群服务暴露出来,我们可以使用NodePort
和Loadbalancer
类型的Service,例如:
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
kubectl apply -f service.yaml
注:
- 需在节点访问,master是访问不到的。
多端口
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
name: test-k8s # 必须配置
targetPort: 8080 # 容器端口
nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
- port: 8090
name: test-other
targetPort: 8090
nodePort: 32000
补充:Service的分类
ClusterIP
默认的,仅在集群内可用
NodePort
暴露端口到节点,提供了集群外部访问的入口
端口范围固定 30000 ~ 32767
LoadBalancer
需要负载均衡器(通常都需要云服务商提供,裸机可以安装 METALLB 测试)
会额外生成一个 IP 对外服务
K8S 支持的负载均衡器:负载均衡器
Headless
适合数据库
clusterIp 设置为 None 就变成 Headless 了,不会再分配 IP,后面会再讲到具体用法。
总结
本文介绍了如何“优雅”地部署服务,后续我们会继续介绍如何部署有状态的服务,例如数据库、Redis等。