本文是《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工程服務;