Kubernetes学习笔记(四):服务

服务介绍#

服务是一种为一组相同功能的pod提供单一不变接入点的资源。当服务存在时,他的IP和端口不会改变。客户端通过IP和端口建立连接,这些连接会被路由到任何一个pod上。如此,客户端不需要知道每个单独提供服务的pod地址,这些pod也可以随时被创建、删除。

服务通过标签选择器决定选择哪些pod。

准备镜像#

首先要准备一个能够提供web服务的镜像,作者将镜像存储到了阿里云的镜像仓库。

web.go#

监听8000端口,接到请求输出当前hostname

Copy
package main import ( "fmt" "log" "net/http" "os" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { hostname,_ := os.Hostname(); fmt.Fprintf(w,"this is %v\n",hostname) }) log.Fatal(http.ListenAndServe(":8000",nil)) }

Dockerfile#

多步骤构建,有关与此以及Dockerfile的文章请见:Docker学习笔记(三):Dockerfile及多步骤构建镜像

Copy
FROM golang:1.14-alpine COPY goweb.go /src/ RUN CGO_ENABLED=0 GOOS=linux go build -o /bin/goweb /src/goweb.go FROM alpine COPY --from=0 /bin/goweb /usr/local/bin/ RUN apk add --no-cache curl EXPOSE 8000 CMD ["/usr/local/bin/goweb"]

构建、测试、推送#

构建完成

Copy
-> [feifei@ffmac.local] [~/work/service] docker build -t registry.cn-hangzhou.aliyuncs.com/orzi/goweb . Sending build context to Docker daemon 3.072kB ...... Successfully built 3db4b643ba0a Successfully tagged registry.cn-hangzhou.aliyuncs.com/orzi/goweb:latest

运行镜像,本地8001映射到容器的8000

Copy
-> [feifei@ffmac.local] [~] docker run --rm -d -p 8001:8000 registry.cn-hangzhou.aliyuncs.com/orzi/goweb 6241a412caeacfe5f025d20af154b2eba98555fcb2b2f55742154a9e6fa46817

请求本地的8001端口

Copy
-> [feifei@ffmac.local] [~] curl http://localhost:8001 this is 6241a412caea

没有问题,推送

Copy
-> [feifei@ffmac.local] [~] docker push registry.cn-hangzhou.aliyuncs.com/orzi/goweb The push refers to repository [registry.cn-hangzhou.aliyuncs.com/orzi/goweb] 8c5325633e9a: Pushed 3e207b409db3: Pushed latest: digest: sha256:2704d806836060237169ea59cfda238c50fc5e5881e15cb1230200b5c8b2f5a0 size: 739

创建服务#

goweb-rs.yaml#

Copy
apiVersion: apps/v1 kind: ReplicaSet metadata: name: goweb-rs spec: replicas: 2 selector: matchLabels: app: goweb template: metadata: labels: app: goweb spec: containers: - name: goweb image: registry.cn-hangzhou.aliyuncs.com/orzi/goweb ports: - containerPort: 8000

goweb-svc.yaml#

Copy
apiVersion: v1 kind: Service metadata: name: goweb-svc spec: ports: - port: 80 # 服务的端口 targetPort: 8000 # 服务将连接转发到容器的端口 selector: # 匹配此选择器的都属于这个服务 app: goweb

创建一个名为goweb-svc的服务,它将在80端口接收请求并将连接路由到具有标签app=goweb的pod的8000端口上。

创建#

Copy
-> [root@kube0.vm] [~] k create -f goweb-svc.yaml service/goweb-svc created -> [root@kube0.vm] [~] k create -f goweb-rs.yaml replicaset.apps/goweb-rs created -> [root@kube0.vm] [~] k get all NAME READY STATUS RESTARTS AGE pod/goweb-rs-6n6fw 1/1 Running 0 14m pod/goweb-rs-vkwqb 1/1 Running 0 14m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/goweb-svc ClusterIP 10.104.46.76 <none> 80/TCP 9s service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 40h NAME DESIRED CURRENT READY AGE replicaset.apps/goweb-rs 2 2 2 14m

kubectl exec#

访问服务可以在集群节点上直接访问,如:

Copy
-> [root@kube0.vm] [~] curl http://10.104.46.76 this is goweb-rs-vkwqb -> [root@kube0.vm] [~] curl http://10.104.46.76 this is goweb-rs-6n6fw

