kubernetes介绍
先说说docker

- namespace:进程隔离
- cgroups:硬件、网络资源隔离、分配
Union File System(AUFS):减少空间占用 aufs是一种支持联合挂载的文件系统,将不同目录挂载到同一个目录下面,只有最上层是可读可写,下层都是只读层。 Docker 中的一个创新是利用了 AUFS 作为底层文件系统实现,通过这种方式,Docker 实现了一种增量式的镜像结构。

kubernetes是什么?
- Kubernetes 是一个可扩展的,用于容器化应用程序编排,管理的平台。由 Google 于 2014 年基于其大规模生产实践经验而开源出来的。Kubernetes 目前在容器编排领域已经成为事实上的标准,社区也非常活跃。
- Kubernetes 在国内外都已经得到广泛的应用,无论是Google, Amazon, GitHub 等还是国内的阿里,腾讯,百度,华为,京东或其他中小公司等也都已全力推进 Kubernetes 在生产中的使用。
- 现在无论是运维,后端,DBA,亦或者是前端,机器学习工程师等都需要在工作中或多或少的用到 Docker, 而在生产中大量使用的话 Kubernetes 也将会成为趋势,所以了解或掌握 Kubernetes 也成为了工程师必不可少的技能之一。
为什么需要 kubernetes?
管理大量的容器带来了新的挑战: 故障迁移?资源调度?环境隔离?权限控制?资源限制?负载均衡? k8s的优势:
- 简化应用部署
- 提高硬件资源利用率
- 健康检查和自修复
- 自动扩容缩容
- 服务发现和负载均衡
kubernetes的集群架构
- 主节点,承载 k8s 的控制和管理整个集群系统的控制
- 工作节点,运行用户实际的应用
+-------------+
| |
| | +---------------+
| | +-----> | Node 1 |
| Kubernetes | | +---------------+
+-----------------+ | Server | |
| CLI | | | | +---------------+
| (Kubectl) |----------->| ( Master ) |<------+-----> | Node 2 |
| | | | | +---------------+
+-----------------+ | | |
| | | +---------------+
| | +-----> | Node 3 |
| | +---------------+
+-------------+
pod-k8s调度的最小单元
一个pod包含一组容器,一个pod不会跨越多个工作节点。

- pod 相当与逻辑主机,每个 pod 都有自己的 IP 地址
- pod 内的容器共享相同的 IP 和端口空间
- 默认情况下,每个容器的文件系统与其他容器完全隔离
kubernetes在线下环境的CI/CD实践
背景
传统的线下环境,由运维手动创建。方式为在物理机上创建虚拟机,通过Jenkins持续集成。使用过程中总结出问题如下:
- 部署困难:涉及到的第三方服务多,出问题难以解决。部署过程中存在大量重复性工作及需要手动配置的部分(如分配端口号),增加了出错的风险。
- 资源占用大:各环境项目无法复用。
- 伸缩困难:采用虚拟机的方式无法动态调节内存占用。
设计思路
- 通过预定义脚本的方式,尽量减少构建项目需要的配置项,减少学习成本。
- 通过容器编排,实现资源的动态申请释放。提供一键复制环境的功能。规避手动操作带来的风险。
- 通过与公司的DNS打通,实现通过域名前缀访问不同环境。
系统设计
系统简要说明
- 系统内部包含有多套互相隔离的环境,每套环境需要配置环境id(如:beike-test),同时支持配置中文别名(中文别名显示在Jenkins系统环境目录的“名称”字段处),便于用户了解环境用途。
- 每个环境拥有自己独立的域名前缀(如:test1.contract.alibaba-inc.com)。在公司内部网络访问该域名时可以解析到对应的环境中,切换环境无需配置hosts文件,只需要更改域名即可。
- 使用Jenkins做为环境及项目的后台系统。用户登录到Jenkins后,可以查看到一些类似于文件夹一样的目录,每个目录对应一个环境,如下图所示:
系统架构基本介绍
系统主要分为以下几部分:
- Kubernetes集群系统:通过容器编排,将所有物理机整合,动态调节资源。同时使用覆盖网络将网络打通。
- Jenkins:使用自己实现的Shell覆盖Jenkins构建项目时执行的Bash Shell,完成更为智能的自动化构建。
- 访问路由系统:通过外部DNS服务以及集群内部的Nginx,实现通过域名前缀访问不同环境。
系统架构图及说明

- 通过Kubernetes将所有机器整合,各个机器的CPU、内存等资源整合成一个共享的资源池,均衡负载。
- 部署Weave容器构建虚拟网桥,使不同节点的容器可以互相访问。
- 部署Kube-DNS服务代替宿主机公网DNS,实现内部动态DNS解析,避免项目重启导致的IP漂移。
- 部署Nginx容器通过解析测试域名中的环境id,转发到对应环境中。
- 除静态文件之外的每个项目均通过Docker容器启动,暴露所需的端口。通过Kubernetes中的网桥访问内部及外部网络,同时向Kube-DNS注册带有环境id的域名,使得Nginx可以转发到该项目。
- 部署Jenkins Master容器,并在每台宿主机上通过SSH配置Slave节点,使Jenkins可以负载均衡到任意一台主机上执行构建任务。
- 将Jenkins执行Shell使用的Bash Shell替换为自定义的Shell。
- 构建项目:脚本通过提取项目配置,构建项目并使用容器部署,动态分配内部网段的IP,并通过环境id拼接域名注册到Kube-DNS。同时构建前检查集群剩余资源是否充足。
- 删除项目:通过环境id,查找到对应环境的对应项目,停止项目并释放资源,删除静态文件等。
- 搭建NFS网络文件系统,将Nginx Conf、Jenkins Shell、Jenkins Slave等目录及文件统一挂载。
- 配置Kubernetes定时任务脚本,定时清理异常项目。
- 在外部DNS服务上配置规则,将带有环境id的域名解析到Kubernetes集群。
- 将项目日志输出统一映射到Jenkins对应项目的工作空间下,使用者可以直接在Jenkins中查看日志。提供一台机器用于命令行查看日志。
系统流程
添加项目
流程图如下:


apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: PROJECT_NAME
labels:
usercreate: "true"
app: PROJECT_NAME
project: PROJECT
group: GROUP_ID
spec:
selector:
matchLabels:
usercreate: "true"
app: PROJECT_NAME
project: PROJECT
group: GROUP_ID
replicas: 1
template:
metadata:
labels:
usercreate: "true"
app: PROJECT_NAME
project: PROJECT
group: GROUP_ID
spec:
containers:
- name: java
image: openjdk:8-jre
resources:
requests:
memory: 1024Mi
env:
- name: transformers_local_id
value: GROUP_ID
workingDir: /usr/target
command: ["/bin/bash"]
args: ["-c","./bin/start.sh"]
ports:
- containerPort: 80
- containerPort: 20880
volumeMounts:
- name: target
mountPath: /usr/target
- name: logback
mountPath: /data/var/log/application
- name: apollo
mountPath: /opt/settings
volumes:
- name: target
hostPath:
path: TARGET_PATH
- name: logback
hostPath:
path: LOGBACK_PATH
- name: apollo
hostPath:
path: APOLLO_PATH
---
访问环境


查看日志
- 在Jenkins中查看
- 通过SSH到宿主机查看
由于使用了NFS或分布式文件系统,并且将日志挂载到宿主机,因此可以到宿主机查看日志
- 进入容器查看