kubernetes快速入门7-service资源

kubernetes快速入门7-service资源

因pod有生命周期,客户端的请求不应该指向pod,service就为客户端访问Pod提供一个较固定的端点。service工作依赖于一个附件叫Core-DNS,较老版本中叫Kube-DNS,此附件为service中3 O . l ^的名称与集群ip地址提供解析服务。

kubect@ * l m z 6 P v [lapiserver提交service相关资源对象信息,并把资源信息保存在etcd中,各工作节点上的 kube-proxy时刻监视(watch)着etch & - _ o Wd上相应的资源变更情况,一n R U e D K # f I旦有service相应的资源创建,删除,变化等就把相应资源的变化转换为当前节点上的iptablese U P z D n N规划或ipvs规则,使service能o M 0 f够到达相应的PoS w ( i x p _ %d资源S 3 L ] } . 4的目标状态。

service的代理模型

userspac0 q 9 ` 2 R a 9e

k8s 1.1之前的版本使用此种模型,工作流程为:

  1. 用户I 9 f | o空间的客户端pod向内核空间的service发起请求,service会把请求转交给该节点的kube-proxy. u 4 # H P ] 调度
  2. kube-proxy调度后又回到v $ v =service,再向目标pod所在节点的kube-proc - + . + ^ }xy发送请求,依赖iptaL d w T s = 3 Hbles规则再调度到相应的pod

iptables

k^ ? ; e F ! j 9 -8s 1.10之前的v } s + b H # q ;版本默N c c ^ Q 9 V %认使用此种模型,工作流程为:

  1. 用户空间的客N / W | E I 4户端1 _ L Qpod向内核空间的service发起请求,直接由service进行调度,并依赖相应节点上的iptables把流量调度到目标pod

iz [ H ; , h { /pvs

k8s 1.11版本开始,默认使用此种模型,工作流程为:

  1. 用户空间的客户端pod向内核空间的sR u c # q ) b 9erv} ` Pice发起请求,直接由servt y E _ T W aice进行调度,并依赖相应节点上的ipvs把流量调度到目标pod

service资源配置

使用kubectl explain servicU o &e查看各个字段的帮助说明

KIND:     Service
VERSION:  v1   属于核心组的v1版本
FIELDS:
spec <Object>
p/ @ + X ) y L z #o6 ] frtsC f O - 5 ( L Y   <[]Object>  service端口与后端的pod的端口` A j `对应
name    <string>       名称
nJ , ) X r 6odePort    <integer&g7 x at;  当 type设置为NodePort才生效,指定映射到工作节点的端口,默认范围:30000-32767
port    <integer>      必选项,发布的端口
protocol    <string>   协议
targetPort  <string> 目标pod使用的端口
selector    <map[string]string>   关联到哪些标签的Pod
sessionAffinity  <string>   会话粘性,Supports "ClientIP" and "None"
type    <string>  serX { - r Y W Rvicb 5 n )  Ee的类型,ExternalName,5 K g ClusterIP, NodePort, and LoadBalanc/ O N } R N ~ 3 =er. Defaults to ClusterIP

service资源记录格式:

SVC_NAME.NS_NAME.D1 ; M 4 3  nOMAIN.LTD  k8s默认的域名后缀为 svc.cluster.local
如 DaemonSet 章节定义的 svc-redis 服务一样,连接redis的服务域? ! j h ~ } . h ,名为 redis.defauD U 8lt.svc.cluster.local

service类型

ClusterIP