或者通过kubectl exec命令在已存在的pod上执行curl

Copy
-> [root@kube0.vm] [~] k exec goweb-rs-vkwqb -- curl -s http://10.104.46.76 this is goweb-rs-vkwqb -> [root@kube0.vm] [~] k exec goweb-rs-vkwqb -- curl -s http://10.104.46.76 this is goweb-rs-6n6fw

双横杠表示kubectl命令项的结束,在此之后的是指要在pod内部执行的命令。这是为了避免异常和歧义,如果需要执行的指令中没有横杠,那么可以不用双横杠。

sessionAffinity#

使用svc.spec.sessionAffinity设置会话亲和性,默认是None。指定为ClientIP会使来自同一个Client IP的请求转发到同一个Pod上。
Kubernetes只支持这两种亲和性设置,不支持cookie,因为Kubernetes不在HTTP层面工作。服务处理TCP和UDP包,不关心其中的内容。

一个服务暴露多个端口#

创建一个多端口服务时,必须给每个端口指定名字。

为服务指定多个端口#

Copy
apiVersion: v1 kind: Service metadata: name: goweb-svc spec: ports: - name: http port: 80 targetPort: 8000 - name: https port: 443 targetPort: 8443 selector: app: goweb

使用命名的端口#

使用方法是:在Pod(或其他资源的Pod模板)的spec.containers.ports.name配置中指定端口名称,然后Service中的spec.ports.targetPort引用。

使用命名端口的好处在于,当Pod更改端口号时,不会影响到Service,因为Service引用的是端口名。

Pod中指定端口名:

Copy
spec: containers: - name: goweb ports: - name: http # 命名8000端口为http containerPort: 8000 - name: https # 命名8443端口为https containerPort: 8443

Service中引用:

Copy
apiVersion: v1 kind: Service metadata: name: goweb-svc spec: ports: - name: http # 将80端口映射到容器中名为http的端口 port: 80 targetPort: http - name: https # 将443端口映射到容器中名为https的端口 port: 443 targetPort: https selector: app: goweb

服务发现#

通过环境变量发现服务#

在容器中执行env,列出一部分结果。
服务名称中的横线被转换为下划线,并且全部转为大写

Copy
-> [root@kube0.vm] [~] k exec goweb-rs-hztlt env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=goweb-rs-hztlt KUBERNETES_SERVICE_HOST=10.96.0.1 KUBERNETES_SERVICE_PORT=443 GOWEB_SVC_SERVICE_HOST=10.98.92.202 GOWEB_SVC_SERVICE_PORT=80 .........

通过DNS发现服务#

Kubernetes集群运行了一个名为kube-dns的服务,提供DNS解析。

Copy
-> [root@kube0.vm] [~] k get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 2d17h

查看容器内的/etc/resolv.conf文件

Copy
-> [root@kube0.vm] [~] k exec goweb-rs-hztlt cat /etc/resolv.conf nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local lan vm options ndots:5

没有错,nameserver指定的IP就是kube-dns服务的地址!

通过FQDN连接服务#

FQDN(Fully Qualified Domain Name):全限定域名
比如:goweb-svc.default.svc.cluster.local,goweb-svc是Service名称,default是命名空间,svc表示资源类型,cluster.local表示本地集群后缀。

根据情况,可以省略命名空间(请求方与Service在相同命名空间下)和 svc.cluster.local,也就是说下列情况都是可以的:

Copy
-> [root@kube0.vm] [~] k exec goweb-rs-dknjv -- curl -s http://goweb-svc this is goweb-rs-dknjv -> [root@kube0.vm] [~] k exec goweb-rs-dknjv -- curl -s http://goweb-svc.default -> [root@kube0.vm] [~] k exec goweb-rs-dknjv -- curl -s http://goweb-svc.default.svc.cluster.local

无法ping通服务IP的原因#

因为服务的集群IP是一个虚拟IP,并且只有在与服务端口结合时才有意义。

Endpoint#

Service与Pod不是直接相连的,有一种资源介于两者之间,他就是Endpoint。

Endpoint暴露一个服务的IP和端口列表。

查看Service

