关于kubernetes:Kubernetes-实战-05-服务让客户端发现-pod-并与之通信下

36次阅读

共计 7415 个字符,预计需要花费 19 分钟才能阅读完成。

将服务裸露给内部客户端 P136

有以下三种形式能够在内部拜访服务:

  • 将服务的类型设置成 NodePort
  • 将服务的类型设置为 LoadBalance
  • 创立一个 Ingress 资源

应用 NodePort 类型的服务 P137

通过创立一个 NodePort 服务,能够让 Kubernetes 在其所有节点上保留一个端口(所有节点上都应用雷同端口号),并将传入的连贯转发给作为服务局部的 pod。P137

创立 NodePort 类型的服务 P137

能够应用如下形容文件 kubia-svc-nodeport.yaml 创立一个 NodePort 类型的服务。

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Service
kind: Service
metadata:
  # Service 的名称
  name: kubia-nodeport
spec:
  # 指定服务类型为 NodePort
  type: NodePort
  # 该服务可用的端口
  ports:
    # 第一个可用端口的名字
    - name: http
      # 可用端口为 80
      port: 80
      # 服务将连贯转发到容器的 8080 端口
      targetPort: 8080
      # 通过集群节点的 30000 端口能够拜访该服务
      nodePort: 30000
    # 第二个可用端口的名字
    - name: https
      # 可用端口为 443
      port: 443
      # 服务将连贯转发到容器的 8443 端口
      targetPort: 8443
      # 通过集群节点的 32767 端口能够拜访该服务
      nodePort: 32767
  # 具备 app=kubia 标签的 pod 都属于该服务
  selector:
    app: kubia

nodePort 属性不是强制的,如果疏忽就会随机抉择一个端口。P137

kubectl get services kubia-nodeport: 查看该服务的根底信息

NAME               TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)                      AGE
kubia-nodeport     NodePort       10.111.59.156    <none>            80:30000/TCP,443:32767/TCP   2s

PORT(S) 列显示集群 IP 外部端口 (80, 443) 和节点端口 (30000, 32767),可通过 10.111.59.156:80<any-node-ip>:30000 等拜访服务。P138

应用 JSONPath 输入须要的信息 :通过指定 kubectl 的 JSONPath,咱们能够只输入须要的信息。例如:kubectl get nodes -o jsonpath='{.items[*].status.addresses[0].address}' 将输入所有节点的 IP 地址。

通过负载均衡器将服务裸露进去 P140

负载均衡器领有本人举世无双的可公开拜访的 IP 地址,并将所有连贯重定向到服务。P140

创立 LoadBalance 服务 P140

能够应用如下形容文件 kubia-svc-loadbalancer.yaml 创立一个 LoadBalancer 类型的服务。

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Service
kind: Service
metadata:
  # Service 的名称
  name: kubia-loadbalancer
spec:
  type: LoadBalancer
  # 该服务可用的端口
  ports:
    # 第一个可用端口的名字
    - name: http
      # 可用端口为 80
      port: 80
      # 服务将连贯转发到容器的 8080 端口
      targetPort: 8080
    # 第二个可用端口的名字
    - name: https
      # 可用端口为 443
      port: 443
      # 服务将连贯转发到容器的 8443 端口
      targetPort: 8443
  # 具备 app=kubia 标签的 pod 都属于该服务
  selector:
    app: kubia

应用 minikube 会发现服务的 EXTERNAL-IP 始终为 <pending>,咱们能够应用 minikube 自带的 minikube tunnel 命令能够实现裸露(02. 开始应用 Kubernetes 和 Docker 介绍过相干解决及踩过的坑)。

LoadBalancer 类型的服务是一个具备额定的基础设施提供的负载均衡器 NodePort 服务。应用 kubectl describe service kubia-loadbalancer 命令能够发现该服务抉择了一个节点端口。P141

理解内部连贯的个性 P142

