一、准备工作
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/