乐趣区

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

简介 P121

pod 通常须要对来自集群外部其余 pod,以及来自集群内部的客户端的 HTTP 申请作出响应,所以须要一种寻找其余 pod 的办法来应用其余 pod 提供的服务。P121

在 Kubernetes 中通过服务 (service) 解决以下问题:P121

  • pod 是短暂的:pod 随时启动和敞开
  • Kubernetes 在 pod 启动前会给曾经调度到节点上的 pod 调配 IP 地址:客户端不能提前晓得 pod 的 IP 地址
  • 程度伸缩意味着多个 pod 可能提供雷同的服务:每个 pod 都有本人的 IP 地址

介绍服务 P122

Kubernetes 服务是一种为一组性能雷同的 pod 提供但以不变的接入点的资源。当服务存在时,它的 IP 地址和端口不会扭转。与服务建设的连贯会被路由到提供该服务的任意一个 pod 上。P122

创立服务 P123

服务应用标签选择器(03. pod: 运行于 Kubernetes 中的容器 中介绍过标签选择器及应用形式)来指定属于同一组的 pod。P123

通过 kubectl expose 创立服务 P124

创立服务的最简略的办法就是通过 kubectl expose,在 02. 开始应用 Kubernetes 和 Docker 中就应用该办法创立服务来裸露 DeploymentP124

通过 YAML 形容文件来创立服务 P124

为了将创立服务,咱们须要应用以下 kubia-svc.yaml 形容文件进创立。

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

kubectl create -f kubia-svc.yaml: 创立服务

kubectl get services: 查看以后所有服务

NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          12d
kubia        ClusterIP   10.111.241.144   <none>        80/TCP,443/TCP   5s

能够发现刚刚启动的服务曾经被调配了一个外部集群 IP,并且对外裸露了两个端口。服务的次要指标就是使集群外部的其余 pod 能够拜访以后这组 pod,但通常也心愿对外裸露服务。P125

从集群内部测试服务 P125

能够通过以下三种形式向服务发送申请:P125

  • 创立一个 pod,它将申请发送到服务的集群 IP 并记录响应。能够通过 kubectl logs 查看 pod 日志查看服务的响应
  • 应用 ssh 近程登录到其中一个 Kubernetes 节点上,而后应用 curl 命令
  • 通过 kubectl exec 命令在一个曾经存在的 pod 中执行 curl 命令

在运行的容器中近程执行命令 P125

kubectl exec kubia-9495d9bf5-2mmv2 -- curl -s 10.111.241.144: 在 pod kubia-9495d9bf5-2mmv2 运行命令 curl -s 10.111.241.144

-- 代表 kubectl 命令项的完结,在 -- 之后的内容是指在 pod 外部须要执行的命令。如果须要执行的命令没有以 - 开始的参数,那么 -- 不是必须的。P125

配置服务上的会话亲和性 P126

如果心愿特定客户端产生的所有申请每次都指向同一个 pod,能够设置服务的 spec.sessionAffinity 属性为 ClientIP,而不是默认值 NoneP127

...
spec:
  sessionAffinity: ClientIP
  ...

这种形式会使服务代理将来自同一个客户端 IP 的所有申请转发至同一个 pod。Kubernetes 仅反对两种模式的会话亲和性服务:NoneClientIPP127

同一个服务裸露多个端口 P127

咱们在后面已将创立了裸露多个端口的服务,这样通过一个集群 IP,应用一个服务就能够将多个端口全副裸露进去。P127

留神 :在创立一个有多个端口的服务的时候,必须给每个端口指定名字。P127

留神 :标签选择器利用于整个服务,不能对每个端口做独自的配置。如果不同的 pod 有不同的端口映射关系,须要创立两个服务。P128

应用命名的端口 P128

咱们能够将 pod 端口定义改为如下模式:

