如何在K8S平台部署微服务

简介:

本文将介绍如何使用 kubernetes 部署微服务,包括 服务发现,监控,路由,日志。用实际的例子来演示自动化流程。主要分为以下几个部分:

  1. 5分钟搭建 K8S 集群

  2. 部署 CNI 网络

  3. 部署监控服务

  4. 部署网关

  5. 部署日志服务

  6. 部署一个应用

5分钟搭建 K8S 集群

第一次完全手动搭建集群大约花了一周时间,主要的问题是在于

  1. K8S的组件多,每个程序的参数有不少,哪些是关键的参数需要花时间搞清楚。

  2. 万恶的墙,代理访问外网比较慢

  3. CNI网络问题,主要是 CNI 网段和云上的局域网网段冲突了,基础知识缺失导致

  4. K8S 的证书和验证方式不清楚

本文相关代码位于github, 欢迎star。

手动部署可以参考我之前的博文,即便是完全熟悉部署流程,不写脚本的情况下,如果纯手动 setup 或者 tear down 一个集群,都是比较耗时间的。直到发现了这个工具 kubeadm, 世界美好了。

这个工具对操作系统有限制, ubuntu 16.04 或 centos 7 以上。其实当初也看到了这个工具, 不过 因为系统限制,并且kubeadm还在alpha版本,又想手动撸一遍部署过程,所以没直接采用。 不过 kubeadm 不建议在生产环境中使用,在 官方文档中的 limitation 中有详细解释.

文档 中第一点就说了, kubeadm部署的是 single master,意味着不是高可用,谨慎使用。 但是作为演示实例再合适不过。

小插曲: 因为最近发布的 k8s 1.6 的 kubeadm 有一个bug,导致用以下步骤安装会有问题,为此社区里有人提了一个patch, 步骤有些多,我写在本文最后了。
kubeadm v1.6.1 已经修复了bug。

开始部署步骤:

  • 在 Digital Ocean 中开三台机器, centos 7,建议2C2G,按小时计费用不了多少钱,用完就销毁。 如果还没有注册账号,并且觉得本文对你有帮助,可以用我的 referral link 注册,可以得到 10美金, 链接. 发现一个更便宜的vps, vultr, 还是SSD

  • 登录三台机器,安装必要组件.

yum clean yum update -y cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://yum.kubernetes.io/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF setenforce 0 yum install -y docker kubelet kubeadm kubectl kubernetes-cni systemctl enable docker && systemctl start docker systemctl enable kubelet && systemctl start kubelet 
# 补充几点 # 1. 因为1.6开始K8S开启了 RBAC 验证,需要在启动 kubelet 的参数中添加 --authentication-token-webhook vim vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 添加 --authentication-token-webhook 
# 2. 如果是 centos, 还需要添加 --cgroup-driver=systemd # 3. v1.6开始,apiserver禁用了 insecure-port, 需要拷贝 /var/kubernetes/ 下的 admin config, 作为验证配置. 
  • 选择一台作为master, 运行

kubeadm init

# 输出
Your Kubernetes master has initialized successfully!

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
 http://kubernetes.io/docs/admin/addons/

You can now join any number of machines by running the following on each node:

kubeadm join --token=e344fa.e007ce406eb41f07 104.236.166.119
完成后会看到提示: `kubeadm join --token=311971.7260777a25d70ac8 104.236.166.119`
  1. 在其他两台机器上分别运行以上提示的命令

  2. 在 master 上查看状态, kubectl get nodes, 如果看到一共有2个node,一个master, 则表示集群创建成功。

部署CNI网络

kubeadm 自动部署了一个插件,就是 kube-dns, 用于服务发现,但是到这里你会发现 kube-dns 这个服务没有启动成功,因为我们还没有部署CNI网络。

kubectl get pods --all-namespaces | grep dns

这里有比较多的选择,我使用了 calico,因为性能比较好,支持一键部署。 这里有一篇对比容器网络的文章,优缺点介绍比较全面, Battlefield: Calico, Flannel, Weave and Docker Overlay Network

配置文件在cni目录下,或者可以直接在master运行:

# for v1.6.0
kubectl apply -f http://docs.projectcalico.org/v2.1/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml

再次查看 dns 服务是否运行成功吧。

# 按需安装 git 和 dig
yum install -y bind-utils git 

监控

在部署之前,我们需要对两台node标记角色,k8s是通过label来自定义各个资源的类型的。
首先确定两台node的name, 通过 kubectl get nodes来查看,之后挑选其中一台作为前端机器(frontend).

kubectl label node centos-2gb-sfo1-03 role=frontend

这里把centos-2gb-sfo2-node1换成你的 node name

Prometheus

应用 monitor 目录下的两个配置文件,如下

kubectl create -f prometheus.config.yaml kubectl create -f prometheus.deploy.yaml

