基于kubeadm部署k8s平台

修改主机名,关闭swap,并配置hosts映射

swap 启用后,在使用磁盘空间和内存交换数据时,性能表现会较差,会减慢程序执行的速度。

有的软件的设计师不想使用交换,例如:kubelet 在 v1.8 版本以后强制要求 swap 必须关闭,否则会报错

1
2
3
4
[root@master ~]# hostnamectl set-hostname master/node
[root@master ~]# swapoff -a

#删除/etc/fstab中swap

Yum源数据的持久化挂载

1
2
3
4
5
[root@master ~]# vi /etc/fstab
/root/bricsskills_cloud paas.iso /opt/paas iso9660 defaults
0 0
/root/CeniOS-7-x86 64-DVD-1804.iso /opt/centos iso9660 defaults 0 0
[root@master ~]# mount -a

Yum 源的编写

1
2
3
4
5
6
7
8
9
10
11
12
[root@master ~]# mv/etc/yum.repos.d/CentOS-* /home
[root@master ~]# vi/etc/yum.repos.d/local.repo
[k8s]
name=k8s
baseurl-file:///opt/paas/kubernetes-repo
gpgcheck-0
enabled=1
[centos]
name=centos
baseurl=file:///opt/centos
gpgcheck=0
enabled-1

在master节点安装ftp服务,将ftp共享目录设置为 /opt/。

1
2
3
[root@master ~]# yam install y ysftpd
[root@master ~]# echo "anon_root=/opt" >> /etc/vsftpd/vsftpd.conf
[root@master ~]# systemetl start vsftpd && systemcil enable vsftpd

node节点yum源编写

1
2
3
4
5
6
7
8
9
10
11
12
[root@node ~]# mv /ete/yum.repos.d/* /home
[root@node ~]# vim /etc/yum.repos.d/ftp.repo
[k8s]
name=k8s
baseurl=ftp://master/paas/kubernetes-repo
gpgcheck=0
enabled=1
[centos]
name=centos
baseurl=ftp://master/centos
gpgcheck=0
enabled=1

设置时间同步服务器

master节点

1
2
3
4
5
6
7
[root@master ~]# yum install -y chrony
[root@master ~]# vim /etc/chrony.conf
server 192.168.100.15 iburst ###masterIP
allow 192.168.100.0/24
local stratum 10
[root@master ~]# systemctl start chronyd
[root@master ~]# systemctl enable chronyd

node节点

1
2
3
4
5
6
7
8
[root@node ~]# yum install -y chrony
[root@node ~]# vi /etc/chrony.conf
server 192.168.100.15 iburst
[root@node ~]# systemctl start chronyd
[root@node ~]# systemctl enable chronyd

###测试
[root@node ~]# chronyc sources

设置免密登录

1
2
3
4
5
6
7
8
9
[root@master ~]# ssh-keygen
[root@master ~]# ssh-copy-id master
[root@master ~]# ssh-copy-id node
[root@master ~]# ssh-copy-id harbor

[root@node ~]# ssh-keygen
[root@node ~]# ssh-copy-id master
[root@node ~]# ssh-copy-id node
[root@node ~]# ssh-copy-id harbor

安装 docker 应用

1
2
3
4
5
6
7
8
###所有节点安装 docker-ce:
[root@master ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@master ~]# yum install -y docker-ce

###启动 Docker:
[root@master ~]# systemctl start docker
[root@master ~]# systemctl enable docker
[root@master ~]# docker version

所有节点配置阿里云镜像加速地址(https://5twf62k1.mirror.aliyuncs.com)并把启动引擎设置为 systemd,配置成功重启 docker 服务

1
2
3
4
5
6
7
8
9
###在所有节点调整部分docker 参数:
[root@master~]# vi/etc/docker/daemon.json
{
"registry-mirrors":["https://5twf62kl.mirror.aliyuncs.com"],
"exec-opts":["native.cgroupdriver=systemd"]
}

###重启dockers
[root@master~]# systemctl restart docker

修改 /etc/sysctl.conf

所有主机将桥接的IPv4流量传递到iptables的链

ipvs 称之为 IP虚拟服务器(IP Virtual Server,简写为 IPVS),由于 ipvs模块已经加入到了 linux 内核的主干,

所以为 kube-proxy(Kubernetes Service) 开启 ipvs 的前提需要加载以下的 linux 内核模块:

开启一些k8s集群中必须的内核参数,所有节点配置k8s内核

1
2
3
4
5
6
7
modprobe br_netfilter

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf

sysctl -p

安装 docker-compose

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master~]# cp -f /opt/paas/docker-compose/v1.25.5-docker-compose-Linux-x86.64 \
> /usr/local/bin/docker-compose
[root@master~]# scp -f /opt/paas/docker-compose/v1.25.5-docker-compose-Linux-x86.64 \
> harbor:/usr/local/bin/docker-compose
[root@master~]# scp -f /opt/paas/docker-compose/v1.25.5-docker-compose-Linux-x86.64 \
> node:/usr/local/bin/docker-compose

[root@master~]# chmod +x /usr/local/bin/docker-compose
[root@master~]# docker-compose version
docker-compose version 1.25.5, build 8alc60f6
docker-py version:4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.01 10 Sep 2019

搭建 horbor仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Harbor 节点部署 Harbor解压安装包:
[root@harbor ~]# cd /opt/paas/harbor/
[root@harbor ~]# tar -zxvf harbor-offline-installer-y2.1.0.tgz -C /usr/local/
[root@harbor ~]# cd /usr/local/harbor/
修改 Harbor配置信息:
[root@harbor ~]# cp harbor.yml.tmpl harbor.yml
[root@harbor ~]# vi harbor.yml
hostname:192.168.100.93# 将域名修改为本机IP
harbor admin password: Harborl2345
#https:#禁用https
# https port for harbor, default is 443
# port: 443
# The path ofcert and key files for nginx
#certificate: /your/certificate/path
# private key: /your/private/key/path

###启动 Harbor:
[root@harbor ~]# ./prepare
[root@harbor ~]# ./installsh --with-clair

修改默认仓库地址:

1
2
3
4
5
6
7
8
[root@master~]# vi /etc/docker/daemonjson
{
"insecure-registries": ["192,168.100.93"],
"registry-mirrors": ["https://5twf62kI.mirroraliyuncs.com"],
"exec-opts": ["nutiye.cgrouipdriver systemd"]
}

[root@master~]# systemetl restart docker

各节点登录harbor

1
2
3
4
5
6
[root@master~]# doeker login 192.168.100.93
Username:admin
Password:
WARNING! Your password will be stored unencrypted in /root..docker/config.jsonConfigure
a credential helper to remove this warning.See
https:/docsdocker.com/engine/reference/commandline/login/#credentials-store

上传 docker 镜像

1
2
3
[root@master~]# for i in $(ls /opt/paas/images);do docker load -i $i ; done

[root@master~]# sh /opt/paas/k8s image_push.sh

安装kubeadm 工具

在master节点、nodel节点、node2 节点分别安装Kubeadm 工具并设置为开机自启动

1
2
[root@master~]# yum install kubeadm-1.18 1 kubectl-1.18.1 kubelet-1.18.1 -y
[root@master~]# systemnctl enable kubelet && systemctl start kubelet

初始化master节点

使用 kubcadm命令生成yaml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master~]# kubeadm config print init-defaults > kubeadm-config.yaml
[root@master~]# vi kubeadm-config.yaml
localAPIEndpoint:
advertiseAddress:192.168.100.15 ###修改为 master 主机 P 地址
imageRepository: 192.168.1.00.16/library/ ###修改为本地镜像仓库地
kubernetesVersion: vl.18.1 ###修改版本号为当前版本号
networking:
dnsDomain: cluster.local
serviceSubnet:10.96.0.0/12
podSubnet: 10.244.0.0/16 ###添加此 subnet 项

###根据yaml文件使用 kubeadm 命令初始化master节点
[root@master~]# kubeadm init --config kubeadm-config.yaml

使用命令初始化

1
2
3
[root@master~]# kubeadm init --kubernetes-version=1.18.1 \
> --apiserver-advertise-address=192.168.100.15 \
> --image-repository 192.168.100.16/library --pod-network-cidr=10.244.0.0/16

初始化完成后执行命令

kubectl 默认会在执行的用户家目录下面的.kube 目录下寻找config 文件。

这里是将在初始化时[kubeconfig]步骤生成的admin.conf 拷贝到.kube/config

1
2
3
[root@master~]# mkdir-p SHOME/.kube/config
[root@master~]# sudo cp -i/etc/kubernetes/admin.conf SHOME/.kube/config
[root@master~]# sudo chown S(id-u):$(id -g)SHOME/kube/config

查看状态

1
2
3
4
5
6
7
8
9
10
11
###查看集群状态:
[root@master~]# kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"healthy":"true"}