理解并避免不必要的网络跳数 :当内部客户端通过节点端口连贯到服务时,随机抉择的 pod 并不一定在接管连贯的同一节点上。可能须要额定的网络跳转能力达到 pod。可配置 Service.spec.externalTrafficPolicy 的值为 Local 指定仅将内部通信重定向到接管连贯的节点上运行的 pod。

  • 如果接管连贯的节点上没有运行对应的 pod,那么连贯将挂起,所以须要确保负载均衡器将连贯转发给至多具备一个 pod 的节点
  • 假如有一个两节点三个 pod 的集群(节点 A 运行一个 pod,节点 B 运行两个 pod),如果负载均衡器在两个节点间均匀分布连贯,那么 pod 的负载散布不平衡

客户端 IP 是不记录的 :当通过节点端口接管到连贯时,因为对数据包执行了源网络地址转换 (SNAT),因而数据包对源 IP 将产生更改。如果配置 Service.spec.externalTrafficPolicy 的值为 Local,那么将会保留客户端 IP,因为在接管连贯的节点和托管指标 pod 的节点之间没有额定的跳跃(不执行 SNAT)。P143

通过 Ingress 裸露服务 P143

为什么须要 Ingress P144

每个 LoadBalancer 服务都须要本人的负载均衡器,以及独有的私有 IP 地址,而 Ingress 只须要一个公网 IP 就能为许多服务提供拜访。当客户端向 Ingress 发送 HTTP 申请时,Ingress 会依据申请的主机名和门路决定申请转发到的服务。P144

Ingress 在网络栈 (HTTP) 的应用层操作,并且能够提供一些服务不能实现的性能,例如基于 cookie 的会话亲和性 (session affinity) 等性能。P144

Ingress 控制器是必不可少的 P144

只有 Ingress 控制器在集群中运行,Ingress 资源能力失常工作。P144

在 minikube 上启动 Ingress 的扩大性能 P145

minikube addons list: 能够列出所有的插件及其启用状态

minikube addons enable ingress: 启用 ingress 插件

kubectl get pods -n kube-system: 查看 kube-system 命名空间下的 pod,能够发现 Ingress 控制器 pod

创立 Ingress 资源 P145

能够应用如下形容文件 kubia-ingress.yaml 创立一个 Ingress 资源。

# 遵循 extensions/v1beta1 版本的 Kubernetes API
apiVersion: extensions/v1beta1
# 资源类型为 Ingress
kind: Ingress
metadata:
  # Ingress 的名称
  name: kubia
spec:
  # Ingress 的规定列表
  rules:
    # 第一条规定匹配的域名为 kubia.example.com
    - host: kubia.example.com
      # 匹配 http
      http:
        # 匹配的门路列表
        paths:
          # 第一条门路为 /
          - path: /
            # 该门路将被转发到的后端服务
            backend:
              # 将被转发到 kubia-nodeport 服务
              serviceName: kubia-nodeport
              # 对应服务的端口为 80
              servicePort: 80

minikube 下创立 Ingress 资源时报错了,提醒超时。起初找到一种解决方案:应用 kubectl edit ValidatingWebhookConfiguration/ingress-nginx-admission 进行编辑,找到 failurePolicy: Fail 这行,并将 Fail 改为 Ignore,而后就能胜利创立 Ingress 资源了,等一段时间后就能够看见其调配了一个 IP 地址 (192.168.64.70)。

为了能将指定的域名 kubia.example.com 指向调配的 IP 地址 (192.168.64.70),能够应用 SwitchHosts 这个软件进行疾速切换。

此时咱们在主机上就能够通过 curl kubia.example.com 拜访 kubia-nodeport 服务了。

理解 Ingress 的工作原理 P147

  1. 客户端对 kubia.example.com 执行 DNS 查找,本地操作系统返回了 Ingress 控制器的 IP
  2. 客户端向 Ingress 控制器发送 HTTP 申请,并在 Host 头中指定 kubia.example.com
  3. 控制器从头部确定客户端尝试拜访哪个服务,通过与该服务关联的 Endpoint 对象查看 pod IP,并将客户端的申请转发给其中一个 pod

Ingress 控制器不会将申请转发给服务,只用它来抉择一个 pod。大多数控制器都是这样工作的。P147

通过雷同的 Ingress 裸露多个服务 P147

Ingerssrulespaths 都是数组,所以它们能够蕴含多个条目,因而一个 Ingress 能够将多个域名和门路映射到多个服务。P147

配置 Ingress 解决 TLS 传输 P149

Ingress 创立 TLS 认证 P149

