Service
9. Service
- 什么是Service概述
Service可以简单的理解为逻辑上的一组Pod。一种可以访问Pod策略,而且其它Pod可以通过这个Service访问到这个Service代理的Pod。相对于Pod而言,它会有一个固定的名称,一旦创建就固定不变
- 前言-一会用到
Pod的IP地址每一次重启之后都是变化的 ,svc会通过标签的方式去关联对应的pod。无须关心Pod的IP地址的变化,如果有删除或者重启它的IP地址都会加入到这个ep资源 svc在进行关联
[root@master01 deployment]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx created
[root@master01 deployment]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-66bbc9fdc5-wxwvd 1/1 Running 0 3s
nginx-66bbc9fdc5-xksz7 1/1 Running 0 3s
[root@master01 deployment]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-66bbc9fdc5-wxwvd 1/1 Running 0 4s
nginx-66bbc9fdc5-xksz7 1/1 Running 0 4s
[root@master01 deployment]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-66bbc9fdc5-wxwvd 1/1 Running 0 12s 10.244.186.218 node03 <none> <none>
nginx-66bbc9fdc5-xksz7 1/1 Running 0 12s 10.244.140.84 node02 <none> <none>
[root@master01 deployment]# curl 10.244.140.84
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
9.1 定义一个svc
[root@master01 svc]# cat nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-svc
name: nginx-svc
spec:
ports:
- name: http #Service端口的名称
port: 80 #Service自己的端口
protocol: TCP #支持UDP TCP SCTP 默认TCP
targetPort: 80 #后端应用的端口
- name: https
port: 443
protocol: TCP
targetPort: 443
selector:
app: nginx
sessionAffinity: None
type: ClusterIP
#可以看出curl一下Pod的IP地址是可以访问的
[root@master01 svc]# kubectl create -f nginx-svc.yaml
service/nginx-svc created
[root@master01 svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 20h
nginx-svc ClusterIP 10.254.172.22 <none> 80/TCP,443/TCP 3s
[root@master01 svc]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox 1/1 Running 0 2m41s 10.244.186.226 node03 <none> <none>
nginx-66bbc9fdc5-wxwvd 1/1 Running 1 51m 10.244.186.224 node03 <none> <none>
nginx-66bbc9fdc5-xksz7 1/1 Running 1 51m 10.244.140.85 node02 <none> <none>
[root@master01 svc]# curl 10.244.186.224
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#curl 一下svc的IP地址 也是可以访问的
[root@master01 svc]# kubectl get svc -o wide --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR LABELS
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 20h <none> component=apiserver,provider
nginx-svc ClusterIP 10.254.172.22 <none> 80/TCP,443/TCP 7m4s app=nginx app=nginx-svc
[root@master01 svc]# curl 10.254.172.22
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#查看一下ep资源有没有对应的记录 可以看到有对应的IP
[root@master01 svc]# kubectl describe svc nginx-svc
Name: nginx-svc
Namespace: default
Labels: app=nginx-svc
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP: 10.254.172.22
Port: http 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.140.85:80,10.244.186.224:80
Port: https 443/TCP
TargetPort: 443/TCP
Endpoints: 10.244.140.85:443,10.244.186.224:443
Session Affinity: None
Events: <none>
- 查看svc的名称是否能解析
#是看到可以访问的
[root@master01 svc]# kubectl exec -it busybox -- sh
#没有curl命令就使用wget
/ # wget http://nginx-svc
Connecting to nginx-svc (10.254.172.22:80)
index.html 100% |*********************************************************************| 612 0:00:00 ETA
/ # cat index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#这个是跨namespace去访问
/ # wget http://nginx-svc.default
Connecting to nginx-svc.default (10.254.172.22:80)
wget: can't open 'index.html': File exists
9.2 使用Service代理k8s外部应用
希望在生产环境中使用某个固定的名称而非IP地址进行访问外部的中间件服务
希望Service指向另一个Namespace中或其它集群的服务,但是不推荐这样做(service代理到另一service)
某个项目正在迁移至k8s集群,但是一部分服务仍然在集群外部,此时可以使用service代理至k8s集群外部的服务
- service代理外部的应用
#关闭标签选择器 他就不会自动的创建ep资源
#其实443端口可以删除掉 svc ep 我就没删除
[root@master01 svc]# cat nginx-svc-external.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-svc-external
name: nginx-svc-external
spec:
ports:
- name: http #Service端口的名称
port: 80 #Service自己的端口
protocol: TCP #支持UDP TCP SCTP 默认TCP
targetPort: 80 #后端应用的端口
- name: https
port: 443
protocol: TCP
targetPort: 443
# selector:
# app: nginx
sessionAffinity: None
type: ClusterIP
#自己创建一个ep资源 把IP地址换成了百度的地址了 然后需要注意的是下面的ports.name的名字都需要与svc的名字相关联 名字要一致
[root@master01 svc]# cat nginx-ep-external.yaml
apiVersion: v1
kind: Endpoints
metadata:
labels:
app: nginx-svc-external
name: nginx-svc-external
namespace: default
subsets:
- addresses:
- ip: 110.242.68.66
ports:
- name: https
port: 443
protocol: TCP
- name: http
port: 80
protocol: TCP
#创建ep资源 可以看到ep资源已经加进去了
[root@master01 svc]# kubectl create -f nginx-ep-external.yaml
endpoints/nginx-svc-external created
[root@master01 svc]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 10.0.0.151:6443 20h
nginx-svc 10.244.140.85:443,10.244.186.224:443,10.244.140.85:80 + 1 more... 40m
nginx-svc-external 110.242.68.66:443,110.242.68.66:80 3s
#测试
[root@master01 svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 21h
nginx-svc ClusterIP 10.254.172.22 <none> 80/TCP,443/TCP 43m
nginx-svc-external ClusterIP 10.254.29.15 <none> 80/TCP,443/TCP 10m
#这里curl名字不通是因为没有配置coredns
[root@master01 svc]# curl nginx-svc-external
curl: (6) Could not resolve host: nginx-svc-external; Unknown error
#访问地址可以看到已经被代理到百度上面去了
[root@master01 svc]# curl 10.254.29.15 -I
HTTP/1.1 200 OK
Date: Sun, 06 Nov 2022 03:28:45 GMT
Server: Apache
Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
ETag: "51-47cf7e6ee8400"
Accept-Ranges: bytes
Content-Length: 81
Cache-Control: max-age=86400
Expires: Mon, 07 Nov 2022 03:28:45 GMT
Connection: Keep-Alive
Content-Type: text/html
#如果想代理到别的服务上面去只需要更改ep资源的IP地址
9.3 Service类型
- ClusterIP
#ClusterIP: 默认的类型,用于k8s内部之间的服务访问,即通过内部的service ip实现服务间的访问,service ip 仅可以在内部访问,不能从外部访问
ClusterIP:在集群中内部使用,也是默认值
ExternalName:通过返回定义的CNAME别名 不常用
NodePort:在所有安装了kube-proxy的节点上打开一个端口,此端口代理至后端的Pod,集群外部可以使用节点的IP地址和NodePort的端口号访问到集群Pod的服务,NodePort端口范围默认是30000-32767
#kubeadm 更改NodePort地址
[root@master01 svc]# cat /etc/kubernetes/manifests/kube-apiserver.yaml
#增加一处
- --service-node-port-range=10000-20000
- NodePort
#NodePort: 在clusterIP的基础之上,通过在每个node节点监听一个可以指定宿主机端口nodePort来暴露服务,从而允许外部client访问k8s集群中的服务,nodePort把外部client的请求转发至service进行处理
#要更改类型nodeport 也可以指定一个nodeport端口 如果不指定它会随机生成端口 范围:30000-32767
#然后宿主机就可以通过IP加端口方式访问了 每一个节点都可以访问
spec:
clusterIP: 10.254.172.22
externalTrafficPolicy: Cluster
ports:
- name: http
nodePort: 31000
port: 80
protocol: TCP
targetPort: 80
- name: https
nodePort: 32141
port: 443
protocol: TCP
targetPort: 443
selector:
app: nginx
sessionAffinity: None
type: NodePort
- LoadBalancer
#LoadBalancer:主要在公有云如阿里云、AWS上使用,LoadBalancer构建在nodePort基础之上,通过公有云服务商提供的负载均衡器将k8s集群中的服务暴露给集群外部的client访问
LoadBalancer:使用云提供商的负载均衡器公开服务
root@k8s-master1:~/4.Ingress-cases# cat 0.1.loadbalancer-dashboard.yaml
kind: Service
apiVersion: v1
metadata:
namespace: kubernetes-dashboard
name: dashboard-lb
labels:
k8s-app: kubernetes-dashboard
spec:
ports:
- protocol: TCP
port: 8443
targetPort: 8443
nodePort: 30063
type: LoadBalancer
selector:
k8s-app: kubernetes-dashboard
- ExtemalName 功能类似于302
ExtemalName:用于将k8s集群外部的服务映射至k8s集群内部访问,从而让集群内部的pod能够通过固定的service name 访问集群外部的服务,有时候也用于将不同namespace之间的pod通过ExtemalName进行访问
root@k8s-master1:~/4.Ingress-cases# cat 0.2.externalName.yaml
apiVersion: v1
kind: Service
metadata:
name: my-external-test-name
namespace: default
spec:
type: ExternalName #service类型
externalName: www.nbrhce.com #外部域名
root@k8s-master1:~/4.Ingress-cases# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 23d
my-external-test-name ExternalName <none> www.nbrhce.com <none> 5s
nginx-service NodePort 10.100.219.106 <none> 88:14729/TCP 17h
#找个在同一个名称空间下测试访问 ping这个svc名字是可以通的
[root@net-test /]# ping my-external-test-name
- Endpoints
root@k8s-master1:~/4.Ingress-cases# cat 0.3.Endpoints.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-production-server-name
namespace: default
spec:
ports:
- port: 3306
---
kind: Endpoints
apiVersion: v1
metadata:
name: mysql-production-server-name
namespace: default
subsets:
- addresses:
- ip: 172.31.7.106
ports:
- port: 3306