一、Service概念
通过创建service可以为一组具有相同功能的容器应用提供一个统一的入口地址,并将请求负载分发到后端的各个容器应用上。
二、Service基本用法
1.定义一个web服务的RC,由两个tomcat容器副本组成
# cat webapp-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: webapp
spec:
replicas: 2
template:
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
2.创建该RC
# kubectl get pod
NAME READY STATUS RESTARTS AGE
webapp-t5q4g 1/1 Running 0 17m
webapp-wq88m 1/1 Running 0 17m
# kubectl get pods -l app=webapp -o yaml | grep podIP
podIP: 10.44.0.2
podIP: 10.36.0.1
3.使用kubectl expose创建一个SVC
# kubectl expose rc webapp
service/webapp exposed
# kubectl get svc
webapp ClusterIP 10.111.192.152 8080/TCP 8s
4.通过svc地址和端口访问
# curl 10.111.192.152:8080
Apache Tomcat/8.5.42
......
对svc地址10.111.192.152:8080的访问被自动负载分发到了后端的两个Pod之一10.44.0.2:8080或10.36.0.1:8080。
kubernets提供了两种负载分发策略:RoundRobin和SessionAffinity,默认情况下采用的是RoundRobin模式进行负载。
- RoundRobin:轮询模式
- SessionAffinity:粘性会话,将来自同一个客户端的请求始终转发至同一个后端的Pod对象,可以通过设置service.spec.sessionAffinity: ClientIP来启用
5.使用配置文件方式创建svc
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
type: ClusterIP
ports:
- port: 8081
targetPort: 8080
selector:
app: webapp
ports:与后端容器端口关联
selector:关联到哪些pod资源上
# kubectl delete svc webapp
service "webapp" deleted
# kubectl create -f webapp-svc.yaml
service/webapp created
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webapp ClusterIP 10.96.231.61 8081/TCP 14s
6.多端口Service创建
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- port: 8080
targetPort: 8080
name: web
- port: 8005
targetPort: 8005
name: management
selector:
app: webapp
7.使用UDP端口模式
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "KubeDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 169.169.0.100
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
8.外部服务Service
在一些环境中,应用系统需要将一个外部数据库作为后端服务进行连接,这时可以通过创建一个没有Selector的svc来实现
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
由于这个 Service 没有 selector,就不会创建相关的 Endpoints 对象。可以手动将 Service 映射到指定的 Endpoints:
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- IP: 1.2.3.4
ports:
- port: 80
三、Headless Service
有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建Headless Service,仅通过Selector将后端的Pod列表返回给调用的客户端
创建一个Headless Service实例
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx
spec:
ports:
- port: 80
clusterIP: None
selector:
app: nginx
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP None 80/TCP 26s
四、从集群外部访问Pod或Service
1.将容器应用的端口映射到物理机
# cat pod-hostport.yaml
apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
hostPort: 8081
此处映射的IP地址为该Pod所在node的IP
# curl 20.0.20.103:8081
Apache Tomcat/8.5.42
通过设置spce.hostNetwork=true,默认hostPort等于containerPort
apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
app: webapp
spec:
hostNetwork: true
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
2.将Service的端口映射到物理机
# cat webapp-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: webapp
spec:
replicas: 2
template:
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
# cat webapp-svcnodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30011
selector:
app: webapp
# curl 20.0.20.101:30011
Apache Tomcat/8.5.42