当客户端创立到 Ingress 控制器到 TLS 连贯时,控制器将终止 TLS 连贯。客户端和控制器之间到通信是加密的,而控制器和后端 pod 之间的通信则未加密。运行在 pod 上的应用程序不须要反对 TLS。P149

为了让 Ingress 控制器负责解决与 TLS 相干的所有内容,须要将证书和私钥附加到 Ingress。这两个必须资源存储在称为 Secret 的 Kubernetes 资源中(将在第 7 章中具体介绍 Secret),而后在 Ingress 的形容文件中援用它。P149

openssl genrsa -out tls.key 2048: 创立私钥

openssl req -new -x509 -key tls.key -out tls.cert -days 365 -subj /CN=kubia.example.com: 创立证书

kubectl create secret tls tls-secret --cert=tls.cert --key=tls.key: 创立 Secret 资源

而后咱们就能够改写 kubia-ingress.yaml 失去 kubia-ingress-tls.yaml 形容文件:

...
spec:
  # 配置 TLS
  tls:
    # 第一条配置的域名列表
    - hosts:
      - kubia.example.com
      # 这些域名应用 tls-secret 取得私钥和证书
      secretName: tls-secret
  ...

而后咱们就能够应用 curl -k -v https://kubia.example.com 通过 HTTPS 拜访服务了。(minikube 下未进行上述操作前也能够拜访,不过能够发现是 Ingress 控制器应用了假证书)P150

pod 就绪后发出信号 P150

与存活探测器(04. 正本机制和其余控制器:部署托管的 pod 中介绍过)相似,Kubernetes 还容许为容器定义就绪探测器。就绪探测器会定期调用,并确保特定的 pod 是否接管客户端申请。当容器的就绪探测器返回胜利时,示意容器已筹备好接管申请。P151

就绪探测器的类型 P151

  • Exec 探测器:在容器内执行任意命令,并查看命令的退出状态码。如果状态码是 0,则探测胜利,认为容器曾经就绪,所有其余状态码都被认为失败
  • HTTP GET 探测器:对容器的 IP 地址(指定的端口和门路)执行 HTTP GET 申请。如果探测器收到响应,并且响应状态码不代表谬误(状态码为 2xx 或 3xx),则认为探测胜利,认为容器曾经就绪。如果服务器返回谬误响应状态码或者没有响应,那么探测就被认为是失败的
  • TCP Socket 探测器:尝试与容器指定端口建设 TCP 连贯。如果连贯胜利建设,则探测胜利,认为容器曾经就绪

理解就绪探测器的操作 P151

启动容器时,能够为 Kubernetes 配置一个等待时间,通过等待时间后才能够执行第一次准备就绪查看。之后,它会周期性地调用探测器,并依据就绪探测器的后果采取行动。如果某个 pod 报告它尚未准备就绪,那么就会从服务中删除该 pod;如果这个 pod 再次准备就绪,那么就会将给 pod 从新增加到服务中。P151

就绪探测器和存活探测器的区别 P151

存活探测器通过杀死异样的容器并用新的失常容器代替它们来放弃 pod 失常工作,而就绪探测器确保只有筹备好解决申请的 pod 才能够接管申请,并不会终止或重新启动容器。P151

就绪探测器的重要性 :确保客户端只与失常的 pod 交互,并且永远不会晓得零碎存在的问题。P152

理解就绪探测器的理论作用 P154

务必定义就绪探测器 P155

应该始终定义一个就绪探测器,即便它只是向基准 URL 发送 HTTP 申请一样简略。如果没有将就绪探测器增加到 pod 中,那么它们启动后简直立刻成为服务端点。P155

不要将进行 pod 的逻辑纳入到就绪探测器中 P155

当一个容器敞开时,运行在其中的应用程序通常会在收到终止信号后立刻进行接管连贯。但在启动关机程序后,没有必要让就绪探测器返回失败以达到从所有服务中移除 pod 目标,因为在该容器删除后,Kubernetes 就会主动从所有服务中移除该容器。P155

应用 headless 服务来发现独立的 pod P155