###查看节点状态:
[root@master~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady master 6mls v1.18.1

在初始化 k8s-master 时并没有网络相关配置,所以无法跟 node 节点通信,因此状态都是“NotReady”。

安装网络插件

1
2
3
4
[root@master~]# kubectl apply -f yaml/kube-flannel.yaml   ###需要修改镜像地址
[root@master~]# kubectl get nodes
NAME STATUS ROLES AGL VERSION
master Ready master 17m V1.18.1

删除污点

1
[root@master~]# kubectl taint nodes master node-role,kubernetes.io/master=:NoSchedule-

给kubernetes 创建证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@master~]# mkdir dashboard-certs
[root@master~]# cd dashboard-certs/
[root@master~]# kubectl create namespace kubernetes-dashboard
[root@master~]# openssl genrsa -out dashboard.key 2048
Generating RSA private key, 2048 bit long modulus
.........+++
..................+++
eis 65537(0x10001)
[root@master~]# openssl req -days 36000 -new -out dashboard.csr \
-key dashboard.key -subj '/CN=dashboard-cert'
[root@master~]# openssl x509 -req -in dashboard.csr -signkey dashboard.key \
-out dashboard.crt
Signature ok
subject=/CN=dashboard-cert
Getting Private key
[root@master~]# kubectl create secret generic kubernetes-dashboard-certs \
--from-file=dashboard.key --from-file=dashboard.crt -n kubernetes-dashboard

图形化界面安装

1
2
3
4
5
6
7
[root@master~]# sed -i "s/kubernetesui/$IP\/library/g" /opt/yaml/dashboard/recommended.yaml
[root@master~]# kubectl apply -f /opt/yaml/dashboard/recommended.yaml
[root@master~]# kubectl apply -f /opt/yaml/dashboard/dashboard-adminuser.yaml

###登录信息
[root@master~]# kubectl describe secrets -n kubernetes-dashboard \
> dashboard-admin-token-7zzs9

将node加入集群

1
2
3
4
5
6
7
8
###在master节点获取证书
[root@master~]# kubeadm token create --ttl=0 ###永久有效 \
> --print-join-command #打印命令

###将输出的命令在node节点执行

###如果加入失败
kubeadm reset重置kubernetes再次加入

安装metrics

1
2
3
4
修改api-server启动参数
vim /etc/kubernetes/manifests/kube-apiserver.yaml
###spec.container.command中添加
- --enable-aggregator-routing=true

kubelet证书

1
2
3
4
5
metrics使用kubelet证书,为kubelet签发证书
在/var/lib/kubelet/config.yaml配置文件中添加
serverTLSBootstrap: true
###重启服务
[root@master ~]# systemctl restart kubelet.service

签发证书

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master ~]# kubectl get certificatesigningrequests.certificates.k8s.io 
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-5qgq9 20s kubernetes.io/kubelet-serving system:node:node Pending
csr-9v68k 101s kubernetes.io/kubelet-serving system:node:master Pending
csr-tw8s7 69m kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:w1no5l Approved,Issued
csr-wv7vv 82m kubernetes.io/kube-apiserver-client-kubelet system:node:master Approved,Issued
[root@master ~]# kubectl certificate
approve deny

[root@master ~]# kubectl certificate approve csr-5qgq9
certificatesigningrequest.certificates.k8s.io/csr-5qgq9 approved
[root@master ~]# kubectl certificate approve csr-9v68k
certificatesigningrequest.certificates.k8s.io/csr-9v68k approved

基于kubeeasy部署k8s平台

基础环境配置

将提供的安装包chinaskills_cloud_paas_v2.0.iso下载至master节点/root目录,并解压到/opt目录:

1
2
3
[root@localhost ~]# mount -o loop chinaskills_cloud_paas_v2.0.1.iso /mnt/
[root@localhost ~]# cp -rfv /mnt/* /opt/
[root@localhost ~]# umount /mnt/

安装kubeeasy

kubeeasy为Kubernetes集群专业部署工具,极大的简化了部署流程。其特性如下:

  • 全自动化安装流程;
  • 支持DNS识别集群;
  • 支持自我修复:一切都在自动扩缩组中运行;
  • 支持多种操作系统(如 Debian、Ubuntu 16.04、CentOS7、RHEL等);
  • 支持高可用。

在master节点安装kubeeasy工具:

1
[root@localhost ~]# mv /opt/kubeeasy /usr/bin/kubeeasy

安装依赖包

此步骤主要完成docker-ce、git、unzip、vim、wget等工具的安装。

在master节点执行以下命令完成依赖包的安装:

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost ~]# kubeeasy install depend \
--host 10.24.2.10,10.24.2.11 \
--user root \
--password Abc@1234 \
--offline-file /opt/dependencies/base-rpms.tar.gz

##重置kubeeasy:
[root@localhost ~]# kubeeasy reset --force \
--master 192.168.200.3 \
--worker 192.168.200.11 \
--user root \
--password 000000

参数解释如下:

  • –host:所有主机节点IP,如:10.24.1.2-10.24.1.10,中间用“-”隔开,表示10.24.1.2到10.24.1.10范围内的所有IP。若IP地址不连续,则列出所有节点IP,用逗号隔开,如:10.24.1.2,10.24.1.7,10.24.1.9。
  • –user:主机登录用户,默认为root。
  • –password:主机登录密码,所有节点需保持密码一致。
  • –offline-file:离线安装包路径。

可通过命令“tail -f /var/log/kubeinstall.log”查看安装详情或排查错误。

配置SSH免密钥

安装Kubernetes集群的时候,需要配置Kubernetes集群各节点间的免密登录,方便传输文件和通讯。

在master节点执行以下命令完成集群节点的连通性检测:

1
2
3
4
[root@localhost ~]# kubeeasy check ssh \
--host 10.24.2.10,10.24.2.11 \
--user root \
--password Abc@1234

在master节点执行以下命令完成集群所有节点间的免密钥配置:

1
2
3
4
[root@localhost ~]# kubeeasy create ssh-keygen \
--master 10.24.2.10 \
--worker 10.24.2.11 \
--user root --password Abc@1234

–mater参数后跟master节点IP,–worker参数后跟所有worker节点IP。

安装Kubernetes集群

本次安装的Kubernetes版本为v1.22.1。

在master节点执行以下命令部署Kubernetes集群:

1
2
3
4
5
6
7
[root@localhost ~]# kubeeasy install kubernetes \
--master 10.24.2.10 \
--worker 10.24.2.11 \
--user root \
--password Abc@1234 \
--version 1.22.1 \
--offline-file /opt/kubernetes.tar.gz

部分参数解释如下:

  • –master:Master节点IP。
  • –worker:Node节点IP,如有多个Node节点用逗号隔开。
  • –version:Kubernetes版本,此处只能为1.22.1。

可通过命令“tail -f /var/log/kubeinstall.log”查看安装详情或排查错误。

部署完成后查看集群状态:

1
2
3
4
5
6
[root@k8s-master-node1 ~]# kubectl cluster-info
Kubernetes control plane is running at https://apiserver.cluster.local:6443
CoreDNS is running at
https://apiserver.cluster.local:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

