14 K8S 服务发现 Service


创建服务资源

利用单个地址访问一组 Pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@k8s-master1 demo]# kubectl get pods -L app
NAME READY STATUS RESTARTS AGE APP
kubia-cq4ht 1/1 Running 0 8s kubia
kubia-mwwxw 1/1 Running 0 8s kubia
kubia-rf5j4 1/1 Running 0 8s kubia

[root@k8s-master1 demo]# kubectl explain service
KIND: Service
VERSION: v1

[root@k8s-master1 demo]# vim kubia-svc.yaml

apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- port: 80 # 服务端口
targetPort: 8080 # 服务转发到容器的端口
selector: # 标签选择器 app: kubia 的pod都属于该服务
app: kubia

[root@k8s-master1 demo]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 3d16h
kubia ClusterIP 10.0.0.22 <none> 80/TCP 38s

# CLUSTER-IP 内部集群IP 内部访问

kubuctl exec 在运行的容器中远程执行命令

1
2
3
4
5
6
7
8
[root@k8s-master1 demo]# kubectl exec kubia-cq4ht -- curl -s 10.0.0.22
You've hit kubia-rf5j4

[root@k8s-master1 demo]# kubectl exec kubia-cq4ht -- curl -s 10.0.0.22
You've hit kubia-cq4ht

[root@k8s-master1 demo]# kubectl exec kubia-cq4ht -- curl -s 10.0.0.22
You've hit kubia-mwwxw

会话亲和性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# sessionAffinity: ClientIP  (默认为None)
# 同一个Client IP的请求会被转发到同一个Pod
# K8s 不支持 cookie的会话保持,因为k8s不是工作在http层上

[root@k8s-master1 demo]# vim kubia-svc.yaml

apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: kubia
sessionAffinity: ClientIP

[root@k8s-master1 demo]# kubectl exec kubia-cq4ht -- curl -s 10.0.0.62
You've hit kubia-rf5j4

[root@k8s-master1 demo]# kubectl exec kubia-cq4ht -- curl -s 10.0.0.62
You've hit kubia-rf5j4

[root@k8s-master1 demo]# kubectl exec kubia-cq4ht -- curl -s 10.0.0.62
You've hit kubia-rf5j4

指定多个端口 80 443

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 在1个容器服务中有多个服务端口 

[root@k8s-master1 demo]# vim kubia-svc.yaml

apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- name: http
port: 80
targetPort: 8080 # svc的 80 转发到 pod 的 8080
- name: https
port: 443
targetPort: 8443 # svc的 443 转发到 pod 的 8443
selector:
app: kubia


[root@k8s-master1 demo]# vim kubia-rs.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: kubia
spec:
replicas: 3
selector:
matchLabels:
app: kubia
template:
metadata:
labels:
app: kubia
spec:
containers:
- image: 172.31.228.68/project/kubia
name: kubia
ports:
- name: http
containerPort: 8080
- name: https
containerPort: 8443

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 3d16h
service/kubia ClusterIP 10.0.0.226 <none> 80/TCP,443/TCP 25s

服务发现

通过环境变量发现服务

1
2
3
1. 客户端如何知道svc的IP和端口?
2. 是否需要先创建svc,然后再手动查找IP再进行配置?
3. k8s提供了svc服务发现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1. 在pod开始运行前,k8s会完成一系列的环境变量配置
2. 如果你创建的服务早于客户端Pod的创建,那么pod可以根据环境变量获得服务的IP和端口

# 先删除之前创建的pod
[root@k8s-master1 demo]# kubectl delete pod --all

[root@k8s-master1 demo]# kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-55cbs 1/1 Running 0 103s
kubia-jpzvx 1/1 Running 0 103s
kubia-zkkgt 1/1 Running 0 103s
[root@k8s-master1 demo]# kubectl exec kubia-55cbs env
...
KUBIA_SERVICE_PORT_HTTP=80
KUBIA_SERVICE_HOST=10.0.0.226
KUBIA_SERVICE_PORT_HTTPS=443
KUBIA_SERVICE_PORT=80
...

通过 DNS 发现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[root@k8s-master1 demo]# kubectl exec kubia-55cbs bash

[root@k8s-master1 demo]# kubectl -it exec kubia-55cbs bash
root@kubia-55cbs:/# cat /etc/resolv.conf
nameserver 10.0.0.2
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

