k8s的无头服务

k8s的无头服务

Headless Services是一种特殊的service,其spec:clusterIP表示为None,这样在实际运行时就不会被分配ClusterIP,也被称为无头服务,通过DNS解析提供服务发现。与普通服务不同的是Headless Services不提供负载均衡功能,每个Pod都有唯一的DNS记录,直接映射到其IP地址,适用于有状态应用的场景,如与StatefulSet一起部署数据库。这种服务使得直接访问单个Pod成为可能,而不经过负载均衡器。

因为 Headless Service 属于 Service ClusterIp 类型,所以在讲解Headless Service前,先简单说下 Service 和服务发现。

构建镜像

[root@chenby ~]# cat > Dockerfile <<EOF
FROM nginx
RUN echo '这是一个本地构建的nginx镜像,第一版' > /usr/share/nginx/html/index.html
EOF

docker build -t z.oiox.cn:18082/library/cby:v1 .

docker push z.oiox.cn:18082/library/cby:v1

编写yaml文件

我这里只是创建了一个最简单的容器,由StatefulSet控制器来管理,同时创建了无头服务的svc

cat > cby.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None   #这使得服务成为无头服务
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: z.oiox.cn:18082/library/cby:v1
        ports:
        - containerPort: 80
          name: web
EOF

查看已经创建的资源

[root@k8s-master01 ~]# kubectl get statefulsets
NAME   READY   AGE
web    2/2     12m
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# kubectl get pod 
NAME                            READY   STATUS    RESTARTS      AGE
web-0                           1/1     Running   0             12m
web-1                           1/1     Running   0             12m
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
nginx          ClusterIP   None             <none>        80/TCP     12m
[root@k8s-master01 ~]# 

修改web-1的html内容

statefulsets控制器是可以将存储持久化的,我这里没做存储持久化,这里就进入容器内进行修改页面信息

kubectl exec web-1 -- sh -c 'echo 这是一个本地构建的nginx镜像,第二版 > /usr/share/nginx/html/index.html'

测试修改是否成功

[root@k8s-master01 ~]# kubectl get pod -o wide |grep web
web-0                           1/1     Running   0             40m   10.0.0.28    k8s-node02   <none>           <none>
web-1                           1/1     Running   0             40m   10.0.3.243   k8s-node01   <none>           <none>
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# curl 10.0.0.28
这是一个本地构建的nginx镜像,第一版
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# curl 10.0.3.243
这是一个本地构建的nginx镜像,第二版
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# 

查看svc的详细

这里可以看到Endpoints已经关联到了后端的pod容器

[root@k8s-master01 ~]# kubectl describe svc nginx
Name:                     nginx
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       None
IPs:                      None
Port:                     web  80/TCP
TargetPort:               80/TCP
Endpoints:                10.0.0.28:80,10.0.3.243:80
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
[root@k8s-master01 ~]#

创建busybox测试容器

cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - name: busybox
    image: docker-ce.chenby.cn/library/busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
EOF

进入测试容器

[root@k8s-master01 ~]# kubectl exec -ti busybox -- sh
/ # 
/ # 
/ # ping nginx.default.svc.cluster.local 
PING nginx.default.svc.cluster.local (10.0.0.28): 56 data bytes
64 bytes from 10.0.0.28: seq=0 ttl=63 time=0.066 ms
64 bytes from 10.0.0.28: seq=1 ttl=63 time=0.077 ms
64 bytes from 10.0.0.28: seq=2 ttl=63 time=0.070 ms
^C
--- nginx.default.svc.cluster.local ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.066/0.071/0.077 ms
/ # 
/ # 
/ # 
/ # ping web-0.nginx.default.svc.cluster.local 
PING web-0.nginx.default.svc.cluster.local (10.0.0.28): 56 data bytes
64 bytes from 10.0.0.28: seq=0 ttl=63 time=0.046 ms
64 bytes from 10.0.0.28: seq=1 ttl=63 time=0.079 ms
64 bytes from 10.0.0.28: seq=2 ttl=63 time=0.064 ms
^C
--- web-0.nginx.default.svc.cluster.local ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.046/0.063/0.079 ms
/ # 
/ # 
/ # 
/ # ping web-1.nginx.default.svc.cluster.local 
PING web-1.nginx.default.svc.cluster.local (10.0.3.243): 56 data bytes
64 bytes from 10.0.3.243: seq=0 ttl=63 time=0.369 ms
64 bytes from 10.0.3.243: seq=1 ttl=63 time=0.373 ms
64 bytes from 10.0.3.243: seq=2 ttl=63 time=0.328 ms
^C
--- web-1.nginx.default.svc.cluster.local ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.328/0.356/0.373 ms
/ # 
/ # 
/ # 
/ # 
/ # cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.0.0.238  busybox
/ # 
/ # 
/ # 
/ # 

进行访问性测试

[root@k8s-master01 ~]# kubectl exec -ti nginx-demo-cccbdc67f-6nkgd -- sh
/ # 
/ # 
/ # curl nginx.default.svc.cluster.local
这是一个本地构建的nginx镜像,第二版
/ # curl nginx.default.svc.cluster.local
这是一个本地构建的nginx镜像,第一版
/ # 
/ # 
/ # 
/ # curl web-0.nginx.default.svc.cluster.local 
这是一个本地构建的nginx镜像,第一版
/ # curl web-0.nginx.default.svc.cluster.local
这是一个本地构建的nginx镜像,第一版
/ # curl web-0.nginx.default.svc.cluster.local
这是一个本地构建的nginx镜像,第一版
/ # 
/ # 
/ # 
/ # curl web-1.nginx.default.svc.cluster.local 
这是一个本地构建的nginx镜像,第二版
/ # curl web-1.nginx.default.svc.cluster.local
这是一个本地构建的nginx镜像,第二版
/ # curl web-1.nginx.default.svc.cluster.local
这是一个本地构建的nginx镜像,第二版

总结

在某些场景中,无需对外提供访问能力,只需要在内部找到自己想找到的Pod资源时,可以通过Headless Service来实现。这种不具有ClusterIP的Service资源就是Headless Service,该 Service 的请求流量不需要 kube-proxy 处理,也不会有负载均衡和路由规则,而是由ClusterDNS的域名解析机制直接去访问固定的Pod资源。

既然是Headless Service,那首先它是Service,一般的Service能被内部和外部访问。之所以叫Headless Service,是因为只对内提供访问,既然只对内访问,那肯定就需要提供稳定的访问能力了,否则就没什么作用了。比如说拥有固定的Pod名称和存储,所以一般会结合StatefulSet一起使用,用来部署有状态的应用。

如果想让部署的有状态应用暴露给集群外部客户端访问的话,可以新建个普通(有ClusterIP)的服务,通过标签选择关联有状态服务实例。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容