在浏览器上访问一道云云开发平台(http://master_IP:30080),设置admin用户的密码(Abc@1234Abc@1234)

1.png

完成后进入平台页面

2.png

部署KubeVirt

在本次安装的KubeVirt版本为v0.47.1。

在master节点执行以下命令安装KubeVirt:

1
[root@k8s-master-node1 ~]# kubeeasy add --virt kubevirt

查看Pod:

1
[root@k8s-master-node1 ~]# kubectl get pod -A

基本使用

创建vmi:

1
# kubectl create -f vmi.yaml

查看vmi:

1
# kubectl get vmis

删除vmi:

1
# kubectl delete vmis <vmi-name>

virtctl工具

virtctl是KubeVirt自带的类似于kubectl的命令行工具,可以直接管理虚拟机,可以控制虚拟机的start、stop、restart等。

启动虚拟机命令:

1
# virtctl start <vmi-name>

停止虚拟机命令:

1
# virtctl stop <vmi-name>

重启虚拟机命令:

1
# virtctl restart <vmi-name>

在Kubernetes集群上完成KubeVirt虚拟化环境的安装。

完成后在master节点执行kubectl -n kubevirt get deployment命令进行验证:

1
2
3
4
5
# kubectl -n kubevirt get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
virt-api 2/2 2 2 85s
virt-controller 2/2 2 2 60s
virt-operator 2/2 2 2 2m2s

部署Istio

安装Istio

本次安装的Istio版本为v1.12.0。

在master节点执行以下命令进行Istio服务网格环境的安装:

1
[root@k8s-master-node1 ~]# kubeeasy add --istio istio

查看Pod:

1
2
3
4
5
6
7
8
9
[root@k8s-master-node1 ~]# kubectl -n istio-system get pods
NAME READY STATUS RESTARTS AGE
grafana-6ccd56f4b6-twwjv 1/1 Running 0 5m15s
istio-egressgateway-7f4864f59c-nxz2l 1/1 Running 0 5m34s
istio-ingressgateway-55d9fb9f-jzhnb 1/1 Running 0 5m34s
istiod-555d47cb65-jwkgp 1/1 Running 0 5m40s
jaeger-5d44bc5c5d-h9t29 1/1 Running 0 5m15s
kiali-79b86ff5bc-v9sfk 1/1 Running 0 5m15s
prometheus-64fd8ccd65-5px64 2/2 Running 0 5m15s

查看Istio版本信息:

1
2
3
4
[root@k8s-master-node1 ~]# istioctl version
client version: 1.12.0
control plane version: 1.12.0
data plane version: 1.12.0 (2 proxies)

istio命令自动补齐

1
[root@k8s-master-node1 ~]# istioctl completion bash > /etc/bash_completion.d/istioctl

Istio可视化

访问Grafana(http://master_IP:33000)

3.png

访问Prometheus(http://master_IP:30090)

4.png

5.png

访问Jaeger(http://master_IP:30686)

6.png

访问Kiali(http://master_IP:20001)

7.png

istioctl基本使用

istioctl用于在Istio系统中创建、列出、修改以及删除配置资源。

可用的路由和流量管理配置类型有virtualservice、gateway、destinationrule、serviceentry、httpapispec、httpapispecbinding、quotaspec、quotaspecbinding、servicerole、servicerolebinding、policy。

使用下面命令展示istioctl可以访问到的Istio配置档的名称:

1
2
3
4
5
6
7
8
9
10
# istioctl profile list
Istio configuration profiles:
default
demo
empty
external
minimal
openshift
preview
remote

展示配置档的配置信息:

1
# istioctl profile dump demo

显示配置文件的差异:

1
# istioctl profile diff default demo

可以使用proxy-status或ps命令概览服务网格:

1
# istioctl proxy-status

如果输出列表中缺少某个代理,则意味着它当前未连接到Polit实例,所以它无法接收到任何配置。此外,如果它被标记为stale,则意味着存在网络问题或者需要扩展Pilot。

istioctl允许使用proxy-config或者pc命令检索代理的配置信息。

检索特定Pod中Envoy实例的集群配置的信息:

1
# istioctl proxy-config cluster <pod-name> [flags]

检索特定Pod中Envoy实例的bootstrap配置的信息:

1
# istioctl proxy-config bootstrap <pod-name> [flags]

检索特定Pod中Envoy实例的监听器配置的信息:

1
# istioctl proxy-config listener <pod-name> [flags]

检索特定Pod中Envoy实例的路由配置的信息:

1
# istioctl proxy-config route <pod-name> [flags]

检索特定Pod中Envoy实例的endpoint配置的信息:

1
# istioctl proxy-config endpoints <pod-name> [flags]

istioctl基础案例

在Kubernetes集群上完成Istio服务网格环境的安装,然后新建命名空间exam,为该命名空间开启自动注入Sidecar:

1
2
# kubectl create namespace exam
# kubectl label namespace exam istio-injection=enabled

在master节点执行kubectl -n istio-system get all命令和kubectl get ns exam –show-labels命令进行验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# kubectl -n istio-system get all
NAME READY STATUS RESTARTS AGE
pod/grafana-6ccd56f4b6-ssmbl 1/1 Running 0 81s
pod/istio-egressgateway-7f4864f59c-qm7wn 1/1 Running 0 97s
pod/istio-ingressgateway-55d9fb9f-jd4pn 1/1 Running 0 97s
pod/istiod-555d47cb65-p5cmq 1/1 Running 0 104s
pod/jaeger-5d44bc5c5d-xqvbj 1/1 Running 0 81s
pod/kiali-9f9596d69-2wsjl 1/1 Running 0 80s
pod/prometheus-64fd8ccd65-w2zrg 2/2 Running 0 80s
......

# kubectl get ns exam --show-labels
NAME STATUS AGE LABELS
exam Active 28s istio-injection=enabled

部署Harbor仓库

在master节点执行以下命令进行Harbor仓库的安装:

1
[root@k8s-master-node1 ~]# kubeeasy add --registry harbor

部署完成后查看Harbor仓库状态:

1
2
3
4
5
6
7
8
9
10
11
[root@k8s-master-node1 ~]# systemctl status harbor
● harbor.service - Harbor
Loaded: loaded (/usr/lib/systemd/system/harbor.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2021-12-06 14:34:49 CST; 30s ago
Docs: http://github.com/vmware/harbor
Main PID: 7819 (docker-compose)
Tasks: 12
Memory: 11.5M
CGroup: /system.slice/harbor.service
└─7819 /usr/local/bin/docker-compose -f /opt/harbor/docker-compose.yml up
Hint: Some lines were ellipsized, use -l to show in full.

在Web端通过http://master_ip访问Harbor

8.png

登录Harbor

使用管理员账号(admin/Harbor12345)登录Harbor

9.png

docker-compose和Helm安装部署

在docker-compose和Helm的安装部署嵌套在Harbor安装部署包内,安装Harbor的同时,也安装了docker-compose以及Helm。

helm常用命令

命令自动补全:

1
[root@k8s-master-node1 ~]# helm completion bash > /etc/bash_completion.d/helm

查看版本信息:

1
# helm version

查看当前安装的Charts:

1
# helm list

查询Charts:

1
# helm search <chart-name>

查看Charts状态:

1
# helm status <chart-name>

删除Charts:

1
# helm delete --purge <chart-name>

创建Charts:

1
# helm create helm_charts

测试Charts语法:

1
# helm lint

打包Charts:

1
# cd helm_charts && helm package ./

查看生成的yaml文件:

1
# helm template helm_charts-xxx.tgz

Helm基础案例

在master节点上完成Harbor镜像仓库及Helm包管理工具的部署。然后使用nginx镜像自定义一个Chart,Deployment名称为nginx,副本数为1,然后将该Chart部署到default命名空间下,Release名称为web:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@k8s-master-node1 ~]# helm create mychart
Creating mychart

[root@k8s-master-node1 ~]# rm -rf mychart/templates/*
[root@k8s-master-node1 ~]# vi mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx

[root@k8s-master-node1 ~]# helm install web mychart
NAME: web
LAST DEPLOYED: Tue Sep 13 16:23:12 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

在master节点执行helm status web命令进行验证:

1
2
3
4
5
6
7
[root@k8s-master-node1 ~]# helm status web
NAME: web
LAST DEPLOYED: Tue Sep 13 16:23:12 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

基础运维

重置集群

若集群部署失败或出现故障,可重置集群重新部署,重置命令如下:

1
[root@k8s-master-node1 ~]# kubeeasy reset

重置完成后再次执行安装步骤,即可重新部署集群。

添加节点

在master节点执行以下命令安装依赖包:

1
2
3
4
5
[root@k8s-master-node1 ~]# kubeeasy install depend \
--host 10.24.2.12 \
--user root \
--password Abc@1234 \
--offline-file /opt/dependencies/base-rpms.tar.gz

其中10.24.2.12为新增节点的IP地址。

在master节点执行以下命令即可加入集群:

1
2
3
4
5
[root@k8s-master-node1 ~]# kubeeasy add \
--worker 10.24.2.12\
--user root \
--password Abc@1234 \
--offline-file /opt/kubernetes.tar.gz

Kubeeasy命令

kubeeasy 为 Kubernetes 集群专业部署工具,极大的简化了部署流程。其特性如下:

 全自动化安装流程;

 支持 DNS 识别集群;

 支持自我修复:一切都在自动扩缩组中运行;

 支持多种操作系统(如 Debian、Ubuntu 16.04、CentOS7、RHEL 等);

 支持高可用。

查看帮助

1
# kubeeasy --help

基础ssh配置

集群连通性检测-ssh

1
2
3
4
kubeeasy check ssh \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000

集群免秘钥设置

1
2
3
4
5
kubeeasy create ssh-keygen \
--master 192.168.1.201 \
--worker 192.168.1.202,192.168.1.203 \
--user root \
--password 00000

集群安装依赖包

1
2
3
4
5
kubeeasy install dependencies \
--host 10.24.2.31,10.24.2.14,10.24.2.46 \
--user root \
--password 000000 \
--offline-file /opt/dependencies/base-rpms.tar.gz

磁盘挂载

使用kubeeasy在集群中挂载数据盘,将其挂载到/data目录,后续的数据存储路径默认都是在/data目录下

磁盘挂载(集群磁盘名相同时)

1
2
3
4
5
6
kubeeasy create mount-disk \
--host 192.168.1.201-192.168.1.203 \
--disk /dev/sdb \
--mount-dir /data \
--user root \
--password 000000

磁盘挂载(集群磁盘名不同时只能按顺序操作)

1
2
3
4
5
6
kubeeasy create mount-disk \
--host 192.168.1.201 \
--disk /dev/sdb \
--mount-dir /data \
--user root \
--password 000000

集群升级系统内核

使用kubeeasy升级集群的内核,将其3.10的内核升级为5.14(建议升级内核)。脚本执行完后,会自动重启主机,以生效系统内核。

1
2
3
4
5
kubeeasy install upgrade-kernel \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000 \
--offline-file ./kernel-rpms-v5.17.9.tar.gz

部署K8S集群

使用kubeeasy部署K8S集群,以下分为普通集群高可用集群的安装方式,根据实际情况选择一种方案部署。安装后的K8S的版本为v1.21.3,使用docker作为容器运行时,网络组件使用calico网络,默认还安装kuboard图形化管理器和K8S存储类(openebs-hostpath),K8S的证书有效期为100年,且开启了证书轮换

[label]如需更改K8S的Pod网段,修改–pod-cidr参数相应的值[/label]

安装k8s集群

1
2
3
4
5
6
7
8
kubeeasy install kubernetes \
--master 192.168.1.201 \
--worker 192.168.1.202,192.168.1.203 \
--user root \
--password 000000 \
--version 1.21.3 \
--pod-cidr 10.244.0.0/16 \
--offline-file ./kubeeasy-v1.3.2.tar.gz

安装高可用k8s集群(master节点个数必须大于等于3)

1
2
3
4
5
6
7
8
9
kubeeasy install kubernetes \
--master 192.168.1.201,192.168.1.202,192.168.1.203 \
--worker 192.168.1.204 \
--user root \
--password 000000 \
--version 1.21.3 \
--virtual-ip 192.168.1.250 \
--pod-cidr 10.244.0.0/16 \
--offline-file ./kubeeasy-v1.3.2.tar.gz

重置K8S节点

使用kubeeasy将集群重置(意思就是删除所有相关软件,恢复一个纯净的系统)

重置正常的K8S集群(会重置整个集群)

1
2
3
kubeeasy reset \
--user root \
--password 000000

强制重置指定的节点(如果节点不正常可以选择强制重置节点)

1
2
3
4
5
kubeeasy reset --force \
--master 192.168.1.201 \
--worker 192.168.1.202 \
--user root \
--password 000000

增加K8S节点

使用kubeeasy将新的节点加入K8S集群中

离线增加K8S节点

增加master节点只适用于高可用集群的模式

1
2
3
4
5
6
7
8
9
10
11
12
# 需要先安装依赖包
kubeeasy install depend \
--host 192.168.1.204,192.168.1.205 \
--user root \
--password 000000 \
--offline-file ./centos-7-rpms.tar.gz
# 加入K8S集群
kubeeasy add \
--worker 192.168.1.204,192.168.1.205
--user root \
--password 000000 \
--offline-file ./kubeeasy-v1.3.2.tar.gz

从普通的K8S集群转换为高可用的K8S集群

修改集群配置文件

修改/root/.kubeeasy/cluster文件,将ha=0改为ha=1,vip=改为vip=10.24.3.10 (自身环境的虚拟IP)

1
2
ha=1
vip=10.24.3.10

部署kube-vip

下载kube-vip.yaml,并修改vip和interface

1
2
3
4
cp /tmp/kubeeasy/manifests/kube-vip.yaml ./
vi +15 kube-vip.yaml ## 管理网卡接口
vi +37 kube-vip.yaml ## 管理网卡接口的虚拟IP地址
mv kube-vip.yaml /etc/kubernetes/manifests/

查看kube-vip

1
2
kubectl get pod -n kube-system
ip addr show eth0

加入master节点

1
2
3
4
kubeeasy add \
--master 10.24.2.25
--user root \
--password 000000

删除K8S节点

使用kubeeasy将节点从K8S集群中删除

删除操作会重置节点,包括删除K8S服务、docker数据等清空操作

1
2
3
4
kubeeasy delete \
--worker 192.168.1.202,192.168.1.203
--user root \
--password 000000

移除K8S节点

使用kubeeasy将节点从K8S集群中移除

移除操作会不会重置节点,只是从K8S集群中移除,并不会删除docker的数据

1
2
3
4
kubeeasy remove \
--worker 192.168.1.202,192.168.1.203
--user root \
--password 000000

集群分发并读取容器镜像

使用kubeeasy将容器镜像离线包分发到指定节点并读取,如test-images.tar.gz。

分发现有的容器镜像并读取

1
2
3
4
5
kubeeasy images load \
--host 192.168.1.201,192.168.1.201,192.168.1.203 \
--user root \
--password 000000 \
--offline-file test-images.tar.gz

容器镜像

使用kubeeasy将容器列表文件的镜像保存到指定目录、也可以将其上传到镜像仓库中,但前提是您需要先登录镜像仓库。

images-list.txt文件命名规范:

test :表示一个镜像包集,下方区域是镜像列表,保存后以test命名

保存镜像离线包

1
2
3
kubeeasy images save \
--images-file images-list.txt \
--images-dir ./images

推送镜像到仓库

1
2
3
4
docker login dockerhub.kubeeasy.local:5000 -u admin -p admin
kubeeasy images push \
--images-file images-list.txt \
--images-registry dockerhub.kubeeasy.local:5000/kongyu

集群优化系统配置

1
2
3
4
5
6
## 依赖于sshpass命令,需要先安装此命令
rpm -ivh https://mirrors.aliyun.com/centos/7/extras/x86_64/Packages/sshpass-1.06-2.el7.x86_64.rpm
kubeeasy install precondition \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000

集群使用命令

1
2
3
4
5
kubeeasy get command \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000 \
--cmd "hostname"

集群时间同步设置

1
2
3
4
5
kubeeasy create time \
--master 192.168.1.201 \
--worker 192.168.1.202,192.168.1.203 \
--user root \
--password 000000

集群系统指标检测(CPU Memory Disk)

1
2
3
4
kubeeasy check system \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000

集群连通性检测-ping

1
2
kubeeasy check ping \
--host 192.168.1.201-192.168.1.203

修改集群root密码

1
2
3
4
kubeeasy create password \
--host 192.168.1.201-192.168.1.203 \ --user root \
--password 000000 \
--new-password 123456

清除历史命令

1
2
3
4
kubeeasy set history \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000

基础运维

资源管理

  • kubectl explain DaemonSet –recursive 可查看模板

  • kubectl api-resources 可以查看资源的kind

pod管理

在master节点/root目录下编写yaml文件nginx.yaml,具体要求如下:

(1)Pod名称:nginx-pod;

(2)命名空间:default;

(3)容器名称:mynginx;

(4)镜像:nginx;拉取策略:IfNotPresent;

(5)容器端口:80。

(6)并将其调度到节点为disk=stat上

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
nodeSelector:
disk: stat
containers:
- image: 192.168.121.21/library/nginx:latest
name: mynginx
ports:
- containerPort: 80
imagePullPolicy: IfNotPresent

指定在命名空间内创建一个Pod名称为test,内含四个指定的镜像nginx、redis、memcached、busybox。

1
2
kubectl run test --image=nginx --image=redis --image=memcached \
> --image=busybox --restart=Never -n <namespace>

创建一个Pod名称为test,镜像为nginx,Volume名称cache-volume为挂在在/data目录下,且Volume是non-Persistent(不持久的)的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: nginx
volumeMounts:
- mountPath: /data
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}

提供一个Pod的yaml,要求添加Init Container,Init Container的作用是创建一个空文件,Pod的Containers判断文件是否存在,不存在则退出。

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Pod
metadata:
name: init-demo
spec:
containers:
- name: nginx
image: busybox:1.28
command:['sh', '-c', 'if [ ! -e "/opt/myfile"]; then exit;fi;']
initContainers:
- name: install
image: busybox
command: ['sh', '-c', 'touch /opt/myfile']

列出Service名为test下的Pod并找出使用CPU使用率最高的一个,将Pod名称写入文件中。

1
2
Kubectl get svc test -o wide (找到app=xxx)
Kubectl top pods -l ‘app=xxx’

使master节点不可调度,并重新分配该节点上的Pod

1
2
3
#直接drain(驱逐节点上所有pod)会出错,
#需要添加--ignore-daemonsets --delete-local-data参数(忽略守护进程--删除本地数据)
kubectl drain master --ignore-daemonsets --delete-local-data

Deployment管理

在master节点/root目录下编写yaml文件nginx-deployment.yaml,具体要求如下:

(1)Deployment名称:nginx-deployment;

(2)命名空间:default;

(3)Pod名称:nginx-deployment,副本数:2;

(4)网络:hostNetwork;

(5)镜像:nginx;

(6)容器端口:80

(7)实现资源限制 :需求内存 300Mi,需求 CPU 300M,限制内存 450Mi,限制 CPU 450M

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: apps/v1 
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
labels:
app: nginx-deployment
spec:
hostNetwork: true
containers:
- name: nginx-deployment
image: 192.168.121.21/library/nginx:latest
ports:
- containerPort: 80
resources:
requests:
cpu: 0.3
memory: 300Mi
limits:
cpu: 0.3
memory: 300Mi

将deployment为nginx-app的副本数从1变成4。

1
Kubectl scale --replicas=4 deployment nginx-app

创建nginx-app的deployment,使用镜像为nginx:1.11.0-alpine,修改镜像为1.11.3-alpine,并记录升级,再使用回滚,将镜像回滚至nginx:1.11.0-alpine。

1
2
3
4
5
6
# 创建nginx-app的deployment
kubectl run nginx-app --image=nginx:1.11.0-alpine --record #记录
# 修改镜像,nginx-app为container的名字
kubectl set image deployment nginx-app nginx-app=nginx:1.11.3-alipne
# 回滚
kubectl rollout undo deployment nginx-app

ReplicaSet管理

在master节点/root目录下编写yaml文件replicaset.yaml,具体要求如下:

(1)Replicaset名称:nginx;

(2)命名空间:default;

(3)副本数:3;

(4)镜像:nginx。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
namespace: default
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: 192.168.121.21/library/nginx:latest
ports:
- contarinerPort: 80

Namespace管理

在master节点/root目录下编写yaml文件my-namespace.yaml,具体要求如下:

(1)Namespace名称:test。

1
2
3
4
5
[root@master ~]# vi my-namespace.yaml 
apiVersion: v1
kind: Namespace
metadata:
name: test

Service管理

在master节点/root目录下编写yaml文件service-clusterip.yaml,具体要求如下:

(1)Service名称:service-clusterip;

(2)命名空间:default;

(3)集群内部访问端口:80;targetPort: 81;

(4)Service类型:ClusterIP。

1
2
3
4
5
6
7
8
9
10
11
12
[root@master ~]# vi service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: default
spec:
ports:
- port: 80
targetPort: 81
protocol: TCP
type: ClusterIP

RBAC管理

在master节点/root目录下编写yaml文件role.yaml,具体要求如下:

(1)Role名称:pod-reader;

(2)命名空间:default;

(3)对default命名空间内的Pod拥有get、watch、list的权限。

1
2
3
4
5
6
7
8
9
10
[root@master ~]# vi role.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","watch","list"]

PV管理

在master节点/root目录下编写yaml文件pv.yaml,具体要求如下:

(1)PV名称:pv-local;

(2)命名空间:default;

(3)回收策略:Delete;

(4)访问模式:RWO;

(5)挂载路径:node节点/data/k8s/localpv;

(6)卷容量:5G。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@master ~]# vi pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-local
namespace: default
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /data/k8s/localpv
nodeAffinity: #定义应用在哪一个节点上(亲和)
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- 192.168.100.20

列出环境内所有的pv并以name字段排序

1
2
Kubectl get pv --stor-by=.metadata.name
Kubectl get pv --stor-by=.spec.capacity.storage (以capacity排序)

创建一个pv,类型是hostPath,位于/data中,大小1G,模式ReadOnlyMany

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-host
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle
hostPath:
path: /data

HPA管理

在master节点/root目录下编写yaml文件hpa.yaml,具体要求如下:

(1)HPA名称:frontend-scaler;

(2)命名空间:default;

(3)副本数伸缩范围:3–10;

(4)期望每个Pod的CPU使用率为50%。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@master ~]# vi hpa.yaml 
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: frontend-scaler
namespace: default
spec:
minReplicas: 3
maxReplicas: 10
scaleTargetRef:
apiVersion: v1
kind: Pod
name: test
targetCPUUtilizationPercentage: 50

Secrets管理

在master节点/root目录下编写yaml文件secret.yaml,具体要求如下:

(1)Secret名称:mysecret;

(2)命名空间:default;

(3)类型:Opaque;

(4)username: YWRtaW4=;password: MWYyZDFlMmU2N2Rm。

1
2
3
4
5
6
7
8
9
10
[root@master ~]# vi secret.yaml 
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: default
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm

创建Secret名为mysecret,内含有password字段,值为bob,然后在Pod1里使用ENV进行调用,Pod2里使用Volume挂载在/data下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#将密码值使用base64加密,记录在Notepad里
echo -n 'bob' | base64
Ym9i

secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque(不透明)
data:
password: Ym9i

pod1.yaml ###使用env进行调用
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef(密钥引用):
name: mysecret
key: password

pod2.yaml ###挂载到data目录下
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: mypod
image: nginx
volumeMounts:
- name: mysecret
mountPath: "/data"
readOnly: true
volumes:
- name: mysecret
secret:
secretName: mysecret

NetworkPolicy管理

在master节点/root目录下编写yaml文件network-policy-deny.yaml,具体要求如下:

(1)NetworkPolicy名称:default-deny;

(2)命名空间:default;

(3)默认禁止所有入Pod流量。

1
2
3
4
5
6
7
8
9
10
[root@master ~]# vi network-policy-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress

健康检查

在master节点/root目录下编写yaml文件liveness_httpget.yaml,具体要求如下:

(1)Pod名称:liveness-http;

(2)命名空间:default;

(3)镜像:nginx;端口:80;

(4)容器启动时运行命令“echo Healty > /usr/share/nginx/html/healthz”;

(5)httpGet请求的资源路径为/healthz,地址默认为Pod IP,端口使用容器中定义的端口名称HTTP;

(6)启动后延时30秒开始运行检测;

(7)每隔3秒执行一次liveness probe。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
namespace: default
spec:
containers:
- name: nginx
image: 192.168.100.10/library/nginx:latest
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- echo Healty > /usr/share/nginx/html/healthz
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 30
periodSeconds: 3

ResourceQuota管理

创建命名空间quota-example,在master节点/root目录下编写yaml文件quota.yaml,具体要求如下:

(1)ResourceQuota名称:compute-resources;

(2)命名空间:quota-example;

(3)命名空间内所有Pod数量不超过4;

(4)命名空间内所有容器内存申请总和不得超过1G;

(5)命名空间内所有内存限制不得超过2G;

(6)命名空间内所有容器申请的CPU不得超过1;

(7)命名空间内所有容器限制的CPU不得超过2。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@master ~]# kubectl create ns quota-example
namespace/quota-example created

[root@master ~]# vi quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: quota-example
spec:
hard:
pods: "4"
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi

Volume管理

在master节点/root目录下编写yaml文件emptydir.yaml,具体要求如下:

(1)Pod名称:pod-emptydir;

(2)命名空间:default;

(3)镜像:nginx;

(4)Volume类型:emptyDir;名称data-volume;

(5)挂载路径:/data。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@master ~]# vi emptydir.yaml 
apiVersion: v1
kind: Pod
metadata:
name: pod-emptydir
namespace: default
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
emptyDir: {}