root@kubia-55cbs:/# curl http://kubia.default.svc.cluster.local
You've hit kubia-55cbs
root@kubia-55cbs:/# curl http://kubia.default.svc.cluster.local
You've hit kubia-jpzvx
root@kubia-55cbs:/# curl http://kubia.default.svc.cluster.local
You've hit kubia-zkkgt

# 解析:
http://kubia.default.svc.cluster.local
# kubia 服务名称
# default 命名空间
# svc.cluster.local 集群域名后缀

# 如果前端pod和数据库pod 在同一命名空间下 可以省略 svc.cluster.local 和 命名空间
root@kubia-55cbs:/# curl http://kubia.default
You've hit kubia-55cbs
root@kubia-55cbs:/# curl http://kubia.default
You've hit kubia-jpzvx
root@kubia-55cbs:/# curl http://kubia.default
You've hit kubia-zkkgt

root@kubia-55cbs:/# curl http://kubia
You've hit kubia-55cbs
root@kubia-55cbs:/# curl http://kubia
You've hit kubia-jpzvx
root@kubia-55cbs:/# curl http://kubia
You've hit kubia-zkkgt

root@kubia-55cbs:/# ping kubia
PING kubia.default.svc.cluster.local (10.0.0.246): 56 data bytes
64 bytes from 10.0.0.246: icmp_seq=0 ttl=64 time=0.054 ms

暴露服务

endpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1. 服务并不是和pod直接相连
2. 之间存在着endpoint
3. endpoint 就是暴露一组服务的IP和端口列表

[root@k8s-master1 demo]# kubectl describe svc kubia
Name: kubia
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=kubia
Type: ClusterIP
IP: 10.0.0.246
Port: http 80/TCP
TargetPort: 8080/TCP
Endpoints: 10.244.0.22:8080,10.244.1.28:8080,10.244.2.26:8080
Port: https 443/TCP
TargetPort: 8443/TCP
Endpoints: 10.244.0.22:8443,10.244.1.28:8443,10.244.2.26:8443
Session Affinity: None
Events: <none>

[root@k8s-master1 demo]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 172.31.228.67:6443 3d17h
kubia 10.244.0.22:8443,10.244.1.28:8443,10.244.2.26:8443 + 3 more... 18m

[root@k8s-master1 demo]# kubectl get ep kubia
NAME ENDPOINTS AGE
kubia 10.244.0.22:8443,10.244.1.28:8443,10.244.2.26:8443 + 3 more... 18m

将服务暴露到外部

1
2
3
4
5
6
# Service 类型
# 有三种方式可以在外部访问服务
1. NodePort: 在每个Node上分配一个端口作为外部访问入口
2. LoadBalancer: 工作在特定的Cloud Provider上,例如Google Cloud,AWS,OpenStack
3. Ingress: 通过一个IP地址公开多个服务 运行在7层http svc是4层
4. ClusterIP:默认,分配一个集群内部可以访问的虚拟IP(VIP)

创建 NodePort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@k8s-master1 demo]# vim kubia-ndp.yaml 

apiVersion: v1
kind: Service
metadata:
name: kubia-nodeport
spec:
type: NodePort
ports:
- name: http
port: 80 # svc 端口
targetPort: 8080 # pod 端口
nodePort: 30123 # 通过集群节点的30123可以访问该svc 如果不添加,默认随机分配一个端口
selector:
app: kubia

[root@k8s-master1 demo]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 3d18h <none>
kubia-nodeport NodePort 10.0.0.87 <none> 80:30123/TCP 55s

# 访问方式
1. NodePort也分配了CLUSTER-IP: 10.0.0.87:80
2. nodeip + 30123

[root@k8s-master1 demo]# netstat -tnlp | grep 30123
tcp6 0 0 :::30123 :::* LISTEN 944/kube-proxy

[root@k8s-node2 ~]# netstat -tnlp | grep 30123
tcp6 0 0 :::30123 :::* LISTEN 903/kube-proxy

查看 ipvsadm 规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@k8s-master1 demo]# kubectl get ep kubia-nodeport
NAME ENDPOINTS AGE
kubia-nodeport 10.244.0.22:8080,10.244.1.28:8080,10.244.2.26:8080 9m30s

[root@k8s-node1 ~]# ipvsadm -ln | grep 30123
TCP 172.17.0.1:30123 rr
TCP 10.244.0.0:30123 rr
TCP 10.244.0.1:30123 rr
TCP 127.0.0.1:30123 rr
TCP 172.31.228.69:30123 rr