最为常见的@ Y Q I 1 w Y K类型,默认使用该类型,该集群IP地址不是配置在某个设备上的地址,而只是出现8 H [ 5 b 5 d y在Iptablesf ! (或ipvs中的地址,无法Ping通

NodePort

把pod的端口发布到每一个工作节点上的某个端口(默认范围:30000-32767),使用工作节点的该端口可以向k8s集群外的环境提供相应的服务

LoadBalancer

在aN B 0 N / f Yliyun, AWSs k Cd a O y Y L L这种云环境下部署k8s后可以借助厂商的LBAAS底层接口调用相应F p @ X d的LB服务实现负载

ExternalName

参考文档:

https://kubernetes.io/zh/docs/concepts/services-networking/service/#%E6%B2%A1%E6%9C%89-sem z - H ` 7 7 % ^lector-%E7%9A%84-service

https://kubeK o ~rnetQ ( -es.io/zh/docs/concepts/serviI [ 0ces-networking/service/#externalname

ExternalName类型是service的特例,它没有selek y 8 r g ? xctor,它将服务映射到一个合法的DNS名称,而不是选择器,集群中查找该服务名称时,coredns返回指向合法DNS的CNAME记录。

适用场景:

  1. 希望在生产环境中使用外部的数据库集M | B * A n群,但测试环境使用自己的数据库
  2. 希望服务指x ; x @ A R [ S向另一个 命名空间

如生产环境中使用0 ( / s d & *了第三方提供的云数据库(如RDS),此时就可以定义一个ExternalName类型的service,让集群内部使用的service名称映射到云数据库的地址。

如果k8s集群定义了多个名称空间,跨名称空间的service名称访问就需要带上各自的名称空间的名称,如果都想用一个名称空间的名称(如default)来访问其他名称空间的service,那也需要使用ExternalName类型的service,以下举个这样的事例。

创建命名空间

k8s@node01:~$ kuh + Q |bectl create namespace nginx-test
k8s@node01:~$ kubectl get namespace
NAME              STATUx ` a ( 9S   AGE
default           Active   4d18h
kube-node-lease   Active   4d18h
kube-public       Active   4d18h
kube-system       Active   4d18h
nginx-test        Active   76m

配置J l W W S a清单

k8s@noR h f Jde01:~/my_maL Z 4 D { !nifests$ cat test/deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
ni  p g eame: nginx
namespa[ ( } b T kce: nginx-test
spec:
replicas: 1
selector:
matchLabels:
app: ngint , Y t } T l , Jx
template:
metadata:
labels:
app: nginx
spec:
containers:
- na: F 4 hme: nginx
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
---
apiVersionm 1 ^ }: v1
kind: Service
metadata:
name: nginx01
namespace: nginx-test
spec:
selecto9 w y J u l ( ]r:
app: nginx
ports:
- name: http
port: 80
targetPort:$ / 4  F `  W http
---
apiVersion: v1
kind: Service
metadata:u ! j q y S m m ^
name: nginx01-svc
namespace: default
spec:
type: ExternalNae L -me
externalName: nginx01.nginx-ts e  )est.svc.cluster.local
ports:
- name: htt7 1 T 6 ~ A e K ap8080
port: 8080
targetPort: 80
---l N  = : E 5 w
apiV* Z ; K + ^ersion: v1
kind: PodM i J Y ~ ;
metadata:
name: bbox
namespacF U X ! x ! E l ie: default
spec:
containers:
- name: bur o K b ; L 2 Wsybox
image: busybox:latest
command: ["/bin/sh", "-c", "sleep 3600"]
k8s@node01:~/my_manifV [ { v *ests$ kubectl a! b c S cpply -f testd 5 Q F n/deploy-nginx.yaml
deployment.apps/nginx creaU S ) V t ) Q : mted
service/nginx01 created
service/nginx01-svc created0 d ? 7 N  e
pod/bbox created

测试服务的名称的解析地址

# 确定集群内coredns的地址
k8s@node01:~$ kubectl get svc -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORF 6 I 5 + nT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TC6 3 X I  ( 0P,9153/TCP   4$ V ` M s Id17h
k8s@node01:~/my_manifests$ kubectl get svc -n nginx-test
NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S6 } n e / B : 3)   AGE
ngin[ ] 4 / ? n V 0x01   Cl3 ! RusterIP   10.103.254.90   <none>        80/TCP    4m41s
k8s@node01U h { ! v P & ] e:~/my_manifestsZ  y ~ Z 3$ kubectl get svc
NAME          TYPE           CLN L o L )USTER-IP   EXTERNAL-IP                            PORT= ` 2 B y n | 7 t(S)    AGE_ @ 1 ] Y w V
kubernetes    ClusterIP      10.96T ! ( U.0.1    <none>                                 443/TCP    4d18h
ngiE q ^ M ] | ^ Bnx01-svc   ExternalName   <nou 7 ; ne>       nginx01.nginx-test.svc.cluster.local   8080/TCP   4m57s
# nginx-test 名称空间中的servV  j I U j : k wice名称解析,能正常解析出对应的IP地址
k8s@node01:~= s  o o$ dig -t A nginx01l C n Z 2 4 k n.nginx-test.svc.cluster.lo3 z # & F ~cal @10.96.0.10
...
ng= W j `inx01.ngig Y 2 ) ] x ! k 3nx-test.svc.cluster.local. 30 IN A   10.103.254.90
# 使用默认名称空间的地址进行解析,指向了externalName中定义的地址
k8s@node01:~$ dig -t A nginx01-svX @ X P ?c.1 . - rdefault.svc.cluster.local @10.96.n ] q ( [0.10
...
nginx01-svc.default.svc.cluster.local. 30 IN CNAME nginx01.nginx-t O A i U J yest.svc.cluster.local.
nginx01.ngR ] t = ;  P &inx-test.svc.clust 6 ? eer.local. 30 IN A   10.103.254.90

Headlu o L iess Services

无头服务,此种service没有ClusterIP地址,spec.clb | Y eusterIP值设置为"None"即创建无头服务。此service后端有哪些pod依赖selector的定义。

k8s@node01:~/Z | umy_manifests$ cat headless-service.yaml
apiVersih N  r | t 8 Pon: apps/v1
kind: Deployment
metadata:
name: nginx-cluster
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
lab [ % ^ %bels:
app: nginx7 e J
spec:
containers:
- name: nginx
image: ikubernetes/myZ i ? t B aapp:v1
imagePullPolicy: IfNotPresent
---
apiVersion: vX U 7 i 7 ^ _ A :1
kind: Service
metadata:
name: headless-svc-nginx
namespace: default
spec:
clusterIx 4 ! k } d x t /P: "None"
selector:
app: nginx
k8s@node01:~/my_manifests$ kubectl apply -f headless-service.yaml
deployment.apps/nginx-cluster created
servicel z ; Y ~/headless-svc-nginx created
k8s@node01:~/my_manifests$ kubectl geta s 3 J k [ T pods -o wide
NAMQ z A L v 4E                             READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
bbox                             1/1     Running   0          42m   10.244.2.78   node03   <none>           <no( n W 6 5 =ne>
nginx-( K 7clusterF I ; T 7 g H [-7469b9bbf5-b9jdr   1/1     Running   0          8s    10.244.2.79   nodi T A be03   <none>           <none>
nginx-cluster-7469b9bbf5-bqf94   1/1     Running   0          8s    10.244.1.62   node02   <none>           <none>
nginx-cluster-7469b9bbf5-pgn [ e % $7zs   1/1     Running   0          8s    1w ) A0.244.1.61   node02   <noneZ u T Y Y }>           <none>
k8s@node01:~/my_manifests$ kubectl get sv? L _ / 5 pc  # cluster-ip为 None
Nd r _ 1 6 k AME                 TYPE           CLUSTER-IP   EXTERNAL-IP                            PORT(S)    AGE
headless-svc-nginx   Cluster` 4 A g -IP      None         <none>                                 <none>     16s
kubernetes           ClusterIP      10.96.0.1    <noneW Q i>                                 443/TCP    4d19h
nginx01-svc          ExterB y i m d L U (nalName   <none&: l x p Qgt;       nginx01.nginx-tes2 d I Ft.svc.cluster.local   8080/TCP   42m
# service名称解析出seletor关联到的Pod的IP地址
k t &8s@node01:~$ dig -t A headleso : { } hs-svc-nginx.default.svc.cluster.local @10.9o ^ + w d6.0.10
...
;; ANSWER SECTION:
headless-svc-nginx.default.svc.cluster.local. 30 IN A 10.244.1.61
headless-s } / Bvc-nginx.default.svc.cluster.local. 30 IN A 10.244.1.62
headless-svc-nginx.default.svc.cluster.local. 30 IN A 10.244.2.79

Endpoints资源

到目前为止我们一直认为service为pod提供了个对外固定的访问端点8 A v u N F,ser( ( ( _ m & [vice的后端就应该是pod,而y 1 e y 5 8实际上service的后b o A B ? [ I _端是En` L i [dpoints资源,其后才是pod资源。如果k8s集群外有个服务需要在集群内部进行访问,也可以通过自定义Endpoints资源并配合无selector的sen { Grvice来进行访问,详细信息请参考这里:https://kubernetes.io/zh/docs/concepts/services-networking/service/#%E6%B2%A1%1 g : @ 8E6%9C%89-selector-%E7%9A%84-service