DaemonSet管理

在master节点/root目录下编写yaml文件daemonset.yaml,具体要求如下:

(1)DaemonSet名称:fluentd;

(2)命名空间:default;

(3)镜像:quay.io/fluentd_elasticsearch/fluentd:v2.5.2;

(4)容器名称:fluentd-container01;

(5)将Pod调度到非污点的节点上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@master ~]# vi daemonset.yaml 
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: default
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-container01
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2

ingress管理

创建ingress

1
2
3
4
5
6
7
8
9
10
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
backend:
serviceName: nginx
serverPort: 80

docker-compose编排

wordpress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '2'
services:
mysql:
image: 192.168.1.10/library/mysql:latest
expose:
- "3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=123456

wordpress:
image: 192.168.1.10/library/wordpress:latest
ports:
- "80:80"
restart: always
environment:
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_USER=root
- WORDPRESS_DB_PASSWORD=123456

owncloud

1
2
3
4
5
6
7
8
9
10
11
12
13
owncloud:
image: 192.168.1.10/library/owncloud
restart: always
ports:
- "80:80"
links:
- mysql:mysql

mysql:
image: 192.168.1.10/library/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=123456

lychee

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mysql:
image: 192.168.1.10/library/mysql
restart: always
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=lychee
- MYSQL_USER=lychee
- MYSQL_PASSWORD=123456