# 都是向三台node上的podIP转发
TCP 172.31.228.69:30123 rr
-> 10.244.0.22:8080 Masq 1 0 0
-> 10.244.1.28:8080 Masq 1 0 0
-> 10.244.2.26:8080 Masq 1 0 0

域名应该找哪个node

1
2
3
4
5
6
7
8
还得有一层负载均衡
这层负载均衡负责 转发给 node集群+对外端口
域名解析 -> 负载均衡器nginx -> nodeIP+对外端口 -> ipvs -> pod+端口

# node1上的30123收到的请求 可以被转发到node1上的pod,也可能是node2上的

# 我使用的阿里云,如果是自建可以选择修改防火墙策略开放node端口
http://47.240.12.170:30123/

Load Badancer 通过负载均衡将服务暴露出来

1
2
3
4
5
6
7
8
1. nodeport 虽然可以解决外部暴露,但是当客户端连接的时候写了其中一个nodeip+端口,但是该node又出现问题会导致服务不可访问
2. nginx+nodeport可以解决该问题,但是还有Load Badancer方式

# 就是前面加一个LB
# LB 转发给 每个nodeIP+port
# 域名解析到LB地址
# 自建LB 需要知道 生成的端口是多少 再添加到LB
# 公有云 LoadBalancer LB 可以自动关联 提供访问 访问流程和NodePort一致
1
2
3
4
5
6
7
1. NodePort
用户 -> 域名 -> 负载均衡(阿里云公网)(后端手动添加) -> NodeIP(内网):Port -> PodIP+Port
2. LoadBalancer
用户 -> 域名 -> 负载均衡(阿里云公网)(自动添加) -> NodeIP(内网):Port -> PodIP+Port

1. LoadBalancer: 特定云提供商底层LB接口 例如aws,google,openstack,aliyun不知道有没有
2. NodePort : NodeIP 不固定,Node Port 可以固定

通过 Ingress 暴露服务

创建 Ingress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@k8s-master1 cfg]# kubectl explain ingress
KIND: Ingress
VERSION: extensions/v1beta1

[root@k8s-master1 demo]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 4d15h
kubia-nodeport NodePort 10.0.0.87 <none> 80:30123/TCP 21h

[root@k8s-master1 demo]# vim kubia-ingress.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: kubia
spec:
rules:
- host: kubia.example.com # 要映射的域名
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport # 转发到哪个 service
servicePort: 80 # 对应 kubia-nodeport svc 的 80 端口

# ingress控制器收到的 请求主机 kubia.example.com 的http请求,将被转发给 服务svc kubia-nodeport 的 80 端口

[root@k8s-master1 demo]# kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
kubia kubia.example.com 80 16s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 测试增加域名解析
# 不添加hosts的话 需要将域名接下到 部署控制器的 node节点上
# 实际工作环境 就是将 域名 解析到 NodeIP上

# windows 修改 hosts文件

# linux 修改 /etc/hosts
[root@k8s-master1 demo]# cat /etc/hosts
149.129.81.90 kubia.example.com
47.240.12.170 kubia.example.com
47.240.15.208 kubia.example.com

[root@k8s-master1 demo]# curl kubia.example.com
You've hit kubia-zkkgt
[root@k8s-master1 demo]# curl kubia.example.com
You've hit kubia-55cbs
[root@k8s-master1 demo]# curl kubia.example.com
You've hit kubia-jpzvx

通过不同路径 映射不同服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 在同一个主机(host),不同的路径上,ingress暴露出多个服务

[root@k8s-master1 demo]# vim kubia-ingress2.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: kubia
spec:
rules:
- host: kubia.example.com
http:
paths:
- path: /kubia # kubia.example.com/kubia 转发给 kubia-nodeport
backend:
serviceName: kubia-nodeport
servicePort: 80
- path: /index
backend:
serviceName: kubia-index # # kubia.example.com/index 转发给 kubia-index
servicePort: 80

不同的服务映射到不同的主机上(host)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# dns本地解析
149.129.81.90 kubia.example.com foo.example.com
47.240.12.170 kubia.example.com foo.example.com
47.240.15.208 kubia.example.com foo.example.com

[root@k8s-master1 demo]# vim kubia-ingress3.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: kubia
spec:
rules:
- host: kubia.example.com
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport
servicePort: 80
- host: foo.example.com
http:
paths:
- path: /
backend:
serviceName: kubia-index
servicePort: 80

配置 Ingress 处理 TLS 传输

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 处理 HTTPS 流量数据
# 证书和私钥需要放到 Ingress
# 需要先放在 secret 中,然后再yaml文件中引用

