K8S集群使用Ingress實現網站入口動靜分離實踐
今年3月份在公司的內部k8s培訓會上,和研發同事詳細探討了應用部署容器化部署的幾個問題,問題簡要如下:
1、java應用容器化部署
首先通過自動化部署工具編譯出全量的war包,將war包直接編譯到docker鏡像後推送到私用倉庫並版本化控制;其次通過更新deployment的yaml文件來實現部署和後續的滾動更新,應用程序需要進行容器化改造。
這裏的難點和工作量在於容器的鏡像制作以及版本化管理,之後準備采用harbor做企業私有倉庫。
2、dashborad面板的權限控制
解決方案參考:http://blog.51cto.com/ylw6006/2113542
3、應用程序日誌的如何收集
解決方案參考:http://blog.51cto.com/ylw6006/2107307
4、網站動靜分離
首先所有的動態應用通過部署tomcat pod的方式來響應,靜態的資源統一部署一個nginx pod方式來響應;
其次,動靜分離的規則配置交給traefik ingress實現;
最後,靜態資源的文件統一存放在pv上,更新靜態資源不需要去編譯docker鏡像.
一、動靜分離舉例說明
以內網測試環境2的虛擬主機站點配置(底層服務)為例:
域名test2.oprman.com(PS:研發大爺喜歡自己YY域名)的靜態資源配置如下
1、/ ——> 對應/usr/local/6.0_files/oprman_test2目錄
2、/mfs ——> 對應/mnt/mfs目錄(這個實際上是一個分布式文件系統的掛載點)域名test2.oprman.com的動態資源配置如下
1、/web ——> 後端tomcat進行相應
2、/api ——> 後端tomcat進行相應
後端的tomcat配置信息
以內網測試環境2的虛擬主機站點配置(平臺服務)為例:
域名resourcesharing.test2.59iedu.com的靜態資源配置如下
1、/ ——> 對應/data/static_files/test2/zygxpt/portal目錄
2、/mfs ——> 對應/mnt/mfs目錄(這個實際上是一個分布式文件系統的掛載點)
3、/admin ——> 對應/data/static_files/test2/zygxpt/admin目錄4、/login ——> 對應/data/static_files/test2/zygxpt/login目錄
5、/play ——> 對應/data/static_files/test2/zygxpt/play目錄域名test2.oprman.com的動態資源配置如下
1、/web ——> 後端tomcat進行相應
後端的tomcat配置信息
這裏補充說明一下,內網存在三套環境
1、開發環境: 主要用於開發人員開發、調試
2、測試環境1:用於測試人員驗證
3、測試環境2:用於開發人員自測與驗證從網站的類型上可以分為底層服務和平臺服務兩種類型,大部分的底層服務是通過dobbo進行內部調用的,容器化之後只要POD之間的網絡可以互聯互通即可相互調用,少部分底層服務需要對外暴露http端口。平臺服務都需要對外暴露http端口。
動靜分離的nginx規則也主要是上述兩類,其中以平臺服務的數量居多,底層服務有動靜分離規則的較少。
二、部署traefik 入口
traefik具體的部署方法可參考前文,前文傳送門:http://blog.51cto.com/ylw6006/2073718
# kubectl get svc,pod,ingress -n kube-system
三、創建處理動態的應用
1、build動態部分的鏡像並推送至私有倉庫
# cat dockerfile
FROM registry.59iedu.com/tomcat_base:v1.0
MAINTAINER yangliangwei "[email protected]"
COPY ROOT-20180509.tgz /home/
RUN tar zxf /home/ROOT-20180509.tgz -C /home/tomcat/webapps/ && rm -rf /home/ROOT-20180509.tgz
# docker build -t oprman-test2:v1 .
# docker tag oprman-test2:v1 registry.59iedu.com/oprman-test2:v1
# docker push registry.59iedu.com/oprman-test2:v1
2、通過yaml文件創建動態應用
# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-oprman-test2-config
data:
filebeat.yml: |
filebeat.prospectors:
- input_type: log
paths:
- "/log/*"
output.elasticsearch:
hosts: ["192.168.1.19:9600"]
index: "filebeat-oprman-test2"
# kubectl create -f configmap.yaml
# cat oprman-test2-tomcat-dp.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: oprman-test2-tomcat
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
name: oprman-test2-tomcat
spec:
containers:
- image: registry.59iedu.com/filebeat:v5.4.0
imagePullPolicy: Always
name: filebeat
volumeMounts:
- name: app-logs
mountPath: /log
- name: filebeat-oprman-test2-config
mountPath: /etc/filebeat/
- image: registry.59iedu.com/oprman-test2:v1
name : oprman-test2-tomcat
imagePullPolicy: Always
env:
- name: JAVA_OPTS
value: "-Xmx2048m -Xms512m"
ports:
- containerPort: 8080
volumeMounts:
- name: app-logs
mountPath: /home/tomcat/logs
volumes:
- name: app-logs
emptyDir: {}
- name: filebeat-oprman-test2-config
configMap:
name: filebeat-oprman-test2-config
# kubectl create -f oprman-test2-tomcat-dp.yaml
# cat oprman-test2-tomcat-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: oprman-test2-tomcat
labels:
name: oprman-test2-tomcat
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
name: http
selector:
name: oprman-test2-tomcat
# kubectl create -f oprman-test2-tomcat-svc.yaml
演示僅部署底層服務的後端tomcat處理動態請求,平臺的後端tomcat部署辦法一樣,出於文章篇幅考慮就不在贅述。
三、創建處理靜態部分的應用
1、我們采用configmap的方式來處理靜態部分的請求路由,動態部分的請求路由將交給
Ingress來實現。nginx配置文件針對平臺部分的配置因為路徑都一樣,所以域名采用$host進行通配,底層的需要單獨配置。(好在底層服務需要暴露http的並不多)
# cat nginx.conf
user nginx;
worker_processes auto;
error_log /usr/share/nginx/html/nginx-error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 102400;
use epoll;
}
http {
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for"‘;
server_tokens off;
access_log /usr/share/nginx/html/nginx-default-access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/conf/extra/*.conf;
server {
listen 80 default_server;
index index.html index.htm;
access_log /usr/share/nginx/html/logs/test2-static-access.log main;
location / {
root /usr/share/nginx/html/$host/portal;
index index.html index.htm;
}
location /admin{
root /usr/share/nginx/html/$host;
index index.html index.htm;
}
location /login {
root /usr/share/nginx/html/$host;
index index.html index.htm;
}
location /play {
root /usr/share/nginx/html/$host;
index index.html index.htm;
}
location /mfs {
root /mnt/mfs;
}
}
server {
listen 80;
server_name test2.oprman.com;
index index.html index.htm;
access_log /usr/share/nginx/html/logs/test2-static-access.log main;
location / {
root /usr/share/nginx/html/test2.oprman.com;
index index.html index.htm;
}
location /mfs {
root /mnt/mfs;
}
}
}
# kubectl create configmap test2-static-etc --from-file nginx.conf
2、創建pv、pvc
# cat test2-static-data-pv-pvc.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: test2-static-data
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
nfs:
path: /home/test2-static-data
server: 192.168.115.5
persistentVolumeReclaimPolicy: Recycle
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test2-static-data
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
# kubectl create -f test2-static-data-pv-pvc.yaml
3、創建deployment
# cat test2-static-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test2-static
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test2-static
labels:
name: test2-static
spec:
replicas: 2
template:
metadata:
labels:
name: test2-static
spec:
containers:
- name: test2-static
image: registry.59iedu.com/nginx:latest
volumeMounts:
- mountPath: /usr/share/nginx/html
name: test2-static-data
- mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
name: test2-static-etc
ports:
- containerPort: 80
volumes:
- name: test2-static-data
persistentVolumeClaim:
claimName: test2-static-data
- name: test2-static-etc
configMap:
name: test2-static-etc
items:
- key: nginx.conf
path: nginx.conf
# kubectl create -f test2-static-deployment.yaml
四、創建統一入口ingress
# cat test2-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-oprman-test2
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: resourcesharing.test2.59iedu.com
http:
paths:
- path: /
backend:
serviceName: test2-static
servicePort: 80
- host: test2.oprman.com
http:
paths:
- path: /
backend:
serviceName: test2-static
servicePort: 80
- path: /web
backend:
serviceName: oprman-test2-tomcat
servicePort: 8080
- path: /api
backend:
serviceName: oprman-test2-tomcat
servicePort: 8080
# kubectl create -f test2-ingress.yaml
五、訪問測試
1、修改host解析
2、底層服務後端tomcat訪問測試
3、平臺前端訪問測試
4、平臺後臺入口訪問測試(前面的nginx配置/admin部分,實際未靜態的內容,輸入用戶名和密碼之後才開始請求到後端的tomcat)
這裏要重點說明一下,把分布式文件系統掛載到nginx主機上並發布出去給用戶訪問,實際上是非常不可取的一種方式,當nginx和mfs master主機之間的網絡連接出現問題的時候,會導致nginx請求被堵塞,80、443等端口連接不順暢,極度影響用戶體驗,這個後續需要合力改進!
K8S集群使用Ingress實現網站入口動靜分離實踐