Copy
-> [root@kube0.vm] [~] k describe svc goweb-svc Name: goweb-svc Namespace: default ....... Endpoints: 10.244.1.58:8000,10.244.2.61:8000 .......

查看Endpoint资源

Copy
-> [root@kube0.vm] [~] k get ep NAME ENDPOINTS AGE goweb-svc 10.244.1.58:8000,10.244.2.61:8000 7h58m kubernetes 192.168.199.117:6443 8h

手动配置服务的Endpoint#

如果创建了不包含Pod选择器的服务,Kubernetes将不会创建Endpoint资源。

创建没有Pod选择器的Service#

external-service.yaml

Copy
apiVersion: v1 kind: Service metadata: name: external-svc spec: ports: - port: 80

查看external-svc

Copy
-> [root@kube0.vm] [~] k describe svc external-svc Name: external-svc Namespace: default Labels: <none> Annotations: <none> Selector: <none> Type: ClusterIP IP: 10.108.251.192 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: <none> Session Affinity: None Events: <none>

为没有选择器的服务创建Endpoint#

Endpoint对象需要与服务具有相同的名字,并包含该服务的目标IP和端口列表

Service和Endpoint都提交到服务器后,Service就又可以像具有Pod选择器那样了。

external-service-endpoint.yaml

Copy
apiVersion: v1 kind: Endpoints metadata: name: external-svc # 名字必须与相应服务的名字相同 subsets: - addresses: # IP、端口列表 - ip: 11.11.11.11 - ip: 22.22.22.22 ports: - port: 80

创建Endpoint

Copy
-> [root@kube0.vm] [~] k create -f external-svc-endpoint.yaml endpoints/external-svc created

查看external-svc服务

Copy
-> [root@kube0.vm] [~] k describe svc external-svc Name: external-svc Namespace: default Labels: <none> Annotations: <none> Selector: <none> Type: ClusterIP IP: 10.108.251.192 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 11.11.11.11:80,22.22.22.22:80 Session Affinity: None Events: <none>

为外部服务创建别名#

创建一个具有别名的外部服务时,需要指定service.spec.type的值为ExternalName;并且指定service.spec. externalName的值为外部服务的完整域名。因此连接到服务的客户端将直接连接到外部服务,完全绕过服务代理。出于这个原因,这些类型的服务也就没有集群IP

external-svc-externalname.yaml

Copy
apiVersion: v1 kind: Service metadata: name: external-svc-externalname spec: type: ExternalName # 服务类型 externalName: www.baidu.com # 外部服务的完整域名 ports: - port: 80

创建、查看别名外部服务,可以看到external-svc-externalname确实没有集群IP

Copy
-> [root@kube0.vm] [~] k create -f external-svc-externalname.yaml service/external-svc-externalname created -> [root@kube0.vm] [~] k get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE external-svc ClusterIP 10.108.251.192 <none> 80/TCP 57m external-svc-externalname ExternalName <none> www.baidu.com 80/TCP 18s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9h

通过external-svc-externalname.default.svc.cluster.local甚至是external-svc-externalname可以访问服务。

NodePort与LoadBalancer#

以下几种方式可在外部访问服务:

  • 将服务的类型设置成NodePort:
    每个集群节点都会打开一个相同的端口,并将该端口的流量重定向到服务。
  • 将服务的类型设置成LoadBalancer:
    LoadBalancer是NodePort的一种扩展,这种类型需要云基础设施提供专用的负载均衡器,负载均衡器将流量转发到集群的节点端口。
    如果不支持LoadBalancer,那么它会变得和NodePort一样。
  • 创建一个Ingress资源:
    通过一个IP地址公开多个服务,它运行在第七层。

NodePort#

goweb-nodeport.yaml

Copy
apiVersion: v1 kind: Service metadata: name: goweb-nodeport spec: type: NodePort # Service类型 ports: - port: 80 # Service的端口 targetPort: 8000 # Pod的端口 nodePort: 31234 # 通过任意Node的此端口访问服务 selector: app: goweb

创建、查看这个类型为NodePort的服务

Copy
-> [root@kube0.vm] [~] k create -f goweb-nodeport.yaml service/goweb-nodeport created -> [root@kube0.vm] [~] k get svc goweb-nodeport NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE goweb-nodeport NodePort 10.105.234.226 <none> 80:31234/TCP 10s

查看节点IP

