💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
推荐:Linux运维老纪的首页,持续学习,不断总结,共同进步,活到老学到老
导航剑指大厂系列:全面总结 运维核心技术:系统基础、数据库、网路技术、系统安全、自动化运维、容器技术、监控工具、脚本编程、云服务等。
常用运维工具系列:常用的运维开发工具, zabbix、nagios、docker、k8s、puppet、ansible等
数据库系列:详细总结了常用数据库 mysql、Redis、MongoDB、oracle 技术点,以及工作中遇到的 mysql 问题等
懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
1.1.2 案例概述
本实验实现:使用 Jenkins 到 GitLab 拉取代码到 Jenkins 本地,在 Jenkins 上编译构
建生成镜像,并将镜像上传到 Harbor 私有仓库上。然后在 Jenkins 上远程执行 yaml 文件,
发布应用到 K8S 群集中,执行 yaml 文件时镜像的拉取是到 Harbor 私有仓库完成的。
1.1.3 案例环境
1.案例环境
实验中虚拟机使用 VMware 来实现,采用 NAT 或桥接网络模式,保证有外网连接即可,
并且虚拟机之间保持互通。实验中包括 GitLab、Jenkins、Harbor 和 K8S 群集,K8S 群集采
用 Kubeadm 方式进行安装,具体配置信息如表 1-1 所示。
主机名 | IP 地址 | 推荐配置 | 操作系统 | 安装软件 |
gitlab | 192.168.11.10 |
1 核 3G
|
CentOS 7.9 x86_64
| gitlab |
jenkins
| 192.168.11.20 |
1 核 2G
|
CentOS 7.9 x86_64
|
Tomcat、Java、Git、
Jenkins
|
harbor
| 192.168.11.30 |
1 核 2G
|
CentOS 7.9 x86_64
|
Docker compose、
Harbor
|
K8s-master | 192.168.11.40 |
2核 2G
|
CentOS 7.9 x86_64
|
kube-apiserver、
kube-scheduler等
|
K8s-node1
| 192.168.11.50 |
1 核 2G
|
CentOS 7.9 x86_64
|
kube-apiserver、
kube-scheduler等
|
K8s-node2
| 192.168.11.60 |
1 核 2G
|
CentOS 7.9 x86_64
|
kube-proxy
、 kubelet
|
2.案例拓扑
本案例拓扑如图 1.1 所示。
图 1.1 实验拓扑
3.案例需求
本实验主要实现以下需求:
(1)K8S 群集部署。
(2)GitLab 部署。
(3)Jenkins 部署。
(4)Harbor 部署
(5)程序发布到 K8S 群集。
4.实现思路
(1)依次部署 K8S 群集、GitLab、Jenkins 和 Harbor 应用。
(2)上传测试程序和生成镜像的 Dockerfile 到 GitLab。
(3)编写 K8S 上发布程序的 yaml 文件及脚本。
(4)Jenkins 发布任务实现程序的自动发布更新。
1.2 案例实施
1.2.1 准备基础环境
1)准备虚拟机
依据案例环境中配置信息为虚拟机设置 IP 地址、网关、DNS 等基础信息,确保可以连
接到互联网,并且虚拟机之间可以互通。
2)配置主机名 以 GitLab 主机为例。
[root@localhost ~]#
hostnamectl set-hostname gitlab
[root@localhost ~]#
bash
[root@gitlab ~]#
其他主机依次改名为 jenkins、harbor、k8s-master、k8s-node1 和 k8s-node2。
3)安装常用软件
所有主机都需要执行,下面以 GitLab 主机执行为例。
[root@gitlab ~]#
yum -y install vim wget net-tools lrzsz
4) 关闭防火墙
所有主机都需要执行,下面以 GitLab 主机执行为例。
[root@gitlab ~]#
systemctl stop firewalld && systemctl disable firewalld
5) 禁用 SELinux
所有主机都需要执行,下面以 GitLab 主机执行为例。
[root@gitlab ~]#
sed -i '/^SELINUX=/s/enforcing/disabled/'
/etc/selinux/config
[root@gitlab ~]#
setenforce 0
1.2.2 部署 K8S 群集
1.环境初始化
1)更新系统
所有 K8S 节点都需要执行,下面以 k8s-master 上执行为例。
[root@k8s-master ~]#
yum -y update systemd
2)绑定 hosts
所有 K8S 节点都需要执行,下面以 k8s-master 上执行为例。
[root@k8s-master ~]#
cat << EOF >> /etc/hosts
192.168.11.40 k8s-master
192.168.11.50 k8s-node1
192.168.11.60 k8s-node2
EOF
3)关闭交换分区 swap
所有 K8S 节点都需要执行,下面以 k8s-master 上执行为例。
[root@k8s-master ~]#
swapoff -a
[root@k8s-master ~]#
sed -i '/swap/s/^/#/' /etc/fstab
2.Docker 部署
K8S 的三个节点(k8s-master、k8s-node1、k8s-node2)都需要安装 Docker,下面以
k8s-master 上安装为例。
1)安装依赖包
[root@k8s-master ~]#
yum install -y yum-utils
device-mapper-persistent-data lvm2
2)添加 YUM 软件源
[root@k8s-master ~]#
yum-config-manager --add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3)安装 Docker
[root@k8s-master ~]#
yum makecache fast
[root@k8s-master ~]#
yum -y install docker-ce
4)配置加速器
[root@k8s-master ~]#
mkdir /etc/docker
[root@k8s-master ~]#
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://g6yrjrwf.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
其中,exec-opts 用于设置 Docker 的 cgroup 驱动类型,需要将其修改为 systemd。因
为 K8S 默认就是使用的 systemd,将 Docker 和 K8S 的驱动类型统一,否则后续会有报错。
需要注意的是:K8S 内的节点上 Docker 环境都需要统一。
5)启动 Docker
[root@k8s-master ~]#
systemctl start docker && systemctl enable docker
6) 内核优化
在 Docker 的使用过程中有时会看到下面这个警告信息。
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
这种警告信息可通过配置内核参数的方式来消除,具体配置如下。
[root@k8s-master ~]#
cat << EOF >> /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
[root@k8s-master ~]#
sysctl -p
3.K8S 部署
1)配置 K8S 的 YUM 源
操作节点:k8s-master, k8s-node1, k8s-node2
[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)安装 Kubelet、Kubeadm 和 Kubectl
操作节点:k8s-master, k8s-node1, k8s-node2
[root@k8s-master ~]#
yum install -y kubelet kubeadm kubectl
[root@k8s-master ~]#
systemctl enable kubelet
其中 kubelet 刚安装完成后,通过 systemctl start kubelet 方式是无法启动的,需要
加入节点或初始化为 master 后才可以启动成功。
3)生成初始化配置文件
操作节点:k8s-master
[root@k8s-master ~]#
kubeadm config print init-defaults > init-config.yaml
4)修改初始化配置文件
操作节点:k8s-master
[root@k8s-master ~]#
vim init-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress:
192.168.11.40
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
imagePullPolicy: IfNotPresent
name:
k8s-master
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository:
registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.22.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16
scheduler: {}
上述加粗的地方要根据环境进行修改。
5)拉取镜像
操作节点:k8s-master
[root@k8s-master ~]#
kubeadm config images list --config init-config.yaml
registry.aliyuncs.com/google_containers/kube-apiserver:v1.22.0
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.22.
0
registry.aliyuncs.com/google_containers/kube-scheduler:v1.22.0
registry.aliyuncs.com/google_containers/kube-proxy:v1.22.0
registry.aliyuncs.com/google_containers/pause:3.5
registry.aliyuncs.com/google_containers/etcd:3.5.0-0
registry.aliyuncs.com/google_containers/coredns:v1.8.4
[root@k8s-master ~]#
kubeadm config images pull --config=init-config.yaml
[config/images] Pulled
registry.aliyuncs.com/google_containers/kube-apiserver:v1.22.0
[config/images] Pulled
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.22.0
[config/images] Pulled
registry.aliyuncs.com/google_containers/kube-scheduler:v1.22.0
[config/images] Pulled
registry.aliyuncs.com/google_containers/kube-proxy:v1.22.0
[config/images] Pulled
registry.aliyuncs.com/google_containers/pause:3.5
[config/images] Pulled
registry.aliyuncs.com/google_containers/etcd:3.5.0-0
failed to pull image
"registry.aliyuncs.com/google_containers/coredns:v1.8.4": output: Error
response from daemon: manifest for
registry.aliyuncs.com/google_containers/coredns:v1.8.4 not found: manifest
unknown: manifest unknown
, error: exit status 1
To see the stack trace of this error execute with --v=5 or higher
如果镜像拉取没有报错,都成功拉取完成,可直接进行后续的初始化操作。如果在执行
拉取命令时,出现了报错信息。
Error response from daemon: manifest for
registry.aliyuncs.com/google_containers/coredns:v1.8.4 not found: manifest
unknown: manifest unknown
说明无法拉取 coredns 镜像,镜像实际存储的名称是 coredns:1.8.4,没有 v 字符。可
以采用先手动拉取镜像,再使用给镜像打 tag 的方式实现。
[root@k8s-master ~]#
docker pull
registry.aliyuncs.com/google_containers/coredns:1.8.4
1.8.4: Pulling from google_containers/coredns
c6568d217a00: Pull complete
bc38a22c706b: Pull complete
Digest:
sha256:6e5a02c21641597998b4be7cb5eb1e7b02c0d8d23cce4dd09f4682d463798890
Status: Downloaded newer image for
registry.aliyuncs.com/google_containers/coredns:1.8.4
registry.aliyuncs.com/google_containers/coredns:1.8.4
[root@k8s-master ~]#
docker tag
registry.aliyuncs.com/google_containers/coredns:1.8.4
registry.aliyuncs.com/google_containers/coredns:v1.8.4
最终完整的镜像列表如下所示。
[root@k8s-master ~]#
docker image ls
REPOSITORY
TAG
IMAGE ID
CREATED
SIZE
registry.aliyuncs.com/google_containers/kube-apiserver
v1.22.0 838d692cbe28 8 days ago
128MB
registry.aliyuncs.com/google_containers/kube-controller-manager
v1.22.0 5344f96781f4 8 days ago
122MB
registry.aliyuncs.com/google_containers/kube-scheduler
v1.22.0 3db3d153007f 8 days ago
52.7MB
registry.aliyuncs.com/google_containers/kube-proxy
v1.22.0 bbad1636b30d 8 days ago
104MB
registry.aliyuncs.com/google_containers/etcd
3.5.0-0
004811815584 8 weeks ago
295MB
registry.aliyuncs.com/google_containers/coredns
8d147537fb7d 2 months ago 47.6MB
registry.aliyuncs.com/google_containers/coredns
v1.8.4
8d147537fb7d 2 months ago 47.6MB
registry.aliyuncs.com/google_containers/pause
3.5
ed210e3e4a5b 4 months ago 683kB
其中的 coredns 镜像,需要保证在 k8s-node1 和 k8s-node2 上同样下载好。
6)初始化 k8s-master
操作节点:k8s-master
[root@k8s-master ~]#
kubeadm init --config=init-config.yaml
...
省略部分内容
...
[mark-control-plane] Marking the node k8s-master as control-plane by
adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node k8s-master as control-plane by
adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: abcdef.0123456789abcdef
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap,
RBAC Roles
[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
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a
rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular
user:
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.11.40:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash
sha256:3a95cfb88f3951320621094e41eebe4e3b5d283312afe9613a131a6678d8123f
7)复制配置文件到用户的 home 目录
操作节点:k8s-master
[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
8)node 节点加入群集
操作节点:k8s-node1 和 k8s-node2
[root@k8s-node01 ~]#
kubeadm join 192.168.11.40:6443 --token
abcdef.0123456789abcdef --discovery-token-ca-cert-hash
sha256:3a95cfb88f3951320621094e41eebe4e3b5d283312afe9613a131a6678d8123f
W0316 17:17:00.739681
1962 join.go:346] [preflight] WARNING:
JoinControlPane.controlPlane settings will be ignored when control-plane flag
is not set.
[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker
cgroup driver. The recommended driver is "systemd". Please follow the guide at
https://kubernetes.io/docs/setup/cri/
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n
kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the
"kubelet-config-1.17" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file
"/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file
"/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was
received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the
cluster.
上述命令中的 token 串要改为自己环境中的值。
9)安装网络
[root@k8s-master ~]#
kubectl apply -f
https://docs.projectcalico.org/v3.20/manifests/calico.yaml
命令执行后,将会在所有节点上创建 calico 相关的 Pod 用于网络通信,在创建 Pod 之
前还需要拉取 calico 镜像。会根据网络快慢,创建 calico 对应的 Pod 时间有长短,如果一
直是创建中的状态,需要耐心等待。
K8S 群集安装完成,查看节点的状态。
[root@k8s-master ~]#
kubectl get node
NAME
STATUS ROLES
AGE VERSION
k8s-master Ready
control-plane,master 15h v1.22.0
k8s-node1
Ready
<none>
15h v1.22.0
k8s-node2
Ready
<none>
15h v1.22.0
至此,通过 Kubeadm 方式安装 K8S 群集已经完成。
1.2.3 部署 GitLab
1)安装 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.11.10’
[root@gitlab ~]#
gitlab-ctl reconfigure
执行 reconfigure 的操作需要较长时间,需耐心等待,等提示执行成功后,进行后续的
GitLab 相关配置。
2)设置 root 密码并登录
浏览器访问 http://192.168.11.10,为默认 root 用户设置密码,密码的设置要符合复
杂度,两次输入的密码要一致。如图 1.2 所示。
图 1.2GitLab 修改密码
密码设置完成后,就会跳转到登录界面,输入
root
用户和刚设置的密码进行登录,如
图
1.3
所示。
图 1.3 GitLab 登录界面
3)创建项目
进入
GitLab
主界面后,单击
“Create a project”
按钮,创建
mytest
项目。将
“Project name”
配置成
“mytest”
,最后单击
“Create project”
按钮创建该项目,如图
1.4
所示。
图 1.4 创建 mytest 项目
4)安装客户端提交工具
配置完 GitLab 仓库后,下面安装提交代码到 GitLab 仓库的客户端工具,这里采用
Windows 系统下的 TortoiseGit 软件,软件名称为 TortoiseGit-2.12.0.0-64bit.mis。该软
件在 Windows 上可以直接通过双击安装,然后一直“下一步”即可完成安装。
5)提交测试页到 GitLab
在 GitLab 上mytest 创 建 成 功 页 , 复 制 项 目 地 址 http://192.168.11.10/root/mytest.git”。如图
1.5 所示。
图 1.5 mytest 项目创建完成
然后在本地 Windows 的 E 盘创建“source_1”目录,在“source_1”目录上右键,选择
“Git Clone”,然后单击“OK”,这样 mytest 项目就拉取到本地。如图 1.6 所示。
图 1.6 克隆 mytest 项目
在 E:\source_1\mytest 目录内创建 index.html 文件,其内容如下所示。
<html>
<head>
<title>my test</title>
</head>
<body>
<h1>
version: 1.1
</h1>
</body>
</html>
文件 index.html 编写完成后,在 mytest 目录内右键单击选择“Git Commit ->master”
,
然后再最上面的“message”中填写备注信息,通常都是对提交内容的注释。下面的
index.html 文件确保已经被选中。如图 1.7 所示。
图 1.7 Git 提交到本地页面
之后单击“Commit”按钮提交到本地仓库,最后单击“Push”按钮上传到 GitLab 中,
从而完成本次代码的提交。如图 1.8 所示。
图 1.8 Git 提交到远端仓库
单击 Push 按钮,之后在单击 OK 按钮,完成提交到远端仓库。提交成功后,可以在 GitLab
中查看到 index.html 文件。如图 1.9 所示。
图 1.9 GitLab 内项目页
1.2.4 部署 Jenkins
1)安装 Jenkins
[root@jenkins ~]#
tar zxf apache-tomcat-9.0.52.tar.gz -C /usr/local
[root@jenkins ~]#
mv /usr/local/apache-tomcat-9.0.52 /usr/local/tomcat
[root@jenkins ~]#
tar zxf jdk-8u301-linux-x64.tar.gz
[root@jenkins ~]#
mv jdk1.8.0_301 /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
[root@jenkins ~]#
source /etc/profile
将 jenkins.war 包上传到 Jenkins 主机的/usr/local/tomcat/webapp 目录下。
2)启动 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.
3)安装 Docker
Jenkins 主机上也需要安装 Docker,因为此主机上承担着通过 Dockerfile 构建镜像的
任务。其安装方法参考 K8S 群集内 Docker 的安装方法。
4)初始化 Jenkins
通过浏览器访问 URL 地址 http://192.168.11.20:8080/jenkins,打开 Jenkins 配置向
导,如图 1.10 所示。
图 1.10 Jenkins 登录页面
查看 Jenkins 登录密码文件。
[root@jenkins ~]#
cat /root/.jenkins/secrets/initialAdminPassword
476b4f82934b427db5f90b09a3bd7537
输入初始密码,单击
“
继续
”
按钮,进入 Jenkins 自定义安装界面。然后单击
“
安装推荐的
插件
”
按钮,安装一些常用的插件,如图 1.11 所示。推荐安装最新稳定版,整个安装过程所
需的时间较长。
图 1.11 Jenkins 插件安装选择界面
推荐插件安装完成后,创建 Jenkins 管理员用户,如图 1.12 所示。
图 1.12 Jenkins 创建 admin 用户界面
保存后,Jenkins 基础配置完成。配置完成后,建议重启下 tomcat 服务,重新加载下
Jenkins,这样部分英文就会变为中文状态。
5)Jenkins 插件安装
为了完成项目的编译构建,需要安装一些插件。单击
“
系统管理
”
->
“
插件管理
”
->
“
可选插
件
”
选项卡,然后在搜索框内依次搜索安装如下插件:
CloudBees Docker Build and Publish
Git Parameter
Git plugin
勾选对应的插件后,分别单击
“
直接安装
”
按钮,等待插件完成安装。
6)凭据的创建
在实验中凭据的设置主要用于登录 GitLab 拉取代码和登录到 Harbor 私有仓库上传镜
像。凭据页面的进入可通过:单击右上角 admin 用户后的下拉小三角,选择凭据,然后单击
下面的“全局”后面的下拉小三角,单击“添加凭据”,如图 1.13 所示。
图 1.13 进入添加凭据
其中填写的对应的用户和密码是管理mytest项目的用户。登录GitLab的凭据创建过程,
如图 1.14 所示。
图 1.14 GitLab 凭据
参照上面创建凭据的过程,创建登录 Harbor 私有仓库的凭据,如图 1.15 所示。
图 1.15 Harbor 仓库凭据
1.2.5 部署 Harbor
1.安装 Harbor
1)安装 Docker
Harbor 主机上也需要安装 Docker,因为 Harbor 是通过 Docker compose 方式安装的,
需要 Docker 环境的支持。其安装方法参考 K8S 群集内 Docker 的安装方法。
2)上传 Docker compose
将 docker-compose 文件上传到/usr/local/bin 目录下,并赋予可执行权限。命令如下
所示。
[root@harbor ~]#
chmod +x /usr/local/bin/docker-compose
3)安装 Harbor
解压缩 Harbor 的安装包到/usr/local 目录下。
[root@harbor ~]#
tar zxf harbor-offline-installer-v2.3.1.tgz -C
/usr/local/
修改 Harbor 的配置文件。
[root@harbor ~]#
cd /usr/local/harbor
[root@harbor harbor]#
/bin/cp harbor.yml.tmpl harbor.yml
[root@harbor harbor]#
vim /usr/local/harbor/harbor.yml
hostname: 192.168.11.30
//
省略了部分内容
# 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 相关内容进行注释,其他的配置项保持默认。本
实验没有生成对应的证书,不采用 https 方式。
启动 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/entrypoint.sh
Up (healthy)
harbor-db
/docker-entrypoint.sh 96 13
Up (healthy)
harbor-jobservice /harbor/entrypoint.sh
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)
nginx
nginx -g daemon off;
Up (healthy)
0.0.0.0:80->8080/tcp,:::80->8080/tcp
redis
redis-server /etc/redis.conf
Up (healthy)
registry
/home/harbor/entrypoint.sh
Up (healthy)
registryctl
/home/harbor/start.sh
Up (healthy)
首 次 安 装 启 动 可 使 用 /usr/local/harbor/install.sh 脚 本 , 后 续 可 使 用
“docker-compose up -d”命令启动 Harbor,使用“docker-compose stop”命令关闭 Harbor。
2.创建私有仓库
1)登录 Harbor
Harbor 启动完成后,浏览器访问 http://192.168.11.30,打开 Harbor Web 页面,如图
1.16 所示。
图 1.16 Harbor 登录页
如果打开的是英文界面,可通过右上角的语言选择,选择中文简体语言。在 Harbor 的
配置文件内有对用户名和密码的定义,默认用户为 admin,密码为 Harbor12345。登录成功
后,进入到 Harbor 的主界面。
2)创建用户
在进一步使用 Harbor 之前,还需要先配置项目所需要的用户。从左侧的用户管理导航
栏进入用户管理界面,如图 1.17 所示。
图 1.17 Harbor 用户管理导航
在用户管理界面,单击“创建用户”,设置一个项目所需的用户,如图 1.18 所示。
图 1.18 用户管理界面
在创建用户界面,创建一个新用户 jenkins。其中用户名填写 jenkins,其他带“*”的
选项都需要填写,如图 1.19 所示。
图 1.19 创建用户界面
用户相关信息都填写完成后,单击“确定”按钮,完成用户创建。
3)创建项目
完成了用户创建之后,还需要创建实验中用到的项目。单击左侧导航栏中的项目,进入
到项目页中。然后再单击新建项目,进入到新建项目页中,如图 1.20 所示。
图 1.20 Harbor 项目页
由于是 Jenkins 构建完成镜像再上传到 Harbor 私有仓库,所以对应的私有仓库名称也
命名为 jenkins。新建项目的项目名称为 jenkins,单击确定按钮完成项目的新建。如图 1.21
所示。
图 1.21 新建项目页
项目 jenkins 创建完成后,如图 1.22 所示。
图 1.22 Harbor 项目页
4)将用户添加到项目中
将新建的 jenkins 用户添加到 jenkins 项目的成员中,这样 jenkins 用户才可以实现对
jenkins 项目的管理,如图 1.23 所示。
图 1.23 jenkins 项目成员页
在“成员”选项卡下,填写成员名称,填写用户“jenkins”,角色选择维护人员。这
样就有权限上传及维护镜像了。最后单击确定按钮完成新成员的添加,如图 1.24 所示。
图 1.24 新建成员页
项目 jenkins 包含两个成员,一个默认的 admin,另一个就是新添加的 jenkins 用户。
如图 1.25 所示。
图 1.25 项目成员页
5)修改 Harbor 连接方式
在需要跟 Harbor 私有镜像仓库连接的服务器上,将其上的 Docker 连接仓库方式修改为
http 模 式 , 因 为 默 认 的 https 方 式 是 无 法 连 接 的 。 定 义 http 连 接 方 式 使 用
insecure-registries 参数,具体的配置信息如下所示。
[root@jenkins ~]#
cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://g6yrjrwf.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["192.168.11.30"]
//
新添加内容
}
1.2.6 发布应用
1.创建 K8S 的 yaml 文件
1)Harbor 仓库身份验证
创建 Pod 的 yaml 文件内包含到 Harbor 私有仓库拉取镜像的步骤,在拉取之前首先要进
行身份验证,只有通过了身份验证,才能开始拉取镜像。本实验就是采用创建 secrets 方式,
创建 secrets 后可以在 yaml 文件内调用。
[root@k8s-master ~]#
kubectl create secret docker-registry
harbor-login-registry --docker-server=192.168.11.30 --docker-username=jenkins
--docker-password=123456
此处的密码需改为自己环境中的密码。
2)创建 yaml 文件
K8S 上的 yaml 文件的作用是:Jenkins 通过远程调用 k8s-master 上的 yaml 文件,生成
对应的 Pod 和 Service。Pod 和 Service 对应的 yaml 文件如下所示。
[root@k8s-master ~]#
mkdir /data && cd /data
[root@k8s-master data]#
vim nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
imagePullSecrets:
- name: harbor-login-registry
containers:
- name: nginx
image: 192.168.11.30/jenkins/nginx:latest
imagePullPolicy: Always
ports:
- containerPort: 80
[root@k8s-master data]#
vim nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
labels:
app: svc-nginx
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30088
selector:
app: nginx
其中,使用 nginx-deploy.yaml 通过 yaml 文件创建 Pod,只定义了一个 Nginx Pod;
imagePullSecrets 参数定义了到 Harbor 仓库验证身份的信息。使用 nginx-svc.yaml 通过
yaml 文件创建 Service,定义了外部访问服务的方式是 NodePort,对外端口是 30088。
3)上传 Dockerfile 及 nginx.repo 到 GitLab
在 E:\source_1\mytest 目录下创建 Dockerfile,其内容如下所示。
FROM centos:7
LABEL maintainer bdqn
RUN yum -y install yum-utils
COPY nginx.repo /etc/yum.repos.d/
RUN yum -y install nginx
COPY index.html /usr/share/nginx/html
RUN chmod 644 /usr/share/nginx/html/index.html
CMD ["nginx","-g","daemon off;"]
在相同目录下创建 nginx.repo 文件,用于在容器内安装 nginx,其内容如下所示。
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearc
h/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
以上两个文件都通过 TortoiseGit 提交到 GitLab 的 mytest 项目目录下。
2.编写发布到 K8S 脚本
该脚本的作用是:在 Jenkins 服务器上远程执行启动 Pod 和 Service 服务使用的。该脚
本也在/data 目录下。脚本内容如下所示。
[root@k8s-master data]#
vim deploy.sh
#!/bin/bash
cd /data
newversion=$1
oldversion=$(cat nginx-deploy.yaml | grep "image:" | awk -F ':' '{print
$NF}')
echo "old version is: "${oldversion}
echo "new version is: "${newversion}
#replace new version
sed -i 's/'"nginx:${oldversion}"'/'"nginx:${newversion}"'/g'
nginx-deploy.yaml
#deploy
kubectl delete -f nginx-deploy.yaml
kubectl create -f nginx-deploy.yaml
在脚本中,首先通过脚本参数获取新版本号,然后在 nginx-deploy.yaml 内获取镜像的
版本,最后再使用新版本好替换文件内的旧版本号。之后先删除再启动对应的 Pod。
3.创建发布任务
在 Jenkins 控制面板页,单击新建任务,创建本次发布任务,任务名称为 nginx,选择
构建一个自由风格的软件项目,最后单击确定按钮。如图 1.26 所示。
图 1.26 创建项目
在“General”面板中,勾选“参数化构建过程”,然后在“添加参数”中选择“Git
参数”,再填写 Git 相关参数。
其中,名称填写“Tag”。
描述是对整个过程的概述。如图 1.27 所示。
图 1.27 Git 参数配置
在源码管理内,选择“Git”,之后填写项目在 GitLab 上的源码地址,选择对应的凭据,
如图 1.28 所示。
图 1.28 源码管理
“源码管理”这一步需要 Jenkins 主机安装了 git 软件。如果提示“无法连接仓库:Error
performing git command”,可在 jenkins 主机上通过“yum -y install git”进行安装。
在“构建”模块内,“增加构建步骤”中选择“Docker Build and Publish”。此步骤
用于从 GitLab 下载源码后,在 Jenkins 内构建镜像并上传到 Harbor 仓库中,如图 1.29 所
示。
图 1.29 构建类型选择
填写构建的具体配置内容,如图 1.30 所示。
图 1.30 Docker 构建页
其中,各个参数的含义如下所示:
Repository Name 是仓库名称,通常是 Harbor 的项目名+镜像名,这里定义了
“jenkins/nginx”,其中 jenkins 是 Harbor 内的项目名,nginx 是镜像名。
Tag 是标签,这里是“General”中定义的 Git 参数。
Docker Host URI 这里是固定写法,定义 Docker 主机的 URI。
Server credentials 是主机认证,这里没有使用到。
Docker registry URL 是 Harbor 仓库的地址,地址中的 jenkins 是 Harbor 中创建
的项目。
Registry credentials 是登录 Harbor 使用的凭据。
在 Jenkins 主机上,要将/var/run/docker.sock 的权限设置为 666。命令如下所示。
[root@jenkins ~]#
chmod 666 /var/run/docker.sock
依然是在“构建”模块内,这次选择“执行 shell”,主要用于通过脚本远程执行发布
Pod、Service 等操作。如图 1.31 所示。
图 1.31 构建类型选择
在“执行 shell”中,填入要执行的脚本,如图 1.32 所示。
图 1.32 执行 shell 命令
命令如下所示。
ssh 192.168.11.40 "cd /data && sh deploy.sh ${Tag}"
从 Jenkins 主机到 k8s-master 主机要配置免秘钥登录,这样上面的命令才能正常执行。
配置免秘钥登录的命令如下所示。
[root@jenkins ~]#
ssh-keygen
[root@jenkins ~]#
ssh-copy-id 192.168.11.40
单击保存按钮,完成整个任务的配置。
进入到 GitLab 项目页内,给当前 GitLab 内版本打 Tag。如图 1.33 所示。
图 1.33 引导新 Tag
新 Tag 命名为 1.1,其他选项保持默认,如图 1.34 所示。
图 1.34 创建新 Tag
单击“Create Tag”按钮,完成新 Tag 的创建。
最后编译构建 nginx 任务,通过选择“Build with Parameters”进行任务的构建。之
后选择 Tag 下的 1.1,单击“开始构建”按钮。如图 1.35 所示。
图 1.35 准备开始构建
构建过程如下所示。
Started by user admin
Running as SYSTEM
Building in workspace /root/.jenkins/workspace/nginx
The recommended git tool is: NONE
using credential 59788235-6e26-4fe4-b501-6a6f65b90907
> git rev-parse --resolve-git-dir /root/.jenkins/workspace/nginx/.git #
timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url http://192.168.11.10/root/mytest.git #
timeout=10
Fetching upstream changes from http://192.168.11.10/root/mytest.git
> git --version # timeout=10
> git --version # 'git version 1.8.3.1'
using GIT_ASKPASS to set credentials gitlab
> git fetch --tags --progress http://192.168.11.10/root/mytest.git
+refs/heads/*:refs/remotes/origin/* # timeout=10
> git rev-parse origin/1.2^{commit} # timeout=10
> git rev-parse 1.2^{commit} # timeout=10
Checking out Revision 4a3d07789a567ecd0aed82bc98bddd076d3c00a7 (1.2)
> git config core.sparsecheckout # timeout=10
> git checkout -f 4a3d07789a567ecd0aed82bc98bddd076d3c00a7 # timeout=10
Commit message: "change file version 1.2"
> git rev-list --no-walk 4a3d07789a567ecd0aed82bc98bddd076d3c00a7 #
timeout=10
[nginx] $ docker build -t 192.168.11.30/jenkins/nginx:1.2 --pull=true
/root/.jenkins/workspace/nginx
WARNING: Support for the legacy ~/.dockercfg configuration file and
file-format is deprecated and will be removed in an upcoming release
Sending build context to Docker daemon 68.61kB
Step 1/6 : FROM centos:7
7: Pulling from library/centos
Digest:
sha256:0f4ec88e21daf75124b8a9e5ca03c37a5e937e0e108a255d890492430789b60e
Status: Image is up to date for centos:7
---> 8652b9f0cb4c
Step 2/6 : LABEL maintainer bdqn
---> Using cache
---> e654b7e54109
Step 3/6 : RUN yum -y install yum-utils
---> Using cache
---> 1ff775120b31
Step 4/6 : COPY nginx.repo /etc/yum.repos.d/
---> Using cache
---> 37fa84992a73
Step 5/6 : RUN yum -y install nginx
---> Using cache
---> b398cfc50c45
Step 6/6 : CMD ["nginx","-g","daemon off;"]
---> Using cache
---> 13dc7ea9f79a
Successfully built 13dc7ea9f79a
Successfully tagged 192.168.11.30/jenkins/nginx:1.2
[nginx] $ docker tag 13dc7ea9f79a 192.168.11.30/jenkins/nginx:latest
WARNING: Support for the legacy ~/.dockercfg configuration file and
file-format is deprecated and will be removed in an upcoming release
[nginx] $ docker inspect 13dc7ea9f79a
WARNING: Support for the legacy ~/.dockercfg configuration file and
file-format is deprecated and will be removed in an upcoming release
[nginx] $ docker push 192.168.11.30/jenkins/nginx:1.2
WARNING: Support for the legacy ~/.dockercfg configuration file and
file-format is deprecated and will be removed in an upcoming release
The push refers to repository [192.168.11.30/jenkins/nginx]
9fa8a918c324: Preparing
30ddc06c9965: Preparing
634e449b866c: Preparing
174f56854903: Preparing
30ddc06c9965: Layer already exists
9fa8a918c324: Layer already exists
634e449b866c: Layer already exists
174f56854903: Layer already exists
1.2: digest:
sha256:e92ac93f6e1737841824cdf5a36ede4a736da9892ba2ee01009bfa3526025cf4 size:
1160
[nginx] $ docker push 192.168.11.30/jenkins/nginx:latest
WARNING: Support for the legacy ~/.dockercfg configuration file and
file-format is deprecated and will be removed in an upcoming release
The push refers to repository [192.168.11.30/jenkins/nginx]
9fa8a918c324: Preparing
30ddc06c9965: Preparing
634e449b866c: Preparing
174f56854903: Preparing
30ddc06c9965: Layer already exists
634e449b866c: Layer already exists
174f56854903: Layer already exists
9fa8a918c324: Layer already exists
latest: digest:
sha256:e92ac93f6e1737841824cdf5a36ede4a736da9892ba2ee01009bfa3526025cf4 size:
1160
[nginx] $ /bin/sh -xe
/usr/local/tomcat/temp/jenkins1710235867695216091.sh
+ ssh 192.168.11.40 'cd /data && sh deploy.sh 1.2'
old version is: latest
new version is: 1.1
deployment.apps "nginx" deleted
deployment.apps/nginx created
Finished: SUCCESS
在 k8s-master 节点上启动 Service,过程如下所示。
[root@k8s-master ~]#
cd /data && kubectl create -f nginx-svc.yaml
查看测试页面内容,如图 1.36 所示。
图 1.36 版本 1.1 测试页
如果出现 403 forbidden,可以修改 nginx 容器内配置文件/etc/nginx/nginx.conf,
将 运 行 用 户 修 改 为 root 用 户 , 重 新 reload 后 , 即 可 显 示 正 常 。 或 者 检 查
/usr/share/nginx/html 目录内的 index.html 是否有可读权限,添加上可读权限即可。
4.对程序进行更新
修改本地 E:\source_1\mytest\index.html 文件内容,将版本号改为 1.2。如下所示。
<html>
<head>
<title>my test</title>
</head>
<body>
<h1>version:
1.2
</h1>
</body>
</html>
通过 TortoiseGit 工具将修改后的 index.html 文件提交到 GitLab 主机中。
在 GitLab 的 mytest 项目页内,项目名称后面的下拉列表内选择“New tag”,创建新
tag,如图 1.37 所示。
图 1.37 新建 tag 选择
在弹出的创建新 tag 页面内,“Tag name”填写 1.2,其他不填写,单击“Create Tag”
按钮保存。
之后在 Jenkins 页面内,nginx 任务下,依然选择“Build with Parameters”,在右
侧选择新添加的版本 1.2 版本,然后单击“开始构建”等待构建结束。如图 1.38 所示。
图 1.38 版本 1.2 构建
再次访问测试页,已经升级成功。如图 1.39 所示。
图 1.39 更新程序后的测试页面