六、K8s 容器编排技术自研总结和Spring cloud 整合

K8s 容器编排技术自研总结和与Spring cloud 整合

kubernetes 是个神器,未来有了它可以减少的工作量不光从开发、运维成本上可以很多很多,这套体系到目前为止我也只是基础上手 。后续我会有条件慢慢去学习 ,他是一套自我修正的过程。Kubemetes 是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台。

为啥非要用K8S,我们虽然使用了微服务这套东西,但是带来负面的东西也不少:

1.系统异构情况严重,中间件、代码等,构建和部署非常麻烦,所以单独找运维不见得能把程序弄好。

2.使用微服务的时候,特别是产品,后期肯定使用分布式,这个时候你如果单独部署,那麻烦事情不是一下两下。要有个东西协调统一。

3.镜像的完美结合。

上三点之后 , K8S 是主流 ,也是必须趋势。

首先推荐书籍和讨论区: Kubernetes权威指南:从Docker到Kubernetes实践全接触(纪念版)

前四章内容反复阅读之后你会大致上手。基础概念不再说明。k8s的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,Kubernetes可以帮你将系统自动得达到和维持在这个状态。Kubernetes用户可以通过编写一个yaml或者json格式的配置文件,也可以通过工具/代码生成或直接请求Kubernetes API创建应用,该配置文件中包含了用户想要应用程序保持的状态,不论整个Kubernetes集群中的个别主机发生什么问题,都不会影响应用程序的状态,你还可以通过改变该配置文件或请求Kubernetes API来改变应用程序的状态。12因素应用 前面已经说明,K8s是全部映射的。十二因素应用构建图:

1.基准代码

每个代码仓库(repo)都生成docker image保存到镜像仓库中,并使用唯一的ID管理,在Jenkins中使用编译时的ID。

2.依赖

显式的声明代码中的依赖,使用软件包管理工具声明,比如Go中的Glide。

3.配置

将配置与代码分离,应用部署到Kubernetes中可以使用容器的环境变量或ConfigMap挂载到容器中。

4.后端服务

把后端服务当作附加资源,实质上是计算存储分离和降低服务耦合,分解单体应用。

5.构建、发布、运行

严格分离构建和运行,每次修改代码生成新的镜像,重新发布,不能直接修改运行时的代码和配置。

6.进程

应用程序进程应该是无状态的,这意味着再次重启后还可以计算出原先的状态。

7.端口绑定

在Kubernetes中每个Pod都有独立的IP,每个运行在Pod中的应用不必关心端口是否重复,只需在service中指定端口,集群内的service通过配置互相发现。

8.并发

每个容器都是一个进程,通过增加容器的副本数实现并发。

9.易处理

快速启动和优雅终止可最大化健壮性,Kuberentes优秀的Pod生存周期控制。

10.开发环境与线上环境等价

在Kubernetes中可以创建多个namespace,使用相同的镜像可以很方便的复制一套环境出来,镜像的使用可以很方便的部署一个后端服务。

11.日志

把日志当作事件流,使用stdout输出并收集汇聚起来,例如到ES中统一查看。

12.管理进程

后台管理任务当作一次性进程运行,kubectl exec进入容器内部操作。

另外,Cloud Native Go 这本书的作者,CapitalOne公司的Kevin Hoffman在TalkingData T11峰会上的High Level Cloud Native的演讲中讲述了云原生应用的15个因素,在原先的12因素应用的基础上又增加了如下三个因素:

API优先

服务间的合约 团队协作的规约 文档化、规范化 RESTful或RPC 监控

实时监控远程应用 应用性能监控(APM) 应用健康监控 系统日志 不建议在线Debug 认证授权

不要等最后才去考虑应用的安全性 详细设计、明确声明、文档化 Bearer token、OAuth、OIDC认证 操作审计

Kubernetes提供了多种资源对象,用户可以根据自己应用的特性加以选择。这些对象有:

类别

名称

资源对象

Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaler

配置对象

Node、Namespace、Service、Secret、ConfigMap、Ingress、Label、CustomResourceDefinition、 ServiceAccount

存储对象

Volume、Persistent Volume

策略对象

SecurityContext、ResourceQuota、LimitRange

Kubernetes提供了多种资源对象,用户可以根据自己应用的特性加以选择。有了K8S整套项目持续集成与发布

应用构建和发布流程说明:

  1. 用户向Gitlab提交代码,代码中必须包含

    Dockerfile

  2. 将代码提交到远程仓库

  3. 用户在发布应用时需要填写git仓库地址和分支、服务类型、服务名称、资源数量、实例个数,确定后触发Jenkins自动构建

  4. Jenkins的CI流水线自动编译代码并打包成Docker镜像推送到Harbor镜像仓库

  5. Jenkins的CI流水线中包括了自定义脚本,根据我们已准备好的Kubernetes的YAML模板,将其中的变量替换成用户输入的选项

  6. 生成应用的Kubernetes YAML配置文件

  7. 更新Ingress的配置,根据新部署的应用的名称,在Ingress的配置文件中增加一条路由信息

  8. 更新PowerDNS,向其中插入一条DNS记录,IP地址是边缘节点的IP地址。关于边缘节点,请查看

    边缘节点配置

  9. Jenkins调用Kubernetes的API,部署应用