# 自制证书
[root@k8s-master1 demo]# openssl genrsa -out tls.key 2048
[root@k8s-master1 demo]# openssl req -new -x509 -key tls.key -out tls.cert -days 360 -subj /CN=kubia.example.com

# 创建 secret
[root@k8s-master1 demo]# kubectl create secret tls tls-secret --cert=tls.cert --key=tls.key
secret/tls-secret created

# 更新 yaml 文件

[root@k8s-master1 demo]# vim kubia-ingress.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: kubia
spec:
tls: # tls 配置
- hosts:
- kubia.example.com # 主机为 kubia.example.com 的 tls 连接
secretName: tls-secret # 从 tls-secret 中获取私钥和证书
rules:
- host: kubia.example.com
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport
servicePort: 80

[root@k8s-master1 demo]# kubectl apply -f kubia-ingress.yaml
ingress.networking.k8s.io/kubia created


[root@k8s-master1 demo]# curl -k -v https://kubia.example.com/
* About to connect() to kubia.example.com port 443 (#0)
* Trying 149.129.81.90...
* Connected to kubia.example.com (149.129.81.90) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
* subject: CN=kubia.example.com
* start date: Mar 14 01:40:52 2020 GMT
* expire date: Mar 09 01:40:52 2021 GMT
* common name: kubia.example.com
* issuer: CN=kubia.example.com
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: kubia.example.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.15.5
< Date: Sat, 14 Mar 2020 01:48:28 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< Strict-Transport-Security: max-age=15724800; includeSubDomains
<
You've hit kubia-jpzvx
* Connection #0 to host kubia.example.com left intact

Pod 就绪指针 就绪后发出信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# pod 现在作为 svc 服务的后端
# 新建的pod 只要具有服务的标签就会被服务代理,请求也会重定向新建的pod
# 如果 pod 没有准备好 如何处理这些请求
# 不想该pod 立即接收请求,直到完全准备就绪

# pod的指针
1. 存活指针
2. 就绪指针

# 当容器准备就绪探测返回成功时,标识容器准备好接收请求

# 存活指针 三类型
1. exec 探针 判断进程退出的状态码
2. httpget 探针 通过状态码
3. tcp socket 探针 判断端口连接

# 就绪指针操作流程:
# 1. 启动容器时 k8s配置一个等待时间 经过等待时间后才执行准备继续检查
# 2. 之后会周期性的调用探针,根据结果采取行动,如果pod未准备就绪,则会从服务中删除pod ,如果再次准备就绪就加入。
# 3. 就绪探针 与 存活探针不同,如果容器未通过检查,不会终止或者重新启动,这是主要区别
# 4. 存活探针杀死异常的容器并用心的容器替代来保持pod的正常工作
# 5. 就绪探针确保只有准备好处理请求的pod,才可以接收请求
# 6. 这在一个容器启动时都是必要的,当然在容器运行一段时间后也是有用的

添加就绪指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
[root@k8s-master1 demo]# vim kubia-rs.yaml 

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: kubia
spec:
replicas: 3
selector:
matchLabels:
app: kubia
template:
metadata:
labels:
app: kubia
spec:
containers:
- image: 172.31.228.68/project/kubia
name: kubia
readinessProbe:
exec:
command:
- ls
- /var/ready
ports:
- containerPort: 8080

# 就绪探针会定期在容器内执行 ls /var/ready ,如果文件存在,ls命令返回退出状态码0,否则非零
# 文件存在探针将成功,否则失败
# 更改 rs的模板对现有pod没有影响 需要删除pod重新创建
# 新建的应该处于就绪失败状态,不会作为服务的端点,直到每个pod中创建了 /var/ready 文件

[root@k8s-master1 demo]# kubectl delete rs kubia
replicaset.apps "kubia" deleted

[root@k8s-master1 demo]# kubectl create -f kubia-rs.yaml
replicaset.apps/kubia created

[root@k8s-master1 demo]# kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-7nwtf 0/1 Running 0 5m52s
kubia-cz2qh 0/1 Running 0 5m52s
kubia-shf8g 0/1 Running 0 5m52s

[root@k8s-master1 demo]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 172.31.228.67:6443 4d17h
kubia-nodeport 23h

# 在其中一个pod 创建文件
[root@k8s-master1 demo]# kubectl exec -it kubia-7nwtf -- touch /var/ready

[root@k8s-master1 demo]# kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-7nwtf 1/1 Running 0 7m
kubia-cz2qh 0/1 Running 0 7m
kubia-shf8g 0/1 Running 0 7m

[root@k8s-master1 demo]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 172.31.228.67:6443 4d17h
kubia-nodeport 10.244.2.33:8080 23h

[root@k8s-master1 demo]# kubectl describe pod kubia-7nwtf
Readiness: exec [ls /var/ready] delay=0s timeout=1s period=10s #success=1 #failure=3
# period 每10秒检查一次

# 所有请求都到了这个 pod
[root@k8s-master1 demo]# curl 10.0.0.87
You've hit kubia-7nwtf
[root@k8s-master1 demo]# curl 10.0.0.87
You've hit kubia-7nwtf
[root@k8s-master1 demo]# curl 10.0.0.87
You've hit kubia-7nwtf

就绪探针的实际作用

1
2
3
4
1. 应该通过删除pod 或者 更改pod标签来移除pod,而不是更改探针
2. enabled=true 可作为开关标签
3. 务必定义就绪探针 ,不能让pod立即成为服务端点
4. 不要将停止pod的逻辑纳入就绪探针,直接删除该容器,移除 Pod

使用 headless 服务来发现独立的 Pod

返回所有的 Pod IP

1
2
3
1. 常规 Service:执行服务的DNS时,返回服务的集群 IP(svc IP)
2. Headless Service: 不需要Cluster-IP,设置为Node ,客户端通过DNS A记录查找会获取该服务所有的Pod IP
3. 客户端可以使用该信息连接到其中的1个、多个或全部

创建 headless 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8s-master1 demo]# vim kubia-svc-headless.yaml 

