云原生初体验:在K8s上部署Springboot应用

云计算 云原生
本文会在window环境下,构建一套基于k8s的istio环境,并且通过skaffold完成镜像的构建和项目部署到集群环境。其实对于实验环境有限的朋友们,完全可以在某里云上,按量付费搞3台”突发性能实例“,玩一晚,也就是杯咖啡钱。

[[417286]]

你会不会对“云原生”很有兴趣,却不知道从何入手?

本文会在window环境下,构建一套基于k8s的istio环境,并且通过skaffold完成镜像的构建和项目部署到集群环境。其实对于实验环境有限的朋友们,完全可以在某里云上,按量付费搞3台”突发性能实例“,玩一晚,也就是杯咖啡钱。

好吧,让我开始吧!

执行流程

整体流程的话,如下图所示,通过 Skaffold+jib 将开发的应用打包成镜像,提交到本地仓库,并且将应用部署到集群中。k8s中部署2个pod,模拟应用不同的版本,并且配置访问权重20%:80%。

环境选择

我之前有文章详细介绍过minikube。本次实验,开始的时候,我就一直沉溺在使用kind的便捷上,而且直接可以在docker上部署集群,可以说非常方便。但是由于我对K8S的理解并不足够,导致后面遇到了很多问题,所以,在这里建议新上手的小伙伴,还是使用minikube吧。k3s和RKE都需要多台虚拟机,碍于机器性能,这种方案暂时不考虑了。

下面表格,对比了minikube、kind、k3s 部署环境,以及支持情况,方便大家选择。 

  minikube kind k3s
runtime VM container native
supported architectures AMD64 AMD64 AMD64, ARMv7, ARM64
supported container runtimes Docker,CRI-O,containerd,gvisor Docker Docker, containerd
startup time initial/following 5:19 / 3:15 2:48 / 1:06 0:15 / 0:15
memory requirements 2GB 8GB (Windows, MacOS) 512 MB
requires root? no no yes (rootless is experimental)
multi-cluster support yes yes no (can be achieved using containers)
multi-node support no yes yes
project page https://minikube.sigs.k8s.io/ https://kind.sigs.k8s.io/

[1] 表格引用自:http://jiagoushi.pro/minikube-vs-kind-vs-k3s-what-should-i-use

docker desktop 没有特殊要求。其他的自己用的顺手就好,还是需要特别说一下minikube,别用最新的coredns一直都拉不下来,除非你的魔法,可以完全搞定,否则,还是用阿里编译的minikube版本吧,别跟自己较劲,别问我为什么...

我用的版本罗列在下面了:

  1. ➜ ~ istioctl version 
  2. client version: 1.10.2 
  3. control plane version: 1.10.2 
  4. data plane version: 1.10.2 (10 proxies) 
  5.  
  6. ➜ ~ minikube version 
  7. minikube version: v1.18.1 
  8. commit: 511aca80987826051cf1c6527c3da706925f7909 
  9.  
  10. ➜ ~ skaffold version 
  11. v1.29.0 

环境搭建

使用minikube创建集群

使用 hyperv 作为引擎 , 内存 8192M cup 4核,不能再少了,否则拉不起来 istio。

  1. ➜ ~ minikube start  --image-mirror-country='cn' --registry-mirror=https://hq0igpc0.mirror.aliyuncs.com --vm-driver="hyperv" --memory=8192 --cpus=4 --hyperv-virtual-switch="minikubeSwitch" --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers 

还要在 hyperv里创建一个虚拟路由,这里我构建了一个内部网络,这样可以通过设置网卡的ip,将内部网络的网段固定下来,否则,每次重启都会变化ip。

配置让内部网络,共享访问互联网。

启动成功:

  1. ➜ istio-1.10.2 minikube start 
  2. 😄 Microsoft Windows 10 Pro 10.0.19042 Build 19042 上的 minikube v1.18.1 
  3. 🎉 minikube 1.20.0 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.20.0 
  4.  
  5. ✨ 根据现有的配置文件使用 hyperv 驱动程序 
  6. 👍 Starting control plane node minikube in cluster minikube 
  7. 🔄 Restarting existing hyperv VM for "minikube" ... 
  8. 🐳 正在 Docker 20.10.3 中准备 Kubernetes v1.20.2… 
  9. 🔎 Verifying Kubernetes components... 
  10.   ▪ Using image registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v4 (global image repository) 
  11.   ▪ Using image registry.hub.docker.com/kubernetesui/dashboard:v2.1.0 
  12.   ▪ Using image registry.hub.docker.com/kubernetesui/metrics-scraper:v1.0.4 
  13.   ▪ Using image registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.2.1 (global image repository) 
  14. 🌟 Enabled addons: metrics-server, storage-provisioner, dashboard, default-storageclass 
  15. 🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default 

