服务 (service) 为一组功能相同的 pod 提供单一不变的接入点的资源.
结合实例解释服务

5.1.1 创建服务
service 使用标签来表示同一组的 pod.

通过 kubectl expose 创建服务
第2章
通过 YAML 描述文件来创建服务

模拟:
apiVersion: v1kind: Servicemetadata:name: hello-svcspec:ports:- port: 80targetPort: 8080selector:app2: svc
创建 service:
$ kubectl create -f hello-svc.yamlservice/hello-svc created
检测新的服务
查看 service ip:
- 只能在内部访问
$ kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhello-svc ClusterIP 10.105.251.136 <none> 80/TCP 2m7skubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d17h
从内部集群测试服务
几种方法:

在运行的容器中远程执行命令
- 查看已有 pod, 随机选择一个
$ kubectl get podNAME READY STATUS RESTARTS AGEhello-rs-6z6gf 1/1 Running 0 10mhello-rs-j47xw 1/1 Running 0 10mhello-rs-w6m2k 1/1 Running 0 10m
- 执行 curl
$ kubectl exec hello-rs-w6m2k -- curl -s http://10.105.251.136OCI runtime exec failed: exec failed: container_linux.go:370: starting container process caused: exec: "curl": executable file not found in $PATH: unknowncommand terminated with exit code 126
执行失败, 我使用的基础镜像是 alpine, 应该没有 curl.

配置服务上的会话亲和性
- sessionAffinity: 配置同一 client IP 始终访问同一 pod
- None
- ClientIP

同一个服务暴露多个端口
创建多端口 service 必须指定端口名字:


使用命名的端口

好处是解耦实际端口号:

5.1.2 服务发现
通过环境变量发现服务
查看环境变量:

注意:
- 先创建 service, 再创建 rs 才能看到与 ip:port 相关的环境变量
$ kubectl exec hello-rs-cg852 -- envPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=hello-rs-cg852HELLO_SVC_PORT_80_TCP_PROTO=tcpKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1KUBERNETES_SERVICE_PORT=443KUBERNETES_PORT_443_TCP_PORT=443HELLO_SVC_PORT=tcp://10.100.55.166:80HELLO_SVC_PORT_80_TCP=tcp://10.100.55.166:80HELLO_SVC_PORT_80_TCP_PORT=80HELLO_SVC_PORT_80_TCP_ADDR=10.100.55.166KUBERNETES_SERVICE_HOST=10.96.0.1KUBERNETES_SERVICE_PORT_HTTPS=443KUBERNETES_PORT=tcp://10.96.0.1:443KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443KUBERNETES_PORT_443_TCP_PROTO=tcpHELLO_SVC_SERVICE_HOST=10.100.55.166HELLO_SVC_SERVICE_PORT=80HOME=/root
通过 DNS 发现服务
kube-dns pod:
- pod 都使用集群内的 dns
/etc/resolv.conf- spec.dnsPolicy 属性可以更改使用的 dns
通过 FQDN 连接服务
backend-database.default.svc.cluster.local :
- backend-database: 服务名
- default: 名称空间
- svc.cluster.local: 集群域后缀
在 pod 容器中运行 shell
注意:
- 容器中必须有 shell 可执行文件
$ kubectl exec -it containerName bash
# $ kubectl exec -it hello-rs-cg852 sh
在容器内部使用 curl:
- 通过 FQDN 访问

查看容器内 resolv.conf 文件:
- 可以省略掉名称空间和集群后缀 (可能跟 search 有关, 需要了解 dns)
/app # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
无法 ping 通服务 IP 的原因
集群的 IP 是虚拟 ip, 11章.