apiVersion: v1
kind: Service
metadata:
name: kubia-headless
spec:
clusterIP: None # 设置为None
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: kubia
1
2
3
4
[root@k8s-master1 demo]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 4d18h
kubia-headless ClusterIP None <none> 80/TCP 49s

通过DNS来发现 Pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 临时任务 不重启 执行后销毁
[root@k8s-master1 demo]# vim busybox.yaml

apiVersion: v1
kind: Pod
metadata:
name: dns-test
spec:
containers:
- name: busybox
image: busybox:1.28.4
args:
- /bin/sh
- -c
- sleep 36000
restartPolicy: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[root@k8s-master1 demo]# kubectl apply -f busybox.yaml 

# 测试

[root@k8s-master1 demo]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 4d18h
kubia-headless ClusterIP None <none> 80/TCP 8m43s
kubia-nodeport NodePort 10.0.0.157 <none> 80:30123/TCP 34s
[root@k8s-master1 demo]# kubectl exec dns-test nslookup kubia-nodeport
Server: 10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name: kubia-nodeport
Address 1: 10.0.0.157 kubia-nodeport.default.svc.cluster.local

[root@k8s-master1 demo]# kubectl exec dns-test nslookup kubia-headless
Server: 10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name: kubia-headless
Address 1: 10.244.1.32 10-244-1-32.kubia-headless.default.svc.cluster.local
Address 2: 10.244.2.33 10-244-2-33.kubia-headless.default.svc.cluster.local
Address 3: 10.244.0.27 10-244-0-27.kubia-headless.default.svc.cluster.local

[root@k8s-master1 demo]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dns-test 1/1 Running 0 5m37s 10.244.1.33 k8s-node2 <none> <none>
kubia-7nwtf 1/1 Running 0 47m 10.244.2.33 k8s-master1 <none> <none>
kubia-cz2qh 1/1 Running 0 47m 10.244.1.32 k8s-node2 <none> <none>
kubia-shf8g 1/1 Running 0 47m 10.244.0.27 k8s-node1 <none> <none>

# headless 直接返回了 pod的IP ,在容器中可以通过 该解析访问 为后面的有状态部署提供帮助

[root@k8s-master1 demo]# kubectl exec dns-test ping 10-244-0-27.kubia-headless.default.svc.cluster.local
PING 10-244-0-27.kubia-headless.default.svc.cluster.local (10.244.0.27): 56 data bytes
64 bytes from 10.244.0.27: seq=0 ttl=62 time=0.724 ms

排查服务故障

1
2
3
4
5
1. 先确保从集群内连接到服务集群IP(svc ip)
2. 是否定义了 就绪探针 ,返回是否成功
3. 检查端点 查看pod是否加入到 service , kubectl get ep
4. 检查svc暴露的端口
5. 检查pod的服务是否正常