💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
本人主要分享计算机核心技术:系统维护、数据库、网络安全、自动化运维、容器技术、云计算、人工智能、运维开发、算法结构、物联网、JAVA 、Python、PHP、C、C++等。
不同类型针对性训练,提升逻辑思维,剑指大厂,非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。
技能目标:
-
掌握
Docker
本地镜像制作及上传
Harbor
仓库
-
掌握使用
Jenkins
拉取代码、构建及发布
Java 项目到 K8S
4.1 案例分析
4.1.1 案例概述
某公司最近开发了一套大型票务类电商网站,被命名为大觅网。大觅网为用户提供了通
过
Web
界面购票的服务,主要功能包括:商品搜索、用户注册登录、商品详情、选座、下
单等功能。大觅网的整个部署过程会用到云计算的相关知识,包括
OpenStack
的多节点部
署、
OpenStack
网络路由创建和云主机创建;也会用到
Docker
容器的相关知识,包括
Dockerfile
制作镜像、
Docker Compose
多容器关联制作等;还会用到
Jenkins
自动构建发
布大觅网项目。整个项目采用多知识相结合,共同协调配合来完成部署。本案例主要介绍将
大觅网部署到
Kubernetes
上。
4.1.2 案例前置知识点
1. 什么是 Tengine
Tengine
是由某网发起的
Web
服务器项目。针对网站访问量大的需求,它基于开源
软件
Nginx
进行了优化,添加了很多高级功能和特性。
Tengine
的性能和稳定性已经在淘宝
网、天猫商城等大型网站得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、
易用的
Web 平台。
2. 什么是 Nexus
Nexus
是
Maven
仓库管理器,也可以叫
Maven
私服。它功能强大,极大地简化了自
己内部仓库的维护和外部仓库的访问。利用
Nexus
只在一个地方就能够完全控制访问和部
署仓库中的每个
Artifact
。
Nexus
是一套
“
开箱即用
”
的系统,不需要数据库,它使用文件系
统和
Lucene
组织数据。
Nexus
不是
Maven
的核心概念,它仅仅是一种衍生出来的特殊的
Maven
仓库。对于
Maven
来说,仓库分为三种:本地仓库、远程仓库和中央仓库。本地仓库就是在
Maven
的
setting.xml
文件中配置的本地仓库地址。由于最原始的本地仓库是空的,因此,
Maven
必
须知道至少一个可用的远程仓库,才能在执行
Maven
命令的时候下载到需要的构件。中央
仓库是
maven
默认的远程仓库。私服是架设在局域网的一种特殊的远程仓库,目的是代理
远程仓库及部署第三方构件。有了私服之后,当
Maven
需要下载构件时,直接请求私服。
如果私服上存在,则下载到本地仓库;否则,私服请求外部的远程仓库,将构件下载到私服,
再提供给本地仓库下载。
3. 什么是 Jenkins
Jenkins
是一个独立的开源自动化服务器,其前身是
Hudson
,是一个可扩展的持续集
成引擎。
Jenkins
可以用来完成自动化构建、测试和部署软件等各种任务,可以通过本地系
统包、
Docker
安装,甚至可以在安装
Java
环境的机器上独立运行。它提供了一种易于使用
的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上。
同时
Jenkins
能实现监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表
的形式形象地展示项目构建的趋势和稳定性。
4. 什么是 Kubernetes
Kubernetes
是一个可移植、可扩展的开源容器编排系统,主要用于自动化部署、扩展
和管理容器应用,提供资源调度、部署管理、服务发现、扩容缩容、监控等功能。
事实上,随着对
K8S
系统架构与设计理念的深入了解,可以发现
K8S
系统正是处处为
运行云原生应用而设计考虑的。
Kubernetes
可以调度计算集群节点、动态管理节点上作业,并保证它们按用户期望状
态运行。通过使用「
Labels
(标签)」和「
Pods
(荚)」的概念,
Kubernetes
将应用按逻
辑单元进行分组,方便管理和服务发现。
4.1.3 案例环境
1. 本案例实验环境
本案例使用三台独立的虚拟机分别部署
Gitlab
、
Harbor
和
Jenkins
,另外三台虚拟机组
成一个
K8S
集群,该集群包括一个
master
和两个
node
节点,共需六台虚拟机。整个环境
的拓扑如图
4.1
所示。
图 4.1 案例拓扑图
具体的虚拟机环境配置如表
4-1
所示。
表
4-1
大觅网综合管理实验环境
主机名 | 操作系统 | IP 地址 | 最低配置 | 主要软件 |
gitlab | CentOS 7.3-x86_64 | 192.168.9.10 | 1 核 2G | Gitlab |
harbor
| CentOS 7.3-x86_64 | 192.168.9.20 | 1 核 2G |
harbor
|
jenkins
| CentOS 7.3-x86_64 | 192.168.9.30 | 1 核 2G |
jenkins
|
k8s-master
| CentOS 7.3-x86_64 | 192.168.9.40 | 2核 2G |
Kube-apiserver 等
|
k8s-node1
| CentOS 7.3-x86_64 | 192.168.9.50 | 1 核 5G |
Kubelet、kube-proxy
|
k8s-node2
| CentOS 7.3-x86_64 | 192.168.9.60 | 1 核 5G |
Kubelet、kube-proxy
|
2. 案例环境权限列表
表
4-2
案例中用到的用户名和密码
类型 | 用户名 | 密码 |
Gitlab | root | bdqn123456 |
MySQL | root | 123456 |
Jenkins | admin | 123456 |
Nexus | admin | admin123 |
Harbor | admin | Harbor123 |
4. 案例需求
(
1
)创建
Gitlab
仓库,存放大觅网后端
java
程序源码。
(
2
)使用
Harbor
搭建
Docker
私有仓库,存放
Docker
镜像。
(
3
)通过
Jenkins
构建生成大觅网
jar
包并发布。
(
4
)搭建
Kubernetes
部署
java
业务程序。
5. 案例实现思路
(
1
)部署
Gitlab
。
(
2
)部署
Harbor
。
(
3
)部署
Jenkins
。
(
4
)部署
Kubernetes
。
(
5
)上传大觅网代码到
Gitlab
仓库。
(
6
)构建生成
Docker
镜像并上传到
Harbor
仓库。
(
7
)通过
Jenkins
构建业务
jar
包并发布。
(
8
)通过浏览器访问测试大觅网。
4.2 案例实施
4.2.1 虚拟机初始化
虚拟机安装完成后,在部署各应用和服务之前,需要先对所有虚拟机进行系统初始化,
所有节点都需要执行初始化脚本,初始化通过执行
first.py
脚本实现,脚本具体内容如下所
示。
[root@localhost ~]#
vi first.py
//
使用
CentOS7.3
默认的
Python2.7
运行
#!/usr/bin/python
import subprocess
import urllib2
serList = ('firewalld', 'postfix')
url="https://mirrors.aliyun.com/repo/epel-7.repo"
def ShutService(svc):
subprocess.call(["systemctl", "stop", "{0}".format(svc)])
subprocess.call(["systemctl","disable", "{0}".format(svc)])
def DisableSELinux():
with open('/etc/selinux/config', 'r+') as f:
all_lines = f.readlines()
f.seek(0)
f.truncate()
for line in all_lines:
line = line.replace('SELINUX=enforcing', 'SELINUX=disabled')
f.write(line)
def InstallYum():
subprocess.call('yum -y install vim net-tools wget lrzsz unzip git', shell=True)
def DownEpel(url):
f = urllib2.urlopen(url)
data = f.read()
with open("/etc/yum.repos.d/epel.repo", "wb") as code:
code.write(data)
def main():
for ser in serList:
ShutService(ser)
DisableSELinux()
InstallYum()
DownEpel(url)
subprocess.call('reboot')
if __name__ == "__main__":
main()
[root@localhost ~]#
python first.py
//
执行初始化脚本
[root@localhost ~]#
hostnamectl set-hostname gitlab
//
以
gitlab
虚拟机为例
[root@localhost ~]#
bash
以
gitlab
虚拟机节点为例设置主机名,其他虚拟机节点也需要配置主机名。初始化完成
后,开始 Gitlab 代码仓库的搭建工作。
4.2.2 Gitlab 搭建
使用
Gitlab
作为大觅网项目的代码仓库,
Gitlab
的搭建是在
Gitlab
虚拟机节点上面执
行的操作。
1. 安装 Gitlab
使用发布包内“大觅网
\software
”目录下的离线包安装
Gitlab
。安装过程如下所示。
[root@gitlab ~]#
yum -y install policycoreutils-python
[root@gitlab ~]#
rpm -ivh gitlab-ce-12.9.0-ce.0.el7.x86_64.rpm
[root@gitlab ~]#
vim /etc/gitlab/gitlab.rb
external_url ‘http://192.168.9.10’
//
将
external_url
配置成
Gitlab
虚拟机的
IP
地址
[root@gitlab ~]#
gitlab-ctl reconfigure
上述最后一步“
reconfigure
”需要较长时间,等完成后就可以进行
Gitlab
用户和密码
的相关配置。
2. 设置 root 密码并登录
Gitlab
提供了
Web
访问页面,通过
Web
页面可进行相关的配置和管理工作。浏览器访
问
http://192.168.9.10
,如图
4.2
所示。
图 4.2 Gitlab 首次访问界面
首次访问
Gitlab
需要设置
root
用户密码,请参考表
4-2
设置密码和确认密码。之后单
击“
Change your password
”按钮,会提示输入登录信息,“
Username
”输入“
root
”,
“
Password
”输入刚设置的密码值,单击“
Sign in
”按钮登录到
Gitlab
,如图
4.3
所示。
图 4.3 Gitlab 登录界面
登录进入
Gitlab
之后,就可以配置
Gitlab
的各种参数以及创建大觅网业务需要的各种
任务了。
3. 从现有备份恢复大觅网项目
本章
Gitlab
代码的上传是通过将备份数据恢复到
Gitlab
完成的。
Gitlab
备份文件在发 布包 内 的路
径 为 “ 大 觅 网 \Gitlab 备 \1590514782_2020_05_27_12.9.0_gitlab_backup.tar”,将备份文件上传到 Gitlab
虚拟机 的“/var/opt/gitlab/backups
”目录下。大觅网代码仓库的恢复操作如下所示。
[root@gitlab ~]#
gitlab-ctl stop unicorn
//
停止相关数据连接服务
[root@gitlab ~]#
gitlab-ctl stop sidekiq
[root@gitlab ~]#
gitlab-rake gitlab:backup:restore BACKUP=1590514782_2020_05_27_12.9.0
//
恢复过程中需要输入“
yes
”继续恢复过程
[root@gitlab ~]#
gitlab-ctl start
恢复完成后,需要等待一会才能正常访问
Gitlab
页面。
4. 介绍新增内容
通 过
Gitlab
备 份 文 件 的 方 式 导 入 后 , 大 觅 网 相 关 源 码 页 面 同 样 可 以 通 过
“
http://192.168.9.10
”进行访问,并不需要修改任何内容。本章的
Gitlab
相较于大觅网业
务部署的
Gitlab
有几点不同的地方,具体说明如下:
(1)Gitlab 相关项目不需要修改 IP 地址
本章大觅网业务发布使用
K8S
方式,各微服务之间采用
Service
模式通信,原来配置
IP
的地方都使用对应的服务名进行代替,在发布后能自动识别,故不再需要配置
IP
地址。
下 面 以
base-consumer
项 目 为 例 进 行 说 明 , 其 配 置 文 件 在
Gitlab
内 的 路 径 为
“
dm-base-consumer/dm-base-consumer/src/main/resources/application.yml
”,具体内
容如图 4.4 所示。
图 4.4 base-consumer 项目
Service
配置
Rabbitmq
的
IP
地址使用“
svc-rabbitmq
”代替;
Redis
的
IP
地址使用“
svc-redis
”代
替;注册服务器
discovery-eureka
使用“
svc-eureka
”代替。像
svc-redis
这种服务名是在
K8S
发布文件内定义的,这里先做了解,后续会做相关说明。其他项目相关配置文件如下
所示。
env_project/dm-config-server/src/main/resources/application.yml
env_project/dm-gateway-zuul/src/main/resources/application.yml
env_project/dm-gateway-zuul/src/main/resources/bootstrap.yml
env_project/dm-zipkin-server/src/main/resources/application.yml
dm-base-consumer/dm-base-consumer/src/main/resources/application.yml
dm-base-provider/dm-base-provider/src/main/resources/application.yml
dm-user-consumer/dm-user-consumer/src/main/resources/application.yml
dm-user-provider/dm-user-provider/src/main/resources/application.yml
dm-order-consumer/dm-order-consumer/src/main/resources/application.yml
dm-order-provider/dm-order-provider/src/main/resources/application.yml
其它省略
大觅网项目的 Dockerfile
在发布包内“大觅网
\Spring Cloud
实施业务服务体系”目录
下。业务部署是将这些
Dockerfile
上传到服务器,通过远程
Jenkins
构建镜像并发布容器。
本章大觅网项目对应的
Dockerfile
采用的是上传到
Gitlab
内,跟业务部署使用的是完全不
同 的 方 式 。 以
base-consumer
项 目 为 例 , 在
Gitlab
代 码 仓 库 内
Dockerfile
在
“
base-consumer/dm-base-consumer
”目录下。使用备份方式还原的
Gitlab
,每个项目的
Dockerfile
都已上传到了对应的目录内。
(3)K8S 对应 yaml 配置文件
以
base-consumer
项目为例,在
Gitlab
的“
base-consumer/dm-base-consumer
”目
录下已上传
base-consumer.yaml
文件,该文件的命名都是采用“项目名
+yaml
”的方式。
这个文件是用于通过
K8S
发布大觅网业务项目使用的,文件内容如图
4.5
所示。
图 4.5 base-consumer.yaml 文件内容
文件的上半部分指定的是
Pod
,下半部分定义的是
Service
,中间以“
---
”分割。
上半部分定义了一个
Deployment
,名字和标签
label
都是“
base-consumer
”,
replicas
定义的副本数量是
1
,启动的
Pod
数量是
1
。
Containers
定义的名字是“
base-consumer
”,
image
是
Harbor
内
base-consumer
镜像的存放地址,
imagePullPolicy
是镜像的处理规则,
“
IfNotPresent
”表示如果本地不存在镜像就去
Harbor
仓库下载对应的镜像。
Ports
是容器
的发布端口。
下半部分定义了一个 Service
,名字和
labels
都是“
svc-base-consumer
”,
selector
选择器过滤的是
base-consumer
对应的
Pod
。
7000
端口是
base-consumer
服务对应的内
部通信端口。
4.2.3 Harbor 搭建
本章
Docker
镜像私有仓库使用
Harbor
存放大觅网基础镜像和业务镜像,
Harbor
私有
仓库相关操作都在
Harbor
虚拟机节点上操作。
1. 部署 Docker
(1)安装 Docker
Harbor
仓库需要
Docker
容器支持,所以
Docker
环境是必不可少的。
Docker
的安装
步骤如下所示。
[root@harbor ~]#
yum install -y yum-utils device-mapper-persistent-data lvm2
[root@harbor
~]#
yum-config-manager
--add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@harbor ~]#
yum makecache fast
[root@harbor~]#
yum -y install docker-ce
[root@harbor~]#
mkdir /etc/docker
[root@harbor~]#
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
]
}
[root@harbor ~]#
systemctl start docker && systemctl enable docker
如果在
Docker
使用过程中出现如下警告信息:
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
请添加如下内核配置参数以启用这些功能。
[root@harbor ~]#
tee -a /etc/sysctl.conf <<-EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
[root@harbor ~]#
sysctl -p
(2)部署 docker-compose
从发布包“大觅网
\software
”路径下上传
docker-compose
文件至
/usr/local/bin/
目录下。
给
docker-compose
文件可执行权限。
[root@harbor ~]#
chmod +x /usr/local/bin/docker-compose
2. 部署 Harbor
Harbor
私有仓库程序采用
docker-compose
方式部署,不同的功能和应用处于不同的
容器,这样带来了很好的兼容性,可在众多支持
Docker
的系统上运行
Harbor
。
Harbor
的
安装配置步骤如下所示。
(1)解压 Harbor 程序
从 发 布 包 “ 大 觅 网
\software
” 目 录 下 上 传
Harbor
程 序 包
“
harbor-offline-installer-v1.10.2.tgz
”,然后解压到
/usr/local
目录下。
[root@harbor ~]#
tar zxf harbor-offline-installer-v1.10.2.tgz -C /usr/local/
(2)修改 Harbor 配置文件
Harbor
的配置文件是
/usr/local/harbor/harbor.yml
文件,默认的
hostname
要修改为
Harbor
虚拟机节点的
IP
地址。
[root@harbor ~]#
vim /usr/local/harbor/harbor.yml
hostname:
192.168.9.20
//
省略了部分内容
# https related config
#https:
//https
相关配置都注释掉,包括
https
、
port
、
certificate
和
private_key
# https port for harbor, default is 443
#port: 443
# The path of cert and key files for nginx
#certificate: /your/certificate/path
#private_key: /your/private/key/path
对
hostname
配置项进行修改,对
https
相关内容进行注释,其他的配置项保持默认。
(3)启动 Harbor
[root@harbor ~]#
cd /usr/local/harbor
[root@harbor harbor]#
sh install.sh
//
省略了部分内容
[Step 5]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating harbor-portal ... done
Creating registryctl
... done
Creating redis
... done
Creating registry
... done
Creating harbor-db
... done
Creating harbor-core
... done
Creating nginx
... done
Creating harbor-jobservice ... done
✔
----Harbor has been installed and started successfully.----
[root@harbor harbor]#
docker-compose ps
Name
Command
State
Ports
---------------------------------------------------------------------------------------
harbor-core
/harbor/harbor_core
Up (healthy)
harbor-db
/docker-entrypoint.sh
Up (healthy)
5432/tcp
harbor-jobservice
/harbor/harbor_jobservice ...
Up (healthy)
harbor-log
/bin/sh -c /usr/local/bin/ ...
Up (healthy)
127.0.0.1:1514->10514/tcp
harbor-portal
nginx -g daemon off;
Up (healthy)
8080/tcp
nginx
nginx -g daemon off;
Up (healthy)
0.0.0.0:80->8080/tcp
redis
redis-server /etc/redis.conf
Up (healthy)
6379/tcp
registry
/home/harbor/entrypoint.sh
Up (healthy)
5000/tcp
registryctl
/home/harbor/start.sh
Up (healthy)
首次安装启动可使用
/usr/local/harbor/install.sh
脚本,后续可使用“
docker-compose up
-d
”命令启动
Harbor
,使用“
docker-compose stop
”命令关闭
Harbor
。
3. Harbor 内创建项目
Harbor
启动完成后,浏览器访问
http://192.168.9.20
,打开
Harbor Web
页面,如图
4.6
所示。
图 4.6 Harbor 登录页
Harbor
的默认用户和密码是
admin/Harbor12345
。输入用户名和密码后单击登录按钮,
进入
Harbor
主页面。单击“新建项目”按钮,如图
4.7
所示。
图 4.7 新建项目
项目名称依次填写“
base
”和“
dmw
”,访问级别勾选“公开”,创建两个项目仓库,
其他选项保持默认,单击“确定”按钮保存项目。
4. 基础镜像构建及上传
大觅网相关业务部署需要基础镜像的支持,比如
MySQL
、
Redis
等。本章在
Harbor
虚拟机节点完成这些基础镜像的构建以及镜像上传
Harbor
私有仓库。具体操作步骤如下所
示。
(1)上传 base 镜像构建文件
Harbor
虚拟机节点上创建
envdm
目录。
[root@harbor ~]#
mkdir -p /home/px2/envdm
将发布包内“大觅网
\base
镜像包
\
”路径下文件及目录内容上传到
Harbor
虚拟机节点
的
/home/px2/envdm
目录下。
[root@harbor envdm]#
cd /home/px2/envdm
[root@harbor envdm]#
ll
total 4
-rw-r--r-- 1 root root 2360 Apr 14 20:30 docker-compose.yml
drwxr-xr-x 2 root root 150 Apr 12 23:09 Elasticsearch
drwxr-xr-x 2 root root
58 Apr 12 23:09 jdk8u171
drwxr-xr-x 2 root root 160 Apr 17 10:12 Jenkins
drwxr-xr-x 2 root root 104 Apr 30 12:30 Kafka
drwxr-xr-x 2 root root 106 May 7 10:57 Kibana
drwxr-xr-x 2 root root
94 Apr 27 11:20 Logstash
drwxr-xr-x 2 root root 125 Apr 12 23:09 Mycat
drwxr-xr-x 3 root root 126 Apr 12 23:09 MySQL
drwxr-xr-x 2 root root 139 Apr 12 23:09 Nexus
drwxr-xr-x 2 root root 118 Apr 12 23:09 RabbitMQ
drwxr-xr-x 3 root root 102 Apr 12 23:09 Redis
drwxr-xr-x 2 root root 314 Apr 12 23:09 Sonar
drwxr-xr-x 2 root root
24 Apr 12 23:09 ssh
drwxr-xr-x 2 root root 284 May 5 12:50 Tengine
drwxr-xr-x 2 root root
83 Apr 12 23:09 tomcat7
(2)生成本地基础镜像
要编译生成大觅网基础镜像,需要
CentOS 7
、
SSH
、
Tomcat
和
Java
四个镜像的支持。
先获取
CentOS 7
镜像,再生成
SSH
、
Tomcat
和
Java
镜像,最后再通过
docker-compose
生 成 大 觅 网 基 础 镜 像 。 另 外 ,
Jenkins
采 用 独 立 的 服 务 器 进 行 了 部 署 , 此 处
docker-compose.yml
内将
Jenkins
配置内容注释掉或者删除掉。
[root@harbor ~]#
docker pull centos:7
[root@harbor ~]#
cd /home/px2/envdm/ssh/
[root@harbor ssh]#
docker build -t yi/centos7-ssh .
[root@harbor ssh]#
cd /home/px2/envdm/jdk8u171
[root@harbor jdk8u171]#
docker build -t yi/centos7-jdk8u171 .
[root@harbor jdk8u171]#
cd /home/px2/envdm/tomcat7
[root@harbor tomcat7]#
docker build -t yi/centos7-tomcat7 .
[root@harbor tomcat7]#
cd /home/px2/envdm/
[root@harbor envdm]#
docker-compose build
//
此步执行的时间较长
查看现有镜像。
[root@harbor ~]#
docker image ls
REPOSITORY | TAG | IMAGE ID | CREATED | SIZE |
envdm_kibana | latest |
42ace969f30d
| 11 days ago | 1.32GB |
envdm_tengine | latest | 3e8f45690cf6 |
13 days ago
|
1.05GB
|
envdm_kafka
| latest |
b4ad1eb9c48f
|
2 weeks ago
|
1.06GB
|
envdm_rabbitmq
|
latest
|
49a996ed2cf8
|
2 weeks ago
|
1.9GB
|
yi/centos7-tomcat7
|
latest
|
8563749eeab9
|
3 weeks ago
|
1.12GB
|
yi/centos7-jdk8u171
|
latest
|
04711511895d
|
3 weeks ago
|
1.02GB
|
goharbor/chartmuseum-photon
|
v1.10.2
|
f7233c953dd9
|
6 weeks ago
|
127MB
|
goharbor/harbor-migrator
|
v1.10.2
|
42527a4df778
|
6 weeks ago
|
362MB
|
goharbor/redis-photon
|
v1.10.2
|
6d87eab10d9f
|
6 weeks ago
|
115MB
|
(3)给生成的镜像打标签
大觅网本地基础镜像为了方便上传到本地
Harbor
仓库中,给这些基础镜像打标签。
[root@harbor ~]#
docker tag envdm_elasticsearch 127.0.0.1/base/elasticsearch
[root@harbor ~]#
docker tag envdm_redis 127.0.0.1/base/redis
[root@harbor ~]#
docker tag envdm_logstash 127.0.0.1/base/logstash
[root@harbor ~]#
docker tag envdm_kibana 127.0.0.1/base/kibana
[root@harbor ~]#
docker tag envdm_kafka 127.0.0.1/base/kafka
[root@harbor ~]#
docker tag envdm_nexus 127.0.0.1/base/nexus
[root@harbor ~]#
docker tag envdm_mysql 127.0.0.1/base/mysql
[root@harbor ~]#
docker tag envdm_sonar 127.0.0.1/base/sonar
[root@harbor ~]#
docker tag envdm_rabbitmq 127.0.0.1/base/rabbitmq
[root@harbor ~]#
docker tag envdm_mycat 127.0.0.1/base/mycat
[root@harbor ~]#
docker tag envdm_tengine 127.0.0.1/base/tengine
(4)上传镜像到 Harbor 通过 docker push 命令将打好标签的镜像上传到 Harbor 仓库中。
[root@harbor ~]#
docker login -u admin -p Harbor12345 http://127.0.0.1
[root@harbor ~]#
docker push 127.0.0.1/base/elasticsearch
[root@harbor ~]#
docker push 127.0.0.1/base/redis
[root@harbor ~]#
docker push 127.0.0.1/base/logstash
[root@harbor ~]#
docker push 127.0.0.1/base/kibana
[root@harbor ~]#
docker push 127.0.0.1/base/kafka
[root@harbor ~]#
docker push 127.0.0.1/base/nexus
[root@harbor ~]#
docker push 127.0.0.1/base/mysql
[root@harbor ~]#
docker push 127.0.0.1/base/sonar
[root@harbor ~]#
docker push 127.0.0.1/base/rabbitmq
[root@harbor ~]#
docker push 127.0.0.1/base/mycat
[root@harbor ~]#
docker push 127.0.0.1/base/tengine
(5)Harbor 仓库 base 项目内镜像查看浏览器打开 Harbor Web 页面 http://192.168.9.20,单击“base”项目,如图 4.8 所示。
图
4.8 Harbor
项目
base
单击“
base
”项目链接,进入“
base
”项目概要,选择概要选项卡右侧的“镜像仓库”
选项,显示
base
下所有镜像的列表,如图
4.9
所示。
图
4.9 base
项目下镜像列表
4.2.4 Jenkins 搭建
本章
Jenkins
的部署是通过
Tomcat
配合
war
包实现的。
Jenkins
启动后需要进行各种
配置,包括基础配置、插件安装、系统配置及全局工具配置。
Jenkins
相关操作都在
Jenkins
虚拟机节点上进行。
1. 部署 Jenkins
上传发布包内如下
Jenkins
安装相关软件包到
Jenkins
虚拟机节点上。
“大觅网
\base
镜像包
\tomcat7\apache-tomcat-7.0.85.tar.gz
”
“大觅网
\base
镜像包
\jdk8u171\jdk-8u171-linux-x64.tar.gz
”
“大觅网
\base
镜像包
\Jenkins\apache-maven-3.6.0-bin.tar.gz
”
具体的安装过程如下所示。
[root@jenkins ~]#
tar zxf apache-tomcat-7.0.85.tar.gz -C /usr/local
[root@jenkins ~]#
mv /usr/local/apache-tomcat-7.0.85 /usr/local/tomcat
将发布包内“大觅网
\base
镜像包
\Jenkins\jenkins.war
”上传到
Jenkins
虚拟机节点的
/usr/local/tomcat/webapps/
目录下。
大觅网项目都是基于
Java
程序,并使用
Maven
方式编译构建的,所以需要安装
Maven
和
JDK
程序包。安装过程如下所示。
[root@jenkins ~]#
tar zxf apache-maven-3.6.0-bin.tar.gz
[root@jenkins ~]#
mv apache-maven-3.6.0 /usr/local/maven
[root@jenkins ~]#
tar zxf jdk-8u171-linux-x64.tar.gz
[root@jenkins ~]#
mv jdk1.8.0_171 /usr/local/java
[root@jenkins ~]#
vim /etc/profile
//
尾部追加如下内容
export JAVA_HOME=/usr/local/java
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=/usr/local/maven/bin:$PATH
[root@jenkins ~]#
source /etc/profile
启动
Jenkins
服务。
[root@jenkins ~]#
cd /usr/local/tomcat/bin/
[root@jenkins bin]#
sh startup.sh
Using CATALINA_BASE:
/usr/local/tomcat
Using CATALINA_HOME:
/usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:
/usr/local/java
Using CLASSPATH:
/usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
Jenkins
虚拟机上也需要安装
Docker
环境。安装步骤如下所示。
[root@jenkins ~]#
yum install -y yum-utils device-mapper-persistent-data lvm2
[root@jenkins
~]#
yum-config-manager
--add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@jenkins ~]#
yum makecache fast
[root@jenkins ~]#
yum -y install docker-ce
[root@jenkins ~]#
mkidr /etc/docker
[root@jenkins ~]#
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
]
}
[root@jenkins ~]#
systemctl start docker && systemctl enable docker
如果在
Docker
使用过程中出现如下警告信息:
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
请添加如下内核配置参数以启用这些功能。
[root@jenkins ~]#
tee -a /etc/sysctl.conf <<-EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
[root@jenkins ~]#
sysctl -p
通过
Jenkins
编译构建大觅网项目时,仍然需要
JDK
和
SSH
镜像的支持,所以在
Jenkins
虚拟机节点上同样需要生成“
yi/centos7-jdk8u171
”和“
yi/centos7-ssh
”这两个镜
像 。 发 布 包 “ 大 觅 网
\base
镜 像 包 ” 路 径 下 , 上 传
ssh
和
jdk8u171
两 个 目 录 到
/home/px2/envdm
。
[root@jenkins ~]#
mkdir -p /home/px2/envdm/
[root@jenkins ~]#
docker pull centos:7
[root@jenkins ~]#
cd /home/px2/envdm/ssh/
[root@jenkins ssh]#
docker build -t yi/centos7-ssh .
[root@jenkins ssh]#
cd /home/px2/envdm/jdk8u171
[root@jenkins jdk8u171]#
docker build -t yi/centos7-jdk8u171 .
2. Jenkins 基础配置
通过浏览器访问
URL
地址
http://192.168.9.30:8080/jenkins
,打开
Jenkins
配置向导,
如图 4.10 所示。
图
4.10
首次访问
Jenkins
页面
查看
Jenkins
登录密码文件。
[root@jenkins ~]#
cat /root/.jenkins/secrets/initialAdminPassword
476b4f82934b427db5f90b09a3bd7537
输入初始密码,单击“继续”按钮,进入
Jenkins
自定义安装界面。然后单击“安装推
荐的插件”按钮,安装一些常用的插件,如图
4.11
所示。因为
Jenkins
的插件安装源是在
国外,所以安装较慢,所需时间稍长。
图 4.11 Jenkins 插件安装选择界面
推荐插件安装完成后,创建
Jenkins
管理员用户,用户名和密码参考案例环境表
4-2
内
的值,如图
4.12
所示。
图 4.12 Jenkins 创建
admin
用户界面
保存后,
Jenkins
基础配置完成。
3. Jenkins 插件安装
现有大觅网业务是通过
Maven
编译构建的,要对
Maven
进行支持,需要安装一些插件。
单击“系统管理”
->
“插件管理”
->
“可选插件”选项卡,然后在右上角搜索框内分别搜索
maven
、
ssh
和
git
,需要安装的插件包括:
Maven Artifact ChoiceListProvider (Nexus)
Maven Metadata Plugin for Jenkins CI server
Maven Integration
Publish Over SSH
SSH
Git Plugin
Pipeline
勾选对应的插件后,分别单击“直接安装”按钮,等待插件完成安装。如图
4.13
所示。
图 4.13 插件安装完成界面
如果出现插件安装失败的情况,请参考大觅网之基础环境部署配置
Nginx
反向代理容
器跳转到清华
Jenkins
源。如果出现无法找到对应的插件名称,请到“已安装”选项卡内查
看是否已被安装好,如果已被安装好了就可以进行后续的插件安装。
4. Jenkins 系统配置
使用
Jenkins
将大觅网业务项目发布到
K8S
上,需要设置通过
SSH
连接远程服务器。
单击“系统管理”
->
“系统配置”,进入界面后下拉到“
Publish over SSH
”模块。单击“新
增”按钮,输入远程服务器的别名、连接地址、用户名、远程连接目录后。单击“高级”按
钮,勾选“
Use password authentication
,
or use a different key
”验证选项,输入
k8s-master
服务器远程登录密码。同时需要在
k8s-master
虚拟机上面创建目录
/data/dmw
,如图
4.14
所示。
图 4.14 Jenkins 远程连接配置
其中
Name
值为
192.168.9.40
,
Hostname
为远程主机的
IP
地址,
Username
为
“
Hostname
”配置
IP
地址的登录用户,
Remote Directory
为远程主机上的目录,如果不存
在则需要新创建。单击下方“
Test Configuration
”按钮,显示
Success
代表连接成功,最
后单击左下角的“保存”退出。如图
4.15
所示。
图 4.15 Jenkins 系统配置测试及保存
5. Jenkins 全局工具配置
单击“系统管理”
->
“全局工具配置”,对
Maven
进行配置,如图
4.16
所示。
图 4.16 设置
Maven
配置文件地址
“默认
settings
提供”和“默认全局
settings
提供”都选择“文件系统中的
settings
文
件”,“
File path
”都填写“
/root/.m2/settings.xml
”。
在
Maven
模块,单击“新增
Maven
”,配置
Maven
相关内容,如图
4.17
所示。
图 4.17 配置
Maven
目录
取消自动安装,“
Name
”可以自定义,“
MAVEN_HOME
”为“
/usr/local/maven
”。
在
JDK
模块,单击“新增
JDK
”,对
JDK
进行配置,如图
4.18
所示。
图 4.18 配置
JDK
目录
取消自动安装,“
Name
”可以自定义,“
JAVA_HOME
”的值为“
/usr/local/java
”。
最后,单击左下角“保存”退出。
6. 凭据的创建
“凭据”的作用是
Jenkins
在拉取
Gitlab
项目代码时,提供身份认证功能。如果没有配
置 “凭据” 或者配置的不对,就会出现报错,最终导致拉取不到
Gitlab
项目。在
Jenkins
首页左侧菜单栏中单击“凭据”后,出现如图
4.19
所示凭据默认页。
图 4.19 凭据默认页
单击中间的“全局”,进入全局凭据页面,如图
4.20
所示。
图 4.20 全局凭据页面
本案例使用全局凭据对业务项目进行验证。单击左侧菜单栏的“添加凭据”链接,进入
添加新凭据页面,如图
4.21
所示。
图 4.21 凭据的创建
此处“类型”选用默认的“
Username with password
”,“范围”选择“全局”,“用
户名”和“密码”填写访问
Gitlab
仓库的权限,可参考案例环境中的权限表格。“
ID
”是
通过任务或配置定义的内部唯一
ID
,默认留空即可,在创建的过程中会自动生成。“描述”
内填写凭据的具体用途,是一种备注说明。填写完成后,单击“确定”按钮完成凭据的创建。
4.2.5 Kubernetes 搭建
大觅网的基础服务和业务服务最终都是发布到
K8S
环境中,就需要提前部署好
K8S
环
境。本章
K8S
环境采用一台
Master
两台
Node
的方式部署。如果无特殊说明,相关操作都
是在
k8s-master
上进行的。
1. 关闭交换分区
K8S
的部署需要
Master
和
Node
节点都关闭交换分区。关闭命令如下所示。
[root@k8s-master ~]#
swapoff -a
[root@k8s-master ~]#
sed -i '/swap/s/^/#/' /etc/fstab
2. 安装 Docker
K8S
依托于
Docker
容器技术,
Docker
环境是必不可少的,需要在
Master
和所有
Node
虚拟机节点上面安装
Docker
程序。下面以
k8s-master
上安装为例,具体的安装步骤如下
所示。
[root@k8s-master ~]#
yum install -y yum-utils device-mapper-persistent-data lvm2
[root@k8s-master
~]#
yum-config-manager
--add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@k8s-master ~]#
yum makecache fast
[root@k8s-master ~]#
yum -y install docker-ce
[root@k8s-master ~]#
mkdir /etc/docker
[root@k8s-master ~]#
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
]
}
[root@k8s-master ~]#
systemctl start docker && systemctl enable docker
如果在
Docker
使用过程中出现如下警告信息:
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
请添加如下内核配置参数以启用这些功能。
[root@k8s-master ~]#
tee -a /etc/sysctl.conf <<-EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
[root@k8s-master ~]#
sysctl -p
3. 修改私有仓库默认访问方式
Master
和
Node
还需要远程访问
Harbor
私有仓库,采用
HTTP
方式访问,但是
Docker
默认访问镜像仓库是
HTTPS
方式,在执行过程中势必会报错。所以这里将
Docker
访问私
有仓库的方式改为
HTTP
。
Master
、
Node
和
Jenkins
节点都需要执行。以
k8s-master
为例,
具体执行步骤如下所示。
[root@k8s-master ~]#
vim /usr/lib/systemd/system/docker.service
//
省略部分内容
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
--insecure-registry
192.168.9.20
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
//
省略部分内容
[root@k8s-master ~]#
systemctl daemon-reload
[root@k8s-master ~]#
systemctl restart docker
4. 安装 K8S
本章采用
Kubeadm
方式部署
K8S
。
(1)配置 K8S YUM 源
Master
和两台
Node
共三台虚拟机都需要配置。
[root@k8s-master ~]#
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
(2)YUM 安装 K8S
三台虚拟机都需要执行。
[root@k8s-master ~]#
yum install -y kubelet-1.18.2 kubeadm-1.18.2 kubectl-1.18.2
[root@k8s-master ~]#
systemctl enable kubelet
(3)拉取基础镜像
在
k8s-master
上执行。
[root@k8s-master ~]#
kubeadm config images list --kubernetes-version=1.18.2
W0509 08:50:22.512171
11722 configset.go:202] WARNING: kubeadm cannot validate
component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
k8s.gcr.io/kube-apiserver:v1.18.2
k8s.gcr.io/kube-controller-manager:v1.18.2
k8s.gcr.io/kube-scheduler:v1.18.2
k8s.gcr.io/kube-proxy:v1.18.2
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.7
[root@k8s-master ~]#
vim k8s_pull_image.sh
//
编辑创建镜像拉取脚本
#!/bin/bash
K8S_VERSION=v1.18.2
//
脚本内这些变量信息根据上面命令的输出适当调整
ETCD_VERSION=3.4.3-0
PAUSE_VERSION=3.2
coredns_version=1.6.7
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:$K8S_VERSION
docker
pull
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:$K8S_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:$K8S_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:$K8S_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$coredns_version
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:$K8S_VERSION
k8s.gcr.io/kube-apiserver:$K8S_VERSION
docker
tag
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:$K8S_VERSION
k8s.gcr.io/kube-controller-manager:$K8S_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:$K8S_VERSION
k8s.gcr.io/kube-scheduler:$K8S_VERSION
docker tag
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:$K8S_VERSION
k8s.gcr.io/kube-proxy:$K8S_VERSION
docker
tag
registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION
k8s.gcr.io/etcd:$ETCD_VERSION
docker
tag
registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
k8s.gcr.io/pause:$PAUSE_VERSION
docker
tag
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$coredns_version
k8s.gcr.io/coredns:$coredns_version
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:$K8S_VERSION
docker
rmi
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:$K8S_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:$K8S_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:$K8S_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$coredns_version
[root@k8s-master ~]#
chmod +x k8s_pull_image.sh
[root@k8s-master ~]#
./k8s_pull_image.sh
[root@k8s-master ~]#
docker image ls
REPOSITORY | TAG | IMAGE ID |
CREATED
| SIZE |
kubernetesui/dashboard | v2.0.0 | 8b32422733b3 |
2 weeks
ago
| 222MB |
k8s.gcr.io/kube-proxy | v1.18.2 | 0d40868643c6 |
3 weeks
ago
| 117MB |
k8s.gcr.io/kube-apiserver | v1.18.2 | 6ed75ad404bd |
3 weeks
ago
| 173MB |
k8s.gcr.io/kube-scheduler | v1.18.2 | a3099161e137 |
3 weeks
ago
| 95.3MB |
Master 节点脚本执行完成后,在 k8s-node1 和 k8s-node2 上面也需要执行脚本
k8s_pull_image.sh
拉取镜像。
(4)初始化 K8S
在
k8s-master
上执行。
[root@k8s-master
~]#
kubeadm
init
--kubernetes-version=v1.18.2
--pod-network-cidr=10.244.0.0/16
//
初始化操作
//
省略部分内容
[bootstrap-token] Using token: ymfx0p.b48y7o87ycjo7r38
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for
nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve
CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in
the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
其它部分省略
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.9.40:6443 --token ymfx0p.b48y7o87ycjo7r38 \
--discovery-token-ca-cert-hash
sha256:f15c29ae3034a505c1308bd075fa56f9a9a57b01d4f03110af5fb740832195e2
[root@k8s-master ~]#
mkdir -p $HOME/.kube
[root@k8s-master ~]#
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master ~]#
chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s-master ~]#
kubectl get nodes
NAME
STATUS
ROLES
AGE
VERSION
k8s-master
NotReady
master
30s
v1.18.2
(5)Node 节点加入集群
在
k8s-node
节上执行。
[root@k8s-node01 ~]#
kubeadm join 192.168.9.40:6443 --token ymfx0p.b48y7o87ycjo7r38
--discovery-token-ca-cert-hash
sha256:f15c29ae3034a505c1308bd075fa56f9a9a57b01d4f03110af5fb740832195e2
[root@k8s-node02 ~]#
kubeadm join 192.168.9.40:6443 --token ymfx0p.b48y7o87ycjo7r38
--discovery-token-ca-cert-hash
sha256:f15c29ae3034a505c1308bd075fa56f9a9a57b01d4f03110af5fb740832195e2
(6)配置 K8S 网络
在
k8s-master
上执行。
[root@k8s-master
~]#
wget
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
//
若下载失败可直接使用发布包内“大觅网
\K8S
”对应的网络文件
kube-flannel.yml
[root@k8s ~]#
sed -i 's@quay.io@quay-mirror.qiniu.com@g' kube-flannel.yml
[root@k8s ~]#
kubectl apply -f kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds-amd64 created
daemonset.apps/kube-flannel-ds-arm64 created
daemonset.apps/kube-flannel-ds-arm created
daemonset.apps/kube-flannel-ds-ppc64le created
daemonset.apps/kube-flannel-ds-s390x created
[root@k8s-master ~]#
kubectl get nodes -o wide
NAME | STATUS | ROLES | AGE | VERSION | INTERNAL-IP | EXTERNAL-IP | OS-IMAGE | KERNEL-VERSION | CONTAINER-RUNTIME |
k8s-master | Ready | master | 78m | v1.18.2 | 192.168.9.40 | <none> |
CentOS
Linux 7 (Core)
| 3.10.0-514.el7.x86_64 | |
k8s-node1 | Ready | <none> | 73m | v1.18.2 | 192.168.9.50 | <none> |
CentOS
Linux 7 (Core)
|
3.10.0-514.el7.x86_64
| |
k8s-node2 | Ready | <none> | 73m | v1.18.2 | 192.168.9.60 | <none> |
CentOS
Linux 7 (Core)
|
3.10.0-514.el7.x86_64
|
(7)查看集群状态
在
k8s-master
上执行。
[root@k8s-master ~]#
kubectl get pods -o wide -n kube-system
NAME | READY | STATUS | RESTARTS | AGE | IP | NODE | NOMINATED NODE | READINESS GATES |
coredns-66bff467f8-9w4dz | 1/1 | Running | 0 | 77m | 10.244.0.2 | k8s-master | <none> | <none> |
coredns-66bff467f8-h2nsk | 1/1 | Running | 0 | 77m | 10.244.0.3 | k8s-master | <none> | <none> |
etcd-k8s-master | 1/1 | Running | 0 | 78m | 10.244.9.40 | k8s-master | <none> | <none> |
kube-apiserver-k8s-master
| 1/1 | Running | 0 | 78m | 10.244.9.40 | k8s-master | <none> | <none> |
kube-controller-manager-k8s-master | 1/1 | Running | 0 | 78m | 10.244.9.40 | k8s-master | <none> | <none> |
4.2.6 Base 基础服务发布
之前在
Harbor
虚拟机节点上已经编译生成了基础的
Docker
镜像并上传到了
Harbor
仓
库内,这些基础镜像的启动发布是在
k8s-master
虚拟机节点上完成的,镜像的拉取是从
Harbor
下载的。
1. 上传 yaml 文件
K8S
使用
yaml
文件发布应用。大觅网基础服务的
yaml
文件在发布包内“大觅网
\K8S\base
”目录下,将该目录下的
yaml
文件上传到
k8s-master
的
/root/base
目录下,若
没有该目录则需要手动创建。
2. 发布 Redis
通常发布应用都是使用
kubectl
命令,它是一个命令行接口,用于对
K8S
集群运行命
令。
kubectl
在命令执行时会到
$HOME/.kube
目录中寻找一个名为
config
的文件,用于证
书相关验证。
Redis
服务的发布需要
Deployment
和
Service
文件,
Deployment
文件的内
容如下所示。
[root@k8s-master ~]#
cd /root/base
[root@k8s-master ~]#
cat redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
//
类型
metadata:
name: redis
//
名字
labels:
app: redis
//
标签
spec:
replicas: 1
//
副本数量
selector:
matchLabels:
app: redis
template:
//
模板
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: 192.168.9.20/base/redis:latest
//harbor
仓库中
redis
基础镜像地址
imagePullPolicy: IfNotPresent
//
镜像拉取策略
ports:
- containerPort: 6379
resources:
limits:
//
资源限制策略
cpu: 150m
memory: 300Mi
requests:
cpu: 100m
memory: 100Mi
Redis
对应的
Service
文件内容如下所示。
[root@k8s-master ~]#
cat redis-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-redis
labels:
app: svc-redis
spec:
ports:
- port: 6379
selector:
app: redis
Redis
服务发布通过“
kubectl create
”命令实现,包括使用
Deployment
文件创建对应
Pod
以及使用
Service
文件创建对应的
Service
。具体命令如下所示。
[root@k8s-master base]#
docker login -u admin -p Harbor12345 http://192.168.9.20
//master
和
node
节点都需要执行登录到
Harbor
仓库
[root@k8s-master base]#
kubectl create -f redis-deployment.yaml
deployment.apps/redis created
[root@k8s-master base]#
kubectl create -f redis-svc.yaml
service/svc-redis created
大觅网的基础服务
Redis
已经发布完成,可以通过如下命令查看
Redis
的
Pod
和
Service
。
[root@k8s-master ~]#
kubectl get pods -o wide
NAME
READY
STATUS
RESTARTS
AGE
IP
NODE
NOMINATED NODE
READINESS GATES
redis-78bff58c7b-lbbzv
1/1
Running
0
8d
10.244.1.86
k8s-node01
<none>
<none>
[root@k8s-master ~]#
kubectl get svc -o wide
NAME
TYPE
CLUSTER-IP
EXTERNAL-IP
PORT(S)
AGE
SELECTOR
svc-redis
ClusterIP
10.102.106.12
<none>
6379/TCP
8d
app=redis
K8S
集群在发布服务时,默认使用
ClusterIP
,通过集群的内部
IP
暴露服务,这种模式
只能够在集群内部访问服务。如果需要将服务暴露到集群外部,可以使用
NodePort
模式,
该模式可以在集群外部通过
<NodeIP>:<NodePort>
访问集群内部服务。
上面
Redis
的
Service
配置文件,显示其属于
ClusterIP
模式发布的服务。大觅网的基
础服务中,除了
Redis
之外,使用
ClusterIP
模式发布的还包括如下服务。
[root@k8s-master ~]#
kubectl create -f elastic-deployment.yaml
[root@k8s-master ~]#
kubectl create -f elastic-svc.yaml
[root@k8s-master ~]#
kubectl create -f kafka-deployment.yaml
[root@k8s-master ~]#
kubectl create -f kafka-svc.yaml
[root@k8s-master ~]#
kubectl create -f kibana-deployment.yaml
[root@k8s-master ~]#
kubectl create -f kibana-svc.yaml
还有几个服务是需要将端口映射到外部的,在
Service
的
yaml
配置文件内是带
NodePort
的配置项的,比如下面的
RabbitMQ
服务。
[root@k8s-master ~]#
cat rabbitmq-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-rabbitmq
labels:
app: svc-rabbitmq
spec:
type: NodePort
ports:
- port: 5672
name: http-5672
targetPort: 5672
nodePort: 30000
//NodePort
方式暴露端口到集群外部
- port: 15672
name: http-15672
targetPort: 15672
nodePort: 30001
selector:
app: rabbitmq
需要暴露端口的是
RabbitMQ
和
Tengine
服务,发布命令如下所示。
[root@k8s-master ~]#
kubectl create -f rabbitmq-deployment.yaml
[root@k8s-master ~]#
kubectl create -f rabbitmq-svc.yaml
[root@k8s-master ~]#
kubectl create -f tengine-deployment.yaml
[root@k8s-master ~]#
kubectl create -f tengine-svc.yaml
3. 发布 Nexus
Nexus
是大觅网项目编译构建时的私服仓库,因为需要往
Nexus
中上传
Alipay
和
Jms
相关软件包,所以
Nexus
的
8081
端口需要通过
NodePort
方式暴露出去,方便在集群外部
访问,从而上传软件包。
Nexus
私服仓库的发布命令如下所示。
[root@k8s-master ~]#
kubectl create -f nexus-deployment.yaml
[root@k8s-master ~]#
kubectl create -f nexus-svc.yaml
在集群外部本地浏览器中访问
http://192.168.9.40:30081
,如图
4.22
所示
图 4.22 Nexus 私服仓库
Web
页面
单击右上角的“
Log In
”,默认用户名密码为“
admin/admin123
”,登录后进入
Nexus
,
如图 4.23 所示。
图
4.23 Nexus
登录界面
Nexus
私服仓库需要手动上传
Alipay
和
Jms
相关包。这两个程序在发布包的路径为“大
觅网
\
大觅私服
nexus
手动上传包”目录下。上传的过程如下:
进入主界面后,单击左侧菜单栏的“
Repositories
”,如图
4.24
所示。
图 4.24 Nexus 仓库界面
以
Alipay
包上传为例,在中间的仓库区域找到“
3rd party
”,左键单击“
3rd party
”,
在下方各属性的最右侧单击的“
Artifact Upload
”选项。“
GAV Definition
”选择“
From POM
”,
下方“
POM Filename
”通过“
Select POM to Upload
”选择对应的
pom
文件,该文件在发
布 包 内 的 路 径 为 : 大 觅 网
\
大 觅 私 服
nexus
手 动 上 传 包
\cn\itrip\alipay\itrip-alipay-pc\1.0\itrip-alipay-pc-1.0.pom
。另外,“
Select Artifact
(
s
)
for
Upload
”下的“
Filename
”选择对应的
itrip-alipay-pc-1.0.jar
,该
jar
包跟上面
pom
文件在
同目录下。如图
4.25
所示
图 4.25 上传包到
Nexus
此处有个地方容易被忽略,从而导致上传失败,如图
4.26
所示。
图 4.26 添加
Artifact
Jar
文件选择完成后,一定要单击下左侧的“
Add Artifact
”按钮,将文件送入“
Artifacts
”
方框内。如图
4.27
所示。
图 4.27 Artifacts 选入
最后单击最下方的“
Upload Artifact(s)
”进行上传。
另一个
jms
包上传方法跟
Alipay
包方法一样。
pom
和
jar
文件在发布包的路径为:大
觅网
\
大觅私服
nexus
手动上传包
\javax\jms\jms\1.1
。这两个文件分别为:
jms-1.1.pom
和
jms-1.1.jar
。添加完文件后,单击最下方的“
Upload Artifact(s)
”上传。
4. 发布 MySQL
MySQL
需要存储多个数据库,为避免
Pod
切换或重建导致的数据不可用问题,这里使
用
PV
(
PersistentVolume
) 来 定 义 存 储 空 间 , 从 而 保 证 数 据 一 直 可 用 。 而
PVC
(
PersistentVolumeClaim
)作为用户对存储资源的需求申请。关于
MySQL
的
PV
以及
PVC
的定义如下所示。
[root@k8s-master base]#
cat mysql-pv.yaml
apiVersion: v1
kind: PersistentVolume
//
永久存储卷类型
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 3Gi
//
存储空间大小
accessModes:
- ReadWriteOnce //
访问模式
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim //
永久存储卷声明
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
MySQL Deployment
和
Service
的定义文件如下所示。
[root@k8s-master base]#
cat mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: 192.168.9.20/base/mysql:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-persistent-storage
mountPath: /usr/local/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
[root@k8s-master base]#
cat mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-mysql
labels:
app: svc-mysql
spec:
type: NodePort
ports:
- port: 3306
targetPort: 3306
nodePort: 30306
selector:
app: mysql
MySQL 服务的发布,需要先创建
PV
,之后再发布
MySQL
。具体操作如下所示。
[root@k8s-master ~]#
kubectl create -f mysql-pv.yaml
[root@k8s-master ~]#
kubectl get pv
NAME
CAPACITY
ACCESS MODES
RECLAIM POLICY
STATUS
CLAIM
STORAGECLASS
REASON
AGE
mysql-pv-volume
3Gi
RWO
Retain
Bound
default/mysql-pv-claim
manual
20d
[root@k8s-master ~]#
kubectl get pvc
NAME
STATUS
VOLUME
CAPACITY
ACCESS MODES
STORAGECLASS
AGE
mysql-pv-claim
Bound
mysql-pv-volume
3Gi
RWO
manual
20d
[root@k8s-master ~]#
kubectl create -f mysql-deployment.yaml
[root@k8s-master ~]#
kubectl create -f mysql-svc.yaml
[root@k8s-master ~]#
kubectl get pods -o wide
NAME
READY
STATUS
RESTARTS
AGE
IP
NODE
NOMINATED NODE
READINESS GATES
mysql-865d49d898-tkd6w
1/1
Running
5
8d
10.244.2.252
k8s-node2
<none>
<none>
[root@k8s-master ~]#
kubectl get svc -o wide
NAME
TYPE
CLUSTER-IP
EXTERNAL-IP
PORT(S)
AGE
SELECTOR
svc-mysql
NodePort
10.100.90.129
<none>
3306:3306/TCP
8d
app=mysql
上面命令显示
MySQL
运行在
k8s-node2
节点上。到
k8s-node2
节点,上传发布包内
“大觅网
-
优化
\K8S\mysql_data.tgz
”文件到
/mnt/data
目录下,该上传文件是
MySQL
初始
文件。同时在
k8s-node2
上还需要执行如下操作。
[root@k8s-node2 ~]#
cd /mnt/data && tar zxf mysql_data.tgz
[root@k8s-node2 ~]#
useradd mysql
[root@k8s-node2 ~]#
chown -R mysql:mysql /mnt/data
MySQL
服务发布完成后,给
root
用户设置密码并且配置远程访问用户。这里
MySQL
发布到单
Pod
,可以使用“
kubectl exec
”方式连接到
MySQL
进行设置。具体操作如下所
示。
[root@k8s-master ~]#
kubectl exec -it mysql-865d49d898-tkd6w -- bash
//pod
名根据自己的进
行修改
[root@mysql-865d49d898-tkd6w mysql]#
mysql -uroot -p
//
输入回车
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 42
Server version: 5.6.38 MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql>
update user set password=password("123456") where user='root';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4 Changed: 4 Warnings: 0
mysql>
grant all privileges on *.* to root@'%' identified by '123456' with grant option;
Query OK, 0 rows affected (0.00 sec)
mysql>
exit
Bye
[root@mysql-865d49d898-tkd6w mysql]#
exit
exit
MySQL
服务通过
NodePort
将
30306
端口暴露到了集群外部,所以可以使用“
Navicat
for MySQL
”工具远程连接数据库,进行创建数据库、导入数据等操作。在发布包内
“
\software\Navicat for MySQL
”目录下,双击“
navicat_trial_11.1.20.0.1449226634.exe
”
安装
Navicat for MySQL
工具。安装完成后,双击“
PatchNavicat.exe
”对其进行破解打补
丁。安装和破解完成后,通过
Navicat for MySQL
工具连接到上面创建的
MySQL
中,如图
4.28 所示。
图 4.28 远程连接
MySQL
容器
在新建的连接上,右键“打开连接”,再右键“新建数据库”。设置“数据库名”为
dm_base
,“字符集”为
utf8
,“排序规则”为
utf8_general_ci
,最后单击“确定”按钮
完成数据库的创建,如图
4.29
所示。
图 4.29 创建
dm_base
数据库
在刚创建的数据库“
dm_base
”上,首先右键“打开数据库”,然后右键选择“运行
SQL
文件”,选择要导入的
SQL
表结构文件
dm_base.sql
,之后单击“开始”按钮进行导
入。导入的大觅网
SQL
文件内包含表结构和初始数据。这些
SQL
文件在提供的发布包内路
径为“大觅网
\
数据库结构
\
大觅网数据库脚本”,具体操作如图
4.30
所示。
图 4.30 导入
SQL
文件到库内
导入完成后,会有“
finished
”和“
successfully
”字符提示。如图
4.31
所示。
图 4.31 数据库导入成功提示
大觅网所需要的数据库包括:
dm_base
、
dm_item
、
dm_pay
、
dm_scheduler
、
dm_user
、
dm_order
、
dm_order1
、
dm_order2
、
dm_order3
、
dm_zipkin
,其他的数据库也需要仿照
dm_base
进行创建和导入。完成后如图
4.32
所示。
图 4.32 数据库完成导入
5. 查看基础镜像发布情况
大觅网的基础镜像都发布完成后,可查看基础服务的
Pod
及对应
Service
情况。操作
命令如下所示。
[root@k8s-master base]#
kubectl get pods -o wide
NAME | READY | STATUS | RESTARTS | AGE | IP | NODE | NOMINATED NODE | READINESS GATES |
elasticsearch-7f6fb5c6b5-g2fh5 | 1/1 | Running | 6 | 8d | 10.244.1.96 | k8s-node01 | <none> | <none> |
kafka-86969f8c5d-mpbvf | 1/1 | Running | 6 | 8d | 10.244.1.85 | k8s-node01 | <none> | <none> |
kibana-68df6fffbc-7rrxr
| 1/1 | Running | 6 | 8d |
10.244.1.93
|
k8s-node01
| <none> | <none> |
mysql-865d49d898-tkd6w
|
1/1
|
Running
|
5
|
8d
|
10.244.2.252
|
k8s-node02
|
<none>
|
<none>
|
nexus-86db5b87dc-jswsf
|
1/1
|
Running
|
6
|
8d
|
10.244.1.94
|
k8s-node01
|
<none>
|
<none>
|
rabbitmq-6d6488987d-sbkqv
|
1/1
|
Running
|
6
|
8d
|
10.244.1.95
|
k8s-node01
|
<none>
|
<none>
|
[root@k8s-master base]# kubectl get svc -o wide
NAME | TYPE | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE | SELECTOR |
kubernetes | ClusterIP | 10.96.0.1 | <none> | 443/TCP | 24d | <none> |
svc-elasticsearch | ClusterIP | 10.100.165.71 | <none> | 9200/TCP,9300/TCP | 8d | app=elasticsearch |
svc-kafka | ClusterIP | 10.102.175.142 | 9092/TCP | 9092/TCP | 8d | app=kafka |
svc-kibana | ClusterIP | 10.109.220.220 | <none> | 5601/TCP | 8d | app=kibana |
svc-mysql | NodePort | 10.100.90.129 | <none> | 3306:3306/TCP | 8d | app=mysql |
svc-nexus | NodePort | 10.110.181.34 | <none> | 8081:8081/TCP | 8d | app=nexus |
在基础镜像发布的过程中,简化了部分操作,比如 Sonar、Mycat 等都没有启动,这些
服务不影响大觅网的启动,适当做了精简。
4.2.7 大觅网业务服务发布
完成了
base
基础镜像的构建和发布,接着进行大觅网业务项目的发布。
1. pipeline-common 项目构建
common
项目属于基础项目,其包含若干子项目,该项目存在的目的就是在
Jenkins
构建时将生成的包文件上传到私有仓库
Nexus
内,以供后续项目编译构建使用。
在构建
common
项目之前需确保在
Jenkins
虚拟机内访问
nexus.local.com
域名指向
Nexus
私有仓库,可在
Jenkins
虚拟机上按如下步骤执行。
[root@jenkins ~]#
vim /etc/hosts
127.0.0.1
nexus.local.com
//
指向本机
127.0.0.1
[root@jenkins ~]#
vim /root/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include
mime.types;
default_type application/octet-stream;
access_log access.log;
error_log
error.log;
sendfile
on;
keepalive_timeout 65;
server {
listen
80;
server_name nexus.local.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass
http://192.168.9.40:30081
; //
反向代理到
k8s-master
的
nexus
}
error_page
500 502 503 504 /50x.html;
location = /50x.html {
root
html;
index index.html index.htm index.jsp index.action default.html;
}
}
}
[root@jenkins ~]#
vim /root/nginx-jenkins-proxy.sh
docker
run
-itd
--restart=always
--name
nginx-jenkins-proxy
-p
80:80
-v
/root/nginx.conf:/etc/nginx/nginx.conf nginx
//Docker
启动命令写入脚本
[root@jenkins ~]#
chmod +x nginx-jenkins-proxy.sh
[root@jenkins ~]#
./nginx-jenkins-proxy.sh
[root@jenkins ~]#
docker ps
CONTAINER ID
IMAGE
COMMAND
CREATED
STATUS
PORTS
NAMES
58ee1fa3964f
nginx
"nginx -g 'daemon of…"
3 weeks ago
Up
20 minutes
0.0.0.0:80->80/tcp
nginx-jenkins-proxy
之所以进行上面域名解析、启动
Nginx
容器相关操作,是因为
common
项目源码程序
内
Nexus
仓库地址配置的是域名
nexus.local.com
,这种方式默认是无法访问到
Nexus
仓
库的。进行了上面的配置后,在
Jenkins
上编译该项目时,解析
nexus.local.com
域名,就
会先到
hosts
内查找对应的
IP
地址,
IP
指向了
127.0.0.1
,在
Nginx
配置文件内又定义跳转
到
Nexus
容器仓库的
30081
端口上,这样就完成
Nexus
仓库的访问。
上述配置完成后,开始在
Jenkins
上创建
pipeline-common
项目。在
Jenkins
首页单击
“新建任务”,项目名称为“
pipeline-common
”,选择“流水线”,然后单击“确定”。
如图
4.33
所示。
图
4.33 pipeline-common
项目的创建
进入
pipeline-common
项目的详细配置页面后,下拉到“
Pipeline
”配置模块,“定义”
选择“
Pipeline script
”,“脚本”内填写流水线构建脚本。如图
4.34
所示。
图
4.34 pipeline-common
项目下
Pipeline
配置模块
Script 内填写流水线构建脚本,具体内容如下。
node {
//
此
node
是从
Git
拉取
common
项目源码
stage('Clone') {
echo "git clone common"
git
credentialsId:
'a7183e0d-90f1-45a5-883b-e216210fff10',
url:
'http://192.168.9.10/root/common.git'
}
}
node {
//
此
node
是编译
dm-common
项目及子项目
stage('Build dm-common') {
echo "begin dm-common"
dir('/root/.jenkins/workspace/pipeline-common/dm-common/') {
//
切换目录
sh 'mvn clean deploy -Dmaven.test.skip=true'
//
通过
maven
编译
dm-common
项目
}
}
stage('Build dm-common-module') {
echo "begin dm-common-module"
dir('/root/.jenkins/workspace/pipeline-common/dm-common/dm-common-module/') {
sh 'mvn clean deploy -Dmaven.test.skip=true'
}
}
stage('Build dm-common-dto') {
echo "begin dm-common-dto"
dir('/root/.jenkins/workspace/pipeline-common/dm-common/dm-common-dto/') {
sh 'mvn clean deploy -Dmaven.test.skip=true'
}
}
stage('Build dm-common-dao') {
echo "begin dm-common-dao"
dir('/root/.jenkins/workspace/pipeline-common/dm-common/dm-common-dao/') {
sh 'mvn clean deploy -Dmaven.test.skip=true'
}
}
stage('Build dm-common-client') {
echo "begin dm-common-client"
dir('/root/.jenkins/workspace/pipeline-common/dm-common/dm-common-client/') {
sh 'mvn clean deploy -Dmaven.test.skip=true'
}
}
stage('Build dm-common-utils') {
echo "begin dm-common-utils"
dir('/root/.jenkins/workspace/pipeline-common/dm-common/dm-common-utils/') {
sh 'mvn clean deploy -Dmaven.test.skip=true'
}
}
stage('Build dm-common-ext-utils') {
echo "begin dm-common-ext-utils"
dir('/root/.jenkins/workspace/pipeline-common/dm-common/dm-common-ext-utils/') {
sh 'mvn clean deploy -Dmaven.test.skip=true'
}
}
}
脚本填写完成后,单击左下角的“保存”按钮,进入
pipeline-common
项目页。
在发布包内提供了流水线脚本,其路径位于“大觅网
\K8S\dmw
”,该目录内还包括了
其他业务项目的流水线脚本。
此外,还需要将
settings.xml
文件上传到
Jenkins
虚拟机内
/root/.m2/
目录下,该文件在
发布包内位于“大觅网
\base
镜像包
\Jenkins
”目录下。将
settings.xml
文件内“
192.168.9.18
”
变更为实验时使用的
IP
地址
192.168.9.40
,端口改为
Nexus
的发布端口
30081
。可通过如
下命令实现。
[root@676bae0eb20a webapps]#
grep 192.168.9 /root/.m2/settings.xml
<url>http://192.168.9.18:8081/content/groups/public/</url>
[root@676bae0eb20a
webapps]#
sed
-i
's/192.168.9.18:8081/192.168.9.40:30081/'
/root/.m2/settings.xml
完成以上内容后,就可以进入项目内开始构建。单击首页的
pipeline-common
项目,
然后单击左侧的“立即构建”,实现代码的编译构建,完成向
Nexus
仓库提交资源包,如
图
4.35
所示。
图 4.35 构建
pipeline-common
项目
项目构建需要较长时间,可以切换到控制台观察输出内容。通过“
Build History
”进入
“
Console Output
”。在图
4.36
中,将鼠标移动到“
#1
”,后面会出现一个下拉三角,单
击三角就会出现如图
4.37
所示情况,选择“
Console Output
”就切换到控制台输出了。
图
4.36
编译历史
图
4.37
进入控制台输出
等编译结束后,会有“
SUCCESS
”提示,如下所示。
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.894 s
[INFO] Finished at: 2020-04-28T23:08:20+08:00
[INFO] ------------------------------------------------------------------------
[Pipeline] }
[Pipeline] // dir
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
切换回编译构建视图界面,查看项目构建完成后结果,如图
4.38
所示。
图 4.38 pipeline-common 项目构建完成
注意:如果在编译
dm-common
项目时提示无法找到
alipay
和
jms
包,可以再次手动
上传一下,之后在进行后续的编译。
至此,
pipeline-common
项目编译构建完成。
2. pipeline-env 项目构建
Pipeline-env
流水线项目包括四个子项目:
dm-config-server
、
dm-discovery-eureka
、
dm-gateway-zuul
、
dm-zipkin-server
。
pipeline-env
项目的编译构建跟上面
pipeline-common
项目类似,只是多了发布到
K8S
的步骤。
在
Jenkins
中新建
pipeline-env
项目。单击“新建任务”,项目名称处填写“
pipeline-env
”,
同样选择“流水线”项目类型,单击“确定”按钮创建该项目。如图
4.39
所示。
图 4.39 Jenkins
创建
pipeline-env
项目
进入
pipeline-env
项目配置页,下拉到
Pipeline
模块,填写流水线脚本,具体的脚本内
容如下所示。
node {
//
下载
env-project
项目源码
stage('Clone ENV') {
echo "Git clone env-project"
git
credentialsId:
'a7183e0d-90f1-45a5-883b-e216210fff10',
url:
'http://192.168.9.10/root/env-project.git'
}
}
node {
stage('Build Discovery') {
echo "Build dm-discovery-eureka"
//
编译
dm-discovery-eureka
子项目
dir('/root/.jenkins/workspace/pipeline-env/dm-discovery-eureka/') {
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('Generate Discovery') {
echo "Generate dm-discovery-eureka mirror"
dir('/root/.jenkins/workspace/pipeline-env/dm-discovery-eureka/') {
sh 'cp Dockerfile discovery-eureka.yaml target' //
拷贝文件到
target
目录下,此操作在
Jenkins workspace
目录内实现
}
dir('/root/.jenkins/workspace/pipeline-env/dm-discovery-eureka/target/') {
sh 'docker build -t 192.168.9.20/dmw/dm-discovery-eureka .'
//
在
k8s-master
上 生 成
Docker
镜像
}
}
stage('Push Discovery') {
echo "Push mirror to Harbor"
//
将生成的镜像上传到
Harbor
仓库
sh "docker login -u admin -p Harbor12345 http://192.168.9.20"
sh "docker push 192.168.9.20/dmw/dm-discovery-eureka "
}
stage('Deploy Discovery') {
echo "Deploy dm-discovery-eureka"
//
通过
kubectl create
命令发布程序到
K8S
sshPublisher(publishers:
[sshPublisherDesc(configName:
'192.168.9.40',
transfers:
[sshTransfer(cleanRemote:
false,
excludes:
'',
execCommand:
'''mkdir
-p
/data/dmw/dm-discovery-eureka
cd /data/dmw/dm-discovery-eureka
kubectl create -f discovery-eureka.yaml''', execTimeout: 120000, flatten: false, makeEmptyDirs:
false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dm-discovery-eureka',
remoteDirectorySDF:
false,
removePrefix:
'dm-discovery-eureka/target/',
sourceFiles:
'dm-discovery-eureka/target/discovery-eureka.yaml')],
usePromotionTimestamp:
false,
useWorkspaceInPromotion: false, verbose: false)])
}
}
node {
stage('Build Config') {
echo "Build dm-config-server"
dir('/root/.jenkins/workspace/pipeline-env/dm-config-server/') {
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('Generate Config') {
echo "Generate dm-config-server mirror"
dir('/root/.jenkins/workspace/pipeline-env/dm-config-server/') {
sh 'cp Dockerfile config-server.yaml target'
}
dir('/root/.jenkins/workspace/pipeline-env/dm-config-server/target/') {
sh 'docker build -t 192.168.9.20/dmw/dm-config-server .'
}
}
stage('Push Config') {
echo "Push mirror to Harbor"
sh "docker login -u admin -p Harbor12345 http://192.168.9.20"
sh "docker push 192.168.9.20/dmw/dm-config-server"
}
stage('Deploy Config') {
echo "Deploy dm-config-server"
sshPublisher(publishers:
[sshPublisherDesc(configName:
'192.168.9.40',
transfers:
[sshTransfer(cleanRemote:
false,
excludes:
'',
execCommand:
'''mkdir
-p
/data/dmw/dm-config-server
cd /data/dmw/dm-config-server
kubectl create -f config-server.yaml''', execTimeout: 120000, flatten: false, makeEmptyDirs:
false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dm-config-server',
remoteDirectorySDF:
false,
removePrefix:
'dm-config-server/target/',
sourceFiles:
'dm-config-server/target/config-server.yaml')],
usePromotionTimestamp:
false,
useWorkspaceInPromotion: false, verbose: false)])
}
}
node {
stage('Build Gateway') {
echo "Build dm-gateway-zuul"
dir('/root/.jenkins/workspace/pipeline-env/dm-gateway-zuul/') {
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('Generate Gateway') {
echo "Generate dm-gateway-zuul mirror"
dir('/root/.jenkins/workspace/pipeline-env/dm-gateway-zuul/') {
sh 'cp Dockerfile gateway-zuul.yaml local_policy.jar US_export_policy.jar target'
}
dir('/root/.jenkins/workspace/pipeline-env/dm-gateway-zuul/target/') {
sh 'docker build -t 192.168.9.20/dmw/dm-gateway-zuul .'
}
}
stage('Push Gateway') {
echo "Push mirror to Harbor"
sh "docker login -u admin -p Harbor12345 http://192.168.9.20"
sh "docker push 192.168.9.20/dmw/dm-gateway-zuul"
}
stage('Deploy Gateway') {
echo "Deploy dm-gateway-zuul"
sshPublisher(publishers:
[sshPublisherDesc(configName:
'192.168.9.40',
transfers:
[sshTransfer(cleanRemote:
false,
excludes:
'',
execCommand:
'''mkdir
-p
/data/dmw/dm-gateway-zuul
cd /data/dmw/dm-gateway-zuul
kubectl create -f gateway-zuul.yaml''', execTimeout: 120000, flatten: false, makeEmptyDirs:
false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dm-gateway-zuul',
remoteDirectorySDF:
false,
removePrefix:
'dm-gateway-zuul/target/',
sourceFiles:
'dm-gateway-zuul/target/gateway-zuul.yaml')],
usePromotionTimestamp:
false,
useWorkspaceInPromotion: false, verbose: false)])
}
}
node {
stage('Build Zipkin') {
echo "Build dm-zipkin-server"
dir('/root/.jenkins/workspace/pipeline-env/dm-zipkin-server/') {
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('Generate Zipkin') {
echo "Generate dm-zipkin-server mirror"
dir('/root/.jenkins/workspace/pipeline-env/dm-zipkin-server/') {
sh 'cp Dockerfile zipkin-server.yaml target'
}
dir('/root/.jenkins/workspace/pipeline-env/dm-zipkin-server/target/') {
sh 'docker build -t 192.168.9.20/dmw/dm-zipkin-server .'
}
}
stage('Push Zipkin') {
echo "Push mirror to Harbor"
sh "docker login -u admin -p Harbor12345 http://192.168.9.20"
sh "docker push 192.168.9.20/dmw/dm-zipkin-server"
}
stage('Deploy Zipkin') {
echo "Deploy dm-zipkin-server"
sshPublisher(publishers:
[sshPublisherDesc(configName:
'192.168.9.40',
transfers:
[sshTransfer(cleanRemote:
false,
excludes:
'',
execCommand:
'''mkdir
-p
/data/dmw/dm-zipkin-server
cd /data/dmw/dm-zipkin-server
kubectl create -f zipkin-server.yaml''', execTimeout: 120000, flatten: false, makeEmptyDirs:
false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dm-zipkin-server',
remoteDirectorySDF:
false,
removePrefix:
'dm-zipkin-server/target/',
sourceFiles:
'dm-zipkin-server/target/zipkin-server.yaml')],
usePromotionTimestamp:
false,
useWorkspaceInPromotion: false, verbose: false)])
}
}
脚本内容填写完成后,单击左下角的“保存”按钮,进入
pipeline-env
项目页。
单击“立即构建”链接,开始编译构建
pipeline-env
项目,项目构建成功后的结果,如
图
4.40
所示。
图 4.40 pipeline-env 项目构建
Jenkins
中
pipeline-env
项目的“立即构建”被单击后,首先到
Gitlab
下载
env-project
项 目 源 码 到
Jenkins
的 “
/root/.jenkins/workspace/pipeline-env
” 目 录 下 ; 然 后 到
dm-discovery-eureka
目 录 内 执 行
maven
编 译 命 令 , 生 成
target
目 录 及 其 内 部 的
dm-discovery-eureka-1.0-SNAPSHOT.jar
文 件 , 并 将
dm-discovery-eureka
目 录 内 的
Dockerfile
和
discovery-eureka.yaml
文件拷贝到
target
目录内;接着在
target
目录内通过
“
docker build
” 命 令 生 成 本 地
Docker
镜 像 , 镜 像 格 式 为
“
192.168.9.20/dmw/dm-discovery-eureka
”,同时将此镜像推送到
192.168.9.20
的
Harbor
服务器上;最后通过远程
SSH
插件,将
yaml
文件推送到
k8s-master
,执行“
kubectl create
”
命 令 发 布
dm-discovery-eureka
项 目 。 同 理 另 外 三 个 子 项 目
dm-config-server
、
dm-gateway-zuul
、
dm-zipkin-server
的编译构建过程也类似。
程序发布到
K8S
的
yaml
文件,拉取镜像的配置值为“
IfNotPresent
”,表示如果镜像
不存在就拉取镜像,如果已存在就使用现有镜像。在大觅网项目构建的时候,如果需要多次
执行可将其值改为“
Always
”或者采用手动删除现有镜像的方式来解决。
Yaml
的配置如图
4.41
所示。
图 4.41 Yaml 拉取镜像配置
3. pipeline-base 项目构建
Jenkins
内单击“新建任务”,然后输入任务名称“
pipeline-base
”,并选择“流水线”,
之后单击“确定”按钮,如图 4.42
所示。
图
4.42 pipeline-base
项目创建
进入项目配置界面后,下拉到
Pipeline
模块填写流水线脚本,脚本的具体内容如下所
示。
node {
stage('Clone Consumer') {
echo "Git clone base-consumer"
git
credentialsId:
'a7183e0d-90f1-45a5-883b-e216210fff10',
url:
'http://192.168.9.10/root/base-consumer.git'
}
}
node {
stage('Build Consumer') {
echo "Build dm-base-consumer"
dir('/root/.jenkins/workspace/pipeline-base/dm-base-consumer/') {
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('Generate Consumer') {
echo "Generate dm-base-consumer mirror"
dir('/root/.jenkins/workspace/pipeline-base/dm-base-consumer/') {
sh 'cp Dockerfile base-consumer.yaml target'
}
dir('/root/.jenkins/workspace/pipeline-base/dm-base-consumer/target/') {
sh 'docker build -t 192.168.9.20/dmw/dm-base-consumer .'
}
}
stage('Push Consumer') {
echo "Push mirror to Harbor"
sh "docker login -u admin -p Harbor12345 http://192.168.9.20"
sh "docker push 192.168.9.20/dmw/dm-base-consumer"
}
stage('Deploy Consumer') {
echo "Deploy dm-base-consumer"
sshPublisher(publishers:
[sshPublisherDesc(configName:
'192.168.9.40',
transfers:
[sshTransfer(cleanRemote:
false,
excludes:
'',
execCommand:
'''mkdir
-p
/data/dmw/dm-base-consumer
cd /data/dmw/dm-base-consumer
kubectl create -f base-consumer.yaml''', execTimeout: 120000, flatten: false, makeEmptyDirs:
false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dm-base-consumer',
remoteDirectorySDF:
false,
removePrefix:
'dm-base-consumer/target/',
sourceFiles:
'dm-base-consumer/target/base-consumer.yaml')],
usePromotionTimestamp:
false,
useWorkspaceInPromotion: false, verbose: false)])
}
}
node {
stage('Clone Provider') {
echo "Git clone base-provider"
git
credentialsId:
'40f0d2de-a3a3-40bc-99cc-cbccef953a6a',
url:
'http://192.168.9.10/root/base-provider.git'
}
}
node {
stage('Build Provider') {
echo "Build dm-base-provider"
dir('/root/.jenkins/workspace/pipeline-base/dm-base-provider/') {
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('Generate Provider') {
echo "Generate dm-base-provider mirror"
dir('/root/.jenkins/workspace/pipeline-base/dm-base-provider/') {
sh 'cp Dockerfile base-provider.yaml target'
}
dir('/root/.jenkins/workspace/pipeline-base/dm-base-provider/target/') {
sh 'docker build -t 192.168.9.20/dmw/dm-base-provider .'
}
}
stage('Push Provider') {
echo "Push mirror to Harbor"
sh "docker login -u admin -p Harbor12345 http://192.168.9.20"
sh "docker push 192.168.9.20/dmw/dm-base-provider"
}
stage('Deploy Provider') {
echo "Deploy dm-base-provider"
sshPublisher(publishers:
[sshPublisherDesc(configName:
'192.168.9.40',
transfers:
[sshTransfer(cleanRemote:
false,
excludes:
'',
execCommand:
'''mkdir
-p
/data/dmw/dm-base-provider
cd /data/dmw/dm-base-provider
kubectl create -f base-provider.yaml''', execTimeout: 120000, flatten: false, makeEmptyDirs:
false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dm-base-provider',
remoteDirectorySDF:
false,
removePrefix:
'dm-base-provider/target/',
sourceFiles:
'dm-base-provider/target/base-provider.yaml')],
usePromotionTimestamp:
false,
useWorkspaceInPromotion: false, verbose: false)])
}
}
单击左下角的“保存”按钮退出后,选择立即构建,等待
pipeline-base
构建完成。项
目构建成功结果,如图 4.43 所示。
图 4.43 pipeline-base 项目构建成功
4. 其他项目的构建
大觅网通过流水线方式发布到
K8S
,除了上面提到的
pipeline-common
、
pipeline-env
、
pipeline-base
项目外,还有其他几个流水线项目,如图
4.44
所示。
图
4.44
大觅网流水线项目
其他流水线项目的构建方法和
pipeline-base
的构建方法相同。
当 所 有 的 业 务 模 块 都 构 建 完 成 后 , 可 以 访 问 微 服 务 的 注 册 中 心 , 地 址 为
http://192.168.9.40:30776
,用户名是
root
,密码为
123456
。所有业务服务正常都应该已经
注册到了注册中心,如图
4.45
所示。
图
4.45
注册中心
4.2.8 项目测试
在 进 行 测 试 之 前 , 还 需 要 确 认 两 处 配 置 。
Tengine
容 器 内 , 前 端 文 件
/usr/local/dm/static/js/1.11375dc8746e5242630d.js
内包含“
192.168.9.6
”的
IP
地址,需
要调整为
gateway
的
service
的名称“
svc-gateway-zuul
”。另外一处是
Tengine
的配置文
件
/usr/local/tengine/conf/nginx.conf
,文件内有跳转到“
192.168.9.18
”的
7600
端口,此
处
IP
地址也要修改为
gateway
的
service
的名称“
svc-gateway-zuul
”。修改方法如下。
[root@k8s-master ~]#
kubectl exec -it tengine-68bbbd5857-q96w7 -- bash
//tengine
对应的
pod
名称
[root@tengine-68bbbd5857-q96w7 local]#
vi /usr/local/dm/static/js/1.11375dc8746e5242630d.js
//
省略部分内容
http://
svc-gateway-zuul
:7600/user/api/p/vendors/wechat/login
//
省略部分内容
[root@tengine-68bbbd5857-q96w7 conf]#
vi /usr/local/tengine/conf/nginx.conf
//
省略部分内容
location ~ /*/api/{
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://
svc-gateway-zuul
:7600;
}
//
省略部分内容
[root@tengine-68bbbd5857-q96w7 conf]#
/usr/local/tengine/sbin/nginx -t
nginx: the configuration file /usr/local/tengine/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/tengine/conf/nginx.conf test is successful
[root@tengine-68bbbd5857-q96w7 conf]#
/usr/local/tengine/sbin/nginx -s reload
相 关 的 基 础 服 务 、 业 务 服 务 都 构 建 完 成 后 , 就 可 以 进 行 项 目 测 试 。 访 问
http://192.168.9.40:30080
查看大觅网的首页内容,如图
4.46
所示。
图 4.46 大觅网首页
至此,大觅网项目搭建发布到
Kubernetes
完成。