写点什么

kubernetes 下的 Nginx 加 Tomcat 三部曲之二:细说开发

作者:程序员欣宸
  • 2022 年 5 月 10 日
  • 本文字数:6122 字

    阅读完需:约 20 分钟

kubernetes下的Nginx加Tomcat三部曲之二:细说开发

欢迎访问我的 GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

列举步骤

  • 需要以下操做才能在 kubernetes 上部署 Nginx 加 Tomcat 的服务:


  1. 开发 Tomcat 上的 web 工程和 Docker 镜像;

  2. 让 kubernetes 的机器用上 web 工程的 Docker 镜像;

  3. 开发 Tomcat 对应的 deployment 脚本;

  4. 开发 Tomcat 对应的 service 脚本;

  5. 开发 Nginx 对应的 Docker 镜像;

  6. 让 kubernetes 的机器用上 Nginx 的 Docker 镜像

  7. 开发 Nginx 对应的 deployment 脚本;

  8. 开发 Nginx 对应的 service 脚本;

  9. 开发启动上述 pod 和 service 的脚本;

  10. 开发停止并清除上述 pod 和 service 的脚本

脚本文件下载

  • 本次体验所需的 deployment 和 service 资源是通过脚本创建的,这个脚本可以通过 GitHub 下载,地址和链接信息如下表所示:



  • 这个 git 项目中有多个目录,本次所需的资源放在 k8s_nginx_tomcat_resource,如下图红框所示:



  • 下到的 k8stomcatcluster20180201.tar 是个压缩包,复制到可以执行 kubectl 命令的 ubuntu 电脑上,然后解压开,是个名为 k8stomcatcluster 的文件夹;

Spring boot 的 web 工程源码下载

  • GitHub 下载,地址和链接信息如下表所示:



  • 这个 git 项目中有多个目录,本次的 web 工程源码放在 k8stomcatdemo,如下图红框所示:



  • 接下来我们开始实战开发吧;

开发环境

  • 本次实战开发环境的具体信息如下:


  1. 操作系统:Ubuntu16;

  2. Docker 版本:17.03.2-ce;

  3. JDK:1.8.0_151;

  4. maven:3.3.3;

Tomcat 上的 web 工程和 Docker 镜像

  • web 工程用来提供 http 服务,返回当前机器的 IP 地址给浏览器,完整源码请参照前面下载的 k8stomcatdemo 工程,这里我们还是重新创建一次;

  • 创建一个 springboot 工程,pom.xml 内容如下:


<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>
<groupId>com.bolingcavalry</groupId> <artifactId>k8stomcatdemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging>
<name>k8stomcatdemo</name> <description>Demo project for Spring Boot</description>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>
<!--新增的docker maven插件--> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.12</version> <!--docker镜像相关的配置信息--> <configuration> <!--镜像名,这里用工程名--> <imageName>bolingcavalry/${project.artifactId}</imageName> <!--TAG,这里用工程版本号--> <imageTags> <imageTag>${project.version}</imageTag> </imageTags> <!--镜像的FROM,使用java官方镜像--> <baseImage>java:8u111-jdk</baseImage> <!--该镜像的容器启动后,直接运行spring boot工程--> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <!--构建镜像的配置信息--> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> </plugins> </build></project>
复制代码


  • 可以看到这是个普通的 springboot 的 web 工程,唯一不同的是多了一个 maven 插件:docker-maven-plugin,使用该插件我们可以将 maven 工程制作成 docker 镜像;

  • 整个工程只有一个 Controller,开通一个 http 接口,将当前服务器 IP 地址返回,源码如下:


@RestControllerpublic class ServerInfo {
@RequestMapping(value = "/getserverinfo", method = RequestMethod.GET) public String getUserInfoWithRequestParam(){ return String.format("server : %s, time : %s", getIPAddr(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); }
/** * 获取本机IP地址 * @return */ private static String getIPAddr(){ String hostAddress = null; try{ InetAddress address = InetAddress.getLocalHost(); hostAddress = address.getHostAddress(); }catch (UnknownHostException e){ e.printStackTrace(); }
return hostAddress; }}
复制代码


  • 以上就是工程的关键源码;

  • 在 pom.xml 所在目录执行 mvn clean package -DskipTests docker:build,会编译构建工程,并且在本地制作好镜像文件,如下:


root@maven:/usr/local/work/github/blog_demos# docker imagesREPOSITORY                                              TAG                 IMAGE ID            CREATED             SIZEbolingcavalry/k8stomcatdemo                             latest              1d41d9980a0b        43 hours ago        658 MBbolingcavalry/k8stomcatdemo                             0.0.1-SNAPSHOT      c91bc368a729        46 hours ago        658 MB
复制代码


让 kubernetes 的机器用上 web 工程的 Docker 镜像

