您的位置:

如何实现k8s的服务发现与注册?

一、准备工作

1、在部署k8s集群的时候需要使用kubectl命令

2、需要提前安装etcd服务

3、在k8s中,使用的是CoreDNS作为服务发现组件,所以需要安装配置好CoreDNS

4、在k8s中,使用的是kube-proxy作为负载均衡的组件,因此需要安装好kube-proxy

二、k8s的服务发现与注册实现

1、基础概念

在k8s中,每个Pod都会分配一个IP地址,这个IP地址只在集群内有效,而外部无法访问。因此,需要一种机制来让服务可以被其他组件(如其他Pod)找到并进行访问。k8s提供了一种服务发现的机制,可以通过服务名(Service)来访问服务,并将请求负载均衡到后端的Pod中。

2、Service的实现

使用kubectl命令创建一个Service:

kubectl expose deployment hello-world --type=LoadBalancer --name=my-service

这个命令会在k8s中创建一个Service,并将它映射到名为`my-service`的Service中。

3、Service的工作机制

创建Service后,Service会绑定一个IP地址,并将指定的Pod加入Service中。当有请求发送到Service的IP地址时,Service会将请求转发给其中的某个Pod。具体选择哪个Pod来处理请求,是根据Service的负载均衡策略决定的。

4、Service的高级用法

除了简单地将Pod组合成一个Service外,还可以对Service进行更多的配置,以满足不同的业务需求。

5、使用CoreDNS来进行服务发现

k8s提供了一个DNS服务,用于将服务名解析为Service的IP地址,从而实现服务发现。在k8s中,使用的是CoreDNS来实现服务发现。CoreDNS是一种轻量级的DNS服务器,可以在k8s中进行部署。在集群中启动CoreDNS后,所有的客户端(如Pod)都可以使用CoreDNS对服务名进行解析。

CoreDNS的配置文件如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods insecure
            upstream
            fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        reload
        loadbalance
    }

6、使用kube-proxy进行负载均衡

k8s中的服务发现机制并没有直接对请求进行负载均衡,而是将负载均衡交给了kube-proxy组件来处理。因此,当有请求发送到Service的IP地址时,kube-proxy会根据Service的负载均衡策略,选择其中的某个Pod来处理请求,并将请求转发给该Pod。

7、示例代码

下面是使用Go语言编写的一个简单的微服务应用:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		fmt.Fprintf(w, "Hello World!\n")
	})

	http.ListenAndServe(":8080", nil)
}

下面是使用Dockerfile将上述应用打包成Docker镜像:

FROM golang:alpine AS build

RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN go build -o main .

FROM alpine
RUN apk add --no-cache curl
COPY --from=build /app/main /app/main
EXPOSE 8080
CMD ["/app/main"]

使用kubectl部署上述Docker镜像:

kubectl apply -f deployment.yaml

下面是部署文件deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      app: hello-world
  replicas: 3
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: myuser/hello-world:v1
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: hello-world-service
spec:
  selector:
    app: hello-world
  ports:
  - name: http
    port: 80
    targetPort: 8080
  type: LoadBalancer

8、参考资料

1、官方文档:https://kubernetes.io/docs/home/

2、CoreDNS:https://coredns.io/

3、kube-proxy:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/