接下来打开 http://front-end-ip:30900 就能看到 prometheus 的界面

400b772f219c610a18bf876d81af0c3cc40b35f8

Grafana

kubectl create -f grafana.deploy.yaml

打开 http://front-end-ip:30200 就能看到 grafana 的界面.

  1. 还需要添加一个 Data Source. 选择 Promethues, 地址填上:
    http://promethues:9090, 因为有kube-dns,所以这样就能访问 pod 中的 service

    23dc8e96cf0db5b8d9277c95ad91eaaccc64cbdc

  2. 添加模板,内容为 grafana.config.k8s.json, 这个模板是针对 k8s 集群的仪表模板,添加时选择对应的 Data Source,然后就能看到效果。

    ed60801aacf9cd4a84ad378a8f4d1ac8076af3a3

网关

类似上面的步骤,配置文件在 gateway 目录下,运行

kubectl create -f traefik.yaml

这样在 http://front-end-ip:30088 能看到 网关的 dashboard。

traefik 可以监听 etcd 中注册的 ingress 的变化,根据 ingress 资源来自动配置路由, 下面会有具体的示例。最后的效果是, 后端服务的配置文件中定义他自己的 服务domain 和 prefix, traefik会自动添加这个路由, 这样就可以通过gateway来访问后端服务了。

日志收集

官方有推荐的Log系统: cAdvisor 和 Heapster.
我比较偏爱 ELK, 主要是生态比较好。有两种方式应用:

  1. 第一种是每个Pod都多加一个 sidecar - Filebeat, 在每个后端服务配置文件中指定本地log的路径(利用 k8s 的 emptyDir 这个volume),在filebeat的配置中指定这个路径,实现日志收集

  2. 还有一种是Filebeat作为 DaemonSet 运行在每台机器,利用 k8s 的 hostPath 这个volume, 这样每台机器只有一个 filebeat 运行,监听一个指定目录;后端服务约定好log都写入这个目录的子目录中,这样也能达到收集效果。

我比较推荐第二种方式,工作量稍微小一些。

第一个服务

终于到了这个紧张刺激的环节。

源文件在 hello-app 目录下,一个简单的 http service, 主要包含两个路由:

  1. /metrics 返回 prometheus 抓取的数据格式

  2. / 其他Path,返回一个随机id和URI

log 日志输入 /tmp/hello-log/hello-app.log;

想要达到的效果是:

  1. 配置文件中配好路由,自动注册到 gateway

  2. promethues 自动发现服务,抓取 http://hello:8080/metrics 的监控数据

  3. 日志能够自动收集

app 的配置文件位于 hello-app 目录下, 运行:

kubectl create -f hello.yaml

接着去 gateway 和 prometheus 的 dashboard 看下,会发现服务已经被发现;

47cd8259d4412e883101298519bd9eee6c2fe4af

再测试一下通过gateway是否能访问到 hello-app 这个服务:

curl http://front-end-ip:30087/v1/hello -H 'Host: www.hello.local' #结果为: ID:5577006791947779410 path:/hello

编译安装 kubeadm

  1. 下载 kubernetes 项目, checkout v1.6.0, 必须是这个tag

  2. cherry-pick 89557110ed4693a7d23e515e738ced266e099365

  3. KUBE_BUILD_PLATFORMS=linux/amd64 hack/make-rules/build.sh cmd/kubeadm

  4. 把生成的 _output 文件打包,放入服务器上

  5. 按照本文第一部分的步骤 yum 安装 docker, kubelet

  6. 编辑文件 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 添加 参数--cgroup-driver=systemd

  7. sudo systemctl daemon-reload && sudo systemctl restart kubelet.service

  8. kubeadm init 能完成,但是 node 状态是 not-ready,因为 cni 没有配置.

  9. 复制 /etc/kubernetes/admin.conf 文件到 ~/.kube/config 然后 执行 kubectl get nodes才可以,因为新版的apiserver启动时,把 insecure-port 禁用了,8080端口不再可用.

Alpine Linux

这次还遇到一个问题, alpine的docker镜像使用不顺利,ubuntu, centos下编译的文件在 alpine 下无法运行, 记得之前还运行成功过,这次得仔细找找原因。

如何打包出最小镜像

