> For the complete documentation index, see [llms.txt](https://long0419.gitbook.io/mileworks-microservice-kit/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://long0419.gitbook.io/mileworks-microservice-kit/k8s-rong-qi-bian-pai-ji-zhu-jie-shao-he-spring-cloud-zheng-he.md).

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

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

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

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

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

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

**3.镜像的完美结合。**

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

首先推荐书籍和讨论区：\
[Kubernetes权威指南：从Docker到Kubernetes实践全接触（纪念版）](https://item.jd.com/12230380.html)

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

![](https://jimmysong.io/kubernetes-handbook/images/12-factor-app.png)

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整套项目持续集成与发布

![](/files/-LepHTa8ODyodwhWOKDU)

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

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地址。关于边缘节点，请查看

   [边缘节点配置](https://jimmysong.io/kubernetes-handbook/practice/edge-node-configuration.html)
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
```

**一般部署的结构图：**

表明共同位置关系，用于后期ci 结合![](https://wdc.objectstorage.softlayer.net/v1/AUTH_7046a6f4-79b7-4c6c-bdb7-6f68e920f6e5/Code-Patterns/deploy-spring-boot-microservices-on-kubernetes/images/Deploy-Spring-Boot-microservices-on-Kubernetes.png)

![](https://cdn-images-1.medium.com/max/1600/1*lneMW3achifpUdFS9cVSCQ.png)

## 番外 **：**

**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 外 其他都是垃圾 。**~~

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

**猪齿鱼 :**&#x20;

* 融合集成一整套Agile/DevOps的工具链，包括知识管理、敏捷管理、应用管理、开发流水线、测试管理、部署流水线和运营管理等。
* 一套基于Spring Cloud的微服务开发框架，帮助企业更快、更高效地进行微服务开发。

```
http://choerodon.io
```

![](/files/-LepHTaFPIsLLraXj2yW)

**Rainbond :**&#x20;

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

```
https://www.rainbond.com
```

![](/files/-LepHTaHIWHgWLk6KZ_k)

## K8S 的部署：

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

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

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

最后熬到捷径 ：

![https://github.com/wise2c-devops/breeze](https://camo.githubusercontent.com/55d32305772690ad84aad3e858900ea0cb8c630d/68747470733a2f2f61736369696e656d612e6f72672f612f764659694d473370747a6459506b5336387263756a34414b4b2e706e67)

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

#### M**inikube ：**

```
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>

**注意：**~~在调试自己工程的时候终于感受到了aliyun的强大，可以使用阿里的镜像库~~[~~https://cr.console.aliyun.com/cn-hangzhou/repositories~~](https://cr.console.aliyun.com/cn-hangzhou/repositories)~~，工程调试镜像可以自己打完tag，丢到阿里云中。~~![](/files/-LepHTaQZqw5dglOAfkm)![](/files/-LepHTaSJELUWslaWhIq)

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

## spring cloud 项目的整合：

先上代码

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

请按步骤执行这里脚本，同时学习代码中的yaml。后续代码有问题的可以来，有坑不教学！，仔细阅读代码是王道。\
![](/files/-LepHTaUWWJhvYW9jq58)![](/files/-LepHTaWyQS8wZ7qFJ_f)

### **补充**

~~**必要性参考：单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
```
