Go微服务架构实战 中篇:2. 基于k8s部署服务和注册中心,验证服务注册和发现

简介: Go微服务架构实战 中篇:2. 基于k8s部署服务和注册中心,验证服务注册和发现

本系列文章主要是针对云原生领域微服务架构的实战,包括网关,k8s,etcd以及grpc等相关技术的应用,同时也会把服务发现与注册,熔断,降级,限流以及分布式锁等加入到系列当中作为补充,课程的最后也会安排分布式链路追踪框架的学习,监控平台的搭建以及灰度发布等技术服务,所以总体来讲,课程范围涉及技术领域较广,知识面比较宽,大家下来各取所需尽量做到熟悉和应用,之后有时间了在研究下源码,乐哉!


上篇已经完成,大家可以看下,我这里贴出来了,中篇从这周开始陆续为大家产出,因为太耗费精力,所以还望大家多多支持!


Go微服务架构实战目录


1. 微服务架构上篇



1. grpc技术介绍

2. grpc+protobuf+网关实战

3. etcd技术介绍

4. 基于etcd的服务发现与注册

5. 基于etcd的分布式锁实战


2. 微服务架构中篇


1. k8s架构介绍


2. 基于pod和deployment的容器化部署



对于k8s来说,所有资源对象都有yaml文件来创建,k8s提供一个工具kubectl来和API server交互,从而创建相应的资源对象。


我们的项目有一个服务端,有一个客户端,还有一个服务发现和注册中心etcd。

我们原来就是裸机用supervisor去托管各个服务进程,比较简单直接,现在用k8s尝试去部署一下。


1. 创建server pod的步骤


  1. 首先为了让server进行容器化部署,得现有Dockerfile,我们来看看server的(Dockerfile):
FROM golang AS build-env //从Docker镜像仓库找golang镜像 
ADD . /go/src/app
WORKDIR /go/src/app
RUN GOOS=linux GOARCH=386 go build -mod vendor cmd/svr/svr.go //构建镜像
FROM alpine //构建二进制镜像
COPY --from=build-env /go/src/app/svr /usr/local/bin/svr //从golang尽享copy到二进制镜像内
CMD [ "svr", "-port", "50009"] //运行服务 指定参数是端口
  1. 用docker build构建镜像docker build -t k8s-grpc-demo -f ./Dockerfile .
  2. 用刚才的镜像创建server的yaml(server.yaml):
apiVersion: apps/v1
kind: Deployment //Deployment就是管理Pod资源的对象
metadata:
  name: k8sdemo-deploy //Pod名称
  labels:
    app: k8sdemo //Pod标签 为service提供负载均衡使用
spec:
  replicas: 1 //副本为1
  selector:
    matchLabels:
      app: k8sdemo
  template:
    metadata:
      labels:
        app: k8sdemo
    spec:
      containers:
      - name: k8sdemo //容器名称
        image: k8s-grpc-demo:latest //用刚才生成的本地镜像
        imagePullPolicy: Never //从本地构建
        ports:
        - containerPort: 50007 //容器端口
  1. 用kubectl创建podkubectl apply -f server.yaml没有指定namespace,默认是在default空间。
  2. 创建之后看下pod是否起来kubectl get pod查看发现server的pod已经running了。


为了多测试几个服务,我们复制创建相同的Dockerfile和server.yaml,比如Dockerfile1 Dockerfile2 以及server1.yaml和server2.yaml,这里就不把配置粘贴出来,可以从github地址查看哈。


2. 创建client的pod的步骤


  1. 创建Dockerfile(Dockerfile3)
