1.1 在k8s上是怎么发布服务的
1.1.1 传统架构:
我们传统架构 Node01上的java1想要访问Node02上的java2 只能通过nginx反向代理
在nginx 上Node01 和 node02 的ip地址都绑定的由域名 我们的java1就可以用node01域名:端口号的形式来访问我们的java2 如果我们用的由springclass 的话 我们就会有一个eureka 我们的java1和java2就可以把这个表单拉到他们呢的本地 上边记载的是 java1和java2的IP地址和端口号
1.1.2 K8s:
在k8s上我们使用service 来访问 我们可以把node01中的Java1和node02中的java1 放到要给service 里边Java2和Java2放到一个service里边 我们的java1想要访问我们的java2 只需要访问我们的java2-srv:端口号 就可以 直接来访问我们的java2 ingress 和nginx 的作用差不多 它负责把我们的流量 分发到我们的service 上 我们也可以通过我们的label 标签来选择service
1.2 什么是Service?
Service中文官网地址:https://kubernetes.io/zh/docs/concepts/services-networking/service/
Service可以简单的理解为逻辑上的一组Pod。一种可以访问Pod的策略,而且其他Pod可以通过这个Service访问到这个Service代理的Pod。相对于Pod而言,它会有一个固定的名称,一旦创建就固定不变。
1.3 创建一个Service
先创建一个deployment
cat nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.15.2
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
创建一个svc 来作为我们deployment的代理
cat nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-svc
name: nginx-svc
spec:
ports:
- name: http # Service端口的名称
port: 80 # Service自己的端口, servicea --> serviceb http://serviceb, http://serviceb:8080
protocol: TCP # UDP TCP SCTP default: TCP
targetPort: 80 # 后端应用的端口
- name: https
port: 443
protocol: TCP
targetPort: 443
selector: #通过这个来过滤要管理的Pod 不同的namespace service 只能管理本namespace内的Pod不能跨空间
app: nginx #我们写了一个app=nginx 的作用是 只要是通过kubect get po –show-labels 查找出来的 含有app-nginx 标签的(本空间内的)我们的service都能管理到
sessionAffinity: None
type: ClusterIP
1.3.1 验证
1)本机验证
我们使用 curl PodIP 和 curl nginx-svcIP 访问的内容是一样的
2)使用别的 Pod进行验证
[
root@k8s-master01 ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 7 (<invalid> ago) 7h34m
nginx-66bbc9fdc5-p7x7n 1/1 Running 0 7m12s
nginx-66bbc9fdc5-qctlg 1/1 Running 0 7m12s
[root@k8s-master01 ~]# kubectl exec -it busybox -- sh
/ # wget http://nginx-svc
Connecting to nginx-svc (10.109.34.124:80)
index.html 100% |*********************************************************************| 612 0:00:00 ETA
/ # rm -rf index.html
/ # wget http://nginx-svc.default 访问不同的namespace之间的service
Connecting to nginx-svc.default (10.109.34.124:80)
index.html 100% |*********************************************************************| 612 0:00:00 ETA
/ # exit
#查询我们新创建的svc的ep 这个ep是因为你在svc的配置文件中写了selector 参数 然后他就会自动帮我们创建ep
ep中写的就是我们pod的IP地址和端口号 我们就是通过这个来连接pod
[root@k8s-master01 ~]# kubectl get ep nginx-svc
NAME ENDPOINTS AGE
nginx-svc 172.168.85.213:443,172.168.85.214:443,172.168.85.213:80 + 1 more... 20m
如果我们把service管理的pod 删除之后 我们的service依然能够管理到我们的Pod只要你在service的yaml文件中写了 selector参数 你删除完成pod之后pod endpoint会对pod进行监控删除玩Pod之后他就会把之前的ip地址从ep之中移除 把从新起来的pod的Ip地址写到ep中 就可以继续完成对pod的代理 (我们使用的是deployment来管理的pod)
1.4 使用Service代理k8s外部应用
使用场景:
- 希望在生产环境中使用某个固定的名称而非IP地址进行访问外部的中间件务
- 希望Service指向另一个Namespace中或其他集群中的服务
- 某个项目正在迁移至k8s集群,但是一部分服务仍然在集群外部,此时可以使用service代理至k8s集群外部的服务
cat nginx-svc-external.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-svc-external #注意这里的YamL 文件的书写app一定不能喝Labels对齐 要推后一格否则创建的时候报错 name和labels是对齐的
name: nginx-svc-external
spec:
ports:
- name: http # Service端口的名称
port: 80 # Service自己的端口, servicea --> serviceb http://serviceb, http://serviceb:8080
protocol: TCP # UDP TCP SCTP default: TCP
targetPort: 80 # 后端应用的端口
sessionAffinity: None
type: ClusterIP
注意我们这里没有selector 所以我们就不会创建ep
查询ep 使用命令 kubectl get ep
Endpoints 官方文档:https://kubernetes.io/zh/docs/concepts/services-networking/endpoint-slices/
我们自己创建 ep 使用Yaml文件
cat nginx-ep-external.yaml
apiVersion: v1
kind: Endpoints
metadata:
labels:
app: nginx-svc-external #这个Name和app要和上边的service保持一致
name: nginx-svc-external #他会自动去帮我们建立连接 否则就来建立不了连接
namespace: default
subsets:
- addresses:
- ip: 39.155.66.14 #外部服务的Ip地址和端口号 我们以百度为例
ports:
- name: http #这个也要和service一致 不然建立不了链接
port: 80
protocol: TCP
1.4.1 验证
curl baidu.com.com -I
curl serviceIp -I
访问这两个结果是一样的
1.5 使用Service反代域名
cat nginx-externalName.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-externalname
name: nginx-externalname
spec:
type: ExternalName #这里不一样 注意一下
externalName: www.baidu.com
1.5.1 验证
配置完之后 我们直接访问我们的serviceName 就可以实现访问我们的百度
1.6 Service类型
- ClusterIP:在集群内部使用,也是默认值。集群外部是访问不了的
- ExternalName:通过返回定义的CNAME别名。
- NodePort:在所有安装了kube-proxy的节点上打开一个端口,此端口可以代理至后端Pod,然后集群外部可以使用节点的IP地址和NodePort的端口号访问到集群Pod的服务。NodePort端口范围默认是30000-32767
- LoadBalancer:使用云提供商的负载均衡器公开服务。