  • 现在的镜像只存在于开发和构建 web 工程的电脑上,为了让 kubernetes 的 node 机器能用上这个镜像,可以用以下几种方式实现:


  1. 用 docker push 命令将本机镜像推送到 hub.docker.com 网站,这样其他机器都可以通过 docker pull 命令取得了,我就是用的这种方法,需要在 hub.docker.com 上注册;

  2. 用 docker save 命令导出镜像文件,再用 docker load 命令导入;

  3. kubernetes 所在机器安装 java 和 maven 环境,将工程在这里编译构建;

  4. 使用 docker 私有仓库,例如搭建局域网私有仓库或者阿里云私有仓库,参考《maven构建docker镜像三部曲之三:推送到远程仓库(内网和阿里云)》

Tomcat 对应的 deployment 脚本

  • 用 yaml 文件将详情配置好,再用 kubectl 命令执行这个配置就能创建 pod,这个 web 应用镜像的配置文件名为 tomcat.yaml,内容如下:


apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: tomcathostspec:  replicas: 3  template:    metadata:     labels:       name: tomcathost    spec:     containers:     - name: tomcathost       image: bolingcavalry/k8stomcatdemo:0.0.1-SNAPSHOT       tty: true       ports:       - containerPort: 8080
复制代码


  • 将上述脚本的几个关键点列举一下:


  1. version 用 extensions/v1beta1;

  2. kind 用 Deployment,支持升级镜像和滚动升级;

  3. 使用的镜像 bolingcavalry/k8stomcatdemo:0.0.1-SNAPSHOT,是我从本地 push 到 hub.docker.com 上去的;

  4. 创建的容器对外暴露了 8080 端口;

Tomcat 对应的 service 脚本

  • 创建了 tomcat 的 pod 之后,为了能在 kubernetes 环境中给其他 service 使用,需要将这些 pod 包装为 service,这里是通过 tomcat-svc.yaml 文件来配置的,内容如下:


apiVersion: v1kind: Servicemetadata:  name: tomcathostspec:  type: ClusterIP  ports:       - port: 8080  selector:    name: tomcathost
复制代码


  • 将上述脚本的几个关键点列举一下:


  1. 服务对应的 pod 是 tomcathost;

  2. type 用 ClusterIP,为内部 service 调用提供统一 IP 地址;

  3. 服务对外暴露了 pod 的 8080 端口;

Nginx 对应的 Docker 镜像