部署 istio

创建 istio-system 的命名空间

kubectl create namespace istio-system

安装 istio

istioctl manifest apply --set profile=demo

安装完成后,执行命令 kubectl get svc -n istio-system

  1. ➜ ~ kubectl get svc -n istio-system 
  2. NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                     AGE 
  3. istio-egressgateway   ClusterIP      10.105.31.73     <none>        80/TCP,443/TCP                                                               8d 
  4. istio-ingressgateway   LoadBalancer   10.103.61.73     <pending>     15021:31031/TCP,80:31769/TCP,443:30373/TCP,31400:31833/TCP,15443:32411/TCP   8d 
  5. istiod                 ClusterIP      10.110.109.205   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP                                       8d 

部署 bookinfo

部署 bookinfo demo 验证环境

执行命令

  1. kubectl label namespace default istio-injection=enabled 
  2.  
  3. kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml 

等待pod都启动起来以后,添加bookinfo网络配置,用于访问 kubectl apply -f .\samples\bookinfo\networking\bookinfo-gateway.yaml

  1. ➜ istio-1.10.2 kubectl apply -f .\samples\bookinfo\networking\bookinfo-gateway.yaml 
  2.  
  3. gateway.networking.istio.io/bookinfo-gateway created 
  4.  
  5. virtualservice.networking.istio.io/bookinfo created 

使用命令查看service : kubectl get services

  1. ➜ ~ kubectl get services 
  2. NAME             TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE 
  3. callme-service   NodePort    10.106.26.24     <none>        8080:30101/TCP   8d 
  4. details         ClusterIP   10.110.253.19   <none>        9080/TCP         8d 
  5. kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP         8d 
  6. productpage     ClusterIP   10.96.246.175   <none>        9080/TCP         8d 
  7. ratings         ClusterIP   10.99.234.109   <none>        9080/TCP         8d 
  8. reviews         ClusterIP   10.103.177.123   <none>        9080/TCP         8d 

查看pods状态 kubectl get pods

  1. ➜ ~ kubectl get pods 
  2. NAME                                 READY   STATUS   RESTARTS   AGE 
  3. callme-service-v1-76dd76ddcc-znb62   2/2     Running   0         4h59m 
  4. callme-service-v2-679db76bbc-m4svm   2/2     Running   0         4h59m 
  5. details-v1-79f774bdb9-qk9q8          2/2     Running   8         8d 
  6. productpage-v1-6b746f74dc-p4xcb      2/2     Running   8         8d 
  7. ratings-v1-b6994bb9-dlvjm            2/2     Running   8         8d 
  8. reviews-v1-545db77b95-sgdzq          2/2     Running   8         8d 
  9. reviews-v2-7bf8c9648f-t6s8z          2/2     Running   8         8d 
  10. reviews-v3-84779c7bbc-4p8hv          2/2     Running   8         8d 

查看集群ip 以及 端口

  1. ➜ ~ kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}' 
  2. 192.168.137.115 
  3.  
  4.  
  5.  
  6. ➜ istio-1.10.2 kubectl get svc istio-ingressgateway -n istio-system 
  7.  
  8. NAME         TYPE     CLUSTER-IP   EXTERNAL-IP PORT(S)                                   AGE 
  9.  
  10. istio-ingressgateway LoadBalancer  10.110.228.32 <pending>   15021:32343/TCP,80:30088/TCP,443:31869/TCP,31400:32308/TCP,15443:32213/TCP 3m17s 

于是访问地址: http://192.168.137.115:31769/productpage

我们 bookinfo 就部署成功了。接下来我们创建应用。

构建应用

