kubernetes听云实战发布版
听云线上使用k8s已经有一段时间了,下面对一些听云使用过程中的问题进行一些梳理,包括架构设计,安装部署和后期维护。 目录结构如下:

下面进入正题:
我们以听云系统的一个报表系统为例来详细进行说明:
1.系统架构
该应用属于Java Web报表类应用,部署在Ucloud云上。系统架构如下:

这是典型web应用的系统架构,在听云内部大部分应用都是此形式,对于并发量不高的业务均可参考此文档。
基本规范:
1.configmap用来管理配置文件
2.deployment用来编排应用,进行升级回滚等
3.pv用于共享存储,后端为glustefsr和nfs
4.daemonset 用于变更不频繁,一台机器一个docker的应用
5.nginx+ingress来做前端负载均衡和自动发现
6.对并发要求很高的应用可以尝试用host模式,不用service做负载均衡
2.部署说明
参考架构图,我们需要nginx-ingress-controller 和 应用的Docker。下面分别进行详细说明。
2.1 准备基础Docker镜像
听云先进行应用的部署,规范是每个项目一个Docker镜像,版本号为jenkins构建的版本号。
为了规范日后上线。我们需要按层次构建镜像,方便日后使用。
构建基础镜像
由于听云的项目中绝大大部分为Java项目,为了精简Docke镜像大小,基础镜像我们没有采用Centos或者Ubuntu,而是采用了alpine,该镜像只有4MB。
Dockerfile内容如下:
FROM registry.tingyun.com/docker.io/alpine
MAINTAINER netop "netop@tingyun.com"
ENV REFRESHED_AT 2016-03-18
RUN apk add --no-cache --update-cache bash
ENV GLIBC_PKG_VERSION=2.23-r1
RUN apk add --no-cache --update-cache curl ca-certificates bash && \
curl -Lo /etc/apk/keys/andyshinn.rsa.pub "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/andyshinn.rsa.pub" && \
curl -Lo glibc-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-${GLIBC_PKG_VERSION}.apk" && \
curl -Lo glibc-bin-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-bin-${GLIBC_PKG_VERSION}.apk" && \
curl -Lo glibc-i18n-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-i18n-${GLIBC_PKG_VERSION}.apk" && \
apk add glibc-${GLIBC_PKG_VERSION}.apk glibc-bin-${GLIBC_PKG_VERSION}.apk glibc-i18n-${GLIBC_PKG_VERSION}.apk
add Shanghai /etc/localtime
ENV LANG en_US.UTF-8
构建镜像
docker build -t registry.tingyun.com/common/alpine .
push 到仓库中
docker push registry.tingyun.com/common/alpine
构建JDK镜像
Dockerfile内容如下:
FROM registry.tingyun.com/common/alpine
MAINTAINER netop "netop@tingyun.com"
ENV REFRESHED_AT 2016-03-14
ADD jdk1.7.0_45.tar.gz /opt
ENV LANG en_US.UTF-8
ENV JAVA_VERSION 1.7.0_45
ENV JAVA_HOME /opt/jdk1.7.0_45
ENV PATH $JAVA_HOME/bin:$PATH
该镜像只添加了一个jdk包,我们build它
docker build -t registry.tingyun.com/common/jdk7 .
push 到仓库中
docker push registry.tingyun.com/common/jdk7
构建tomcat镜像
Docker内容如下:
FROM registry.tingyun.com/common/jdk7
MAINTAINER netop "netop@tingyun.com"
ENV REFRESHED_AT 2016-03-14
ADD apache-tomcat-6.0.45.tar.gz /opt
RUN ln -s /opt/apache-tomcat-6.0.45 /opt/apache-tomcat
ADD server.xml /opt/apache-tomcat/conf/server.xml
ENV CATALINA_HOME /opt/apache-tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
ENV TOMCAT_MAJOR 6
ENV TOMCAT_VERSION 6.0.45
ENV JAVA_OPTS -server -Djava.library.path=/opt/apache-tomcat/lib -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/apache-tomcat/logs/gc.log
WORKDIR $CATALINA_HOME
ENV TINGYUN_APP_NAME="Java Application" \
TINGYUN_LICENSE_KEY=f451bae910b4c3f4473e0c83d2113742
RUN curl -o /tingyun-agent-java-latest.zip http://download.tingyun.com/agent/java/latest/tingyun-agent-java-latest.zip
RUN mkdir /opt/tingyun_agent;unzip /tingyun-agent-java-latest.zip -d /opt/tingyun_agent
RUN rm /tingyun-agent-java-latest.zip -rf
ENV CONNECTOR='<Connector port="8080" maxHttpHeaderSize="8192" maxThreads="300" minSpareThreads="25" maxSpareThreads="300" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" />'
ENV CONTEXT=""
ENV ACCESS_LOG="<Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs\" prefix=\"access_log.\" suffix=\".log\" pattern='%{X-Request-Start}i %{X-Queue-Start}i %{X-Forwarded-For}i %h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\" %T' resolveHosts=\"false\"/>"
ADD run.sh /run.sh
EXPOSE 8080
CMD ["/run.sh"]
run.sh内容如下:
#!/bin/bash
TINGYUN_AGENT_PATH="/opt/tingyun_agent/tingyun/tingyun.properties"
TOMCAT_CONF_PATH="/opt/apache-tomcat/conf/server.xml"
sed -i "s/Java Application/$TINGYUN_APP_NAME/" $TINGYUN_AGENT_PATH
sed -i "s/<%=license_key%>/$TINGYUN_LICENSE_KEY/" $TINGYUN_AGENT_PATH
sed -i "s#CONNECTOR#$CONNECTOR#" $TOMCAT_CONF_PATH
sed -i "s#CONTEXT#$CONTEXT#" $TOMCAT_CONF_PATH
sed -i "s#ACCESS_LOG#$ACCESS_LOG#" $TOMCAT_CONF_PATH
catalina.sh run
server.xml内容如下:
此处不贴文本了,内容为标准的server.xml 做了字符串替换。
此处将Connector注释掉,改为CONNECTOR