lychee:
image: 192.168.1.10/library/lychee
restart: always
ports:
- "80:80"
links:
- "mysql:mysql"
environment:
- WONCLOUD_DB_NAME: lychee
- WONCLOUD_DB_USER: lychee
- WONCLOUD_DB_PASSWORD: 123456

启动/停止命令

1
2
3
docker-compose -f docker-compose.yml up
docker-compose -f docker-compos.yaml down
docker rm $(docker ps -qa)

电商后台管理系统

云梦公司开发了一套基于SpringBoot+MyBatis微服务架构的ChinaSkillsMall电商系统,并实现全容器化部署,ChinaSkillsMall电商应用系统架构图如下:

*模块* *说明*
mall-monitor 监控中心
mall-gateway 微服务网关
mall-auth 认证中心
mall-admin 商城后台服务
mall-portal 商城前台服务

10.jpeg

请将MariaDB数据库组件、Redis消息组件、RabbitMQ消息组件、Nacos-Registry注册中心服务组件和前端Nginx组件按照要求进行容器化(镜像mall/mall-gateway:1.0-SNAPSHOT、mall/mall-admin:1.0-SNAPSHOT、mall/mall-auth:1.0-SNAPSHOT已提供)

容器化部署MariaDB

在master节点上编写/root/mall-swarm/Dockerfile-mariadb文件构建chinaskillmall-mariadb:v1.1镜像,具体要求如下:

(1)基础镜像:centos:centos7.5.1804;

(2)作者:Chinaskill;

(3)安装并初始化mariadb,密码:root;

(4)设置数据库编码为UTF-8;

(5)开放端口:3306

(6)设置mariadb开机自启。

完成后构建镜像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@master ~]# tar zxvf mall-swarm.tar.gz
###解压后删除mall-swarm.tar.gz文件,防止构建镜像,文件过大

[root@master ~]# cd mall-swarm
###编写yum源
[root@master mall-swarm]# vim local.repo
[mall]
name=mall
baseurl=file:///opt/mall-repo
gpgcheck=0

###编写初始化脚本init.sh
[root@master mall-swarm]# vim init.sh
#!/bin/bash
mysql_install_db --user=root
mysqld_safe --user=root &
sleep 8
mysqladmin -u root password 'root'
mysql -uroot -proot -e "grant all on *.* to 'reader'@'%' identified by '123456';"
mysql -uroot -proot -e "flush privileges;"
mysql -uroot -proot -e "create database mall;use mall;source /opt/mall.sql;"

编写Dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@master mall-swarm]# vim Dockerfile-mariadb
FROM 192.168.1.30/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
COPY local.repo /etc/yum.repos.d/local.repo
COPY mall-repo /opt/mall-repo
COPY mall.sql /opt/mall.sql
COPY init.sh /opt/init.sh
ENV LC_ALL en_US.UTF-8
RUN yum -y install mariadb-server && bash /opt/init.sh
EXPOSE 3306
CMD ["mysqld_safe","--user=root"]