...
kind: Pod
spec:
  containers:
    - name: kubia
      ports:
        # 利用监听端口 8080,并命名为 http
        - name: http
          containerPort: 8080
        # 利用监听端口 8443,并命名为 https
        - name: https
          containerPort: 8443

而后咱们就能够将在服务中援用命名的端口:

...
kind: Service
spec:
  ports:
    - name: http
      port: 80
      targetPort: 8080
    - name: https
      port: 443
      targetPort: https

采纳命名端口的形式能够使得更换 pod 端口时毋庸更改服务的 spec,并且不同的 pod 能够应用不同的端口。P129

服务发现 P129

当初能够通过一个繁多稳固的 IP 地址拜访到 pod,然而还没法让客户端 pod 晓得服务的 IP 和端口,所以咱们须要配置进行发现服务。P129

通过环境变量发现服务 P129

在 pod 开始运行时,Kubernetes 会初始化一系列环境变量指向当初存在的服务。如果 pod 先于服务启动,那么能够先把这些 pod 删除,期待 Development 主动创立新的 pod,这样所有 pod 都能领有现存服务的的相干环境变量了。P129

kubectl exec kubia-9495d9bf5-4jbtf env: 查看指定 pod 的环境变量,能够发现其中有 kubiakubernetes 服务的 IP 地址和端口号的环境变量

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kubia-9495d9bf5-4jbtf
...
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBIA_SERVICE_HOST=10.111.232.152
KUBIA_SERVICE_PORT=80
KUBIA_SERVICE_PORT_HTTP=80
KUBIA_SERVICE_PORT_HTTPS=443
...

留神 :环境变量中,服务名作为前缀时,所有字母变为变为大写,且服务名称中的 - 将被转换为 _ P130

通过 DNS 发现服务 P130

命名空间 kube-system 下有几个以 coredns 为前缀的 pod。这些 pod 运行 DNS 服务,在集群中的其余 pod 都被配置成应用其作为 dns (Kubernetes 通过批改每个容器的 etc/resolv.conf 文件实现 )。运行在 pod 上的过程 DNS 查问都会被 Kubernetes 本身的 DNS 服务器响应,该服务器晓得零碎中运行的所有服务。P130

留神 :pod 是否应用外部的 DNS 服务器是依据 pod 的 spec.dnsPolicy 属性决定的。P130

每个服务从外部 DNS 服务器中取得一个 DNS 条目,客户端的 pod 在晓得服务名称的状况下能够通过全限定域名 (FQDN) 来拜访。P131

通过 FQDN 连贯服务 P131

咱们能够通过 kubia.default.svc.cluster.local 来拜访 kubia 服务。其中 kubia 对应于服务名称,default 示意服务所在的命名空间,svc.cluster.local 是所在集群本地服务名称中应用的可配置集群域后缀。P131

留神 :客户端依然必须晓得服务的端口号。如果服务没有应用规范端口号,那么客户端依然须要从环境变量中获取端口号。P131

如果服务和客户端在同一个命名空间下,那么可是间接应用服务名(例如:kubia)指代服务。P131

在 pod 容器中运行 shell P131

kubectl exec -ti <pod-name> bash: 能够在一个 pod 容器上运行 bash(也可指定其余模式的 shell)P131

无奈 ping 通服务 IP 的起因 P132

服务的集群 IP 是一个虚构 IP,并且只有在与服务端口联合时才有意义。将在后续文章中具体解说。P132

连贯集群内部的服务 P132

在集群中运行的客户端 pod 能够像连贯到外部服务一样连贯到内部服务,这样做能够充分利用负载平衡和服务发现。P132

介绍服务 endpoints P133

服务并不是与 pod 间接相连的,而是通过 Endpoints 资源与 pod 连贯。Endpoints 资源就是裸露一个服务的 IP 地址和端口列表,和其余 Kubernetes 资源一样。P133

kubectl get endpoints kubia: 查看 kubia 的 endpoints 根本信息

NAME    ENDPOINTS                                                  AGE
kubia   10.88.0.2:8443,10.88.0.3:8443,10.88.0.3:8443 + 3 more...   3d