要让客户端连贯到所有 pod,须要找出每个 pod 的 IP。Kubernetes 容许客户通过 DNS 查找发现 pod IP。通常,当执行服务的 DNS 查找时,DNS 服务器会返回单个 IP —— 服务的集群 IP。然而,如果通知 Kubernetes,不须要为服务提供集群 IP(通过在服务 spec 中将 clusterIP 字段设置为 None 来实现此操作),则 DNS 服务器将会返回 pod IP 而不是单个服务 IP。P155

DNS 服务器不会返回单个 DNS A 记录,而是会为该服务返回多个 A 记录,每个记录指向过后反对该服务的单个 pod 的 IP。客户端因而能够做一个简略的 DNS A 记录查问并获取属于该服务的所有 pod 的 IP。客户端能够应用该信息连贯到其中的一个、多个或全副。P155

创立 headless 服务 P156

能够应用如下形容文件 kubia-svc-headless.yaml 创立一个 headless 的 Service 资源。

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Service
kind: Service
metadata:
  # Service 的名称
  name: kubia-headless
spec:
  # 该服务的集群 IP 为 None,使其变为 headless 的
  clusterIP: None
  # 该服务可用的端口
  ports:
    # 第一个可用端口的名字
    - name: http
      # 可用端口为 80
      port: 80
      # 服务将连贯转发到容器的 8080 端口
      targetPort: 8080
    # 第二个可用端口的名字
    - name: https
      # 可用端口为 443
      port: 443
      # 服务将连贯转发到容器的 8443 端口
      targetPort: 8443
  # 具备 app=kubia 标签的 pod 都属于该服务
  selector:
    app: kubia

通过 DNS 发现 pod P156

kubia 容器镜像不蕴含 nslookup 二进制文件,所以须要用一个新的容器镜像来执行相应的命令。P156

kubectl run dnsutils --image=tutum/dnsutils --generator=run-pod/v1 --command -- sleep infinity: 创立一个能够执行 nslookup 命令的 pod

kubectl exec dnsutils nslookup kubia-headless: 在 dnsutils pod 内执行 nslookup kubia-headless 命令,能够发现 DNS 服务器为 kubia-headless.default.svc.cluster.local FQDN 返回了多个 IP,且它们都是 pod 的 IP,能够通过 kubectl get pods -o wide 进行确认

kubectl exec dnsutils nslookup kubia: 在 dnsutils pod 内执行 nslookup kubia 命令,能够发现 DNS 服务器为 kubia.default.svc.cluster.local FQDN 返回了一个 IP,该 IP 是服务的集群 IP

只管 headless 服务看起来可能与惯例服务不同,然而在客户的视角上它们并无不同。对于 headless 服务,因为 DNS 返回了 pod 的 IP,客户端间接连贯到该 pod,而不是通过服务代理(留神这里是间接拜访的 pod,所以对应的端口要改成 pod 的端口)。P157

留神 :headless 服务依然提供跨 pod 的负载平衡,然而通过 DNS 轮循机制不是通过服务代理 P157

发现所有的 pod —— 包含未就绪的 pod P157

能够通过在 Service.metadata.annotations 上面减少一条 service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" 通知 Kubernetes 无论 pod 的筹备状态如何,心愿将所有 pod 增加到服务中 P158

排除服务故障 P158

如果无奈通过服务拜访 pod,应依据上面的列表进行排查:P158

  • 确保从集群内连贯到服务的集群 IP
  • 不要通过 ping 服务 IP 来判断服务是否可拜访(服务的集群 IP 是虚构 IP,是无奈 ping 通的)
  • 如果曾经定义了就绪探测器,请确保它返回胜利;否则该 pod 不会成为服务的一部分
  • 要确认某个容器是服务的一部分,请应用 kubectl get endpoints 来查看相应的端点对象
  • 如果尝试通过 FQDN 或其中一部分来拜访服务,但并不起作用,请查看是否能够应用其集群 IP 而不是 FQDN 来拜访服务
  • 查看是否连贯到服务公开的端口,而不是指标端口
  • 尝试间接连贯到 pod IP 以确认 pod 正在接管正确端口上的连贯
  • 如果甚至无奈通过 pod 的 IP 拜访利用,请确保利用不是仅绑定到 localhost (127.0.0.1)

本文首发于公众号:满赋诸机(点击查看原文)开源在 GitHub:reading-notes/kubernetes-in-action

正文完
 0