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

结合实例解释服务

image.png

5.1.1 创建服务

service 使用标签来表示同一组的 pod.

image.png

通过 kubectl expose 创建服务

第2章

通过 YAML 描述文件来创建服务

image.png

模拟:

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: hello-svc
  5. spec:
  6. ports:
  7. - port: 80
  8. targetPort: 8080
  9. selector:
  10. app2: svc

创建 service:

  1. $ kubectl create -f hello-svc.yaml
  2. service/hello-svc created

检测新的服务

查看 service ip:

  • 只能在内部访问
  1. $ kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. hello-svc ClusterIP 10.105.251.136 <none> 80/TCP 2m7s
  4. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d17h

从内部集群测试服务

几种方法:

image.png

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

  1. 查看已有 pod, 随机选择一个
  1. $ kubectl get pod
  2. NAME READY STATUS RESTARTS AGE
  3. hello-rs-6z6gf 1/1 Running 0 10m
  4. hello-rs-j47xw 1/1 Running 0 10m
  5. hello-rs-w6m2k 1/1 Running 0 10m
  1. 执行 curl
  1. $ kubectl exec hello-rs-w6m2k -- curl -s http://10.105.251.136
  2. OCI runtime exec failed: exec failed: container_linux.go:370: starting container process caused: exec: "curl": executable file not found in $PATH: unknown
  3. command terminated with exit code 126

执行失败, 我使用的基础镜像是 alpine, 应该没有 curl.

image.png

配置服务上的会话亲和性

  • sessionAffinity: 配置同一 client IP 始终访问同一 pod
    • None
    • ClientIP

image.png

同一个服务暴露多个端口

创建多端口 service 必须指定端口名字:

image.png
image.png

使用命名的端口

image.png

好处是解耦实际端口号:

image.png

5.1.2 服务发现

通过环境变量发现服务

查看环境变量:

image.png

注意:

  • 先创建 service, 再创建 rs 才能看到与 ip:port 相关的环境变量
  1. $ kubectl exec hello-rs-cg852 -- env
  2. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  3. HOSTNAME=hello-rs-cg852
  4. HELLO_SVC_PORT_80_TCP_PROTO=tcp
  5. KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
  6. KUBERNETES_SERVICE_PORT=443
  7. KUBERNETES_PORT_443_TCP_PORT=443
  8. HELLO_SVC_PORT=tcp://10.100.55.166:80
  9. HELLO_SVC_PORT_80_TCP=tcp://10.100.55.166:80
  10. HELLO_SVC_PORT_80_TCP_PORT=80
  11. HELLO_SVC_PORT_80_TCP_ADDR=10.100.55.166
  12. KUBERNETES_SERVICE_HOST=10.96.0.1
  13. KUBERNETES_SERVICE_PORT_HTTPS=443
  14. KUBERNETES_PORT=tcp://10.96.0.1:443
  15. KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
  16. KUBERNETES_PORT_443_TCP_PROTO=tcp
  17. HELLO_SVC_SERVICE_HOST=10.100.55.166
  18. HELLO_SVC_SERVICE_PORT=80
  19. HOME=/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 访问

image.png

查看容器内 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章.