构建一个普通的springboot工程,添加编译插件,这里我们使用了本地的docker仓库存储镜像。

  1. <build> 
  2.       <plugins> 
  3.           <plugin> 
  4.               <groupId>org.springframework.boot</groupId> 
  5.               <artifactId>spring-boot-maven-plugin</artifactId> 
  6.               <executions> 
  7.                   <execution> 
  8.                       <goals> 
  9.                           <goal>build-info</goal> 
  10.                           <goal>repackage</goal> 
  11.                       </goals> 
  12.                   </execution> 
  13.               </executions> 
  14.           </plugin> 
  15.           <plugin> 
  16.               <groupId>com.google.cloud.tools</groupId> 
  17.               <artifactId>jib-maven-plugin</artifactId> 
  18.               <version>3.1.1</version> 
  19.               <configuration> 
  20.                   <to
  21.                       <image>127.0.0.1:9001/${project.artifactId}:${project.version}</image> 
  22.                       <auth> 
  23.                           <username> 
  24.                               xxx 
  25.                           </username> 
  26.                           <password
  27.                               xxx 
  28.                           </password
  29.                       </auth> 
  30.                   </to
  31.                   <allowInsecureRegistries>true</allowInsecureRegistries> 
  32.               </configuration> 
  33.           </plugin> 
  34.       </plugins> 
  35.   </build> 

 构建一个简单的rest,现实一个构建名称,以及配置的一个版本号。

  1. @Autowired 
  2. BuildProperties buildProperties; 
  3. @Value("${VERSION}"
  4. private String version; 
  5.  
  6. @GetMapping("/ping"
  7. public String ping() { 
  8.    LOGGER.info("Ping: name={}, version={}", buildProperties.getName(), version); 
  9.    return "I'm callme-service " + version; 

创建 skaffold.xml 用于给 skafflod 编译镜像,提交集群使用。

  1. kind: Config 
  2. build: 
  3. artifacts: 
  4.   - image: 127.0.0.1:9001/callme-service 
  5.     jib: {} 
  6. tagPolicy: 
  7.   gitCommit: {} 

创建k8s的部署描述k8s/deployment.yml,以及service用于访问。

  1. apiVersion: apps/v1 
  2. kind: Deployment 
  3. metadata: 
  4. name: callme-service-v1 
  5. spec: 
  6. replicas: 1 
  7. selector: 
  8.   matchLabels: 
  9.     app: callme-service 
  10.     version: v1 
  11. template: 
  12.   metadata: 
  13.     labels: 
  14.       app: callme-service 
  15.       version: v1 
  16.   spec: 
  17.     containers: 
  18.       - name: callme-service 
  19.         image: 127.0.0.1:9001/callme-service 
  20.         imagePullPolicy: IfNotPresent 
  21.         ports: 
  22.           - containerPort: 8080 
  23.         env: 
  24.           - name: VERSION 
  25.             value: "v1" 
  26. --- 
  27. apiVersion: apps/v1 
  28. kind: Deployment 
  29. metadata: 
  30. name: callme-service-v2 
  31. spec: 
  32. replicas: 1 
  33. selector: 
  34.   matchLabels: 
  35.     app: callme-service 
  36.     version: v2 
  37. template: 
  38.   metadata: 
  39.     labels: 
  40.       app: callme-service 
  41.       version: v2 
  42.   spec: 
  43.     containers: 
  44.       - name: callme-service 
  45.         image: 127.0.0.1:9001/callme-service 
  46.         imagePullPolicy: IfNotPresent 
  47.         ports: 
  48.           - containerPort: 8080 
  49.         env: 
  50.           - name: VERSION 
  51.             value: "v2" 
  52. --- 
  53. apiVersion: v1 
  54. kind: Service 
  55. metadata: 
  56. name: callme-service 
  57. labels: 
  58.   app: callme-service 
  59. spec: 
  60. type: NodePort 
  61. ports: 
  62. - port: 8080 
  63.   name: http 
  64.   nodePort: 30101 
  65. selector: 
  66.   app: callme-service 

创建 istio描述文件 k8s\istio-rules.yaml:

  1. apiVersion: networking.istio.io/v1beta1 
  2. kind: DestinationRule 
  3. metadata: 
  4. name: callme-service-destination 
  5. spec: 
  6. host: callme-service 
  7. subsets: 
  8.   - name: v1 
  9.     labels: 
  10.       version: v1 
  11.   - name: v2 
  12.     labels: 
  13.       version: v2 
  14. # trafficPolicy: # --- enable for adding circuit breaker into DestinationRule 
  15. #   connectionPool: 
  16. #     http: 
  17. #       http1MaxPendingRequests: 1 
  18. #       maxRequestsPerConnection: 1 
  19. #       maxRetries: 0 
  20. #   outlierDetection: 
  21. #     consecutive5xxErrors: 3 
  22. #     interval: 30s 
  23. #     baseEjectionTime: 1m 
  24. #     maxEjectionPercent: 100 
  25. --- 
  26. apiVersion: networking.istio.io/v1beta1 
  27. kind: VirtualService 
  28. metadata: 
  29. name: callme-service-route 
  30. spec: 
  31. hosts: 
  32.   - callme-service 
  33. http: 
  34.   - route: 
  35.     - destination: 
  36.         host: callme-service 
  37.         subset: v2 
  38.       weight: 80 
  39.     - destination: 
  40.         host: callme-service 
  41.         subset: v1 
  42.       weight: 20 
  43.     retries: 
  44.       attempts: 3 
  45.       retryOn: gateway-error,connect-failure,refused-stream 
  46.     timeout: 0.5s 
  47. #     fault: # --- enable for inject fault into the route 
  48. #       delay: 
  49. #         percentage: 
  50. #           value: 33 
  51. #         fixedDelay: 3s 

运行 skaffold 进行编译,提交镜像,并部署应用 skaffold run --tail。

  1. ➜ callme-service git:(master) ✗ skaffold run --tail 
  2. Generating tags... 
  3.  
  4. - 127.0.0.1:9001/callme-service -> 127.0.0.1:9001/callme-service:e9c731f-dirty 
  5.   Checking cache... 
  6. - 127.0.0.1:9001/callme-service: Found Locally 
  7.   Starting test... 
  8.   Tags used in deployment: 
  9. - 127.0.0.1:9001/callme-service -> 127.0.0.1:9001/callme-service:60f1bf39367673fd0d30ec1305d8a02cb5a1ed43cf6603e767a98dc0523c65f3 
  10.   Starting deploy... 
  11. - deployment.apps/callme-service-v1 configured 
  12. - deployment.apps/callme-service-v2 configured 
  13. - service/callme-service configured 
  14. - destinationrule.networking.istio.io/callme-service-destination configured 
  15. - virtualservice.networking.istio.io/callme-service-route configured 
  16.   Waiting for deployments to stabilize... 
  17. - deployment/callme-service-v1: waiting for init container istio-init to start 
  18.   - pod/callme-service-v1-76dd76ddcc-znb62: waiting for init container istio-init to start 
  19. - deployment/callme-service-v2: waiting for init container istio-init to start 
  20.   - pod/callme-service-v2-679db76bbc-m4svm: waiting for init container istio-init to start 
  21. - deployment/callme-service-v2 is ready. [1/2 deployment(s) still pending] 
  22. - deployment/callme-service-v1 is ready. 
  23.   Deployments stabilized in 45.671 seconds 

访问查看结果:

致此,我们初级的环境搭建基本完成了,对应云原生,感觉懂了一点,好像又没有懂,需要理解的东西还有很多,这个系列也会持续下去,希望大家和我交流,也欢迎关注,转发。

参考链接;

https://piotrminkowski.com/2020/02/14/local-java-development-on-kubernetes/

https://pklinker.medium.com/integrating-a-spring-boot-application-into-an-istio-service-mesh-a55948666fd

https://blog.csdn.net/xixingzhe2/article/details/88537038 

https://blog.csdn.net/chenleiking/article/details/86716049

本文转载自微信公众号「麒思妙想」,可以通过以下二维码关注。转载本文请联系麒思妙想公众号。

 

责任编辑:武晓燕 来源: 麒思妙想
相关推荐

2021-08-26 07:20:05

云原生K8sSpringboot

2023-11-03 08:43:00

云原生TLS 证书

2023-03-01 07:42:12

HBase编排部署数据

2022-11-06 21:31:11

云原生Sentinel集群模式

2023-09-06 08:12:04

k8s云原生

2024-09-26 09:50:07

2020-12-22 07:42:05

云原生开源项目k8s

2023-03-06 07:19:50

2022-07-04 08:48:23

K8sSpringBoot

2022-01-02 08:42:50

架构部署容器

2022-09-07 09:22:36

SpringBootWeb

2021-04-25 10:26:58

云计算云原生

2021-06-09 05:44:45

云原生 CICD

2023-08-07 08:48:13

2020-06-03 15:56:46

红帽云原生Quarkus

2022-11-08 08:55:31

2023-03-07 07:56:37

Sqoopk8s底层

2022-10-14 07:42:50

LuceneHTTPWeb

2024-06-12 13:21:06

2023-03-03 07:54:21

点赞
收藏

51CTO技术栈公众号