Copy
-> [root@kube0.vm] [~] k get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kube0.vm Ready master 3d5h v1.17.3 192.168.199.117 <none> CentOS Linux 7 (Core) 5.6.14-1.el7.elrepo.x86_64 docker://19.3.6 kube1.vm Ready <none> 3d5h v1.17.3 192.168.199.231 <none> CentOS Linux 7 (Core) 5.6.14-1.el7.elrepo.x86_64 docker://19.3.6 kube2.vm Ready <none> 3d5h v1.17.3 192.168.199.212 <none> CentOS Linux 7 (Core) 5.6.14-1.el7.elrepo.x86_64 docker://19.3.6

使用不同节点IP访问服务

Copy
-> [root@kube0.vm] [~] curl http://192.168.199.231:31234 this is goweb-rs-pbxvx -> [root@kube0.vm] [~] curl http://192.168.199.212:31234 this is goweb-rs-6wc2f

搞个图

LoadBalancer#

goweb-loadbalancer.yaml

Copy
apiVersion: v1 kind: Service metadata: name: goweb-loadbalancer spec: type: LoadBalancer # 更改了类型 ports: # 去掉了nodePort、随机分配 - port: 80 targetPort: 8000 selector: app: goweb

创建、查看这个类型为LoadBalancer的服务

Copy
-> [root@kube0.vm] [~] k create -f goweb-loadbalancer.yaml service/goweb-loadbalancer created -> [root@kube0.vm] [~] k get svc goweb-loadbalancer NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE goweb-loadbalancer LoadBalancer 10.106.251.246 <pending> 80:31141/TCP 21m

EXTERNAL-IP字段一直是<pending>,是作者的环境不支持LoadBalancer。退而求其次,将其作为NodePort使用:

Copy
-> [root@kube0.vm] [~] curl http://192.168.199.212:31141 this is goweb-rs-pbxvx -> [root@kube0.vm] [~] curl http://192.168.199.231:31141 this is goweb-rs-6wc2f

搞个图

外部连接的特性#

externalTrafficPolicy#

sservice.spec.externalTrafficPolicy设置为local,则服务代理会选择运行本地的Pod。如果本地Node没有Pod,则连接将挂起。

客户端IP是不记录的#

节点端口接收到连接是,会对包的源地址进行转换(SNAT),因此数据包的源IP将发生改变。

但是externalTrafficPolicy为local的不会进行SNAT

Ingress#

因为每个LoadBalancer服务都需要自己的负载均衡器,以及独有的共有IP地址。而Ingress只需要一个地址就可以为多个服务提供访问。当客户端向Ingress发送Http请求时,Ingress会根据请求的主机名和路径决定请求转发到那个服务。

部署Ingress控制器#

只有Ingress控制器在集群中运行,Ingress资源才能正常工作。所以我们要先部署Ingress控制器,需要做的工作非常简单:
进入ingress-nginx官网,复制粘贴以下内容,然后执行就可以了。

Copy
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/baremetal/deploy.yaml

这时候查看Namespace,会发现多出一个ingress-nginx,具体内容就不细述了。

Copy
-> [root@kube0.vm] [~] k get ns NAME STATUS AGE default Active 3d15h ingress-nginx Active 15m kube-node-lease Active 3d15h kube-public Active 3d15h kube-system Active 3d15h

除此之外还要做个小改动,执行k edit -n ingress-nginx service/ingress-nginx-controller,在spec下添加工作节点的IP。出处请见官网

Copy
externalIPs: - 192.168.199.231 - 192.168.199.212

然后删除其管理的Pod,使其重建。

Copy
-> [root@kube0.vm] [~] k delete -n ingress-nginx pod/ingress-nginx-controller-f8d756996-8prk2 pod "ingress-nginx-controller-f8d756996-8prk2" deleted

goweb-ingress.yaml#

Copy
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: goweb-ingress spec: rules: - host: www.goweb.com http: paths: - path: / backend: serviceName: goweb-svc servicePort: 80

创建、查看goweb-ingress

Copy
-> [root@kube0.vm] [~] k create -f goweb-ingress.yaml ingress.extensions/goweb-ingress created -> [root@kube0.vm] [~] k get ing NAME HOSTS ADDRESS PORTS AGE goweb-ingress www.goweb.com 192.168.199.212 80 61s

