Categories
程式開發

在Kubernetes上運行SpringBoot應用



{“ type”:“ doc”,“ content”:[{“type”:”blockquote”,”content”:[{“type”:”paragraph”,”content”:[{“type”:”text”,”text”:”花仲抒站在荒凉的山丘上,看着两位截移派大神WebLogic和WebSphere老态龙钟渐行渐远的背影,心中竟有些许伤感,不禁吟道:”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“內容”:[{“type”:”text”,”text”:”滚滚长江东逝水,浪花淘尽英雄。”}]},{“ type”:“ paragraph”,“ content”:[{“type”:”text”,”text”:”是非成败转头空。”}]},{“ type”:“ paragraph”,“ content”:[{“type”:”text”,”text”:”青山依旧在,几度夕阳红。”}]},{“ type”:“ paragraph”,“ content”:[{“type”:”text”,”text”:”白发渔樵江渚上,惯看秋月春风。”}]},{“ type”:“ paragraph”,“ content”:[{“type”:”text”,”text”:”一壶浊酒喜相逢。”}]},{“ type”:“ paragraph”,“ content”:[{“type”:”text”,”text”:”古今多少IT技,都付笑谈中。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“內容”:[{“type”:”text”,”text”:”吟罢双腿微曲,体内运行着库泊大法,将真虚二气容纳其中,纵身一跃,跳上旁边一颗古树,起落之间已经站在树梢,一套SpringBoot春初拳施展开来,真是行云流水,简约轻盈至极。”}]}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”本文介绍如何将一个SpringBoot应用打docker镜像包,推送到docker镜像库,然后部署到kubernetes上运行。”}]},{“ type”:“標題”,“ attrs”:{“ align”:null,“ level”:4},“ content”:[{“type”:”text”,”text”:”一、环境准备”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”首先检查你的kubernetes集群环境已经就绪,如果你没有的话,最简单的方式是使用Minikube,如何安装详见kubernetes官网 https://kubernetes.io/docs/tasks/tools/install-minikube/ “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”执行以下命令检查k8s环境”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”[email protected]:~$ kubectl versionnClient Version: version.Info{Major:”1″, Minor:”17″, GitVersion:”v1.17.0″, GitCommit:”70132b0f130acc0bed193d9ba59dd186f0e634cf”, GitTreeState:”clean”, BuildDate:”2019-12-07T21:20:10Z”, GoVersion:”go1.13.4″, Compiler:”gc”, Platform:”linux/amd64″}nServer Version: version.Info{Major:”1″, Minor:”17″, GitVersion:”v1.17.2″, GitCommit:”59603c6e503c87169aea6106f57b9f242f64df89″, GitTreeState:”clean”, BuildDate:”2020-01-18T23:22:30Z”, GoVersion:”go1.13.5″, Compiler:”gc”, Platform:”linux/amd64″}[email protected]:~$ kubectl get nodesnNAME STATUS ROLES AGE VERSIONnubuntu-box Ready master 40d v1.17.2″}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”这是一个单节点的minikube环境,一切正常,Let us go!”}]},{“ type”:“標題”,“ attrs”:{“ align”:null,“ level”:4},“ content”:[{“type”:”text”,”text”:”二、编写一个简单的SpringBoot应用”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”本文采用在 “},{“type”:”link”,”attrs”:{“href”:”https://start.spring.io/”,”title”:null},”content”:[{“type”:”text”,”text”:”https://start.spring.io/”}]},{“ type”:“ text”,“ text”:“創建SpringBoot應用的方式,創建一個只需要Spring Web依賴的簡單web應用,如下圖所示”}“

},{“ type”:“ image”,“ attrs”:{“ src”:“ https://static001.geekbang.org/infoq/af/af14e78e3f157d949f986f92c91c2d08.png”,“ alt”:null,“ title”: ““,“樣式”:[{“key”:”width”,”value”:”100%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null},” content“:[{“type”:”text”,”text”:”点击”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”GENERATE”}]},{“ type”:“ text”,“ text”:“按鈕,將下載到本地的zip包解壓,然後用IDE打開,添加一個控制器類”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ java”},“ content”:[{“type”:”text”,”text”:”package com.tiehuapen.hellok8s;nnimport org.springframework.web.bind.annotation.GetMapping;nimport org.springframework.web.bind.annotation.RestController;[email protected] class Hellok8sController {nn @GetMapping(“/”)n public String home() {n return “Hello K8S!”;n }n}”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”执行 “},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”mvn clean package”}]},{“ type”:“ text”,“ text”:“並檢查在本地能正常運行。”}]},{“ type”:“標題”,“ attrs”:{“ align”:null,“ level”:4},“ content”:[{“type”:”text”,”text”:”三、打包docker镜像”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”你可以采用Dockerfile方式创建Docker镜像,这种方式需要你本地安装了Docker。你也可以采用谷歌提供的容器化工具JIB来打包镜像,这种方式更方便,无需本地安装Docker,maven/gradle命令调用插件即可。”}]},{“ type”:“ image”,“ attrs”:{“ src”:“ https://static001.geekbang.org/infoq/26/26075b7472d3d5b3d27ce073b58bfd1c.png”,“ alt”:null,“ title”: ““,“樣式”:[{“key”:”width”,”value”:”100%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ heading”,“ attrs”:{“ align”:null,“ level”:5},“內容”:[{“type”:”text”,”text”:”方式一:使用Dockerfile”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”在Spring boot项目根目录下创建一个名为Dockerfile的文件,文件内容如下:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ dockerfile”},“ content”:[{“type”:”text”,”text”:”FROM openjdk:8-jdk-alpinenARG JARFILE=target/*.jarnCOPY ${JARFILE} app.jarnENTRYPOINT [“java”,”-jar”,”/app.jar”]“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”然后在项目根目录下执行构建镜像包的命令:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ docker build -t tiehuapen/hellok8s:v1 .”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”构建完成后,执行镜像列表查询的命令:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ docker imagesnREPOSITORY TAG IMAGE ID CREATED SIZEntiehuapen/hellok8s v1 9228d650f5e3 22 seconds ago 122MB”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”可以看到该镜像已经构建好了,接下来在本地docker环境测试一下该镜像是否可以正常运行,执行运行容器的命令:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ docker run -p 8080:8080 –rm tiehuapen/hellok8s:v1″}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”打开浏览器访问 http://localhost:8080/ ,运行正常。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”上面那个Dockerfile非常简洁,但是它默认采用root用户执行程序,另外,为了将Spring Boot fat jar中依赖项和应用程序资源之间干净分离,我们将Dockerfile做一些改进,改进后如下所示:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ dockerfile”},“ content”:[{“type”:”text”,”text”:”FROM openjdk:8-jdk-alpinenRUN addgroup -S spring && adduser -S spring -G springnUSER spring:springnARG DEPENDENCY=target/dependencynCOPY ${DEPENDENCY}/BOOT-INF/lib /app/libnCOPY ${DEPENDENCY}/META-INF /app/META-INFnCOPY ${DEPENDENCY}/BOOT-INF/classes /appnENTRYPOINT [“java”,”-cp”,”app:app/lib/*”,”com.tiehuapen.hellok8s.Hellok8sApplication”]“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”然后在项目根目录下执行构建镜像包的命令,并将tag设置为v2,注意:在构建之前要先将Spring Boot far jar解压到Dockerfile中指定的路径中。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ sh”},“ content”:[{“type”:”text”,”text”:”$ mkdir -p target/dependencyn$ cd .\target\dependency\n$ jar -xf ../*.jarn$ docker build -t tiehuapen/hellok8s:v2 .”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”构建完成后,执行镜像列表查询的命令:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ docker imagesnREPOSITORY TAG IMAGE ID CREATED SIZEntiehuapen/hellok8s v2 81e53377d1ea 9 minutes ago 122MBntiehuapen/hellok8s v1 f79127e183a1 About an hour ago 122MB”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”可以看到镜像v2也已经构建好了,类似v1版本,在本地docker环境测试一下是否可以正常运行。”}]},{“ type”:“標題”,“ attrs”:{“ align”:null,“ level”:5},“ content”:[{“type”:”text”,”text”:”方式二:使用Google GIB插件”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”采用Google GIB插件无需调用docker命令,可直接使用maven/gradle命令构建docker镜像。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”首先,在pom.xml中添加GIB插件:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ html”},“ content”:[{“type”:“text”,“text”:“nnnnnntcomgooglecloudtoolsntjib-maven-pluginnt210ntntnt[{“type”:”text””text”:”nnnnnntcomgooglecloudtoolsntjib-maven-pluginnt210ntntnt[{“type”:“text”,“text”:“nnnnnntcomgooglecloudtoolsntjib-maven-pluginnt210ntntnt[{“type”:”text””text”:”nnnnnntcomgooglecloudtoolsntjib-maven-pluginnt210ntntnt在Kubernetes上運行SpringBoot應用 1openjdk:高山 n t n t n t 在Kubernetes上運行SpringBoot應用 1tiehuapen / hellok8s:v3 n t n t n n … n n n … n“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”需要配置的主要信息就是from.image和to.image,from.image设置基础镜像,to.image设置将要构建的镜像名和标签。上面的from.image没有设置仓库地址,这表示将从默认的仓库地址docker.io下载基础镜像,速度一般会比较慢。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”如果你本地docker环境已经有该基础镜像了,那你也可以直接从本地docker环境获取基础镜像,如下所示:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ html”},“ content”:[{“type”:“text”,“text”:“n[{“type”:”text””text”:”n[{“type”:“text”,“text”:“n[{“type”:”text””text”:”n在Kubernetes上運行SpringBoot應用 1docker:// openjdk:alpine n“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”构建镜像命令如下所示,你可以选择将镜像生成在本地docker环境,也可以选择生成并上传到远程的镜像仓库。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”# 将镜像生成在本地docker环境n$ mvn compile jib:dockerBuildnn# 生成并上传到远程的镜像仓库n$ mvn compile jib:build”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”上面的例子中,将镜像生成在本地docker环境会执行成功,构建完成后,执行镜像列表查询的命令,可以看到本地docker已经有hellok8s:v3了。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ docker imagesnREPOSITORY TAG IMAGE ID CREATED SIZEntiehuapen/hellok8s v2 81e53377d1ea 19 hours ago 122MBntiehuapen/hellok8s v1 f79127e183a1 20 hours ago 122MBnopenjdk alpine 5801f7d008e5 21 months ago 103MBntiehuapen/hellok8s v3 a26b5c4f4e7b 50 years ago 120MB”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”但是生成并上传到远程的镜像仓库的命令会执行失败,报 401 Unauthorized 错误,这是因为to.image没有设置仓库地址(默认为docker hub),也没有设置用户鉴权信息。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”现在我们来设置将生成镜像上传到阿里云容器镜像仓库,同时还可以指定多个标签,如下所示:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ html”},“ content”:[{“type”:“text”,“text”:“n[{“type”:”text””text”:”n[{“type”:“text”,“text”:“n[{“type”:”text””text”:”n在Kubernetes上運行SpringBoot應用 1Registry.cn-beijing.aliyuncs.com/tiehuapen/hellok8s:v3n n xxx n yyy n n n三角帆 n最新 n n“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”其中的username和password是阿里云容器镜像服务的账号密码,而tiehuapen则是阿里云容器镜像服务的命名空间。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”再次执行”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”mvn compile jib:build”}]},{“ type”:“ text”,“ text”:“,結果顯示BUILD SUCCESS。在阿里雲控制台訪問容器託管服務,可以發現該已有已經成功。”}]},{“ type”:“ image”,“ attrs”:{“ src”:“ https://static001.geekbang.org/infoq/f1/f160f73d6eb26733cbed0bd924b285ab.png”,“ alt”:null,“ title”: ““,“樣式”:[{“key”:”width”,”value”:”100%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null},” content“:[{“type”:”text”,”text”:”关于GIB最后要说的是,可以将jib的构建目标绑定到maven的生命周期,比如”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”package”}]},{“ type”:“ text”,“ text”:“,如下所示:”}]]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ html”},“ content”:[{“type”:”text”,”text”:”n com.google.cloud.toolsn jib-maven-pluginn …n n n packagen n dockerBuildn n n n”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”现在执行”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”mvn package”}]},{“ type”:“ text”,“ text”:“,將會自動調用JIB插件命令,並實現。”}]},{“ type”:“標題”,“ attrs”:{“ align”:null,“ level”:4},“ content”:[{“type”:”text”,”text”:”四、部署到kubernetes”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”有了docker镜像之后,我们来将该镜像部署到kubernetes。首先创建一个namespace给我们这个演示使用,你当然也可以用已经存在的namespace,不过单独的命名空间更利于资源管理和清理。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl create ns demonnamespace/demo created”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”接下来,我们以两种不同的方式来将hellok8s应用部署到Kubernetes,一种是命令行方式,一种是yaml文件方式。”}]},{“ type”:“標題”,“ attrs”:{“ align”:null,“ level”:5},“ content”:[{“type”:”text”,”text”:”方式一:命令行方式部署”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”首先执行”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”kubectl create deployment”}]},{“ type”:“ text”,“ text”:“來部署hellok8s應用,如下所示,在命令中指定圖像和命名空間。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl create deployment hellok8s –image=registry.cn-beijing.aliyuncs.com/tiehuapen/hellok8s:v3 -n demondeployment.apps/hellok8s created”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”查询命名空间demo中的资源,发现deployment资源已经成功创建,并且随之创建了replicaset和pod。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl get all -n demonNAME READY STATUS RESTARTS AGEnpod/hellok8s-dd4ddd4dc-gt6v2 1/1 Running 0 8snnNAME READY UP-TO-DATE AVAILABLE AGEndeployment.apps/hellok8s 1/1 1 1 8snnNAME DESIRED CURRENT READY AGEnreplicaset.apps/hellok8s-dd4ddd4dc 1 1 1 8sn”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”现在,hellok8s应用可以通过K8S内部pod进行访问了,但是我们想通过浏览器来外部访问,为此,我们可以通过”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”kubectl expose deployment”}]},{“ type”:“ text”,“ text”:“命令,創建服務資源來暴露hellok8s給外部訪問。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl expose deployment hellok8s –type=LoadBalancer –name hellok8s-svc \n> –port 80 –target-port 8080 -n demonservice/hellok8s-svc exposed”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”执行成功后,执行”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”kubectl get svc”}]},{“ type”:“文本”,“ text”:“命令來查詢結果。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl get svc -n demonNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnhellok8s-svc LoadBalancer 10.108.10.165 80:32483/TCP 5m49snn$ kubectl get node -o widenNAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIMEnubuntu-box Ready master 44d v1.17.2 192.168.1.109 Ubuntu 16.04.3 LTS 4.4.0-87-generic docker://19.3.6″}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”其中,CLUSTER-IP为k8s集群内部IP,只可内部访问;可以发现该service在k8s节点的端口32483上对外暴露访问,执行”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”kubectl get node”}]},{“ type”:“文本”,“ text”:“查詢節點的IP地址後,打開瀏覽器即可成功訪問了。”]]},{“ type”:“ image”,“ attrs”:{“ src”:“ https://static001.geekbang.org/infoq/01/015352889f177522172f3cf30ca64b0e.png”,“ alt”:null,“ title”: ““,“樣式”:[{“key”:”width”,”value”:”100%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ heading”,“ attrs”:{“ align”:null,“ level”:5},“內容”:[{“type”:”text”,”text”:”方式二:yaml文件方式部署”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”更好的方式是编写yaml文件,在yaml文件中规定要创建的deployment和service,然后只需要apply这个文件就可以了,hellok8s.yaml文件如下所示。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ text”},“ content”:[{“type”:”text”,”text”:”apiVersion: apps/v1nkind: Deploymentnmetadata:n name: hellok8sn namespace: demonspec:n replicas: 2n selector:n matchLabels:n app: hellok8sn template:n metadata:n name: hellok8sn labels:n app: hellok8sn spec:n containers:n – image: registry.cn-beijing.aliyuncs.com/tiehuapen/hellok8s:v3n name: hellok8s-webn imagePullPolicy: IfNotPresentn—napiVersion: v1nkind: Servicenmetadata:n name: hellok8s-svcn namespace: demonspec:n type: NodePortn ports:n – port: 80n targetPort: 8080n nodePort: 30123n selector:n app: hellok8sn”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”通过”},{“type”:”codeinline”,”content”:[{“type”:”text”,”text”:”kubectl apply”}]},{“ type”:“ text”,“ text”:“命令部署該文件所描述的資源。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl apply -f hellok8s.yamlndeployment.apps/hellok8s creatednservice/hellok8s-svc created”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”查询执行结果,结果显示2个Pod实例已经成功运行,服务已经在指定的端口30123对外暴露。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl get all -n demonNAME READY STATUS RESTARTS AGEnpod/hellok8s-68dffd9c4-dp8vj 1/1 Running 0 10snpod/hellok8s-68dffd9c4-jmqlv 1/1 Running 0 10snnNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnservice/hellok8s-svc NodePort 10.108.245.158 80:30123/TCP 10snnNAME READY UP-TO-DATE AVAILABLE AGEndeployment.apps/hellok8s 2/2 2 2 10snnNAME DESIRED CURRENT READY AGEnreplicaset.apps/hellok8s-68dffd9c4 2 2 2 10s”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”打开浏览器输入 192.168.1.109:30123 即可成功访问。”}]},{“ type”:“標題”,“ attrs”:{“ align”:null,“ level”:4},“ content”:[{“type”:”text”,”text”:”五、从Kubernetes清除应用”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”文章的最后,我们来清理干净上面演示中所创建的资源,因为上面都是在命名空间demo中操作的,所以就非常容易清理了。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl delete all –all -n demonpod “hellok8s-68dffd9c4-dp8vj” deletednpod “hellok8s-68dffd9c4-jmqlv” deletednservice “hellok8s-svc” deletedndeployment.apps “hellok8s” deletednreplicaset.apps “hellok8s-68dffd9c4″ deleted”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”当然,你也可以直接删除命名空间demo,那么它里面的资源也会自动删除。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ shell”},“ content”:[{“type”:”text”,”text”:”$ kubectl delete ns demonnamespace “demo” deleted”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”看完这篇文章之后,你是不是跃跃欲试,想把自己的SpringBoot应用跑到Kubernetes上面去呢。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”更多精彩文章,请扫码关注我的微信公众号。”}]},{“ type”:“ image”,“ attrs”:{“ src”:“ https://static001.geekbang.org/infoq/bb/bb0e5e41b44bba7a777e29300dd3fb3b.png”,“ alt”:null,“ title”: ““,“樣式”:[{“key”:”width”,”value”:”25%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null}},{” type“:” paragraph“,” attrs“:{” indent“:0,” number“:0,” align“:null,” origin“:null} }]}