大神地址:

https://jimmysong.io/

其他:

https://developer.ibm.com/patterns/deploy-spring-boot-microservices-on-kubernetes/

https://medium.com/@AnimeshSingh_74972/microservices-polyglot-apps-websites-scalable-databases-hosted-repositories-bring-them-all-on-2f99eecb9039

工具:

https://www.oschina.net/p/wayne

一般部署的结构图:

番外

Consul :

学习K8s之初,有个东西必须先要研究,就是它的服务发现系统 --- Consul , Consul是一个分布式高可用的系统. 这节将包含一些基础,我们忽略掉一些细节这样你可以快速了解Consul是如何工作的.如果要了解更多细节,请参考深入的架构描述.

每个提供服务给Consul的节点都运行了一个Consul agent . 发现服务或者设置和获取 key/value存储的数据不是必须运行agent.这个agent是负责对节点自身和节点上的服务进行健康检查的.

Agent与一个和多个Consul Server 进行交互.Consul Server 用于存放和复制数据.server自行选举一个领袖.虽然Consul可以运行在一台server , 但是建议使用3到5台来避免失败情况下数据的丢失.每个数据中心建议配置一个server集群.

你基础设施中需要发现其他服务的组件可以查询任何一个Consul 的server或者 agent.Agent会自动转发请求到server .

每个数据中运行了一个Consul server集群.当一个跨数据中心的服务发现和配置请求创建时.本地Consul Server转发请求到远程的数据中心并返回结果.

参考文档:

https://book-consul-guide.vnzmi.com/
https://my.oschina.net/tree/blog/1594206

基于Docker + Consul + Registrator的服务注册与发现集群搭建:
https://juejin.im/post/5b2a6b606fb9a00e594c676d

注意:在node节点下的时候打以下命令:
加入ip用下面指令
JOIN_IP="$(docker inspect -f '{{.NetworkSettings.IPAddress}}' node1)"

单节点下使用docker部署consul
https://my.oschina.net/yangchen1127/blog/1600954

K8S 常用命令:

KUBERNETES_USERNAME=admin
KUBERNETES_PASSWORD=nGu8thYuPSz0tL9v
KUBERNETES_SERVER=35.194.219.153

kubectl config set-credentials fabric8 --username=$KUBERNETES_USERNAME --password=$KUBERNETES_PASSWORD
kubectl config set-cluster fabric8 --insecure-skip-tls-verify=true --server=https://$KUBERNETES_SERVER
kubectl config set-context fabric8 --user=fabric8 --namespace=default --cluster=fabric8
kubectl config use-context fabric8

https://kubernetes.io/docs/getting-started-guides/ubuntu/#official-ubuntu-guides

c
kubectl logs init-tenant-db-6f6bbd9b8c-pmhf4

kubectl logs -p wit-69cd7b4f99-fg5n9

kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
helm init --service-account tiller --upgrade

fabric8】: 不用看了,除了用java调用K8S api 外 其他都是垃圾 。

这里看好的国内的两个项目 , 有机会要尝试一把:

猪齿鱼 :

  • 融合集成一整套Agile/DevOps的工具链,包括知识管理、敏捷管理、应用管理、开发流水线、测试管理、部署流水线和运营管理等。

  • 一套基于Spring Cloud的微服务开发框架,帮助企业更快、更高效地进行微服务开发。

http://choerodon.io

Rainbond :

深度整合基于Kubernetes的容器管理、ServiceMesh微服务架构最佳实践、多类型CI/CD应用构建与交付、多数据中心资源管理等技术, 为用户提供云原生应用全生命周期解决方案,构建应用与基础设施、应用与应用、基础设施与基础设施之间互联互通的生态体系, 满足支撑业务高速发展所需的敏捷开发、高效运维和精益管理需求。

https://www.rainbond.com

K8S 的部署:

能把k8s能玩的很转的应该在国内很少,因为不光从这个东西部署,到实际应用上都是麻烦事情,不是简单点点安装就完了。因为这个东西最终的目标是集群,这个集群不是广义上丢手的集群,而是整个项目后期只要一个构建脚本,全部实现项目集群部署和逻辑实现。

我个人部署集群上花了好多时间,这个东西绕不过去,他是学习k8s和后期项目实战,绕不过去坎。 想偷懒的话几个东西必须要学习:vgarantharbor 等,推荐教程:

