共计 6520 个字符,预计需要花费 17 分钟才能阅读完成。
Service简介
service控制器定义了一组网络逻辑集合(通常由Label Selector)和一个访问入口策略,目前常用service控制器有四种
- NodePort
- LoadBalancer
- ClusterIP
- ExternalName
NodePort
对于 NodePort 类型的 Service,k8s为其分配一个节点端口(对于同一 Service,在每个节点上的节点端口都相同),该端口的范围在初始化 apiserver 时可通过参数 –service-node-port-range 指定(默认是:30000-32767)。NodePort 类型访问方式:
- 在集群内部通过 $(ClusterIP): $(Port) 访问
- 在集群外部通过 $(NodeIP): $(NodePort) 访问
# 创建测试deployment文件
[root@master service-test]# cat nginx2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx2
labels:
app: nginx2
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
initContainers:
- name: init-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh"]
env:
# - name: MY_POD_NAME
# valueFrom:
# fieldRef:
# fieldPath: metadata.name
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
args:
[
"-c",
"echo ${HOSTNAME} ${MY_POD_IP} > /wwwroot/index.html",
]
volumeMounts:
- name: wwwroot
mountPath: "/wwwroot"
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
volumes:
- name: wwwroot
emptyDir: {}
# 创建deployment
[root@master service-test]# kubectl apply -f nginx2.yaml
deployment.apps/nginx2 created
# 查看详情
[root@master service-test]# kubectl get pods -l app=nginx2 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx2-6b7d48d445-4rr7p 1/1 Running 0 4m37s 10.100.166.137 node1 <none> <none>
nginx2-6b7d48d445-jf7jf 1/1 Running 0 4m37s 10.100.104.9 node2 <none> <none>
nginx2-6b7d48d445-zh598 1/1 Running 0 4m37s 10.100.104.10 node2 <none> <none>
创建 NodePort Service类型服务
[root@master service-test]# cat >nginx2-nodeport.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx2-nodeport
spec:
type: NodePort
selector:
app: nginx2
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
EOF
[root@master service-test]# kubectl apply -f nginx2-nodeport.yaml
service/nginx2-nodeport created
[root@master service-test]# kubectl get -f nginx2-nodeport.yaml
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx2-nodeport NodePort 10.96.31.19 <none> 80:30985/TCP 7s
测试验证 NodePort 类型服务
# 访问任意node的30985端口
[root@master service-test]# curl 10.200.1.139:30985
nginx2-6b7d48d445-4rr7p 10.100.166.137
[root@master service-test]# curl 10.200.1.139:30985
nginx2-6b7d48d445-jf7jf 10.100.104.9
[root@master service-test]# curl 10.200.1.139:30985
nginx2-6b7d48d445-zh598 10.100.104.10
# 访问NodePort服务的clusterip
[root@master service-test]# curl 10.96.31.19
nginx2-6b7d48d445-zh598 10.100.104.10
[root@master service-test]# curl 10.96.31.19
nginx2-6b7d48d445-jf7jf 10.100.104.9
[root@master service-test]# curl 10.96.31.19
nginx2-6b7d48d445-4rr7p 10.100.166.137
ClusterIP
ClusterIP 类型的 Service 会拥有一个 clusterip(vip),仅可在集群内访问,集群外无法访问。
# 创建测试deployment文件
[root@master service-test]# cat >nginx1.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
labels:
app: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
initContainers:
- name: init-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh"]
env:
# - name: MY_POD_NAME
# valueFrom:
# fieldRef:
# fieldPath: metadata.name
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
args:
[
"-c",
"echo ${HOSTNAME} ${MY_POD_IP} > /wwwroot/index.html",
]
volumeMounts:
- name: wwwroot
mountPath: "/wwwroot"
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
volumes:
- name: wwwroot
emptyDir: {}
EOF
# 创建deployment
[root@master service-test]# kubectl apply -f nginx1.yaml
deployment.apps/nginx1 created
[root@master service-test]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-9f5cb7f94-nbctt 1/1 Running 0 5d21h 10.100.104.2 node2 <none> <none>
nginx1-859486d7bb-7mc4h 1/1 Running 0 11s 10.100.166.136 node1 <none> <none>
nginx1-859486d7bb-r2sg4 1/1 Running 0 11s 10.100.166.135 node1 <none> <none>
nginx1-859486d7bb-shzzp 1/1 Running 0 11s 10.100.104.8 node2 <none> <none>
此时为 nginx1 创建一个 ClusterIP 类型 Service,ClusterIP 是 ServiceType 的默认值。
[root@master service-test]# cat >nginx1-clusterip.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx1-clusterip
spec:
selector:
app: nginx1
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
EOF
[root@master service-test]# kubectl apply -f nginx1-clusterip.yaml
service/nginx1-clusterip created
[root@master service-test]# kubectl get -f nginx1-clusterip.yaml
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
[root@master service-test]# kubectl get -f nginx1-clusterip.yaml
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx1-clusterip ClusterIP 10.96.218.0 <none> 80/TCP 43m
# 查看该service对应的Endpoints
[root@master service-test]# kubectl describe svc nginx1-clusterip
Name: nginx1-clusterip
Namespace: default
Labels: <none>
Annotations: Selector: app=nginx1
Type: ClusterIP
IP: 10.96.218.0
Port: http 80/TCP
TargetPort: 80/TCP
Endpoints: 10.100.104.8:80,10.100.166.135:80,10.100.166.136:80
Session Affinity: None
Events: <none>
测试访问验证clusterip
[root@master service-test]# curl 10.96.218.0
nginx1-859486d7bb-shzzp 10.100.104.8
[root@master service-test]# curl 10.96.218.0
nginx1-859486d7bb-7mc4h 10.100.166.136
[root@master service-test]# curl 10.96.218.0
nginx1-859486d7bb-r2sg4 10.100.166.135
LoadBalance
LoadBalance 类型Service 可提供外部负载均衡访问入口,由云服务商定义写法,本文不再描述
参考链接:https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer
ExternalName
ExternalName 类型 Service 可提供映射外部服务,上面那些类型 Service 是提供内部服务映射的。通常用于外部服务发生服务维护切换服务入口链接,此时便要修改应用程序链接地址,不方便。所以可以使用 ExternalName 给外部服务地址做Cname 映射。其他Service的转发发生再porxy,而这个则是再DNS Level
# 创建ExternalName demo服务,externalName字段不能填写ip地址,会被当做字符串域名。
[root@master service-test]# cat >test-externalname.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
type: ExternalName
externalName: www.xadocker.cn
EOF
[root@master service-test]# kubectl apply -f test-externalname.yaml
[root@master service-test]# kubectl get -f test-externalname.yaml
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ExternalName <none> www.xadocker.cn <none> 7m58s
[root@master service-test]# kubectl describe -f test-externalname.yaml
Name: my-service
Namespace: default
Labels: <none>
Annotations: Selector: <none>
Type: ExternalName
IP:
External Name: www.xadocker.cn
Session Affinity: None
Events: <none>
测试
# 此时集群应用可以使用 my-service.default.svc.cluster.local 来调用该服务
# 创建一个busybox来测试解析域名
[root@master service-test]# cat >busybox.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
name: test-busybox
labels:
app: test-busybox
spec:
containers:
- name: test-busybox
image: busybox:latest
command: ['sh','-c','echo testing! && sleep 3600']
EOF
[root@master service-test]# kubectl apply -f busybox.yaml
[root@master service-test]# kubectl exec -it test-busybox -- /bin/sh
/ # nslookup my-service.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10:53
my-service.default.svc.cluster.local canonical name = www.xadocker.cn
Name: www.xadocker.cn
Address: 43.13.47.25
*** Can't find my-service.default.svc.cluster.local: No answer