ps:因为公司开发的服务器转化为K8s,公司内的大部分并没有开始搭建,故自己先对此进行记录
Kubernetes具体服务部署
- Kubernetes简介
Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用。
对于服务用于Kuberntes有四个核心:
ConfigMap Name/NameSpace Pod/Pod控制器 Service/Ingress
1.1 ConfigMap
在生产及对应环境中,经常会遇到修改配置文件的情况,传统的修改方式不仅会影响到服务的正常运行,而且修改以及操作步骤会非常繁琐,为了解决这个问题,Kubernetes提供了ConfigMap功能,用于将配置和程序分离出来,这种方式不仅可以实现程序的复用性,而且可以提高配置的灵活性,用户可以通过环境变量或者外挂文件的方式挂入到容器中
ConfigMap是以Key:Value方式存储,即可以表示一个默认的状态值
也可以用于文件内容的存储,如:server.xml : ....
apiVersion: v1
kind: ConfigMap
metadata:
name: data-platform-3 # configmap名称
namespace: develop # 为要导入的命名空间(项目)
labels:
name: data-platform-3 # 打标签(为了后面绑定此标签)
data:
hbase-site.xml: |
<?xml version="1.0" ...
....
server.xml: |
<?xml version="1.0" ...
....
1.1.2 执行方式
在Kubernetes主节点上执行此yaml文件 -f 指定文件名称,也可以使用指定url
kubelctl apply -f data-platform-3-configmap.yaml
从图形化管理Kubernetes页面导入此yaml文件,例如:(rancher)
1.2 Name/NameSpcae/Pod
1.2.1 Name
由于Kubernetes内部,使用"资源"来定义每一个逻辑概念(功能),所以每种资源都应该有自己的"名称" 资源有:API版本(apiVersion)\ 类别(kind)\ 元数据(metadata)\ 定义清单(spec)\ 状态(status)等配置信息 "名称"通常定义在"资源"的"元数据"信息中
1.2.2 NameSpace
随着项目增多,人员增加,集群需要扩大,需要有一个隔离Kubernetes内部资源的方法,称为:名称空间(命令空间)
命令空间可以理解为Kubernetes的内部虚拟组
不同名称空间内的资源 名称可以相同,相同名称空间内的同种资源 名称 不能相同
查询Kubernets里特定的资源,需要带上相应的名称空间
1.3 Pod/Pod控制器
1.3.1 Pod
Pod是Kubernetes里的最小逻辑单元(原子单元)
1个Pod里面可以运行多个容器,互相共享UTS+NET+IPC名称空间
可以把Pod理解成豌豆荚,而同一个Pod内的每一个容器都是一颗豌豆
一个Pod里运行多个容器,又叫:边车(SideCar)模式
1.3.2 Pod控制器
Pod控制器是Pod启动的一种模板,用来保证Kubernetes里启动的Pod始终按照人们的预期运行(副本数,生命周期,健康检查状态等) Kubernetes里提供了众多的Pod控制器,常用的有如下几种方式 Deployment:由Kubernetes内部调度部署,按照副本集数量进行部署,调整副本集的数量即可实现高可用 DaemonSet:由Kubernetes内部调度部署,会在Kubernetes的每个节点上进行部署,有统一的ClusterIp,DaemonSet部署方式 可自动实现负载均衡
1.4 Service/Ingress
1.4.1 Service
在Kubernetes的世界里,虽然每一个Pod都会分配独立的IP,但这个Ip会随着Pod的销毁而消失 Service就是用来解决这个问题的核心概念 一个Service可以看作一组提供服务的Pod的对外访问接口 Service作用于哪些Pod是由标签选择器来定义的
1.4.2 Ingress
Ingress是Kubernetes集群里工作在OSI网络参考模型下,第七层的应用,对外暴露的接口 Service只能提供L4流量调度,表现形式是IP+PORT Ingress则可以调度不同业务域丶不同URL访问路径的业务流量
2. 服务部署Kubernetes
服务部署基本分为4个步骤:
ConfigMap Deployment Service Ingress
以数据平台为对象,执行这4个步骤为:
将data-platform-3的配置文件导入到配置文件管理中心,也就是说将经常需要配置的文件外挂出来,不需要由于版本的变化让配置文件也需要重新配置(ConfigMap) 开始部署data-platform-3,拉取镜像,挂载配置文件到容器内部,以及其他的配置都在这一步完成,这一步称为部署服务(Deployment) 服务部署成功后,如ems-saas-web去调用数据平台,访问数据平台,如何那?那就是Service的作用,将程序启动的端口以及程序需要的端口从容器内部映射出来和Service进行绑定也就是说程序的端口被公布开来,其他服务访问时,只需要用服务名称和端口即可像IP:PORT方式一样使用(Service) 最后一步,称为服务暴露,也就是说上一步可以称为服务发现是作用于Kubernetes集群内部的,那这一步就是将服务暴漏在Kubernetes集群外部,从外部可以访问这个服务。如果是说服务并无需要从外部访问的情况,可不对外进行暴露(Ingress)
2.1 tomcat(数据平台)
以数据平台data-platform-3为例:
apiVersion: v1
kind: ConfigMap
metadata:
name: data-platform-3
namespace: develop
labels:
name: data-platform-3
data:
hbase-site.xml: |
<?xml version="1.0" encoding="UTF-8"?>
...
config.properties: |
env=prod
...
---
apiVersion: v1
kind: Service
metadata:
name: data-platform-3
labels:
app: data-platform-3
spec:
selector:
app: data-platform-3
ports:
- name: server-port
port: 8080
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: data-platform-3
spec:
replicas: 1
selector:
matchLabels:
app: data-platform-3
template:
metadata:
labels:
app: data-platform-3
spec:
hostAliases:
- ip: "192.168.100.90"
hostnames:
- "node1"
- "namenode"
- "secondarynamenode"
- "zookeeper1"
- ip: "192.168.100.91"
hostnames:
- "node2"
- "datanode1"
- "zookeeper2"
- ip: "192.168.100.92"
hostnames:
- "node3"
- "datanode2"
- "zookeeper3"
containers:
- name: data-platform-3
image: persagy-registry:8080/jixian/data-platform-3:1.1.2
ports:
- containerPort: 8080
name: server-port
volumeMounts:
- name: hbasesite
mountPath: /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/hbase-site.xml
subPath: path/to/hbase-site.xml
- name: config
mountPath: /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/config.properties
subPath: path/to/config.properties
- name: "nfs-pvc"
mountPath: "/usr/local/tomcat/webapps/ROOT/WEB-INF/classes/property"
subPath: "data-platform-3/property"
volumes:
- name: hbasesite
configMap:
name: data-platform-3
defaultMode: 0777
items:
- key: hbase-site.xml
path: path/to/hbase-site.xml
- name: config
configMap:
name: data-platform-3
defaultMode: 0777
items:
- key: config.properties
path: path/to/config.properties
- name: "nfs-pvc"
persistentVolumeClaim:
claimName: "nfs-develop-persagy"
2.2 SpringCloud (ems-saas-web)
SpringCloud 程序,有统一的bootstrap.yml配置文件,所以所有SpringCloud程序,使用同一ConfigMap配置文件,先导入此配置,然后再部署SpringCloud程序
SpringCloud配置文件如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: springcloud
namespace: develop
labels:
name: springcloud
data:
bootstrap.yml: |
spring:
cloud:
config:
discovery:
# 开启配置中心
enabled: true
# 配置中心的service-id 与 Eureka Server中注册的service-id保持一种
service-id: poems-config
# 配置文件使用的环境[profile] dev,prod,test等
profile: dev
# 代表要请求哪个git分支,默认master主分支
label: master
eureka:
client:
#是否将该应用实例注册到Eureka Server
fetch-registry: true
#表示是否从Eureka Server上获取注册信息,默认为true
register-with-eureka: true
service-url:
#defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
defaultZone: http://pbsage:123456@poems-eureka:9931/eureka/
SpringCloud程序配置清单如下:
---
apiVersion: v1
kind: Service
metadata:
name: ems-saas-web
labels:
app: ems-saas-web
spec:
selector:
app: ems-saas-web
ports:
- name: server-port
port: 9939
targetPort: 9939
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ems-saas-web
spec:
replicas: 1
selector:
matchLabels:
app: ems-saas-web
template:
metadata:
labels:
app: ems-saas-web
spec:
hostAliases:
- ip: "192.168.100.90"
hostnames:
- "node1"
- "namenode"
- "secondarynamenode"
- "zookeeper1"
- ip: "192.168.100.91"
hostnames:
- "node2"
- "datanode1"
- "zookeeper2"
- ip: "192.168.100.92"
hostnames:
- "node3"
- "datanode2"
- "zookeeper3"
containers:
- name: ems-saas-web
image: persagy-registry:8080/jixian/ems-saas-web:2.0.1
ports:
- containerPort: 9939
name: server-port
volumeMounts:
- name: springcloud
mountPath: /data/SpringCloud/bootstarp.yml
subPath: path/to/application.yml
volumes:
- name: springcloud
configMap:
name: springcloud
defaultMode: 0777
items:
- key: bootstrap.yml
path: path/to/application.yml
前端静态文件
由于前端静态文件依赖于nginx,所以每个前端静态文件都依赖于nginx镜像制作,所以nginx统一配置文件为前端nginx.conf
nginx.conf配置文件
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-web-conf
namespace: persagy-standard
labels:
name: nginx-web-conf
data:
nginx.conf: |
#user tony;
worker_processes 4;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
worker_rlimit_nofile 100001;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
access_log /var/log/nginx/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;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript application/css text/css application/xml text/javascript application/x-httpd-php
gzip_vary on;
server {
listen 80 default_server;
root /usr/persagy/saas-web;
location /app {
try_files $uri $uri/ /app/index.html;
}
# FMS
location /fms {
try_files $uri $uri/ /fms/index.html;
}
}
}
2.4.2 前端静态资源部署清单(fms)
---
apiVersion: v1
kind: Service
metadata:
name: fms
labels:
app: fms
spec:
selector:
app: fms
ports:
- name: server-port
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fms
spec:
replicas: 1
selector:
matchLabels:
app: fms
template:
metadata:
labels:
app: fms
spec:
containers:
- name: fms
image: persagy-registry:8080/jixian/fms:v1.1.0
ports:
- containerPort: 80
name: server-port
volumeMounts:
- name: config
mountPath: /etc/nginx/nginx.conf
subPath: path/to/nginx.conf.js
volumes:
- name: config
configMap:
name: nginx-web-conf
defaultMode: 0777
items:
- key: nginx.conf
path: path/to/nginx.conf.js