###构建镜像
[root@master mall-swarm]# docker build -t chinaskillmall-mariadb:v1.1 -f Dockerfile-mariadb .

容器化部署 Redis

在 master 节 点 上 编 写 /root/mall-swarm/Dockerfile-redis 文 件 构 建chinaskillmallredis:v1.1 镜像,具体要求为 :

(1) 基础镜像:centos:centos7.5.1804;

(2) 作者:Chinaskill;

(3) 安装 redis 服务;

(4) 修改配置文件中的 bind 127.0.0.1 为 bind 0.0.0.0;

(5) 设置 redis 免密,并关闭保护模式;

(6) 开放端口:6379;

(7) 设置服务开机自启

编写dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@master mall-swarm]# vim Dockerfile-redis
FROM 192.168.1.30/library/centos:centos7.5.1804
MAINTAINER chinaskill
RUN rm -rf /etc/yum.repos.d/*
COPY mall-repo /opt/mall-repo
COPY local.repo /etc/yum.repos.d/local.repo
RUN yum install redis -y
RUN sed -i "s/127.0.0.1/0.0.0.0/g" /etc/redis.conf
RUN sed -i "s/protected-mode yes/protected-mode no/g" /etc/redis.conf
EXPOSE 6379
CMD ["/usr/bin/redis-server","/etc/redis.conf"]

###构建镜像
[root@master mall-swarm]# docker build -t chinaskillmall-redis:v1.1 -f Dockerfile-redis .

容器化部署 Nacos-Registry

在 master 节点上编写 /root/mall-swarm/Dockerfile-nacos 文件构建 chinaskillmallnacos:v1.1 镜像,具体要求为

(1) 基础镜像:centos:centos7.5.1804;

(2) 作者:Chinaskill;

(3) 安装 jdk 工具和 nacos-server 工具;

(4) 设置 nacos 服务开机自启。

编写run.sh运行文件

1
2
3
4
[root@master mall-swarm]# vim run.sh
#!/bin/bash
/usr/local/bin/nacos/bin/startup.sh -m standalone ###地址不要写错
tail -f /usr/local/bin/nacos/logs/start.out

dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@master mall-swarm]# vim Dockerfile-nacos
FROM 192.168.1.30/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
COPY mall-repo /opt/mall-repo
COPY local.repo /etc/yum.repos.d/local.repo
COPY run.sh /opt/run.sh
ADD jdk-8u121-linux-x64.tar.gz /usr/local/bin/
ADD nacos-server-1.1.0.tar.gz /usr/local/bin/
ENV JAVA_HOME /usr/local/bin/jdk1.8.0_121
EXPOSE 8848:8848
CMD ["/bin/bash","/opt/run.sh"]

###构建镜像
[root@master mall-swarm]# docker build -t chinaskillmall-nacos:v1.1 -f Dockerfile-nacos .

容器化部署前端服务

在master节点上安装node工具,对mall-admin-web项目进行打包,然后编写/root/mall-swarm/Dockerfile-nginx文件构建chinaskillmall-nginx:v1.1镜像,具体要求如下:(需要用到的软件包在/桌面/附件/容器云附件/Mall-swarm.tar.gz)

(1)基础镜像:centos:centos7.5.1804;

(2)作者:Chinaskill;

(3)安装nginx服务;

(4)将mall-admin-web项目打包后的文件拷贝到/usr/share/nginx/html目录下;

(5)设置nginx服务开机自启。

完成后构建镜像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@master mall-swarm]# tar zxvf mall-admin-web.tar
[root@master mall-swarm]# vim mall-admin-web/config/prod.env
###改环境ip
'use strict'
module.exports = {
NODE_ENV: '"production"',
BASE_API: '"http://192.168.1.10:8201/mall-admin"'
}

[root@master mall-swarm]# tar zxvf node-v6.17.1-linux-x64.tar.gz
[root@master mall-swarm]# mv node-v6.17.1-linux-x64 /usr/local/node
[root@master mall-swarm]# vim /etc/profile
###配置文件最后添加环境变量
export NODE_HOME=/usr/local/node
export PATH=$NODE_HOME/bin/:$PATH
[root@master mall-swarm]# source /etc/profile
[root@master mall-swarm]# node -v
v6.17.1

###npm打包项目
[root@master mall-swarm]# cd mall-admin-web
[root@master mall-admin-web]# npm run build

###打包好之后,网页在dist目录下
[root@master mall-admin-web]# mv dist/ ../

编辑dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master nginx]# vim Dockerfile-nginx
FROM 192.168.1.30/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
COPY local.repo /etc/yum.repos.d/local.repo
COPY mall-repo /opt/mall-repo
RUN yum install -y nginx
COPY dist/ /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx","-g","daemon off;"]

###构建镜像
[root@master mall-swarm]# docker build -t chinaskillmall-nginx:v1.1 -f Dockerfile-nginx .

编排部署ChinaSkillsMall商城

在master节点上编写/root/mall-swarm/docker-compose.yaml文件,具体要求如下:

(1)容器1名称:chinaskillmall-admin;镜像:mall/mall-admin:1.0-SNAPSHOT;端口映射:8080:8080;

(2)容器2名称: chinaskillmall-auth;镜像:mall/mall-auth:1.0-SNAPSHOT;端口映射:8401:8401;

(3)容器3名称:chinaskillmall-gateway;镜像:mall/mall-gateway:1.0-SNAPSHOT;端口映射:8201:8201;

(4)容器4名称:chinaskillmall-mysql;镜像:chinaskillmall-mariadb:v1.1;端口映射:3306:3306;

(5)容器5名称:chinaskillmall-nacos;镜像:chinaskillmall-nacos:v1.1;端口映射:8848:8848;

(6)容器6名称:chinaskillmall-nginx;镜像:chinaskillmall-nginx:v1.1;端口映射:8888:80;

(7)容器1名称:chinaskillmall-redis;镜像:chinaskillmall-redis:v1.1;端口映射:6379:6379。

完成后编排部署ChinaSkillsMall商城。

1
2
3
4
###将所需镜像解压
[root@master mall-swarm]# docker load -i images/mall_mall-admin_1.0-SNAPSHOT.tar
[root@master mall-swarm]# docker load -i images/mall_mall-auth_1.0-SNAPSHOT.tar
[root@master mall-swarm]# docker load -i images/mall_mall-gateway_1.0-SNAPSHOT.tar

编写docker-compose文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
[root@master mall-swarm]# vim docker-compose
version: '3'
services:
mysql:
image: chinaskillmall-mariadb:v1.1
container_name: chinaskillmall-mysql
restart: always
ports:
- 3306:3306
redis:
image: chinaskillmall-redis:v1.1
container_name: chinaskillmall-redis
restart: always
ports:
- 6379:6379
nginx:
image: chinaskillmall-nginx:v1.1
container_name: chinaskillmall-nginx
restart: always
ports:
- 8888:80
nacos-registry:
image: chinaskillmall-nacos:v1.1
container_name: chinaskillmall-nacos
restart: always
ports:
- 8848:8848
mall-admin:
image: mall/mall-admin:1.0-SNAPSHOT
container_name: chinaskillmall-admin
restart: always
ports:
- 8080:8080
links:
- mysql:db
mall-gateway:
image: mall/mall-gateway:1.0-SNAPSHOT
container_name: chinaskillmall-gateway
restart: always
ports:
- 8201:8201
links:
- redis:redis
- nacos-registry:nacos-registry
mall-auth:
image: mall/mall-auth:1.0-SNAPSHOT
container_name: chinaskillmall--auth
ports:
- 8401:8401
links:
- nacos-registry:nacos-registry

###启动
[root@node mall-swarm]# docker-compose up -d
1.使用 docker-compose ps 命令查看所有容器是否正常启动,
2.查看商城页面,ip:8888 账号admin/macro123登录

11.jpeg

商城应用系统

将云梦公司开发的应用商城Mall重新实现全容器化部署,原应用商城系统各模块功能及系统架构如下:

*模块* *使用技术* *备注*
mall.sql MySQL 网站的数据库
dist目录 Nginx 网站的前端项目
mall-shopping web项目 8081端口,商品/购物车/首页渲染等交互
mall-user 8082端口,提供用户相关的交互,如登录、注册、个人中心等
user-provider 后端服务 提供用户相关服务
shopping-provider 提供购物车、推荐商品、商品等服务

12.png

容器化部署MariaDB

镜像名为mall-mysql:v1.1,使用centos:7.9.2009基础镜像,安装mariadb数据库,

设置数据库支持UTF-8编码,设定root用户的密码为123456,并设置服务开机自启。

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM 192.168.121.21/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rvf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
ADD gpmall.sql /root/
RUN yum install -y mariadb-server
RUN sed -i "13cport = 8066" /etc/my.cnf.d/server.cnf
ADD init.sh /root/init.sh
RUN chmod +x /root/init.sh
RUN /root/init.sh
ENV LC_ALL en_US.UTF-8
EXPOSE 3306
EXPOSE 8066
CMD ["mysqld_safe"]

init.sh

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
mysql_install_db --user=mysql
mysqld_safe &
sleep 3s
mysqladmin -u root password '123456'
sleep 3s
mysql -uroot -p123456 -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456'"
sleep 3s
mysql -uroot -p123456 -e "create database gpmall;use gpmall;"
mysql -uroot -p123456 gpmall < /root/gpmall.sql

ftp.repo

1
2
3
4
5
6
7
8
9
10
[gpmall]
name=gpmall
baseurl=ftp://192.168.121.21/ChinaskillMall/gpmall-repo
gpgcheck=0
nabled=1
[centos]
name=centos
baseurl=ftp://192.168.121.21/centos
gpgcheck=0
enabled=1

创建镜像

1
docker build -t mall-xxxx:v1.1 .

容器化部署 Redis

镜像名为mall-redis:v1.1,使用centos:centos7.9.2009基础镜像,安装Redis服务,

设置Redis免密,并关闭保护模式,开放端口6379,并设置服务开机自启。

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM 192.168.121.21/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rvf /etc/yum.repos.d/*
COPY ftp.repo /etc/yum.repos.d/local.repo
RUN yum clean all
RUN yum list
RUN yum -y install redis
RUN sed -i -e 's@bind 127.0.0.1@bind 0.0.0.0@g' /etc/redis.conf
RUN sed -i -e 's@protected-mode yes@protected-mode no@g' /etc/redis.conf
RUN sed -i -e 's@daemonize yes@daemonize no@g' /etc/redis.conf
EXPOSE 6379
ENTRYPOINT redis-server /etc/redis.conf
CMD ["redis-server"]

创建镜像

1
docker build -t mall-xxxx:v1.1 .

容器化部署 kafka

镜像名为mall-kafka:v1.1,使用centos:centos7.9.2009基础镜像,

安装Kafka服务,开放端口9092,并设置服务开机自启。

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
FROM 192.168.121.21/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rvf /etc/yum.repos.d/*
COPY ftp.repo /etc/yum.repos.d/local.repo
RUN yum -y install java-1.8.0
ADD kafka_2.11-1.1.1.tgz /usr/local
ENV KAFKA_HOME /usr/local/kafka_2.11-1.1.1
RUN sed -i 's/localhost:2181/zk1.mall:2181,zk2.mall:2181,zk3.mall:2181/g' \
/usr/local/kafka_2.11-1.1.1/config/server.properties
EXPOSE 9092
ENTRYPOINT [ "/usr/local/kafka_2.11-1.1.1/bin/kafka-server-start.sh", \
"/usr/local/kafka_2.11-1.1.1/config/server.properties" ]

创建镜像

1
docker build -t mall-xxxx:v1.1 .

容器化部署 ZooKeeper

镜像名为mall-zookeeper:v1.1,使用centos:7.9.2009基础镜像,

安装ZooKeeper服务,开放端口2181;并设置服务开机自启。

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
FROM 192.168.121.21/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rvf /etc/yum.repos.d/*
COPY ftp.repo /etc/yum.repos.d/local.repo
RUN yum -y install java-1.8.0
ADD zookeeper-3.4.14.tar.gz /usr/local
ENV ZOOKEEPER_HOME /usr/local/zookeeper-3.4.14
ENV PATH $PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$ZOOKEEPER_HOME/bin
EXPOSE 2181
EXPOSE 2888
EXPOSE 3888
CMD $ZOOKEEPER_HOME/bin/zkServer.sh start-foreground

创建镜像

1
docker build -t mall-xxxx:v1.1 .

容器化部署 nginx

镜像名为mall-nginx:v1.1,使用centos:7.9.2009基础镜像,

安装nginx服务,开放端口2181;并设置服务开机自启。

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
FROM 192.168.121.21/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rvf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
RUN yum install nginx -y
RUN sed -i '12ilocation /user {proxy_pass http://jar:8082;}' /etc/nginx/conf.d/default.conf
RUN sed -i '12ilocation /shopping {proxy_pass http://jar:8081;}' /etc/nginx/conf.d/default.conf
RUN rm -rf /usr/share/nginx/html/*
ADD dist/ /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx","-g","daemon off;"]

创建镜像

1
docker build -t mall-xxxx:v1.1 .

制作jar包运行环境镜像

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM 192.168.121.21/library/centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rvf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
#RUN yum install -y java-1.8.0
ADD jdk-8u77-linux-x64.tar.gz /opt
ENV JAVA_HOME=/opt/jdk1.8.0_77
ENV JRE_HOME=${JAVA_HOME}/jre
ENV CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH=${JAVA_HOME}/bin:$PATH
ADD gpmall-shopping-0.0.1-SNAPSHOT.jar /opt/
ADD gpmall-user-0.0.1-SNAPSHOT.jar opt/
ADD shopping-provider-0.0.1-SNAPSHOT.jar /opt/
ADD user-provider-0.0.1-SNAPSHOT.jar /opt/
ADD start.sh /start.sh
RUN chmod +x /start.sh
EXPOSE 8081
EXPOSE 8082
EXPOSE 20880
EXPOSE 20881
EXPOSE 9090
CMD ["bash","/start.sh"]

start.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
sleep 5
nohup java -jar /opt/shopping-provider-0.0.1-SNAPSHOT.jar &
sleep 30
nohup java -jar /opt/user-provider-0.0.1-SNAPSHOT.jar &
sleep 30
nohup java -jar /opt/gpmall-shopping-0.0.1-SNAPSHOT.jar &
sleep 30
nohup java -jar /opt/gpmall-user-0.0.1-SNAPSHOT.jar &
sleep 30
while [[ true ]]; do
sleep 1
done

创建镜像

1
docker build -t mall-xxxx:v1.1 .

编排部署Mall应用商城。

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
version: '2'
services:
zk1.mall:
image: 192.168.1.10/library/mall-xxxx:v1.1
restart: always
expose:
- 2181
- 2888
- 3888
volumes:
- ./zookeeper1/conf:/usr/local/zookeeper-3.4.14/conf
- ./zookeeper1/data:/data

zk2.mall:
image: 192.168.1.10/library/mall-xxxx:v1.1
restart: always
expose:
- 2181
- 2888
- 3888
volumes:
- ./zookeeper2/conf:/usr/local/zookeeper-3.4.14/conf
- ./zookeeper2/data:/data

zk3.mall:
image: 192.168.1.10/library/mall-xxxx:v1.1
restart: always
expose:
- 2181
- 2888
- 3888
volumes:
- ./zookeeper3/conf:/usr/local/zookeeper-3.4.14/conf
- ./zookeeper3/data:/data

kafka1.mall:
image: 192.168.1.10/library/mall-xxxx:v1.1
restart: always
expose:
- 9092
links:
- zk1.mall
- zk2.mall
- zk3.mall

redis.mall:
image: 192.168.1.10/library/mall-xxxx:v1.1
expose:
- 6379

mysql.mall:
image: 192.168.1.10/library/mall-xxxx:v1.1
expose:
- 8066

nginx:
image: 192.168.1.10/library/mall-xxxx:v1.1
restart: always
ports:
- "80:80"
links:
- jar

jar:
image: 192.168.1.10/library/mall-xxxx:v1.1
links:
- kafka1.mal
- mysql.mall
- redis.mall
- zk1.mall
- zk2.mall
- zk3.mall
expose:
- 8081
- 8082
- 20880
- 20881
- 9090

CI/CD

基于k8s构建持续集成

该公司决定采用GitLab +Jenkins来构建CICD环境,以缩短新功能开发上线周期,及时满足客户的需求,实现DevOps的部分流程,来减轻部署运维的负担,实现可视化容器生命周期管理、应用发布和版本迭代更新,请完成GitLab + Jenkins + Kubernetes的CICD环境部署(构建持续集成所需要的所有软件包在软件包Jenkins_offline.tar中)。CICD应用系统架构如下:

13.png

部署Jenkins服务

具体要求如下:

(1)容器名称:jenkins;

(2)端口映射:8080:8080;

(3)使用root身份生成容器;

(4)离线安装Jenkins插件;

(5)设置Jenkins用户:chinaskill;密码:000000;

(6)在授权策略中配置“任何用户可以做任何事(没有任何限制)”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@master ~]# vim docker-compose.yml
version: "3"
services:
jenkins:
container_name: jenkins
image: jenkins/jenkins
ports:
- "8080:8080"
volumes:
- "/home/jenkins_home:/var/jenkins_home" ###如果jenkins起不来就把这行注释
- "/usr/bin/docker:/usr/bin/docker" ###docker命令
- "/usr/bin/kubectl:/usr/local/bin/kubectl" ###kubectl命令
- "/var/run/docker.sock:/var/run/docker.sock" ###docker锁文件
- "/root/.kube:/root/.kube"

###通过docker-compose up -d启动Jenkins

离线安装插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
###找到插件包
[root@master CICD]# ls
apache-maven-3.6.3-bin.tar.gz gitlab jenkins.tar
repository ChinaskillProject jenkins plugins ###插件包

###copy到Jenkins家目录下
[root@master CICD]# docker cp plugins/ 23e29963b96d:/var/jenkins_home/

###重启Jenkins
[root@master jenkins]# docker stop 6070eb42546f
6070eb42546f
[root@master jenkins]# docker start 6070eb42546f
6070eb42546f
###deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
nodeSelector:
kubernetes.io/hostname: k8s-master-node1
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
type: Socket
- name: kube
hostPath:
path: /root/.kube
type: Directory
- name: kubectl
hostPath:
path: /usr/bin/kubectl
type: File
- name: docker
hostPath:
path: /usr/bin/docker
type: File
- name: m2
hostPath:
path: /root/CICD/repository
type: Directory
- name: plugins
hostPath:
path: /root/CICD/plugins
type: Directory
containers:
- name: jenkins
image: jenkins/jenkins:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock
- name: kube
mountPath: /var/jenkins_home/kube
- name: kubectl
mountPath: /usr/bin/kubectl
- name: docker
mountPath: /usr/bin/docker
- name: m2
mountPath: /var/jenkins_home/.m2/repository
- name: plugins
mountPath: /var/jenkins_home/plugins

---
apiVersion: v1
kind: Service
metadata:
name: jenkins
spec:
selector:
app: jenkins
ports:
- name: 8080-30880
port: 8080
protocol: TCP
targetPort: 8080
nodePort: 30880
type: NodePort

浏览器访问IP:8080

14.png

1
2
3
4
5
6
 ###进入容器
[root@master jenkins]# docker exec -it 6070eb42546f /bin/bash

###查看密码
jenkins@6070eb42546f:/$ cat /var/jenkins_home/secrets/initialAdminPassword
9b07aba3086e4b7c811b2881018c5e88

配置安全策略

系统配置——->全局安全配置——->策略授权

15.png

16.png

安装Gitlab环境

在master节点上使用镜像gitlab/gitlab-ce:12.9.2-ce.0部署Gitlab服务,具体要求如下:

(1)容器名称:mygitlab;

(2)端口映射:1022:22、81:80、443:443;

(3)容器重启策略:always;

(4)设置root用户及密码;

(5)使用root用户登录Gitlab,密码:00000000;

(6)新建项目ChinaskillProject,将/opt/ChinaskillProject中的代码上传到ChinaskillProject项目中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
[root@master ~]# vim docker-compose.yml
version: "3"
services:
gitlab:
container_name: gitlab
image: gitlab/gitlab-ce:12.9.2-ce.0
ports:
- "1022:22"
- "80:80"
- "443:443"
restart: always
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitlab
spec:
replicas: 1
selector:
matchLabels:
app: gitlab
template:
metadata:
labels:
app: gitlab
spec:
nodeSelector:
kubernetes.io/hostname: k8s-master-node1
containers:
- name: gitlab
image: gitlab/gitlab-ce:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
env:
- name: GITLAB_ROOT_PASSWORD
value: admin123
---
apiVersion: v1
kind: Service
metadata:
name: gitlab
spec:
selector:
app: gitlab
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
nodePort: 30888
type: NodePort

浏览器访问IP:80

创建项目

17.png

上传项目

18.png

1
2
3
4
5
6
[root@master gitlab]# yum install git -y
[root@master gitlab]# git init
[root@master gitlab]# git add .
[root@master gitlab]# git remote add origin http://IP:30880/root/chinaskillproject.git
[root@master gitlab]# git commit -m "gpmall"
[root@master gitlab]# git push -u origin master

配置Jenkins连接Gitlab

配置Jenkins连接Gitlab,具体要求如下:

(1)设置Outbound requests;

(2)生成“Access Tokens”并命名为jenkins;

(3)设置Jenkins取消对’/project’ end-point进行身份验证;

(4)测试Jenkins与Gitlab的连通性。

19.png

20.png

21.png

22.png

jenkins

系统管理-系统配置

23.png

24.png

25.png

配置Jenkins连接maven

配置Jenkins连接maven,具体要求如下:

(1)采用docker in docker的方式在Jenkins内安装maven;

(2)在Jenkins中配置maven信息。

配置docker in docker

1
2
3
4
5
6
7
8
9
10
###docker命令和锁文件已经挂载到容器内,只需修改权限
[root@master CICD]# ll /var/run/docker.sock
srw-rw---- 1 root docker 0 Feb 26 08:40 /var/run/docker.sock
[root@master CICD]# chmod 666 /var/run/docker.sock
[root@master CICD]# ll /var/run/docker.sock
srw-rw-rw- 1 root docker 0 Feb 26 08:40 /var/run/docker.sock

###在docker容器中可以使用docker命令就算配置成功
[root@master CICD]# docker exec -it 23e29963b96d /bin/bash
bash-4.4$ docker images

在jenkins中安装maven

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
###Jenkins容器中没有tar命令,需要在本地解压,copy到容器中
[root@master CICD]# tar xvf jdk-8u141-linux-x64.tar.gz -C /usr/local/ ###java环境
[root@master CICD]# tar xvf apache-maven-3.8.5.tar.gz -C /usr/local/

###配置本地maven仓库地址及阿里云镜像加速: ###没有网络可不配
[root@master ~]# vim /usr/local/apache-maven-3.8.5/conf/settings.xml
<!-- 本地仓库地址 -->
<localRepository>/opt/localrepo</localRepository>
<!-- 阿里云maven仓库镜像地址,加速jar包下载速度 -->
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
<mirror>
<id>aliyun-maven</id>
<mirrorOf>*</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>


[root@master CICD]# docker cp /usr/local/maven/ 23e29963b96d:/usr/local/
[root@master CICD]# docker cp /usr/local/jdk1.8.0_121/ 23e29963b96d:/usr/local/

###在本地编写环境变量copy至容器
[root@master CICD]# vim /etc/profile
###末尾添加
export JAVA_HOME=/usr/local/jdk1.8.0_121/
export PATH=$PATH:/usr/local/apache-maven-3.8.5/bin:$JAVA_HOME/bin

###进入容器启用变量
[root@master CICD]# docker cp /etc/profile 23e29963b96d:/etc/
bash-4.4$ source /etc/profile

bash-4.4$ echo $JAVA_HOME
/usr/local/jdk1.8.0_121/

bash-4.4$ echo $MAVEN_HOME
/usr/local/maven

bash-4.4$ mvn -v
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/maven
Java version: 1.8.0_121, vendor: Oracle Corporation, runtime:
/usr/local/jdk1.8.0_121/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "3.10.0-862.el7.x86_64", arch: "amd64", family: "unix"

在Jenkins中配置maven信息

系统配置——->全局工具配置——->配置Java–配置maven——->保存

26.jpg

27.jpg

配置CI/CD

配置CI/CD,具体要求如下:

(1)新建一个流水线模块ChinaskillProject;

(2)编写流水线脚本,构建ChinaskillProject项目中的gateway和config服务,将构建后的镜像自动上传到Harbor仓库的chinaskillproject项目,并自动发布gateway和config服务到Kubernetes集群的springcloud命名空间下;

(3)配置Webhook;

(4)在Harbor中新建公开项目chinaskillproject。

28.png

29.png

30.png

31.png

32.png

流水线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
node{
stage('git clone'){
git credentialsId: '805c5026-5817-40aa-9d29-fef875e744da', url: 'http://192.168.0.10:81/root/gpmall.git'
}
stage('image build'){
sh'''
docker build -t 192.168.0.10/gpmall/chinaskill-mariadb:$BUILD_ID -f mariadb/Dockerfile mariadb
docker build -t 192.168.0.10/gpmall/chinaskill-redis:$BUILD_ID -f redis/Dockerfile redis
docker build -t 192.168.0.10/gpmall/chinaskill-kafka:$BUILD_ID -f kafka/Dockerfile kafka
docker build -t 192.168.0.10/gpmall/chinaskill-zookeeper:$BUILD_ID -f zookeeper/Dockerfile zookeeper
docker build -t 192.168.0.10/gpmall/chinaskill-nginx:$BUILD_ID -f nginx/Dockerfile nginx'''
}
stage('upload image'){
sh'''
docker login -u=admin -p=Harbor12345 192.168.0.10
docker push 192.168.0.10/gpmall/chinaskill-mariadb:$BUILD_ID
docker push 192.168.0.10/gpmall/chinaskill-redis:$BUILD_ID
docker push 192.168.0.10/gpmall/chinaskill-kafka:$BUILD_ID
docker push 192.168.0.10/gpmall/chinaskill-zookeeper:$BUILD_ID
docker push 192.168.0.10/gpmall/chinaskill-nginx:$BUILD_ID'''
}
stage('deploy project'){
sh'''
sed -i "s/chinaskill-mariadb:v1.1/192.168.0.10\\/gpmall\\/chinaskill-mariadb:$BUILD_ID/g" gpmall.yaml
sed -i "s/chinaskill-redis:v1.1/192.168.0.10\\/gpmall\\/chinaskill-redis:$BUILD_ID/g" gpmall.yaml
sed -i "s/chinaskill-kafka:v1.1/192.168.0.10\\/gpmall\\/chinaskill-kafka:$BUILD_ID/g" gpmall.yaml
sed -i "s/chinaskill-zookeeper:v1.1/192.168.0.10\\/gpmall\\/chinaskill-zookeeper:$BUILD_ID/g" gpmall.yaml
sed -i "s/chinaskill-nginx:v1.1/192.168.0.10\\/gpmall\\/chinaskill-nginx:$BUILD_ID/g" gpmall.yaml
kubectl apply -f gpmall.yaml'''
}
}

配置harbor

33.png

触发CI/CD

将ChinaskillProject项目中的代码上传到Gitlab中触发构建

34.png

35.png