静态编译

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o hello hello-app/*.go

the -a flag means to rebuild all the packages we’re using, which means all the imports will be rebuilt with cgo disabled.
https://github.com/golang/go/...

建议使用 bash 作为 base image, 毕竟还有一些操作例如 mkdir, mv , cp 等需要执行。

如何查看 二进制文件 的 动态依赖?

# ldd hello linux-vdso.so.1 => (0x00007ffde7df8000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff931ae5000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff93171e000) /lib64/ld-linux-x86-64.so.2 (0x00005637b0ae4000) 

# readelf -d hello Dynamic section at offset 0x697100 contains 19 entries: Tag Type Name/Value 0x0000000000000004 (HASH) 0xa959e0 0x0000000000000006 (SYMTAB) 0xa95e60 0x000000000000000b (SYMENT) 24 (bytes) 0x0000000000000005 (STRTAB) 0xa95c40 0x000000000000000a (STRSZ) 518 (bytes) 0x0000000000000007 (RELA) 0xa95650 0x0000000000000008 (RELASZ) 24 (bytes) 0x0000000000000009 (RELAENT) 24 (bytes) 0x0000000000000003 (PLTGOT) 0xa97000 0x0000000000000015 (DEBUG) 0x0 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0] // 动态依赖库 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] // 动态依赖库 0x000000006ffffffe (VERNEED) 0xa95960 0x000000006fffffff (VERNEEDNUM) 2 0x000000006ffffff0 (VERSYM) 0xa95920 0x0000000000000014 (PLTREL) RELA 0x0000000000000002 (PLTRELSZ) 648 (bytes) 0x0000000000000017 (JMPREL) 0xa95680 0x0000000000000000 (NULL) 0x0

Alpine 编译

alpine linux 使用 musl libc,而 ubuntu, centos 使用的是 glibc, 所以在 ubuntu,centos下编译的文件一般不能直接使用在 alpine 环境。

# export WORKDIR=/go/src/hello-app 
# docker run --rm -v $GOPATH/src:/go/src -v "$PWD":${WORKDIR} -w ${WORKDIR} golang:1.8-alpine go build -o hello-alpine hello-app/main.go 

注意,编译的依赖package 被映射入了 /go/src 中; -w 表示 working directory.

本文转自中文社区-如何在K8S平台部署微服务

相关文章
|
7月前
|
jenkins Java 持续交付
使用 Jenkins 和 Spring Cloud 自动化微服务部署
随着单体应用逐渐被微服务架构取代,企业对快速发布、可扩展性和高可用性的需求日益增长。Jenkins 作为领先的持续集成与部署工具,结合 Spring Cloud 提供的云原生解决方案,能够有效简化微服务的开发、测试与部署流程。本文介绍了如何通过 Jenkins 实现微服务的自动化构建与部署,并结合 Spring Cloud 的配置管理、服务发现等功能,打造高效、稳定的微服务交付流程。
832 0
使用 Jenkins 和 Spring Cloud 自动化微服务部署
|
9月前
|
数据采集 弹性计算 自然语言处理
微服务化采集平台:可扩展性与容错机制
本文介绍一个基于财经场景的微服务化数据采集平台,解决新浪财经等内容站点信息分散、结构多变、更新频繁等痛点。通过代理配置、动态解析、自动分类与容错机制,实现要闻、突发、证券资讯的高效抓取与结构化处理,为舆情监控、NLP分析和投研建模提供实时数据支撑,提升市场响应速度与数据质量。
158 1
微服务化采集平台:可扩展性与容错机制
|
9月前
|
存储 监控 Shell
SkyWalking微服务监控部署与优化全攻略
综上所述,虽然SkyWalking的初始部署流程相对复杂,但通过一步步的准备和配置,可以充分发挥其作为可观测平台的强大功能,实现对微服务架构的高效监控和治理。尽管未亲临,心已向往。将一件事做到极致,便是天分的展现。
|
Kubernetes Cloud Native 持续交付
容器化、Kubernetes与微服务架构的融合
容器化、Kubernetes与微服务架构的融合
594 82
|
监控 Kubernetes Cloud Native
基于阿里云容器服务Kubernetes版(ACK)的微服务架构设计与实践
本文介绍了如何基于阿里云容器服务Kubernetes版(ACK)设计和实现微服务架构。首先概述了微服务架构的优势与挑战,如模块化、可扩展性及技术多样性。接着详细描述了ACK的核心功能,包括集群管理、应用管理、网络与安全、监控与日志等。在设计基于ACK的微服务架构时,需考虑服务拆分、通信、发现与负载均衡、配置管理、监控与日志以及CI/CD等方面。通过一个电商应用案例,展示了用户服务、商品服务、订单服务和支付服务的具体部署步骤。最后总结了ACK为微服务架构提供的强大支持,帮助应对各种挑战,构建高效可靠的云原生应用。
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
857 24
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
580 7
|
监控 Cloud Native Java
基于阿里云容器服务(ACK)的微服务架构设计与实践
本文介绍如何利用阿里云容器服务Kubernetes版(ACK)构建高可用、可扩展的微服务架构。通过电商平台案例,展示基于Java(Spring Boot)、Docker、Nacos等技术的开发、容器化、部署流程,涵盖服务注册、API网关、监控日志及性能优化实践,帮助企业实现云原生转型。
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
808 6
|
监控 Nacos 数据安全/隐私保护
动态服务管理平台在微服务架构中的实践与探索
动态服务管理平台在微服务架构中的实践与探索

推荐镜像

更多