在host文件中添加 192.168.199.212 www.goweb.com。然后访问

Copy
-> [root@kube0.vm] [~] curl http://www.goweb.com this is goweb-rs-mhvj4 -> [root@kube0.vm] [~] curl http://www.goweb.com this is goweb-rs-88k9t

暴露多个服务#

需要暴露多个服务,参照goweb-ingress.yaml:

  • 将多个服务映射到同一个域名只要在pahts下再配置一个path即可。
  • 将多个服务映射到不同域名则配置多个host即可。

Ingress工作原理#

从表面上看请求的流程是:client->ingress->service->pod,但实际上是client->ingress->pod。
在Ingress收到客户端的请求后,会根据域名和路径来确定服务,通过与该服务关联的Endpoint对象查看Pod IP,并将客户端的请求转发给其中一个pod。也就是说,请求不会转发给服务,服务只是被用来选择pod。

处理TLS传输#

占个位置,以后补上。

就绪探针#

就绪探针(readinessProbe)的类型与存活探针(livenessProbe)一样,请见此文它与存活探针的不同在于:如果容器未通过检查,则不会被终止或重新启动,但Pod会被从服务的Endpoint中移除,它确保了客户端只与正常的Pod交互。

在众多的微服务中存在很多依赖关系,被依赖服务只有在准备就绪后,才能接收请求。所以就绪探针务必要定义。

goweb-readiness.yaml#

Copy
apiVersion: apps/v1 kind: ReplicaSet metadata: name: goweb-readiness spec: replicas: 2 selector: matchLabels: app: goweb template: metadata: labels: app: goweb spec: containers: - name: goweb image: registry.cn-hangzhou.aliyuncs.com/orzi/goweb ports: - name: http containerPort: 8000 readinessProbe: exec: command: ["ls","/var/ready"]

运行查看goweb-readiness#

创建之后等了一段时间,可以看到两个Pod都处于为就绪状态,goweb-svc的Endpoints也是空的。

Copy
-> [root@kube0.vm] [~] k create -f goweb-readiness.yaml replicaset.apps/goweb-rs created -> [root@kube0.vm] [~] k get po NAME READY STATUS RESTARTS AGE goweb-readiness-9k9kv 0/1 Running 0 11s goweb-readiness-x2gfb 0/1 Running 0 11s -> [root@kube0.vm] [~] k describe svc goweb-svc Port: http 80/TCP TargetPort: http/TCP Endpoints: Session Affinity: None Events: <none>

让我们来给 goweb-readiness-9k9kv 创建一个/var/ready文件,使其准备就绪。

Copy
-> [root@kube0.vm] [~] k exec goweb-readiness-9k9kv touch /var/ready

再来查看、可以看到已经有一个Pod就绪了,Endpoints也有内容了。

Copy
-> [root@kube0.vm] [~] k get po NAME READY STATUS RESTARTS AGE goweb-readiness-9k9kv 1/1 Running 0 89s goweb-readiness-x2gfb 0/1 Running 0 89s -> [root@kube0.vm] [~] k describe svc goweb-svc Endpoints: 10.244.2.74:8000

headless#

将服务的spec.clusterIP设置为None会使服务成为headless服务。它不会被分配集群IP,DNS对其解析时就会返回Pod IP。

默认情况下,DNS对headless服务名解析只会返回已经就绪的Pod的IP。

goweb-headless.yaml#

Copy
apiVersion: v1 kind: Service metadata: name: goweb-headless spec: clusterIP: None ports: - name: http port: 80 targetPort: 8000 selector: app: goweb

创建、查看#

ReplicaSet是使用前面的goweb-readiness.yaml创建的。

Copy
-> [root@kube0.vm] [~] k create -f goweb-headless.yaml service/goweb-headless created -> [root@kube0.vm] [~] k get all -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/goweb-readiness-2jj49 0/1 Running 0 10m 10.244.2.4 kube2.vm <none> <none> pod/goweb-readiness-5h5sg 0/1 Running 0 10m 10.244.1.5 kube1.vm <none> <none> NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/goweb-headless ClusterIP None <none> 80/TCP 9m54s app=goweb service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 79m <none> NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/goweb-readiness 2 2 1 10m goweb registry.cn-hangzhou.aliyuncs.com/orzi/goweb app=goweb

