大觅网之综合管理(Comprehensive Management of Da Mi Network)

news2024/11/15 5:39:55

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

本人主要分享计算机核心技术:系统维护、数据库、网络安全、自动化运维、容器技术、云计算、人工智能、运维开发、算法结构、物联网、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 地址最低配置主要软件
gitlabCentOS 7.3-x86_64192.168.9.101 2GGitlab
harbor
CentOS 7.3-x86_64192.168.9.201 2G
harbor
jenkins
CentOS 7.3-x86_64192.168.9.301 2G
jenkins
k8s-master
CentOS 7.3-x86_64192.168.9.4022G
Kube-apiserver
k8s-node1
CentOS 7.3-x86_64192.168.9.501 核 5G
Kubeletkube-proxy
k8s-node2
CentOS 7.3-x86_64192.168.9.601 核 5G
Kubeletkube-proxy

2. 案例环境权限列表

4-2 案例中用到的用户名和密码
类型用户名密码
Gitlabrootbdqn123456
MySQLroot123456
Jenkinsadmin123456
Nexusadminadmin123
HarboradminHarbor123

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
REPOSITORYTAGIMAGE IDCREATEDSIZE
envdm_kibanalatest
42ace969f30d
11 days ago1.32GB
envdm_tenginelatest3e8f45690cf6
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
TAGIMAGE ID
CREATED
SIZE
kubernetesui/dashboardv2.0.08b32422733b3
2 weeks
ago
222MB
k8s.gcr.io/kube-proxyv1.18.20d40868643c6
3 weeks
ago
117MB
k8s.gcr.io/kube-apiserverv1.18.26ed75ad404bd
3 weeks
ago
173MB
k8s.gcr.io/kube-schedulerv1.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
NAMESTATUSROLESAGEVERSIONINTERNAL-IPEXTERNAL-IPOS-IMAGEKERNEL-VERSIONCONTAINER-RUNTIME
k8s-masterReadymaster78mv1.18.2192.168.9.40<none>
CentOS
Linux 7 (Core)
3.10.0-514.el7.x86_64
k8s-node1Ready<none>73mv1.18.2192.168.9.50<none>
CentOS
Linux 7 (Core)
3.10.0-514.el7.x86_64
k8s-node2Ready<none>73mv1.18.2192.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
NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES
coredns-66bff467f8-9w4dz1/1Running077m10.244.0.2k8s-master<none><none>
coredns-66bff467f8-h2nsk1/1Running 077m10.244.0.3k8s-master<none><none>
etcd-k8s-master1/1Running 078m10.244.9.40k8s-master<none> <none>
kube-apiserver-k8s-master
1/1Running 078m10.244.9.40k8s-master<none><none>
kube-controller-manager-k8s-master1/1Running 078m10.244.9.40k8s-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
NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES
elasticsearch-7f6fb5c6b5-g2fh51/1Running68d10.244.1.96k8s-node01<none><none>
kafka-86969f8c5d-mpbvf 1/1Running68d10.244.1.85k8s-node01<none><none>
kibana-68df6fffbc-7rrxr
1/1Running68d
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

NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGESELECTOR
kubernetesClusterIP10.96.0.1<none>443/TCP24d<none>
svc-elasticsearchClusterIP10.100.165.71<none>9200/TCP,9300/TCP8dapp=elasticsearch
svc-kafkaClusterIP10.102.175.1429092/TCP9092/TCP8dapp=kafka
svc-kibanaClusterIP10.109.220.220<none>5601/TCP8dapp=kibana
svc-mysqlNodePort10.100.90.129<none>3306:3306/TCP8dapp=mysql
svc-nexusNodePort10.110.181.34<none>8081:8081/TCP8dapp=nexus

在基础镜像发布的过程中,简化了部分操作,比如 SonarMycat 等都没有启动,这些

服务不影响大觅网的启动,适当做了精简。
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 完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2165772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL InnoDB 事务commit逻辑分析

一、前言 事务提交是事务即将落盘的一系列操作&#xff0c;涉及redo\undo log的写盘、bin log的写盘、事务状态的重置、各种参数的改变、无用undo log的清理等方方面面。 在commit过程会有两个阶段&#xff1a;一个是prepare阶段&#xff0c;入口函数为trx_prepare_low&#…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-25

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-25 1. PromSec: Prompt Optimization for Secure Generation of Functional Source Code with Large Language Models (LLMs) M Nazzal, I Khalil, A Khreishah, NH Phan - arXiv preprint arXiv:2409.12699, 2…

无人机探测:光电侦测技术详解

无人机探测技术作为现代军事、安防及民用领域的重要组成部分&#xff0c;其核心在于高效、精准地识别与跟踪空中目标。光电侦测技术&#xff0c;作为无人机探测的主要手段之一&#xff0c;利用光学与电子学原理&#xff0c;通过捕捉并分析无人机反射或发射的光信号&#xff0c;…

Debian与Ubuntu:深入解读两大Linux发行版的历史与联系

Debian与Ubuntu&#xff1a;深入解读两大Linux发行版的历史与联系 引言 在开源操作系统的领域中&#xff0c;Debian和Ubuntu是两款备受瞩目的Linux发行版。它们不仅在技术上有着密切的联系&#xff0c;而且各自的发展历程和理念也对开源社区产生了深远的影响。本文将详细介绍…