此处将access_log和 context部分 删掉 ,替换为图片中字符串。

我们进行build
docker build -t registry.tingyun.com/common/jdk7-tomcat6 .
docker push registry.tingyun.com/common/jdk7-tomcat6
查看该Dockerfile会注意到我们将听云Server探针进行了嵌入。是否启用探针我们会在后续的k8s配置文件进行控制,因为应用在k8s上跑具体跑在哪台机器上是不固定的,原有的zabbix jmx监控无法满足需求,我们利用听云Server来进行监控。
2.2 利用jenkins构建应用镜像
按照上文方式,准备好相关的基础镜像,如jdk7-tomcat6 jdk8-tomcat8等。
下边利用jenkins来构建应用镜像。
由于听云的jenkins本身操作系统版本太低,无法使用docker, 所以要选一台部署了docker的机器作为build机,通过ssh的方式来进行build。(此处视build的数量考虑是否需要利用jenkins slave的方式来进行build。简单测试过mesos 作为slave的方式,流程跑通,没有深测)
听云工程师们是通过写个通用的build脚本,用来build应用的镜像。
vi build_tomcat_docker.sh
#!/bin/bash
FUN_DIR=$1
APP_DIR=$2
PACK_NAME=$3
PACK_MD5=$4
APP_NAME=$5
BASE_IMG=$6
FINISH_IMG=$7
BUILD_NUM=$8
if [ -d "/data/tmp" ];then
rm /data/tmp/* -rf
else
mkdir /data/tmp -p
fi
if [ ! -n "$1" ] || [ ! -n "$2" ] || [ ! -n "$3" ] || [ ! -n "$4" ] || [ ! -n "$5" ] || [ ! -n "$6" ] || [ ! -n "$7" ] || [ ! -n "$8" ] ;then
echo "build error,please input vars"
else
PACK_URL=http://192.168.1.16/tingyun/${PACK_NAME}
MD5_URL=http://192.168.1.16/tingyun/${PACK_MD5}
/usr/bin/curl -o /data/tmp/${PACK_NAME} $PACK_URL
/usr/bin/curl -o /data/tmp/${PACK_MD5} $MD5_URL
MD5_ORIGN=`/usr/bin/curl $MD5_URL | awk '{print $1}'`
MD5_WGET=`cat /data/tmp/${PACK_MD5} | awk '{print $1}'`
if [ "$MD5_ORIGN" = "$MD5_WGET" ]; then
echo "md5sum sucess"
/usr/bin/unzip /data/tmp/${PACK_NAME} -d /data/tmp/${APP_NAME}
ADD_FILE="ADD ${APP_NAME} /opt/${FUN_DIR}/${APP_DIR}/${APP_NAME}"
cp /data/build/Dockerfile_template /data/tmp/Dockerfile
sed -i "s#BASE_IMG#$BASE_IMG#" /data/tmp/Dockerfile
sed -i "s#ADD_FILE#$ADD_FILE#" /data/tmp/Dockerfile
docker build --no-cache=true -t ${FINISH_IMG}:${BUILD_NUM} /data/tmp/
docker push ${FINISH_IMG}:${BUILD_NUM}
echo "build img is ${FINISH_IMG}:${BUILD_NUM}"
else
echo "md5sum failed"
fi
fi
vim Dockerfile_template
FROM BASE_IMG
MAINTAINER netop "netop@tingyun.com"
ENV REFRESHED_AT 2016-02-18
ADD_FILE
如果Java探针有更新,需要重新build下前边的基础镜像,在build机器上重新pull镜像后再构建应用镜像。
打开jenkins该项目,标红处添加该行,用于记录要升级的镜像和build号
注意命名规范:中间列是产品线。

添加下列用于构建镜像的机器

用jenkins build
build 成功。

2.3 k8s配置应用
镜像已经准备好了,接下来配置应用
2.3.1 配置configmap
应用的配置文件统一通过conigmap来管理
mkdir configmap
cd configmap
ls -al

配置文件放到该目录下
vim create_configmap.sh
kubectl create configmap report-app-beta-config --from-file=configmap
vim reload_configmap.sh
kubectl delete configmap report-app-beta-config
kubectl create configmap report-app-beta-config --from-file=configmap
2.3.2 配置deployment
下面配置deployment
vim deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: report-app-beta #应用名称
spec:
replicas: 10 #启动副本个数
minReadySeconds: 60 #滚动升级时60s后认为该pod就绪
strategy:
rollingUpdate:
maxSurge: 50% #滚动升级时会先启动20%的pod
template:
metadata:
labels:
name: report-app-beta
spec:
volumes:
- name: config-volume #configmap的挂载点
configMap:
name: report-app-beta-config
- name: pv-mapping-files #pvc的挂载点
persistentVolumeClaim:
claimName: mapping-files
nodeSelector: #选择调度的node节点
zone: low
# hostNetwork: true
containers:
- name: report-app-beta
# livenessProbe: #监控
# httpGet:
# path: /healthCheck
# port: 8080
# initialDelaySeconds: 30
# timeoutSeconds: 10
image: registry.tingyun.com/app/report-app:1
command: #小hack,为了不重打镜像,不执行默认的命令
- sh
- "-c"
- ln -s /opt/mapping_files/puuid /bin/puuid && /run.sh
env: #环境变量
- name: TINGYUN_APP_NAME
value: report-app
- name: TINGYUN_LICENSE_KEY
value: f451bae910b4c3f4473e0c83d2113742
- name: JAVA_OPTS
value: "-server -Djava.library.path=/opt/apache-tomcat/lib -Xms512m -Xmx2048m -XX:NewRatio=4 -Xss1024k -XX:PermSize=64M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/apache-tomcat/logs/gc.log -javaagent:/opt/tingyun_agent/tingyun/tingyun-agent-java.jar -Duser.language=zh -Duser.region=CN -Duser.timezone=GMT+08 -DappName=report-app"
- name: CONNECTOR
value: '<Connector port="8080" maxHttpHeaderSize="8192" maxThreads="300" minSpareThreads="25" maxSpareThreads="300" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" /> '
- name: CONTEXT
value: '<Context path="/mobile" reloadable="false" allowLinking="true" docBase="/opt/tingyun/report-app/webapp/" workDir="/opt/tingyun/report-app/work/"/> '
ports:
- containerPort: 8080
volumeMounts: #上边的挂载点挂载到容器中的路径
- name: config-volume
mountPath: /opt/tingyun/report-app/conf
- name: pv-mapping-files
mountPath: /opt/mapping_files
kubectl create -f deployment.yaml
kuectl get pods
看pod已经起来了

2.3.3 配置Service
下面配置service
vim service.yaml
apiVersion: v1
kind: Service
metadata:
name: report-app-beta
labels:
name: report-app-beta
spec:
# sessionAffinity: ClientIP #在基于新的nginx-ingress-controller已经不需要配置该项,session绑定在nginx处配置
ports:
- port: 8080
selector:
name: report-app-beta
kubectl create -f service.yaml
kubectl get service

2.3.4 配置ingress
下面配置ingress
vim ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: report-app-beta
spec:
rules:
- host: report-beta.tingyun.com #域名
http:
paths:
- path: /mobile #访问路径
backend:
serviceName: report-app-beta #service名称
servicePort: 8080 #service端口
kubectl create -f ingress.yaml
kubect get ingress

2.4 创建nginx-ingress-controller
nginx-ingress-controller 需要监听宿主机的80端口,固定在某几台机器上,为此需要给相关node 定义标签。
kubectl label nodes ucd-ty-k8s-node-001.ucd.tingyun.com role=nginx-lb
kubectl get nodes --show-labels
创建configmap
vim nginx.tmpl
该文件可以去github上下载
https://github.com/kubernetes/contrib/blob/master/ingress/controllers/nginx/nginx.tmpl
kubectl create configmap nginx-template --from-file=nginx.tmpl=nginx.tmpl
为了将为所有在nginx后的项目开启session保持,同时听云的开发工程师要打开后端监控页面,需要修改两个地方。

这里暂时先改为无论如何都启用session保持

这里直接启用traffic_status
vim rc.yaml
该文件可以去github下载
kubectl create rc.yaml
查看nginx_status界面
http://10.10.228.175:8080/nginx_status

接下来即可访问该项目

原文链接:http://blog.tingyun.com/web/article/detail/825
kubernetes听云实战发布版的更多相关文章
- 利用听云Server和听云Network实测Kubernetes和Mesos在高并发下的网络性能
文章出自:听云博客 随着公司业务的不断增长,我们的应用数量也有了爆发式增长.伴随着应用爆发式的增长,管理的难度也随之加大.如何在业务爆发增长的同时快速完成扩容成了很大的挑战.Docker的横空出世恰巧 ...
- 阿里云重磅发布RDS for SQL Server AlwaysOn集群版
2018年双十一刚过,阿里云数据库发布RDS for SQL Server AlwaysOn集群版,这是业界除微软云SQL Database外,首家云计算公司基于SQL Server最新AlwaysO ...
- Kubernetes 应用部署实战
Kubernetes 应用部署实战 2018-08-08 19:44:56 wuxiangping2017 阅读数 3084 收藏 更多 分类专栏: linux运维与架构师 简介 伙计们,请搬好 ...
- 【活动】写#听云#原创博文 赢取iPhone 6超级大奖
移动应用的使用量和重要性与日俱增,用户体验的要求也越来越高.与桌面程序相比,移动应用耗电小,速度慢,但手机用户却希望享受到与桌面程序同样的加载速度.那么如何发现移动应用的性能黑洞,优化移动应用性能,这 ...
- 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息
第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...
- 第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息
在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同). 公众号可通过本接口来根据O ...
- 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单
我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...
- 第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token
一.access_token简介 为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台 开放了许多接口,包括自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等, 开 ...
- 第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理
温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发 第三篇 :微信公众 ...
随机推荐
- spring 数据校验之Hibernate validation
1.需要的jar包 2.springsevlet-config.xml配置 在spring3之后,任何支持JSR303的validator(如Hibernate Validator)都可以通过简单配置 ...
- ROS 常用命令字典
版权声明:本文为博主原创文章,转载请标明出处: http://www.cnblogs.com/liu-fa/p/5761448.html 该博文适合已经具备一定的ROS编程基础的人,快速查看ROS相关 ...
- 观察者模式(Observer pattern)
知识点 使对象之间达到松耦合的效果. 观察者模式定义了对象之间一对多的关系.主题用一个共同的接口来更新观察者. 观察者和被观察者之间通过松耦合的方式结合,被观察者不用理会观察者的实现细节,只需要观察者 ...
- EasyUI datagrid 行编辑
一.HTML: <div class="info"> <div class="info_tt"> <span class=&quo ...
- Mssql中一些常用数据类型的说明和区别
Mssql中一些常用数据类型的说明和区别 1.bigint 占用8个字节的存储空间,取值范围在-2^63 (-9,223,372,036,854,775,808) 到 2^63-1 (9,223,37 ...
- 让Windows2008R2也能进入手柄设置(游戏控制器设置)
在Windows2008 R2系统中,插入XB360手柄后能自动完成驱动安装,在[设备和打印机]中也会出现手柄,但在上面右键→游戏控制器设置却没反应,什么都没打开,虽然不影响实际游戏,但总感觉有点堵. ...
- ASP.NET页面事件:顺序与回传详解
当页面被提交请求第一个方法永远是构造函数.您可以在构造函数里面初始一些自定义属性或对象,不过这时候因为页面还没有被完全初始化所以多少会有些限制.特别地,您需要使用HttpContext对象.当前可以使 ...
- css3飞机起飞进度条
效果:http://hovertree.com/texiao/css3/27/ 源码下载:http://hovertree.com/h/bjaf/pgwql1x2.htm 本效果使用Font Awes ...
- 2016暑假多校联合---Another Meaning
2016暑假多校联合---Another Meaning Problem Description As is known to all, in many cases, a word has two m ...
- Windows Git中文文件名乱码
在Windows下使用git,安装包如下: https://git-for-windows.github.io/ 在使用git bash时git 默认中文文件名是 xx% 是因为 对0x80以上的字符 ...