FROM golang AS build-env
ADD . /go/src/app
WORKDIR /go/src/app
RUN GOOS=linux GOARCH=386 go build -mod vendor cmd/cli/cli.go
FROM alpine
COPY --from=build-env /go/src/app/cli /usr/local/bin/cli
CMD [ "cli"]
  1. 构建Dockerfiledocker build -t k8s-grpc-demo3 -f ./Dockerfile3 .
  2. 用刚才的镜像创建client的yaml(client.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8sdemo-cli-deploy //客户端pod名称
  labels:
    app: k8sdemo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8sdemo
  template:
    metadata:
      labels:
        app: k8sdemo
    spec:
      containers:
      - name: k8sdemocli
        image: k8s-grpc-demo3:latest //用刚才构建的镜像
        imagePullPolicy: Never
        ports:
        - containerPort: 50010
  1. 用kubectl创建podkubectl apply -f client.yaml没有指定namespace,默认是在default空间。
  2. 创建之后看下pod是否起来kubectl get pod查看
  3. 640.png
  4. 发现client的pod已经running了。


3. 创建etcd的pod的步骤


因为etcd镜像我们用Docker官网里面的,所以不用自己构建了,这里直接把创建etcd的pod的yaml贴出来。


apiVersion: apps/v1
kind: Deployment
metadata:
  name: etcd3 //etcd名称
  labels:
    name: etcd3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: etcd3
  template:
    metadata:
      labels:
        app: etcd3
    spec:
      containers:
        - name: etcd3 //容器名称
          image: quay.io/coreos/etcd:latest //etcd镜像
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - mountPath: /data //数据存储挂载路径
              name: etcd-data
          env:
            - name: host_ip
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
          command: ["/bin/sh","-c"]
          args: //启动etcd
            - /usr/local/bin/etcd //etcd的可执行文件
              --name etcd3 //etcd集群的名称
              --initial-advertise-peer-urls http://0.0.0.0:2380
              --listen-peer-urls http://0.0.0.0:2380
              --listen-client-urls http://0.0.0.0:2379
              --advertise-client-urls http://0.0.0.0:2379
              --initial-cluster-token etcd-cluster-1
              --initial-cluster etcd3=http://0.0.0.0:2380
              --initial-cluster-state new
              --data-dir=/data
      volumes:
        - name: etcd-data
          emptyDir: {} //当前容器作为存储路径


然后用kubectl命令直接创建pod

kubectl apply -f etc.yaml

kubectl get pod查看

640.png

发现etcd的pod是running了。


但是有pod不一定有对内提供服注册和发现能力,得需要service对内pod提供服务,因此创建etcd的service如下:


apiVersion: v1
kind: Service
metadata:
  name: etcd3 //service的名称 服务注册和发现的时候使用 很重要
spec:
  ports:
    - name: client
      port: 2379 //service对内pod的client访问端口
      targetPort: 2379
    - name: etcd3
      port: 2380 //service对内pod的server访问端口
      targetPort: 2380
  selector:
    app: etcd3 //找到需要关联的etcd pod 即上面创建的etcd pod

我们看下是否创建成功:

640.png


bingo。至此服务,客户端以及以及etcd的服务注册和发现中心部署好了。

接下来做点小改动,就可以实现服务注册和发现了。


3. 服务注册


因为我们的pod也是有ip的,所以服务注册之前得先获取pod的ip。代码如下:


//获取本地eth0 IP 大家下来在源码中可以看到实现哈
func GetLocalIP() string


然后有两个地方需要修改:


  1. 注册中心的地址(etcd address) 从原来的localhost改为http://etcd3:2379,至于为什么,我可以做个简单介绍,因为不同pod之间localhost是不通的,localhost只能在同一个Pod中的容器之间相互通信,不同pod是没有办法通信的。所以需要通信的pod必须通过etcd的svc名称去访问,k8s集群内提供了相关dns自动会解析到svc ip的,所以pod就可以访问etcd注册中心。
  2. 把原来服务默认监听的localhost改为从本地获取ip

1,2修改代码如下:

640.png


4. 客户端发现

客户端也需要修改注册中心地址:


640.png

5. 验证

等以上修改完成之后,我们还需要经历上述的重新构建步骤和部署步骤,因为代码改动了哦。

我们重新部署完成之后,在最后启动客户端的时候发现日志中有了多个服务端的请求,而且是RR轮循返回的响应,我们可以看下客户端和服务的pod列表:

640.png


客户端日志如下:

640.png


至此我们基于k8s的服务部署和服务注册中心就搭建起来了,后续为大家带来故障转移,滚动更新以及扩缩容等内容,欢迎大家关注,分享和点赞。


github地址:

https://github.com/guojiangli/k8s-grpc-demo

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
10月前
|
Linux Go iOS开发
Go语言100个实战案例-进阶与部署篇:使用Go打包生成可执行文件
本文详解Go语言打包与跨平台编译技巧,涵盖`go build`命令、多平台构建、二进制优化及资源嵌入(embed),助你将项目编译为无依赖的独立可执行文件,轻松实现高效分发与部署。
1523 162
|
10月前
|
存储 前端开发 JavaScript
Go语言实战案例-项目实战篇:编写一个轻量级在线聊天室
本文介绍如何用Go语言从零实现一个轻量级在线聊天室,基于WebSocket实现实时通信,支持多人消息广播。涵盖前后端开发、技术选型与功能扩展,助你掌握Go高并发与实时通信核心技术。
988 158
|
11月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
1139 0
|
11月前
|
存储 人工智能 Go
Go-Zero全流程实战即时通讯
Go-Zero 是一个功能丰富的微服务框架,适用于开发高性能的即时通讯应用。它具备中间件、工具库和代码生成器,简化开发流程。本文介绍其环境搭建、项目初始化及即时通讯功能实现,涵盖用户认证、消息收发和实时推送,帮助开发者快速上手。
565 0
|
11月前
|
数据采集 Go API
Go语言实战案例:使用context控制协程取消
本文详解 Go 语言中 `context` 包的使用,通过实际案例演示如何利用 `context` 控制协程的生命周期,实现任务取消、超时控制及优雅退出,提升并发程序的稳定性与资源管理能力。
568 152
|
9月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
11月前
|
负载均衡 监控 Java
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
在微服务架构中,高可用与稳定性至关重要。本文详解熔断、限流与负载均衡三大关键技术,结合API网关与Hystrix-Go实战,帮助构建健壮、弹性的微服务系统。
983 1
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
|
11月前
|
安全 Go 开发者
Go语言实战案例:使用sync.Mutex实现资源加锁
在Go语言并发编程中,数据共享可能导致竞态条件,使用 `sync.Mutex` 可以有效避免这一问题。本文详细介绍了互斥锁的基本概念、加锁原理及实战应用,通过构建并发安全的计数器演示了加锁与未加锁的区别,并封装了一个线程安全的计数器结构。同时对比了Go中常见的同步机制,帮助开发者理解何时应使用 `Mutex` 及其注意事项。掌握 `Mutex` 是实现高效、安全并发编程的重要基础。
|
11月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
11月前
|
Go 开发者
Go语言实战案例:使用select监听多个channel
本文为《Go语言100个实战案例 · 网络与并发篇》第5篇,详解Go并发核心工具`select`的使用。通过实际案例讲解如何监听多个Channel、实现多任务处理、超时控制和非阻塞通信,帮助开发者掌握Go并发编程中的多路异步事件处理技巧。

热门文章

最新文章