  • 定制的 Nginx 镜像和 Nginx 官方镜像相比,唯一的区别就是 nginx.conf 文件不同,我们用的 nginx.conf 内容如下:


user  nginx;worker_processes  1;
error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;

events { worker_connections 1024;}

http { include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on; #tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#include /etc/nginx/conf.d/*.conf;
upstream tomcat_client { server tomcathost:8080; }
server { server_name ""; listen 80 default_server; listen [::]:80 default_server ipv6only=on;
location / { proxy_pass http://tomcat_client; proxy_redirect default; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }}
复制代码


  • 以上配置中,新增的 upstream 对应的 IP 地址是 tomcathost,这是 tomcat 的 service 名称,在 Nginx 运行的时候,通过 tomcathost 就能访问到 tomcat 的 Pod;

  • 制作 Docker 镜像的 Dockerfile 文件内容如下,每行都有注释就不再多说了:


# First docker file from bolingcavalry# VERSION 0.0.1# Author: bolingcavalry
#基础镜像FROM nginx:stable
#作者MAINTAINER BolingCavalry <zq2599@gmail.com>
#定义工作目录ENV WORK_PATH /etc/nginx
#定义conf文件名ENV CONF_FILE_NAME nginx.conf
#删除原有配置文件RUN rm $WORK_PATH/$CONF_FILE_NAME
#复制新的配置文件COPY ./$CONF_FILE_NAME $WORK_PATH/
#给shell文件赋读权限RUN chmod a+r $WORK_PATH/$CONF_FILE_NAME
复制代码


  • 将 nginx.conf 和 Dockerfile 放在同一个目录,然后执行命令 docker build -t bolingcavalry/nginx-with-tomcat-host:0.0.1 .,就能构建镜像文件了,如下:


root@maven:/usr/local/work/nginx# docker build -t bolingcavalry/nginx-with-tomcat-host:0.0.1 .Sending build context to Docker daemon 14.51 MBStep 1/7 : FROM nginx:stable ---> dfe062ee1dc8Step 2/7 : MAINTAINER BolingCavalry <zq2599@gmail.com> ---> Using cache ---> 93f4bf154c55Step 3/7 : ENV WORK_PATH /etc/nginx ---> Using cache ---> d0158757fc9cStep 4/7 : ENV CONF_FILE_NAME nginx.conf ---> Using cache ---> 7a18a8b417d6Step 5/7 : RUN rm $WORK_PATH/$CONF_FILE_NAME ---> Using cache ---> f6f27d25539dStep 6/7 : COPY ./$CONF_FILE_NAME $WORK_PATH/ ---> Using cache ---> 33075a2b0379Step 7/7 : RUN chmod a+r $WORK_PATH/$CONF_FILE_NAME ---> Using cache ---> 58ce530e160bSuccessfully built 58ce530e160b
复制代码

让 kubernetes 的机器用上 Nginx 的 Docker 镜像

  • 这一步和之前的 web 工程的镜像放到 kubernetes 一样,有多种方式,我用的还是通过 docker push 推送到 hub.docker.com 网站,再在 kubernetes 上 pull 下来;

Nginx 对应的 deployment 脚本

  • 用 yaml 文件将详情配置好,再用 kubectl 命令执行这个配置就能创建 pod,这个 web 应用镜像的配置文件名为 nginx.yaml,内容如下:


apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: ngspec:  replicas: 1  template:    metadata:     labels:      name: ng    spec:     containers:     - name: ng       image: bolingcavalry/nginx-with-tomcat-host:0.0.1       ports:       - containerPort: 80
复制代码


  • 以上配置中有几点要注意:


  1. 使用镜像是刚才创建的 nginx 镜像 bolingcavalry/nginx-with-tomcat-host:0.0.1

  2. pod 容器创建后,对外暴露 80 端口;

Nginx 对应的 service 脚本

  • 通过 service 定义的 yaml 文件 nginx-svc.yam,将前面创建的 nginx 的 pod 包装为 service:


apiVersion: v1kind: Servicemetadata:  name: ngspec:  type: NodePort  ports:       - port: 80         nodePort: 30006  selector:    name: ng
复制代码


  • 以上配置中有几点要注意:


  1. type 使用 NodePort,这样可以通过节点机器的 IP 访问此 service;

  2. 将节点机器的 30006 端口和 pod 的 80 端口绑定,因此,外部访问节点 IP+30006 端口就能访问到此 Nginx 服务了;

启动上述 pod 和 service 的脚本

  • 接下来我们创建一个 shell 脚本 start_all.sh,将上述的 tomcat 和 nginx 的 pod 以及 service 全部创建和启动:


kubectl create -f tomcat.yamlkubectl create -f tomcat-svc.yamlkubectl create -f nginx.yamlkubectl create -f nginx-svc.yamlecho ""echo "nginx and tomcat running now"
复制代码


  • 如上所示,通过 kubectl create -f 加文件名,就能创建好 yaml 文件中定义的 pod 和 service;

停止并清除上述 pod 和 service 的脚本

  • 创建一个 shell 脚本 stop_all.sh,能够将上述的 tomcat 和 nginx 的 pod 以及 service 全部清除掉:


kubectl delete service tomcathostkubectl delete deployment tomcathostkubectl delete service ngkubectl delete deployment ngecho "nginx and tomcat stop now"
复制代码


  • 如上所示,其实就是通过 kubectl delete 命令将指定的 pod 和 service 资源删除;


以上就是在 kubernetes 搭建整个 Nginx 加 Tomcat 环境的所有资源,您就可以用这些像《kubernetes下的Nginx加Tomcat三部曲之一:极速体验》文中那样去搭建和体验 kubernetes 下的 Nginx 加 Tomcat;


  • 下一章,我们会在此环境的基础上实战 Tomcat 服务的扩容,并修改 web 工程的代码,再创建新的镜像,并且将 kubernetes 环境下在线升级新的 web 工程服务;

欢迎关注 InfoQ:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

发布于: 2022 年 05 月 10 日阅读数: 31
用户头像

搜索"程序员欣宸",一起畅游Java宇宙 2018.04.19 加入

前腾讯、前阿里员工,从事Java后台工作,对Docker和Kubernetes充满热爱,所有文章均为作者原创,个人Github:https://github.com/zq2599/blog_demos

评论

发布
暂无评论
kubernetes下的Nginx加Tomcat三部曲之二:细说开发_Java_程序员欣宸_InfoQ写作社区