描述

最近在使用nacos和k8s的时候遇到一个问题:nacos部署在k8s的外部,服务部署在K8s内部,服务注册该怎么玩呢? 其实我们现实环境中,不可能所有的服务都部署在k8s内部的,总有些服务要部署在k8s外部的。下面我聊一下我的想法

LoadBalancer

创建一个LoadBalancer类型的service,这样就会把我们服务映射到外部的负载均衡上了。 我们k8s内部的服务需要注册负载均衡的地址到nacos。如果你的k8s是安装在下面这些环境的,那么你可以使用这种方式(居然没有阿里云)
在这里插入图片描述
在这里插入图片描述

使用Kong

这种方式是在K8s内部安装一套Kong,K8s内部的服务首先注册到Kong上,然后向nacos注册的时候,注册Kong的地址
在这里插入图片描述

注册节点的Ip和Pod的hostPort

这种方式我觉得最好了,但是实际环境中我没有实现,还请大神相助

  • 我们的服务在k8s里面启动成deployment
  • 利用k8s的downward ApI将pod所在的节点的IP,设置成容器的环境变量
  • 我卡在此处了, 没有办法将hostPort设置成容器的环境变量
  • pod启动的时候,程序通过环境变量获取节点的Ip和hostPort,并注册到nacos
  • 外部服务通过NodeIP + hostPort访问服务
    在这里插入图片描述
注册service的Nodeport和pod所在的节点的IP
  • 启动一个NodePort类型的service
  • 我们的服务在k8s里面启动成deployment, 通过downward ApI将pod所在节点的IP,设置为容器内部的环境变量
  • pod启动的时候通过K8s的API获取service的Nodeport
  • 将节点的Ip和service的NodePort注册到nacos中去
该方案的实际操作
  • 启动一个service
apiVersion: v1
kind: Service
metadata:
  name: service-to-external
  namespace: testuser
spec:
  selector:
    app:  nginx-to-external
  type: NodePort 
  ports:   
    - name: http 
      port: 80
  • 启动deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: to-external-deployment
  namespace: testuser
  labels:
    app: to-external
spec:
  replicas: 1
  selector:
    matchLabels:
      app:  nginx-to-external
  template:
    metadata:
      labels:
        app: nginx-to-external
    spec:
      containers:
      - name:  nginx-to-external-deployment
        env:
        - name: node_ip
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: namespace
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: service_name
          value: service-to-external
        image:  172.16.0.96:800/demaxieya/python-script:v1.0
        ports:
           - containerPort: 80
             name: web
  • node_ip 就是通过downward ApI获取节点的Ip
  • namespace 就是通过downward ApI获取namespace
    service_name 前面创建的service的名字
  • 镜像启动时执行的脚本
import os 
import requests

namespace = os.getenv("namespace")
node_ip = os.getenv("node_ip")
service_name = os.getenv("service_name")
url = "https://kubernetes.default.svc/api/v1/namespaces/%s/services/%s" % (namespace, service_name)
cert = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"

response = requests.get(url, verify=cert)
print("节点的ip:" , node_ip)
print("service的信息: ", response.json())
  • kubernetes.default.svc 这个是API server的地址
  • 默认pod启动的时候使用的是default的serviceAccount,没有访问service的权限,需要我们做一个角色绑定。或者自己创建一个具有查看service权限的账户
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets-global
subjects:
- kind: User
  name: system:anonymous
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io
  • 查看脚本的输出
    下图中可以看到我们已经获取到ip地址和Nodeport了, 后面就可以向nacos注册了。我就省略了注册的步骤了
    在这里插入图片描述

先写到这里了,服务注册是大话题,小弟也只是理解一部分, 如果有异议或者问题 请进QQ群630300475,大家聊聊

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