使用nslookup解析goweb-headless,没有返回任何Pod的IP,这是因为两个Pod都未就绪。

Copy
-> [root@kube0.vm] [~] k exec goweb-readiness-2jj49 nslookup goweb-headless Server: 10.96.0.10 Address: 10.96.0.10:53 ** server can't find goweb-headless.default.svc.cluster.local: NXDOMAIN ** server can't find goweb-headless.svc.cluster.local: NXDOMAIN ........

为goweb-readiness-2jj49创建/var/ready使其满足就绪条件

Copy
k exec goweb-readiness-2jj49 touch /var/ready

再使用nslookup查看,可以看到返回了goweb-readiness-2jj49 的 IP

Copy
-> [root@kube0.vm] [~] k exec goweb-readiness-2jj49 nslookup goweb-headless Server: 10.96.0.10 Address: 10.96.0.10:53 ...... Name: goweb-headless.default.svc.cluster.local Address: 10.244.2.4 ......

如法炮制,使另一个Pod生效,就能看到两个Pod的IP了

publishNotReadyAddresses#

service.spec.publishNotReadyAddresses设置为true,允许DNS解析headless服务是发现未就绪的Pod。

将goweb-readiness的Pod副本变成3个

Copy
-> [root@kube0.vm] [~] k scale --replicas=3 rs goweb-readiness replicaset.apps/goweb-readiness scaled -> [root@kube0.vm] [~] k get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES goweb-readiness-2jj49 1/1 Running 0 24m 10.244.2.4 kube2.vm <none> <none> goweb-readiness-5h5sg 1/1 Running 0 24m 10.244.1.5 kube1.vm <none> <none> goweb-readiness-jb74c 0/1 Running 0 31s 10.244.1.6 kube1.vm <none> <none>

然后编辑goweb-headless,写入publishNotReadyAddresses: true

Copy
-> [root@kube0.vm] [~] k edit svc goweb-headless service/goweb-headless edited

nslookup查看,虽然有未就绪的,但IP还是全都返回了。

Copy
-> [root@kube0.vm] [~] k exec goweb-readiness-2jj49 nslookup goweb-headless Server: 10.96.0.10 Address: 10.96.0.10:53 Name: goweb-headless.default.svc.cluster.local Address: 10.244.2.4 Name: goweb-headless.default.svc.cluster.local Address: 10.244.1.5 Name: goweb-headless.default.svc.cluster.local Address: 10.244.1.6

注意事项#

  • 双横杠表示kubectl命令项的结束,在此之后的是指要在pod内部执行的命令
  • 创建一个多端口服务时,必须给每个端口指定名字。
  • 服务的IP无法ping通:因为服务的集群IP是一个虚拟IP,并且只有在与服务端口结合时才有意义。
  • sservice.spec.sessionAffinity设置会话亲和性,默认为None,可以设置为ClientIP
  • 创建ExternalService需要将spec.type设置为ExternalName,此类服务只在DNS级别实施(为服务创建了CNAME DNS),也因此不会获得集群IP。
  • service.spec.externalTrafficPolicy设置为local,则服务代理会选择运行本地的Pod。如果本地Node没有Pod,则连接将挂起。
  • service.spec.publishNotReadyAddresses设置为true,允许DNS解析headless服务是发现未就绪的Pod。

小结#

  • 服务是一种为一组相同功能的pod提供单一不变接入点的资源
  • 创建了不包含Pod选择器的服务,Kubernetes将不会创建Endpoints资源。
  • 服务对外暴露的方法:NodePort、LoadBalancer、Ingress
  • Ingress的的工作原理是:client->ingress->pod,而不是client->ingress->service->pod。
  • 就绪探针与存活探针:
    • 就绪探针:作用确保客户端只与正常的Pod交互。如果检查未通过,不会终止或重启容器,但Pod会被从服务的Endpoint中移除。
    • 存活探针:作用是让集群知道Pod是否正常运行。如果检查未通过,则终止异常容器并重新启动。
  • 一些概念:Service、Endpoint、对外暴露、就绪探针,服务发现。
posted @   虾敏四把刀  阅读(895)  评论(1编辑  收藏  举报
编辑推荐:
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
阅读排行:
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
点击右上角即可分享
微信分享提示
CONTENTS