【kubernetes】K8S 部署 SpringBoot 项目
K8S部署 SpringBoot 项目构建镜像构建镜像仓库修改镜像源推送镜像使用 deplpyment 启动 Pod使用 NodePort 暴露端口测试访问构建镜像原来的部署方式:将java应用打成 jar 包,再使用 java 命令启动应用java -jar springBootAdmin-0.0.1-SNAPSHOT.jar存在的问题:需要服务器已经安装了相应版本的java环境、mysql环境
K8S部署 SpringBoot 项目
构建镜像
-
原来的部署方式:
将java应用打成 jar 包,再使用 java 命令启动应用
java -jar springBootAdmin-0.0.1-SNAPSHOT.jar
-
存在的问题:需要服务器已经安装了相应版本的java环境、mysql环境等等
-
解决方法:
- 容器化部署
- 所有机器都安装Docker,任何应用都是镜像,所有机器都可以运行
-
创建一个SpringBoot程序
@RestController public class testController { private int count = 0; @RequestMapping("/test") public String test(){ return "有【"+ count++ +"】 人访问了这个页面"; } }
-
编写 Dockerfile
FROM openjdk:8-jdk-slim COPY target/*.jar /app.jar ENTRYPOINT ["java","-jar","app.jar"]
去 DockerHub 上找想要的镜像
之前有个小疑惑:为啥这里只有 JDK ,而不需要 maven?- maven 并不需要写在Dockerfile中,应为maven这里作用就是一个打包工具
- 在windows打jar包的过程中已经将需要的以来下载下来,并打进jar包里了,所以项目部署环境里并不需要maven
- 仔细一想确实不需要
- 但如果复杂项目中,需要调用的运行着mysql、redis的容器,这些怎么配还不太清楚…
-
使用maven 打包,只保留 Dockerfile 与 jar包 dockerSpringBootDemo-0.0.1-SNAPSHOT.jar
-
传到服务器上:
[root@master DockerSpringBootDemo]# ls Dockerfile target [root@master DockerSpringBootDemo]# cd target/ [root@master target]# ls dockerSpringBootDemo-0.0.1-SNAPSHOT.jar [root@master target]# cd .. [root@master DockerSpringBootDemo]# pwd /root/springBootDemo/DockerSpringBootDemo
-
构建镜像
[root@master DockerSpringBootDemo]# docker build -t srping_boot_demo:v1.0 . Sending build context to Docker daemon 17.56MB Step 1/3 : FROM openjdk:8-jdk-slim 8-jdk-slim: Pulling from library/openjdk a2abf6c4d29d: Pull complete 2bbde5250315: Pull complete 115191490c27: Pull complete 61b680ac8083: Pull complete Digest: sha256:25efb6e0609b95af243b4e3ce2c27dbc1022ef2a4db2164b7afa066c0db18137 Status: Downloaded newer image for openjdk:8-jdk-slim ---> 9afd0fe33df7 Step 2/3 : COPY target/*.jar /app.jar ---> 37304d0eb2ec Step 3/3 : ENTRYPOINT ["java","-jar","app.jar"] ---> Running in 549652c11e1d Removing intermediate container 549652c11e1d ---> 0d2fd9fd3003 Successfully built 0d2fd9fd3003 Successfully tagged srping_boot_demo:v1.0
镜像的名字不能带有大写字母!
[root@master DockerSpringBootDemo]# docker build -t srpingBootDemo:v1.0 . invalid argument "srpingBootDemo:v1.0" for "-t, --tag" flag: invalid reference format: repository name must be lowercase See 'docker build --help'.
-
查看镜像
[root@master DockerSpringBootDemo]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE srping_boot_demo v1.0 0d2fd9fd3003 11 seconds ago 313MB
-
启动容器(这里启动容器只是想测试一下镜像是否正常)
[root@master DockerSpringBootDemo]# docker run -d -p 8080:8080 srping_boot_demo:v1.0 e50243abeadc4ab1f51edc7929db3296774d2a5ee8369d9d52fc557c53cecd49
-
查看容器
[root@master DockerSpringBootDemo]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50243abeadc srping_boot_demo:v1.0 "java -jar app.jar" 7 seconds ago Up 6 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp kind_yalow
-
http://192.168.10.171:8080/test
访问成功
构建镜像仓库
新建一台机器:
[root@registry ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens32
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens32"
UUID="9be4c57a-42b1-4fdb-b940-b1b6770e9a20"
DEVICE="ens32"
ONBOOT="yes"
IPADDR=192.168.10.174
GATEWAY=192.168.10.2
DNS1=192.168.10.2
[root@registry ~]# cat /etc/hostname
registry
[root@registry ~]# cat /etc/hosts
192.168.10.171 master
192.168.10.174 registry
在本地镜像服务器上操作
-
安装 Docker
-
安装 wget
yum install wget
-
安装 Docker
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo yum -y install docker-ce-18.06.1.ce-3.el7 systemctl enable docker && systemctl start docker docker --version
-
给 Docker 配置阿里云加速
cat > /etc/docker/daemon.json << EOF { "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] } EOF
-
重启docker 服务
systemctl daemon-reload systemctl restart docker
-
验证阿里云仓库是否配置成功
docker info ... Registry Mirrors: https://b9pmyelo.mirror.aliyuncs.com/ ...
-
-
pull 一个官方给的registry 的模板镜像,用于在镜像仓库服务器上构建仓库
[root@registry ~]# docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always registry
修改镜像源
在 K8S 集群的 master 节点、node01节点、node02节点上操作
-
修改端口配置文件,将上面的阿里云仓库改成 自建的本地镜像仓库
[root@registry ~]# vim /etc/docker/daemon.json
{ "insecure-registries": ["192.168.10.110:5000"] }
注意这里是:
insecure-registries
-
重启docker
[root@registry ~]# systemctl daemon-reload [root@registry ~]# systemctl restart docker
-
查看此时使用的 Docker 镜像仓库
[root@registry ~]# docker info ... Insecure Registries: 192.168.10.174:5000 127.0.0.0/8 ...
一定记得将集群中所有的 node 节点也修改镜像仓库源!
镜像的拉取是在Pod 调度之后的,也就是说真正 Pull 镜像的是 node 节点,踩坑:由于只改了 master 节点的镜像仓库源,会导致镜像一直下载失败
[root@master DockerSpringBootDemo]# kubectl get pod NAME READY STATUS RESTARTS AGE springbootdemo 0/1 ContainerCreating 0 5s [root@master DockerSpringBootDemo]# kubectl describe pod springbootdemo ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m38s default-scheduler Successfully assigned default/springbootdemo to node02 # ⭐ pod 被调度给 node02,node02开始下载镜像 Warning Failed 63s (x2 over 114s) kubelet Failed to pull image "springbootdemo:v1.0": rpc error: code = Unknown desc = Error response from daemon: http: server gave HTTP response to HTTPS client Warning Failed 63s (x2 over 114s) kubelet Error: ErrImagePull Normal BackOff 49s (x2 over 114s) kubelet Back-off pulling image "springbootdemo:v1.0" Warning Failed 49s (x2 over 114s) kubelet Error: ImagePullBackOff Normal Pulling 34s (x3 over 2m37s) kubelet Pulling image "springbootdemo:v1.0"
推送镜像
在 K8S 集群的 master 节点上操作
-
向本地镜像仓库 push 镜像
-
修改要上传的镜像的名字:
上传镜像需要的镜像标识符:
仓库地址/userName/imageName:tag
[root@master DockerSpringBootDemo]# docker tag springbootdemo:v1.0 192.168.10.174:5000/springbootdemo:v1.0
-
push 镜像
[root@master DockerSpringBootDemo]# docker push 192.168.10.174:5000/springbootdemo:v1.0 The push refers to repository [192.168.10.174:5000/springbootdemo] 773f14f8f38a: Pushed c8fa2e981776: Pushed 3341e899db61: Pushed afda989d53ee: Pushed 2edcec3590a4: Pushed v1.0: digest: sha256:0a9303110e485a3ac6bcd9e21e07124eaea97b05447204b05ceaf8e8f53c28dc size: 1372
-
查看本地镜像仓库上的镜像
[root@master DockerSpringBootDemo]# curl -XGET http://192.168.10.174:5000/v2/_catalog {"repositories":["springbootdemo"]}
-
-
测试本地自建镜像仓库上的镜像是否可用
-
使用远程镜像启动容器
[root@master DockerSpringBootDemo]# docker run --name springbootdemo -p 8080:8080 192.168.10.174:5000/springbootdemo:v1.0 Unable to find image '192.168.10.174:5000/springbootdemo:v1.0' locally # 本地没有找到镜像 v1.0: Pulling from springbootdemo # 去自建镜像仓库下载 a2abf6c4d29d: Already exists 2bbde5250315: Already exists 115191490c27: Already exists 61b680ac8083: Already exists 587148c8979a: Already exists Digest: sha256:0a9303110e485a3ac6bcd9e21e07124eaea97b05447204b05ceaf8e8f53c28dc Status: Downloaded newer image for 192.168.10.174:5000/springbootdemo:v1.0
-
访问:http://192.168.10.171:8080/test
运行成功
-
使用 deplpyment 启动 Pod
-
使用命令获取 yaml 文件模板
[root@master ~]# kubectl create deployment springbootdemo --image=192.168.10.174:5000/springbootdemo:v1.0 --dry-run=client -o yaml > springbootdemo.yaml [root@master ~]# ls ... springbootdemo.yaml ... [root@master ~]# vi springbootdemo.yaml
-
对 yaml 配置做需求修改
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: springbootdemo name: springbootdemo spec: replicas: 3 # 启动三个高可用的服务 selector: matchLabels: app: springbootdemo strategy: {} template: metadata: creationTimestamp: null labels: app: springbootdemo spec: containers: - image: 192.168.10.174:5000/springbootdemo:v1.0 # 本地自建镜像仓库的镜像 name: springbootdemo resources: {} status: {}
-
启动 deployment
[root@master ~]# kubectl create -f springbootdemo.yaml deployment.apps/springbootdemo created
-
查看 deployment
[root@master ~]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE springbootdemo 3/3 3 3 13s
-
产看 pod
[root@master ~]# kubectl get pod NAME READY STATUS RESTARTS AGE springbootdemo-75f458f7fc-65c64 1/1 Running 0 21s springbootdemo-75f458f7fc-9n6r7 1/1 Running 0 21s springbootdemo-75f458f7fc-djgjf 1/1 Running 0 21s
使用 NodePort 暴露端口
-
创建 service yaml 文件
apiVersion: v1 kind: Service metadata: name: springbootdemo-service spec: selector: app: springbootdemo # ⭐ 这里标签选择器一定要写,不然service不知道给哪个deploy暴露端口!且要与deploy的标签对应 type: NodePort # sevice 类型是 nodeport ports: - port: 8080 # service 的端口 nodePort: 30000 # node 节点的端口 targetPort: 8080 # 应用程序的端口(在代码里已经写好了)
nodePort 的指定由范围要求:
The Service "service-nodeport" is invalid: spec.ports[0].nodePort: Invalid value: 3000: provided port is not in the valid range. The range of valid ports is 30000-32767
-
创建 service ,给deployment 暴露对外的服务
[root@master ~]# kubectl create -f springbootdemoservice.yaml service/springbootdemo-service created
-
查看 service
[root@master ~]# kubectl get svc -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d <none> springbootdemo-service NodePort 10.100.146.163 <none> 8080:30000/TCP 4s app=springbootdemo
-
也可以使用
expose
命令直接对外暴露服务[root@master ~]# kubectl expose deployment springbootdemo --port=8080 --type=NodePort service/nginx exposed
测试访问
访问:http://192.168.10.171:30000/test
更多推荐
所有评论(0)