服务中在 spec.selector 定义了 pod 选择器,然而在重定向传入连贯时不会间接应用它。选择器用于构建 IP 和端口列表,而后存储在 Endpoints 资源中。当客户端连贯到服务时,服务代理抉择这些 IP 和端口对中的一个,并将传入连贯重定向到该地位监听的服务器。P133

手动配置服务的 endpoints

如果将服务的 endpoints 与服务解耦,那么就能够手动配置和更新它们。P133

如果创立了不蕴含 pod 选择器的服务,Kubernetes 将不会创立 Endpoints 资源。这样就须要创立 Endpoints 资源来指定该服务的 endpoints 列表。P133

创立没有 pod 选择器的服务 P133

应用以下形容文件 external-service.yaml 能够创立一个不指定 pod 选择器的服务。

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Service
kind: Service
metadata:
  # Service 的名称
  name: external-service
spec:
  # 该服务可用的端口
  ports:
    # 第一个可用端口的名字
    - name: http
      # 可用端口为 80
      port: 80
      targetPort: http
    # 第二个可用端口的名字
    - name: https
      # 可用端口为 443
      port: 443
      targetPort: https

应用以下形容文件 external-service-endpoints.yaml 能够创立一个 Endpoints 资源。

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Endpoints
kind: Endpoints
metadata:
  # Endpoints 的名称,与对应的 Service 名称统一
  name: external-service
# 该 Endpoints 的子集
subsets:
  # 第一个子集的地址信息
  - addresses:
      # 地址蕴含以下 ip 列表
      - ip: 11.11.11.11
      - ip: 22.22.22.22
    # 第一个子集的端口信息
    ports:
      # 每个 ip 可用的端口列表
      #【留神】这个名字必须和服务端端口的名字对应
      - name: http
        port: 80
      - name: https
        port: 443

Endpoints 对象须要与服务具备雷同的名称,并蕴含该服务将要重定向的指标 IP 地址和端口列表。当服务和 Endpoints 都创立后,服务就会主动应用对该当 Endpoints,并可能像具备 pod 选择器那样当服务失常应用。P134

为内部服务创立别名 P135

除了手动配置服务的 Endpoints 来代替公开内部服务的办法,还能够通过其齐全限定域名 (FQDN) 来拜访内部服务。P135

创立 ExternalName 类型的服务 P135

通过以下形容文件 external-service-externalname.yaml 能够创立一个 ExternalName 类型的服务,这个服务会将申请转发到 spec.externalName 指定的理论服务的齐全限定域名。P135

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Service
kind: Service
metadata:
  # Service 的名称
  name: external-service
spec:
  # Service 的类型为 ExternalName
  type: ExternalName
  # 这个服务将所有申请都转发到 someapi.somecompany.com
  externalName: leetcode-cn.com
  # 该服务可用的端口
  ports:
    # 第一个可用端口的名字
    - name: http
      # 可用端口为 80
      port: 80
      # 应用 ExternalName 时,targetPort 将被疏忽
    # 第一个可用端口的名字
    - name: https
      # 可用端口为 443
      port: 443
      # 应用 ExternalName 时,targetPort 将被疏忽 

服务创立实现后,pod 能够通过 external-service(.default.svc.cluster.local) 域名(括号内的可不加)连贯到内部服务,而不必应用内部服务的理论 FQDN。这样容许批改服务的定义,并且在当前能够批改 externalName 指向到不同的服务,或者将类型变为 ClusterIP 并为服务创立 Endpoints。P135

ExternalName 服务仅在 DNS 级别施行——为服务创立了简略 CNAME DNS 记录。因而,连贯到服务的客户端将间接连贯到内部服务,齐全绕过服务代理,所以这类型的服务不会取得集群 IP。P135

留神 CNAME 记录指向齐全限定的域名而不是 IP 地址。P136

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

退出移动版