zoukankan      html  css  js  c++  java
  • kubernetes下的Nginx加Tomcat三部曲之二:细说开发

    本文是《kubernetes下的Nginx加Tomcat三部曲》的第二章,在《kubernetes下的Nginx加Tomcat三部曲之一:极速体验》一文我们快速部署了Nginx和Tomcat,达到以下效果: 
    这里写图片描述

    本文我会详细说明在kubernetes部署上述网络服务时,需要做哪些具体的工作;

    列举步骤

    需要以下操做才能在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资源是通过脚本创建的,这个脚本可以通过以下两种方式中的任意一种下载: 
    1. CSDN下载(无法设置免费下载,只能委屈您用掉两个积分了):http://download.csdn.net/download/boling_cavalry/10235034 
    2. GitHub下载,地址和链接信息如下表所示:

    名称链接备注
    项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
    git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
    git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议


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

    这里写图片描述

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

    Spring boot的web工程源码下载

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

    名称链接备注
    项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
    git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
    git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议


    这个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工程,这里我们还是重新创建一次; 
    1. 创建一个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镜像; 
    2. 整个工程只有一个Controller,开通一个http接口,将当前服务器IP地址返回,源码如下:

    @RestController
    public 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;
        }
    }

    以上就是工程的关键源码; 
    3. 在pom.xml所在目录执行mvn clean package -DskipTests docker:build,会编译构建工程,并且在本地制作好镜像文件,如下:

    root@maven:/usr/local/work/github/blog_demos# docker images
    REPOSITORY                                              TAG                 IMAGE ID            CREATED             SIZE
    bolingcavalry/k8stomcatdemo                             latest              1d41d9980a0b        43 hours ago        658 MB
    bolingcavalry/k8stomcatdemo                             0.0.1-SNAPSHOT      c91bc368a729        46 hours ago        658 MB

    想了解更多maven制作docker镜像的细节,请看《maven构建docker镜像三部曲之二:编码和构建镜像》

    让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/v1beta1
    kind: Deployment
    metadata:
      name: tomcathost
    spec:
      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: v1
    kind: Service
    metadata:
      name: tomcathost
    spec:
      type: ClusterIP
      ports:
           - port: 8080
      selector:
        name: tomcathost

    将上述脚本的几个关键点列举一下: 
    1. 服务对应的pod是tomcathost; 
    2. type用ClusterIP,为内部service调用提供统一IP地址; 
    2. 服务对外暴露了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 MB
    Step 1/7 : FROM nginx:stable
     ---> dfe062ee1dc8
    Step 2/7 : MAINTAINER BolingCavalry <zq2599@gmail.com>
     ---> Using cache
     ---> 93f4bf154c55
    Step 3/7 : ENV WORK_PATH /etc/nginx
     ---> Using cache
     ---> d0158757fc9c
    Step 4/7 : ENV CONF_FILE_NAME nginx.conf
     ---> Using cache
     ---> 7a18a8b417d6
    Step 5/7 : RUN rm $WORK_PATH/$CONF_FILE_NAME
     ---> Using cache
     ---> f6f27d25539d
    Step 6/7 : COPY ./$CONF_FILE_NAME $WORK_PATH/
     ---> Using cache
     ---> 33075a2b0379
    Step 7/7 : RUN chmod a+r $WORK_PATH/$CONF_FILE_NAME
     ---> Using cache
     ---> 58ce530e160b
    Successfully built 58ce530e160b

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

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

    Nginx对应的deployment脚本

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

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: ng
    spec:
      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: v1
    kind: Service
    metadata:
      name: ng
    spec:
      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.yaml
    kubectl create -f tomcat-svc.yaml
    kubectl create -f nginx.yaml
    kubectl create -f nginx-svc.yaml
    echo ""
    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 tomcathost
    kubectl delete deployment tomcathost
    kubectl delete service ng
    kubectl delete deployment ng
    echo "nginx and tomcat stop now"

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

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

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

  • 相关阅读:
    左孩子右兄弟的字典树
    UVA 1401 Remember the Word
    HDOJ 4770 Lights Against Dudely
    UvaLA 3938 "Ray, Pass me the dishes!"
    UVA
    Codeforces 215A A.Sereja and Coat Rack
    Codeforces 215B B.Sereja and Suffixes
    HDU 4788 Hard Disk Drive
    HDU 2095 find your present (2)
    图的连通性问题—学习笔记
  • 原文地址:https://www.cnblogs.com/yhaing/p/8568584.html
Copyright © 2011-2022 走看看