【C++指南】C++中的内存对齐规则及原因详解

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C指南》 期待您的关注 目录 引言 一、为什么要进行内存对齐 二、C中的内存对齐规则 三、内存对齐示例讲解 示例代码 运行…

Spring Boot 进阶-第一个程序HelloWorld

从我们学习编程语言开始,每次入门一个语言都是从Hello World开始,当然这里我们也不例外。首先从一个简单的HelloWorld程序开始。 既然是要学着做Java Web开发,那么首先需要了解的就是如何去编写一个RESTFul风格的接口,这里我们就需要引入一个pom的依赖。 <dependency&g…

矩阵分析 学习笔记4 内积与Gram矩阵

内积 定义 由于对称&#xff0c;第二变元线性那第一变元也线性了。例如这个&#xff1a;

【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差

本文内容来自YashanDB官网&#xff0c;具体内容请见https://www.yashandb.com/newsinfo/7396959.html?templateId1718516 问题现象 yashandb执行带oracle dblink表的sql性能差&#xff1a; 同样的语句&#xff0c;同样的数据&#xff0c;oracle通过dblink访问远端oracle执行…

spring学习 【基础】

目录 1.将bean交给spring容器管理 1. 编写bean对象 2. 在resources目录下创建spring config xml文件&#xff0c;并管理bean对象 3. spring容器管理工厂 2.Spring Bean 生命周期 2.1 Spring Bean初始化方法 2.1.1 自定义初始化方法 2.1.2 实现接口(InitializingBean)…

Spring6梳理12——依赖注入之注入Map集合类型属性

以上笔记来源&#xff1a; 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09;https://www.bilibili.com/video/BV1kR4y1b7Qc 12 依赖注入之注入Map集合类型属性 12.1 创建Student类和Teacher类 Student类中创建了run…

灵当CRM multipleUpload.php 文件上传致RCE漏洞复现

0x01 产品描述&#xff1a; 灵当CRM是一款专为中小企业量身定制的智能客户关系管理工具&#xff0c;由上海灵当信息科技有限公司开发和运营。该系统广泛应用于多个行业&#xff0c;包括金融、教育、医疗、IT服务及房地产等领域&#xff0c;旨在满足企业对客户个性化管理的需求&…

集合ArrayList常用方法

源代码&#xff1a; 输出结果&#xff1a;

小米Civi2机型工程固件 资源预览 刷写说明 与nv损坏去除电阻图示

小米Civi2机型机型代码为:ziyi。次期开始讲在博文中陆续解析机型nv损坏修复的一些步骤与当前机型去除校验电阻相关的图示与说明。注意。米系列机型有串码校验。去除电阻需要一定的技术,请谨慎操作。 通过博文了解 1💝💝💝-----此机型工程固件的资源刷写注意事项 2�…

【计算机网络 - 基础问题】每日 3 题(二十四)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

音乐服务器测试报告

项目背景 该音乐服务器系统使用的是前后端分离的方式来实现,将相关数据存储到数据库中, 且将其部署到云服务器上. 前端主要构成部分有: 登录页面, 列表页面, 喜欢页面, 添加歌曲4个页面组成. 通过结合后端实现了主要的功能: 登录, 播放音乐, 添加音乐, 收藏音乐, 删除音乐, 删…

uniapp实现在表单中展示多个选项,并且用户可以选择其中的一个或多个选项

前言 uni-data-checkbox是uni-app的一个组件,用于在表单中展示多个选项,并且用户可以选择其中的一个或多个选项。该组件可以通过设置不同的参数来控制选项的样式、布局和行为。 提示:以下是本篇文章正文内容,下面案例可供参考 uni-data-checkbox组件具有以下特点:: 1、跨…

Git 工作区、暂存区与修改全解析

工作区和暂存区是 Git 中一个非常重要的概念&#xff0c;弄明白了他们&#xff0c;就弄明白了 Git 的很多操作到底干了什么。 ‍ 工作区&#xff08;Working Directory&#xff09; 工作区&#xff0c;就是一个目录&#xff0c;比如我的 LearnGit ​文件夹就是一个工作区&am…

JavaScript --模版字符串用反引号

用反引号 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, i…

SpringBoot集成阿里easyexcel(一)基础导入导出

easyexcel主要用于excel文件的读写&#xff0c;可使用model实体类来定义文件读写的模板&#xff0c;对开发人员来说实现简单Excel文件的读写很便捷。可参考官方文档 https://github.com/alibaba/easyexcel 一、引入依赖 <!-- 阿里开源EXCEL --><dependency><gr…

《深度学习》ResNet残差网络、BN批处理层 结构、原理详解

目录 一、关于ResNet 1、什么是ResNet 2、传统卷积神经网络存在的问题 1&#xff09;梯度消失和梯度爆炸问题 2&#xff09;训练困难 3&#xff09;特征表示能力受限 4&#xff09;模型复杂度和计算负担 3、如何解决 1&#xff09;解决梯度问题 BN层重要步骤&#xff1a; 2…