K8s资源第三篇(Service)
Service: Service是定义在集群中一组运行Pod集合的抽象资源,它提供了所有相同的功能,当一个Service资源被创建后,将会分配一个唯一的IP,也叫做集群IP,这个IP地址将存在于Service的整个生命资源中,Service一旦被创建,整个IP无法进行修改。Pod可以通过Service进行通信,并且所有的通信将会通过Service自动负载均衡到所有的Pod中的容器。Serv...
Service:
Service是定义在集群中一组运行Pod集合的抽象资源,它提供了所有相同的功能,当一个Service资源被创建后,将会分配一个唯一的IP,也叫做集群IP,这个IP地址将存在于Service的整个生命资源中,Service一旦被创建,整个IP无法进行修改。
Pod可以通过Service进行通信,并且所有的通信将会通过Service自动负载均衡到所有的Pod中的容器。
- Service是真实应用服务的抽象。
- Service通常用来将浮动的资源与后端真实提供服务的容器进行关联。
- Service对外表现为一个单一的访问接口,外部不需要了解后端的规模与机制。
Server工作模式:
- userspace:1.1版本以及之前的版本所使用。
- iptables:被1.10版本以及之前的版本所使用。
- ipvs:被1.11版本以及以上的版本所使用。
Service类型:
- ClusterIP:默认方式,根据是否生成ClusterIP又可分为Service和Headless Service。
- Service:通过Kubernetes的Service分配一个集群内部可访问的固定虚拟。
- Headless Service:该服务不会分配Cluster IP,也不会通过kube-proxy做反向代理和负载均衡。而是通过DNS提供稳定的网络ID来访问,DNS会将Headless Service的后端直接解析为PodIP列表,主要提供StatefulSet使用。
- NodePort:除了使用Cluster IP之外,还通过将Service的port映射到集群内每个节点的相同一个端口,实现通过NodeIP:NodePort从集群外访问。
- LoadBalancer:和NodePort类似,不过除了使用一个Cluster IP和NodePort之外还会向所使用的公有云申请一个负载均衡器(负载均衡器后端映射到各节点的NodePort),实现集群外通过LB访问服务。
- ExternalName:是Service的特例,此模式主要面向在集群外部的服务,通过它可以将外部服务映射到k8s集群,且具备k8s内服务的一些特征(如namesapce等属性),来为集群内部提供服务。此模式要求k8s-dns的版本为1.7或以上,这种模式和前三种模式(除了Headless Service)最大的不同是重定向依赖的是DNS层次,而不是通过kube-proxy。
ClusterIP:
创建Service时k8s默认为ClusterIP,创建好Service,会生成一个ClusterIP,集群内可以访问这个ClusterIP,集群外部无法访问它。
#创建一个service
[root@k8smaster data]# vim redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
role: logstor
template:
metadata:
labels:
app: redis
role: logstor
spec:
containers:
- name: redis
image: redis:4.0-alpine
ports:
- name: redis
containerPort: 6379
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
namespace: default
spec:
selector:
matchLabels:
app: filebeat
release: stable
template:
metadata:
labels:
app: filebeat
release: stable
spec:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.5-alpine
env:
- name: REDIS_HOST
value: redis.default.svc.cluster.local
- name: REDIS_LOG_LEVEL
value: info
[root@k8smaster data]# kubectl apply -f redis.yaml
deployment.apps/redis created
daemonset.apps/filebeat-ds unchanged
[root@k8smaster data]# vim redis-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
selector:
app: redis
role: logstor
clusterIP: 10.97.97.97
type: ClusterIP
ports:
- port: 6379
targetPort: 6379
[root@k8smaster data]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 44d
redis ClusterIP 10.97.97.97 <none> 6379/TCP 17m
[root@k8smaster data]# kubectl apply -f redis-svc.yaml
service/redis created
[root@k8smaster data]# kubectl describe svc redis
Name: redis
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"clusterIP":"10.97.97.97","...
Selector: app=redis,role=logstor
Type: ClusterIP
IP: 10.97.97.97
Port: <unset> 6379/TCP
TargetPort: 6379/TCP
Endpoints: 10.244.2.147:6379
Session Affinity: None
Events: <none>
#使用命令创建
[root@k8smaster kubernetes]# kubectl create deployment nginx-deployment --image=nginx
deployment.apps/nginx-deployment created
[root@k8smaster kubernetes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-6f77f65499-dbhvp 1/1 Running 0 2m33s 10.244.1.95 k8snode1 <none> <none>
[root@k8smaster kubernetes]# kubectl create service clusterip nginx-deployment --tcp=80:80
service/nginx-deployment created
[root@k8smaster kubernetes]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d20h
nginx-deployment ClusterIP 10.103.139.34 <none> 80/TCP 12s
[root@k8smaster kubernetes]# kubectl describe service/nginx-deployment
Name: nginx-deployment
Namespace: default
Labels: app=nginx-deployment
Annotations: <none>
Selector: app=nginx-deployment
Type: ClusterIP
IP: 10.103.139.34
Port: 80-80 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.95:80 #Endpoints为关联的Pod的IP
Session Affinity: None
Events: <none>
[root@k8smaster kubernetes]# curl 10.103.139.34
<!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>
如果删除Pod:
[root@k8smaster kubernetes]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-6f77f65499-dbhvp 1/1 Running 0 5m38s
[root@k8smaster kubernetes]# kubectl delete pods nginx-deployment-6f77f65499-dbhvp
pod "nginx-deployment-6f77f65499-dbhvp" deleted
[root@k8smaster kubernetes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-6f77f65499-f8xtb 1/1 Running 0 26s 10.244.2.87 k8snode2 <none> <none>
[root@k8smaster kubernetes]# kubectl describe service/nginx-deployment
Name: nginx-deployment
Namespace: default
Labels: app=nginx-deployment
Annotations: <none>
Selector: app=nginx-deployment
Type: ClusterIP
IP: 10.103.139.34
Port: 80-80 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.87:80 #删掉原来的Pod,Endpoints关联到了新的Pod。
Session Affinity: None
Events: <none>
[root@k8smaster kubernetes]# curl 10.103.139.34
<!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>
访问Service:
[root@k8smaster kubernetes]# curl nginx-deployment
curl: (6) Could not resolve host: nginx-deployment; Unknown error
[root@k8smaster kubernetes]# kubectl get service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 2d21h
[root@k8smaster kubernetes]# kubectl get service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 2d21h
[root@k8smaster kubernetes]# vim /etc/resolv.conf
# Generated by NetworkManager
nameserver 10.96.0.10
# nameserver 2408:84e1:a3:98c4::f7
[root@k8smaster kubernetes]# curl nginx-deployment.default.svc.cluster.local
<!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>
如果删除Service:
[root@k8smaster kubernetes]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d21h
nginx-deployment ClusterIP 10.103.139.34 <none> 80/TCP 15m
[root@k8smaster kubernetes]# kubectl delete service/nginx-deployment
service "nginx-deployment" deleted
[root@k8smaster kubernetes]# kubectl create service clusterip nginx-deployment --tcp=80:80
service/nginx-deployment created
[root@k8smaster kubernetes]# kubectl describe service/nginx-deployment
Name: nginx-deployment
Namespace: default
Labels: app=nginx-deployment
Annotations: <none>
Selector: app=nginx-deployment
Type: ClusterIP
IP: 10.101.21.249
Port: 80-80 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.87:80 #只要关联到Pods的名字,就能实现访问,不管IP变没变。
Session Affinity: None
Events: <none>
[root@k8smaster kubernetes]# curl 10.101.21.249
[root@k8smaster kubernetes]# curl 10.101.21.249
<!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>
实时伸缩:
[root@k8smaster ~]# kubectl delete deployment nginx-deployment
deployment.extensions "nginx-deployment" deleted
[root@k8smaster kubernetes]# kubectl create deployment myapp-deployment --image=ikubernetes/myapp:v1
deployment.apps/myapp-deployment created
[root@k8smaster kubernetes]# kubectl create service clusterip myapp-deployment --tcp=80:80
service/myapp-deployment created
[root@k8smaster kubernetes]# kubectl scale --replicas=3 deployment myapp-deployment
deployment.extensions/myapp-deployment scaled
[root@k8smaster ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deployment-558f94fb55-plk4v 1/1 Running 0 85m 10.244.2.93 k8snode2 <none> <none>
myapp-deployment-558f94fb55-rd8f5 1/1 Running 0 99m 10.244.2.91 k8snode2 <none> <none>
myapp-deployment-558f94fb55-zzmpg 1/1 Running 0 85m 10.244.1.101 k8snode1 <none> <none>
[root@k8smaster ~]# kubectl describe service/myapp-deployment
Name: myapp-deployment
Namespace: default
Labels: app=myapp-deployment
Annotations: <none>
Selector: app=myapp-deployment
Type: ClusterIP
IP: 10.110.41.201
Port: 80-80 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.101:80,10.244.2.91:80,10.244.2.93:80 #发现关联了3个。
Session Affinity: None
Events: <none>
[root@k8smaster ~]# curl 10.110.41.201/hostname.html
myapp-deployment-558f94fb55-zzmpg
[root@k8smaster ~]# curl 10.110.41.201/hostname.html
myapp-deployment-558f94fb55-rd8f5
[root@k8smaster ~]# curl 10.110.41.201/hostname.html
myapp-deployment-558f94fb55-zzmpg
#发现Service自动实现了Pod的负载均衡。(调度方式是随机调度)
NodePort:
NodePort时引导外部流量到集群内服务最原始的方式,NodePort,正如这个名字所示,在所有节点上开发一个特定的端口,任何发送到该端口的流量都被转发到对应服务。
- 端口范围为30000~32767。
- 节点的IP可能会发生变化。
不建议在生成环境上用这种方式暴露服务,如果运行的服务不要求一直可用,或者对成本笔记敏感,你可以使用这种方法。
[root@k8smaster ~]# kubectl delete service/myapp-deployment
service "myapp-deployment" deleted
[root@k8smaster ~]# kubectl create service nodeport myapp-deployment --tcp=80:80
service/myapp-deployment created
[root@k8smaster ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d23h
myapp-deployment NodePort 10.107.69.16 <none> 80:30930/TCP 79s #30930为宿主机端口,我们来访问以下。
myweb-deployment ClusterIP 10.99.246.129 <none> 80/TCP 162m
nginx-deployment ClusterIP 10.101.21.249 <none> 80/TCP 169m
LoadBalancer:
这种方式也会在节点上开放一个端口,所有通过该端口的流量都会被转发到对应的服务上,它没有过滤规则,没有路由。这意味着你可以发送任何协议的流量,如HTTP,TCP,UDP,Websocket,gRPC或其他任意协议,这种方式会通过给你一个公网ip的方式来将服务暴露在公网上,但是每个使用LoadBalancer的服务都用于一个公网IP,每个公网IP都将会付费,开销比较大。
更多推荐
所有评论(0)