https://github.com/Mileworks/follow-me-install-kubernetes-cluster
https://github.com/Mileworks/kubernetes-vagrant-centos-cluster

最后熬到捷径 :

有价值项目:
a.部署相关
https://github.com/wise2c-devops/breeze  
b.ci
https://github.com/gardener/gardener

Minikube :

https://yq.aliyun.com/articles/221687

退一步:如果没有实力搞集群,只是开发。这里只针对实际本地开发时候搭建k8s,官方推荐的是minikube。关注https://github.com/AliyunContainerService/minikube 每次可以从这里make 镜像 。

运行环境

ubuntu 18.04 至少这个版本 低了不行 没有snap 可以访问互联网 docker 环境

安装步骤

更新系统apt包相关资源,需要手动调整到国内的镜像源 不然要慢死人了。 安装snap snapd 方便后续安装kubectl:

sudo apt update 
&
&
 sudo apt upgrade   
sudo apt install snap  snapd

1:安装kubectl 比较懒 采用 snap(类似apt的东西) 安装kubectl

sudo snap install kubectl (妈的 这步安装之后始终会报下面的错,后可以从github下载对应版本的kubectl)

2:安装golang 使用apt 安装golang

sudo apt install golang

3: 安装minikube

curl -Lo minikube http://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v0.25.0/minikube-linux-amd64 
&
&
 chmod +x minikube 
&
&
 sudo mv minikube /usr/local/bin/

4:启动minikube

minikube start --registry-mirror=https://registry.docker-cn.com
minikube ssh

手动拉取镜像: 配合本地docker环境 阿里的镜像查询地址:https://dev.aliyun.com/search.html

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-addon-manager-amd64:v6.4-beta.2
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-addon-manager-amd64:v6.4-beta.2 gcr.io/google-containers/kube-addon-manager:v6.4-beta.2

docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/kubernetes-dashboard-amd64:v1.7.0
docker tag registry.cn-hangzhou.aliyuncs.com/google-containers/kubernetes-dashboard-amd64:v1.7.0 gcr.io/google-containers/kubernetes-dashboard-amd64:v1.7.0


docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-dns-kube-dns-amd64:1.14.5
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-dns-kube-dns-amd64:1.14.5 gcr.io/google-containers/k8s-dns-kube-dns-amd64:1.14.5

docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5
docker tag registry.cn-hangzhou.aliyuncs.com/google-containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5 gcr.io/google-containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5

docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/k8s-dns-sidecar-amd64:1.14.5
docker tag registry.cn-hangzhou.aliyuncs.com/google-containers/k8s-dns-sidecar-amd64:1.14.5 gcr.io/google-containers/k8s-dns-sidecar-amd64:1.14.5

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kubedns-amd64:1.9
docker tag registry.cn-hangzhou.aliyuncs.com/google-containers/kubedns-amd64:1.9 gcr.io/google-containers/kubedns-amd64:1.9

docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/kube-dnsmasq-amd64:1.4
docker tag registry.cn-hangzhou.aliyuncs.com/google-containers/kube-dnsmasq-amd64:1.4 gcr.io/google-containers/kube-dnsmasq-amd64:1.4

docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/exechealthz-amd64:1.2
docker tag registry.cn-hangzhou.aliyuncs.com/google-containers/exechealthz-amd64:1.2 gcr.io/google-containers/exechealthz-amd64:1.2

docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/echoserver:1.4
docker tag  registry.cn-hangzhou.aliyuncs.com/google-containers/echoserver:1.4 gcr.io/google-containers/echoserver:1.4

docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0
docker tag registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0 gcr.io/google-containers/pause-amd64:3.0

5:尝试kubectl是否可用

kubectl get all

注意: 如果出现如下信息的解决办法:

Error from server (NotAcceptable): unknown (get pods)

先到 https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md#client-binaries-1从github上找到对应的client binaries。然后复制连接地址。然后执行以下命令

wget https://dl.k8s.io/v1.9.3/kubernetes-client-linux-amd64.tar.gz
tar -zxvf kubernetes-client-linux-amd64.tar.gz
cd kubernetes/client/bin
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

6:打开k8s web ui

minikube dashboard

如果报以下错误信息,解决办法

Waiting, endpoint for service is not ready yet...

后面要在进入minikube ssh后,在minikube 里面构建registry 仓库,然后kubenetes 每次会从minikube 自己仓库里面拿镜像。https://blog.hasura.io/sharing-a-local-registry-for-minikube-37c7240d0615

后期kubernets 全部从这里拉镜像。

spring cloud 项目的整合:

先上代码

https://github.com/Mileworks/microservices-demo

补充

必要性参考:单web app k8s 部署

https://codelabs.developers.google.com/codelabs/cloud-springboot-kubernetes/index.html 
https://dzone.com/articles/quick-guide-to-microservices-with-kubernetes-sprin

Last updated