谷粒商城篇章13--P340-P360--k8s/KubeSphere【高可用集群篇一】

1 k8s

1.1 簡介

????????Kubernetes 簡稱 k8s。 是用于自動部署, 擴展和管理容器化應用程序的開源系統。

中文官網: https://kubernetes.io/zh/

中文社區: https://www.kubernetes.org.cn/

官方文檔: https://kubernetes.io/zh/docs/home/

社區文檔: http://docs.kubernetes.org.cn/

1.1.1?為什么需要Kubernetes,它能做什么?

官方文檔:Kubernetes官方文檔

Kubernetes為你提供:

(1)服務發現和負載均衡 ;(2)存儲編排;(3)自動部署和回滾;(4)自動完成裝箱計算;

(5)自我修復;(6)密鑰與配置管理;(7)批處理執行;(8)水平擴展;

(9)IPv4/IPv6雙棧;(10)為可擴展性設計.

1.1.2 Kubernete不是什么

官方文檔:Kubernetes官方文檔

1.1.3 部署方式的進化

?官方文檔:Kubernetes官方文檔

docker的兩種集群方式對比:K8s和swarm。參考如下:

容器云技術選擇之kubernetes和swarm對比_docker swarm pod-CSDN博客

1.2 架構原理&核心概念

1.2.1 架構

1.2.1.1 整體主從方式

如果想部署一個應用,是由Master去調度所有的Node節點,將應用放到一個合適的docker運行環境中

1.2.1.2 Master 節點架構?

  • kube-apiserver
    • 對外暴漏 k8s 的api接口,是外界進行資源操作的唯一入口;
    • 提供認證、授權、訪問控制、API 注冊和發現等機制。
  • etcd
    • etcd 是兼具一致性和高可用性的鍵值數據庫,可以作為保存 Kubernets 所有集群數據的后臺數據庫。
    • Kubernets 集群的 etcd 數據庫通常需要有個備份計劃。
  • kube-scheduler
    • 主節點上的組件,該組件監視那些新創新的未指定運行節點的 Pod,并選擇節點讓 Pod 在上面運行;
    • 所有對 k8s 的集群操作,都必須經過主節點進行調度
  • kube-controller-manager
    • 這些主節點上運行控制器的組件;
    • 這些控制器包括:
      • 節點控制器(Node Controller):負責在節點出現故障時進行通知和響應。
      • 副本控制器(Replication Controller):負責為系統中的每個副本控制器對象維護正確數量的 Pod。
      • 端點控制器(Endpoints Controller):填充端點(Endpoints)對象(即加入 Service 與 Pod)。
      • 服務賬戶和令牌控制器(Service Account & Token Controllers):為新的命名空間創建默認賬戶和 API 訪問令牌。
1.2.1.3 Node 節點架構

  • kubelet
    • 一個在集群中每個節點上運行的代理。它保證容器都運行在 Pod 中。
    • 負責維護容器的生命周期,同時也負責Volume(CSI) 和容器網絡接口(CNI) 的管理。
  • kube-proxy
    • 負責為Service提供Cluster內部的服務發現和負載均衡。
  • 容器運行環境(Container Runtime)
    • 容器運行環境是負責運行容器的軟件。
    • Kubernetes 支持多個容器運行環境:Docker、containerd、cri-o、rktlet 以及任何實現 Kubernetes CRI(容器運行環境接口)。
  • fluentd
    • 是一個守護進程,它有助于提供集群層面日志?

1.2.2 概念

  • Container:容器,可以是 docker 啟動的一個容器。
  • Pod:
    • k8s 使用 Pod 來組織一組容器。
    • 一個Pod中的所有容器共享同一網絡。
    • Pod 是 k8s 中的最小部署單元。
  • Volume:
    • 聲明在 Pod 容器中可訪問的文件目錄。
    • 可以被掛載在 Pod 中一個或多個容器指定路徑下。
    • 支持多種后端存儲抽象(本地存儲、分布式存儲、云存儲...)

  • Controllers:更高層次對象,部署和管理 Pod;
    • ReplicaSet:確保預期的 Pod 副本數量。
    • Deplotment:無狀態應用部署。
    • StatefulSet:有狀態應用部署。
    • DaemonSet:確保所有 Node 都運行一個指定 Pod。
    • Job:一次性任務。
    • Cronjob:定時任務。

解釋:

1)無狀態應用:購物車等代碼屬于無狀態應用

2)有狀態應用:比如mysql(A)會在本地磁盤存儲一些數據,如果A宕機,在別的服務器在拉起一個mysql(B),A在本地磁盤存的數據其實就沒了。

3)部署應用,其實是kubernetes執行一次controller,比如是有狀態部署還是無狀態部署、部署多少個,這是一個controller。

  • Deployment:
    • 定義一組 Pod 的副本數目、版本等。
    • 通過控制器(Controller)維持 Pod 數目(自動回復失敗的 Pod)。
    • 通過控制器以指定的策略控制版本(滾動升級,回滾等)。

  • Service:
    • 定義一組 Pod 的訪問策略。
    • Pod 的負載均衡,提供一個或者多個 Pod 的穩定訪問地址。
    • 支持多種方式(ClusterIP、NodePort、LoadBalance)。

  • Label:標簽,用于對象資源的查詢,篩選

  • Namespace:命名空間,邏輯隔離(所有命名空間的作用)
    • 一個集群內部的邏輯隔離機制(鑒權、資源)。
    • 每個資源都屬于一個 namespace。
    • 同一個 namespace 所有資源名不能重復。
    • 不同 namespace 可以資源名重復。

API: 我們通過 kubernetes 的 API 來操作整個集群。 可以通過 kubectl、 ui、 curl 最終發送 http+json/yaml 方式的請求給 API Server, 然后控制 k8s 集群。 k8s 里的所有的資源對象都可以采用 yaml 或 JSON 格式的文件定義或描述 。

1.3 集群搭建

部署步驟,如下:

1.3.1 環境準備

1.3.1.1 VirtualBox配置

1. 全局設定

點擊,管理->全局設定

選擇一個足夠大的位置存儲虛擬機相關文件。

2. 主機網絡管理器

點擊,管理->主機網絡管理器

創建網卡

虛擬機創建好后的樣子,有兩個網卡,如下:

(1)網卡1:網絡地址轉換(NAT),為了讓虛擬機和我們的本機同樣都可以訪問互聯網;

(2)網卡2:僅主機(Host-Only)網絡,虛擬機內部共享的私有網絡。

1.3.2?創建三個虛擬機

1. 在D盤創建一個新文件夾gulimall_k8s(文件夾名字可取任意英文)存放Vagrantfile文件,文件內容如下:

Vagrant.configure("2") do |config|(1..3).each do |i|config.vm.define "k8s-node#{i}" do |node|# 使用box,必須先掛載好node.vm.box = "centos7"# 設置虛擬機的主機名node.vm.hostname = "k8s-node#{i}"# 設置虛擬機的IPnode.vm.network "private_network", ip: "192.168.56.#{99+i}", netmask: "255.255.255.0"# 設置主機和虛擬機的共享目錄# node.vm.synced_folder "~/Documents/vagrant/share","/home/vagrant/share"# 使用基于virtualbox虛擬化配置node.vm.provider "virtualbox" do |v|v.customize ["modifyvm", :id, "--name", "k8s-node#{i}", "--memory", "4096","--cpus","4"]endendend
end

2. 存放Vagrantfile的文件夾cmd進入命令窗口,輸入vagrant up 創建并啟動虛擬機,如下:

?3. 進入三個虛擬機,開啟 root 的密碼訪問權限。

# 進入虛擬機
vagrant ssh 主機名稱# 切換到root用戶
su密碼為vagrant# 修改SSH的配置文件,開啟root的密碼訪問權限
vi /etc/ssh/sshd_configa 進入輸入模式
修改 PasswordAuthentication yes
esc退出輸入模式
:wq 保存退出# 重啟服務
service sshd restart

(1)進入k8s-node1

sshd_config中的修改點,開啟密碼訪問權限,如下:?

(2)進入k8s-node2

同 k8s-node1,開啟密碼訪問權限

(3)進入k8s-node3

4. 使用工具連接三臺虛擬機,分別是

k8s-node1(192.168.56.100)、

k8s-node2(192.168.56.101)、

k8s-node3(192.168.56.102),密碼都是vagrant,如下:

注意:老師使用的工具是 Xshell,我這里使用 MobaXterm。

1.3.3 NAT網絡和前置環境

1.3.3.1 設置NAT網絡

1. 在三個節點中都輸入以下命令,結果如下:

# 查看當前系統的路由表,默認網卡是eth0
ip route show
# 顯示設備的ip地址
ip addr

發現,三個節點的網卡1的ip都一樣。?

在kubernetes中,默認網卡eth0的的ip都一樣即每個節點的默認ip都一樣是不行的。

2. 添加新的NAT網絡,步驟,如下:

(1)在 VirtualBox管理器中選中三個虛擬機并關閉電源。

(2)管理->全局設定中,選擇網絡,點擊添加新NAT網絡,添加一個NAT。

(3)選中k8s-node1/k8s-node2/k8s-node3->設置,重新生成網絡1的網卡,1網絡才是kubernets集群中要用的網絡,2網絡是為了讓宿主機連上虛擬機。

3. 啟動三臺虛擬機

4. 查看網絡1的ip地址和查看節點間是否網絡互通,是否能連接外網,如下:?

1.3.3.2 前置環境?
1.3.3.2.1 設置 linux 環境(三個節點都執行
  • 關閉防火墻
systemctl stop firewalld
systemctl disable firewalld
  • 關閉 selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0

  • 關閉 swap?
swapoff -a 臨時
sed -ri 's/.*swap.*/#&/' /etc/fstab 永久
free -g 驗證, swap 必須為 0

  • 添加主機名與 IP 對應關系

可以先使用 ip addr命令查詢網卡1(eth0)對應的ip.?

vi /etc/hosts# 添加如下對應關系
10.0.2.15 k8s-node1
10.0.2.10 k8s-node2
10.0.2.9 k8s-node3

  • 將橋接的 IPv4 流量傳遞到 iptables 的鏈:

為了讓系統精確統計流量指標

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF# 系統應用規則
sysctl --system

1.3.3.2.2 節點備份

前置環境弄好之后可進行備份,必要時可恢復備份。

1.3.4 所有節點安裝 Docker、kubeadm、kubelet、kubectl

(三個節點都安裝)

Docker:容器

kubeadm:集群部署,kubeadm init(Master)、kubeadm join(Node節點加到集群)

kubelet:Node節點代理

kubectl:命令行

1.3.4.1 安裝 Docker

1. 卸載系統之前的 Docker

yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

2. 安裝 Docker-CE

yum install -y yum-utils device-mapper-persistent-data lvm2

報錯信息,如下:

解決方案,如下:

修改CentOS倉庫配置文件,具體修改內容如下。

vi /etc/yum.repos.d/CentOS-Base.repo

baseurl=http://vault.centos.org/7.9.2009/os/$basearch/

baseurl=http://vault.centos.org/7.9.2009/updates/$basearch/

baseurl=http://vault.centos.org/7.9.2009/extras/$basearch/

baseurl=http://vault.centos.org/7.9.2009/centosplus/$basearch/

重新運行,安裝 Docker-CE 的命令:yum install -y yum-utils device-mapper-persistent-data lvm2,結果如下:

添加 Docker 官方源,如下:?

# 設置 docker repo 的 yum 位置
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

?如果添加 Docker 官方源,報如下錯誤,可臨時切換DNS:

臨時將 DNS 修改為 Google 或阿里云的公共 DNS,重新添加 Docker 官方源,如下:

echo "nameserver 8.8.8.8" > /etc/resolv.conf  # Google DNS
# 或者使用阿里云 DNS
# echo "nameserver 223.5.5.5" > /etc/resolv.conf

安裝 docker 、docker-cli ,(注意版本適配問題)如下?:

#安裝 docker, 以及 docker-cli
sudo yum install -y docker-ce docker-ce-cli containerd.io# 安裝指定版本與 Kubernetes1.17.3版本匹配【推薦】
yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8 containerd.io-19.03.8

3. 配置 docker 加速

阿里云加速地址:阿里云鏡像加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://自己的.mirror.aliyuncs.com"]
} 
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

4. 啟動 docker 設置 docker 開機自啟

systemctl enable docker

1.3.4.2 添加阿里云 yum 源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

1.3.4.3 安裝 kubeadm、kubelet 和 kubectl
# 安裝 kubelet kubeadm kubectl
yum install -y kubelet-1.17.3 kubeadm-1.17.3 kubectl-1.17.3

# 設置 kubelet 開機自啟
systemctl enable kubelet

# 啟動 kubelet
systemctl start kubelet
# 查看 kubelet 的狀態
systemctl status kubelet

注意:目前 kubelet 是啟動不起來的,還需其他配置。

1.3.5 部署 k8s-master

1.3.5.1 master 節點初始化

1. 將k8s-node1作為主節點,進行重命名,如下:?

2. 由于默認拉取鏡像地址 k8s.gcr.io 國內無法訪問, 這里指定阿里云鏡像倉庫地址。 可以手動按照我們的 images.sh 先拉取鏡像【直接初始化master節點可能會報錯,所以先拉取鏡像】,地址變為 registry.aliyuncs.com/google_containers 也可以,如下:

k8s文件夾下,有master_images.sh文件,將k8s文件夾拖至k8s-node1(master)節點下

# 查看當前目錄下所有的文件
ls
# 將 k8s 文件夾拖至當前目錄下ls
# 查看 k8s 文件夾下文件的權限
ll
# 讓擁有者有 master_images.sh 的讀、寫、執行權限
chmod 700 master_images.shll
# 執行 master_images.sh 文件
./master_images.sh

注意:執行用Nodepad++編寫的?master_images.sh 文件,可能會報以下錯誤,如下:

說明:windows下編寫的腳本在linux下格式存在問題,可以執行以下命令對 master_images.sh 文件進行轉換后執行,如下:

sed -i "s/\r//" master_images.sh

3. master節點初始化:【推薦使用 kubeadm 搭建 kubernetes 集群】

????????service-cidr:service間的網絡地址;

????????pod-network-cidr:pod間的網絡地址。

kubeadm init \
--apiserver-advertise-address=10.0.2.15 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version v1.17.3 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16
# API服務器所公布的其真正在監聽的IP地址。如果未設置,則使用默認網絡接口。
--apiserver-advertise-address=10.0.2.15
# 指定拉取控制平面鏡像的容器倉庫
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
# 指定 kubernetes 版本
--kubernetes-version v1.17.3
# 定義服務(Service)的IP地址范圍,這個范圍通常是一個CIDR塊,用于確保服務之間的通信不會沖突?。
--service-cidr=10.96.0.0/16
# 指明 pod 網絡可以使用的IP地址段
--pod-network-cidr=10.244.0.0/16

如果出現以下信息,說明初始化成功:

注意:Kubernetes 和 Docker之間的版本是否匹配,如果不匹配,master節點初始化也會報錯

初始化報錯,重置 Kubernetes 集群,在重新執行初始化命令:

kubeadm reset
1.3.5.2 測試 kubectl(主節點執行)?
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

先保存下來,等網絡加入完成,在從節點執行以下命令:

kubeadm join 10.0.2.15:6443 --token m6wxar.b2wbt89yghboq4ww \--discovery-token-ca-cert-hash sha256:2109e0efa3288a81d26077c0d7d8d4037926b3820402db5793f89028a49e4749

1.3.6 安裝 pod 網絡插件(CNI)

kubectl apply -f \
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

以上地址可能被墻, 大家獲取上傳我們下載好的 flannel.yml 運行即可, 同時 flannel.yml 中指定的 images 訪問不到可以去 docker hub 找一個wget yml 的地址

vi 修改 yml 所有 amd64 的地址都修改了即可。等待大約 3 分鐘

kubectl get pods -n kube-system 查看指定名稱空間的 pods

kubectl get pods --all-namespaces 查看所有名稱空間的 pods

這里使用下載好的 kube-flannel.yml,如下

運行kube-flannel.yml即可,如下:

# 應用文件配置
kubectl apply -f kube-flannel.yml# 刪除文件配置
kubectl delete -f kube-flannel.yml

kube-flannel.yml具體內容如下:【flannel.yml中指定的images訪問不到,鏡像已經改成了阿里云的】

---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:name: psp.flannel.unprivilegedannotations:seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/defaultseccomp.security.alpha.kubernetes.io/defaultProfileName: docker/defaultapparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/defaultapparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:privileged: falsevolumes:- configMap- secret- emptyDir- hostPathallowedHostPaths:- pathPrefix: "/etc/cni/net.d"- pathPrefix: "/etc/kube-flannel"- pathPrefix: "/run/flannel"readOnlyRootFilesystem: false# Users and groupsrunAsUser:rule: RunAsAnysupplementalGroups:rule: RunAsAnyfsGroup:rule: RunAsAny# Privilege EscalationallowPrivilegeEscalation: falsedefaultAllowPrivilegeEscalation: false# CapabilitiesallowedCapabilities: ['NET_ADMIN']defaultAddCapabilities: []requiredDropCapabilities: []# Host namespaceshostPID: falsehostIPC: falsehostNetwork: truehostPorts:- min: 0max: 65535# SELinuxseLinux:# SELinux is unused in CaaSPrule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:name: flannel
rules:- apiGroups: ['extensions']resources: ['podsecuritypolicies']verbs: ['use']resourceNames: ['psp.flannel.unprivileged']- apiGroups:- ""resources:- podsverbs:- get- apiGroups:- ""resources:- nodesverbs:- list- watch- apiGroups:- ""resources:- nodes/statusverbs:- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:name: flannel
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: flannel
subjects:
- kind: ServiceAccountname: flannelnamespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:name: flannelnamespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:name: kube-flannel-cfgnamespace: kube-systemlabels:tier: nodeapp: flannel
data:cni-conf.json: |{"name": "cbr0","cniVersion": "0.3.1","plugins": [{"type": "flannel","delegate": {"hairpinMode": true,"isDefaultGateway": true}},{"type": "portmap","capabilities": {"portMappings": true}}]}net-conf.json: |{"Network": "10.244.0.0/16","Backend": {"Type": "vxlan"}}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: kube-flannel-ds-amd64namespace: kube-systemlabels:tier: nodeapp: flannel
spec:selector:matchLabels:app: flanneltemplate:metadata:labels:tier: nodeapp: flannelspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: beta.kubernetes.io/osoperator: Invalues:- linux- key: beta.kubernetes.io/archoperator: Invalues:- amd64hostNetwork: truetolerations:- operator: Existseffect: NoScheduleserviceAccountName: flannelinitContainers:- name: install-cniimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:amd64command:- cpargs:- -f- /etc/kube-flannel/cni-conf.json- /etc/cni/net.d/10-flannel.conflistvolumeMounts:- name: cnimountPath: /etc/cni/net.d- name: flannel-cfgmountPath: /etc/kube-flannel/containers:- name: kube-flannelimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:amd64command:- /opt/bin/flanneldargs:- --ip-masq- --kube-subnet-mgrresources:requests:cpu: "100m"memory: "50Mi"limits:cpu: "100m"memory: "50Mi"securityContext:privileged: falsecapabilities:add: ["NET_ADMIN"]env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacevolumeMounts:- name: runmountPath: /run/flannel- name: flannel-cfgmountPath: /etc/kube-flannel/volumes:- name: runhostPath:path: /run/flannel- name: cnihostPath:path: /etc/cni/net.d- name: flannel-cfgconfigMap:name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: kube-flannel-ds-arm64namespace: kube-systemlabels:tier: nodeapp: flannel
spec:selector:matchLabels:app: flanneltemplate:metadata:labels:tier: nodeapp: flannelspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: beta.kubernetes.io/osoperator: Invalues:- linux- key: beta.kubernetes.io/archoperator: Invalues:- arm64hostNetwork: truetolerations:- operator: Existseffect: NoScheduleserviceAccountName: flannelinitContainers:- name: install-cniimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:arm64command:- cpargs:- -f- /etc/kube-flannel/cni-conf.json- /etc/cni/net.d/10-flannel.conflistvolumeMounts:- name: cnimountPath: /etc/cni/net.d- name: flannel-cfgmountPath: /etc/kube-flannel/containers:- name: kube-flannelimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:arm64command:- /opt/bin/flanneldargs:- --ip-masq- --kube-subnet-mgrresources:requests:cpu: "100m"memory: "50Mi"limits:cpu: "100m"memory: "50Mi"securityContext:privileged: falsecapabilities:add: ["NET_ADMIN"]env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacevolumeMounts:- name: runmountPath: /run/flannel- name: flannel-cfgmountPath: /etc/kube-flannel/volumes:- name: runhostPath:path: /run/flannel- name: cnihostPath:path: /etc/cni/net.d- name: flannel-cfgconfigMap:name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: kube-flannel-ds-armnamespace: kube-systemlabels:tier: nodeapp: flannel
spec:selector:matchLabels:app: flanneltemplate:metadata:labels:tier: nodeapp: flannelspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: beta.kubernetes.io/osoperator: Invalues:- linux- key: beta.kubernetes.io/archoperator: Invalues:- armhostNetwork: truetolerations:- operator: Existseffect: NoScheduleserviceAccountName: flannelinitContainers:- name: install-cniimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:armcommand:- cpargs:- -f- /etc/kube-flannel/cni-conf.json- /etc/cni/net.d/10-flannel.conflistvolumeMounts:- name: cnimountPath: /etc/cni/net.d- name: flannel-cfgmountPath: /etc/kube-flannel/containers:- name: kube-flannelimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:armcommand:- /opt/bin/flanneldargs:- --ip-masq- --kube-subnet-mgrresources:requests:cpu: "100m"memory: "50Mi"limits:cpu: "100m"memory: "50Mi"securityContext:privileged: falsecapabilities:add: ["NET_ADMIN"]env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacevolumeMounts:- name: runmountPath: /run/flannel- name: flannel-cfgmountPath: /etc/kube-flannel/volumes:- name: runhostPath:path: /run/flannel- name: cnihostPath:path: /etc/cni/net.d- name: flannel-cfgconfigMap:name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: kube-flannel-ds-ppc64lenamespace: kube-systemlabels:tier: nodeapp: flannel
spec:selector:matchLabels:app: flanneltemplate:metadata:labels:tier: nodeapp: flannelspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: beta.kubernetes.io/osoperator: Invalues:- linux- key: beta.kubernetes.io/archoperator: Invalues:- ppc64lehostNetwork: truetolerations:- operator: Existseffect: NoScheduleserviceAccountName: flannelinitContainers:- name: install-cniimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:ppc64lecommand:- cpargs:- -f- /etc/kube-flannel/cni-conf.json- /etc/cni/net.d/10-flannel.conflistvolumeMounts:- name: cnimountPath: /etc/cni/net.d- name: flannel-cfgmountPath: /etc/kube-flannel/containers:- name: kube-flannelimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:ppc64lecommand:- /opt/bin/flanneldargs:- --ip-masq- --kube-subnet-mgrresources:requests:cpu: "100m"memory: "50Mi"limits:cpu: "100m"memory: "50Mi"securityContext:privileged: falsecapabilities:add: ["NET_ADMIN"]env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacevolumeMounts:- name: runmountPath: /run/flannel- name: flannel-cfgmountPath: /etc/kube-flannel/volumes:- name: runhostPath:path: /run/flannel- name: cnihostPath:path: /etc/cni/net.d- name: flannel-cfgconfigMap:name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: kube-flannel-ds-s390xnamespace: kube-systemlabels:tier: nodeapp: flannel
spec:selector:matchLabels:app: flanneltemplate:metadata:labels:tier: nodeapp: flannelspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: beta.kubernetes.io/osoperator: Invalues:- linux- key: beta.kubernetes.io/archoperator: Invalues:- s390xhostNetwork: truetolerations:- operator: Existseffect: NoScheduleserviceAccountName: flannelinitContainers:- name: install-cniimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:s390xcommand:- cpargs:- -f- /etc/kube-flannel/cni-conf.json- /etc/cni/net.d/10-flannel.conflistvolumeMounts:- name: cnimountPath: /etc/cni/net.d- name: flannel-cfgmountPath: /etc/kube-flannel/containers:- name: kube-flannelimage: registry.cn-zhangjiakou.aliyuncs.com/test-lab/coreos-flannel:s390xcommand:- /opt/bin/flanneldargs:- --ip-masq- --kube-subnet-mgrresources:requests:cpu: "100m"memory: "50Mi"limits:cpu: "100m"memory: "50Mi"securityContext:privileged: falsecapabilities:add: ["NET_ADMIN"]env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacevolumeMounts:- name: runmountPath: /run/flannel- name: flannel-cfgmountPath: /etc/kube-flannel/volumes:- name: runhostPath:path: /run/flannel- name: cnihostPath:path: /etc/cni/net.d- name: flannel-cfgconfigMap:name: kube-flannel-cfg

# 查看命名空間
kubectl get ns
# 查看所有名稱空間的 pods
kubectl get pods --all-namespaces

  • 問題一:【coredns無法正常啟動】

# 獲取所有節點
kubectl get nodes

coredns無法正常啟動,master節點狀態為NotReady,說明網絡加入存在問題。

原因排查:

檢查kubelet的狀態,結果如下:

# 檢查 kubelet 的狀態
systemctl status kubelet

報錯信息:failed to find plugin "flannel" in path [/opt/cni/bin]

說明 Kubernetes 無法在指定的路徑?/opt/cni/bin?下找到 Flannel CNI 插件。Flannel 是一種網絡插件,用于在 Kubernetes 集群中實現 Pod 之間的網絡通信。

解決方案:

需要下載 CNI plugins v0.8.6

github下載地址:https://github.com/containernetworking/plugins/releases/tag/v0.8.6

(在1.0.0版本后CNI Plugins中沒有flannel)

解壓后將 flannel 文件拷貝至 /opt/cni/bin/目錄下?

# 創建文件夾
mkdir /opt/cni-plugins
# 將壓縮包 cni-plugins-linux-amd64-v0.8.6.tgz 放到 /opt/cni-plugins 路徑下cd /opt/cni-plugins
# 解壓 CNI 插件壓縮包
tar -zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni-plugins/
# 拷貝 flannel 到 /opt/cni/bin/路徑下
cp flannel /opt/cni/bin/

查看節點狀態:

master節點處于Ready狀態。同理,k8s-node2、k8s-node3進行同樣操作,問題解決。

注意:master 節點為 Ready 狀態,才可以加入從節點。

1.3.7 加入 Kubernetes Node(從節點)

在 Node 節點執行。

向集群添加新節點,執行在 kubeadm init 輸出的 kubeadm join 命令:

確保 node 節點成功。

默認情況下,kubeadm init 生成的 token 有效期是24小時

1. token 過期怎么辦

使用 kubeadm token list 命令可以列出所有當前的 token 及其有效期。

kubeadm token list

# 創建 token,并打印出集群所需的命令
kubeadm token create --print-join-command# 創建一個永不過期的 token,不指定 --ttl 參數,kubeadm 會生成一個默認有效期為24小時的令牌
kubeadm token create --ttl 0 --print-join-command

2. 加入?Kubernetes Node

在 k8s-node2、k8s-node3 執行 kubeadm init 輸出的 kubeadm join 命令:

kubeadm join 10.0.2.15:6443 --token m6wxar.b2wbt89yghboq4ww \--discovery-token-ca-cert-hash sha256:2109e0efa3288a81d26077c0d7d8d4037926b3820402db5793f89028a49e4749

3. 檢查節點狀態

執行 watch kubectl get pod -n kube-system -o wide 監控 pod 進度
等 3-10 分鐘,完全都是 running 以后使用 kubectl get nodes 檢查狀態

1.3.8 入門操作 kubernetes 集群

master節點調度任意一個從節點部署一個pod運行tomcat6

1. 部署一個 tomcat

(1)部署一個 tomcat

# 創建部署一個 tomcat
kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8# 可以獲取到 tomcat 信息
kubectl get all -o wide

(2)上圖可以看出 tomcat 部署在 k8s-node2節點,進入k8s-node2節點進行驗證,如下:

# 查詢默認命名空間下的Pod
kubectl get pods# 查詢所有命名空間下的Pod
kubectl get pods --all-namespaces# 查詢默認命名空間下的Pod詳細信息
kubectl get pods -o wide# 查看所有資源
kubectl get all

(3)測試容災恢復,模擬 k8s-node2節點出問題,如下:?

  • 關閉正在運行的tomcat容器,會自動重新拉起一個tomcat容器

  • 模擬k8s-node2宕機 ,可以看到 master 節點又重新在 node3 創建部署一個tomcat

測試完成后,重新啟動 k8s-node2,如下:

2. 暴漏 tomcat 訪問?

# Pod 的 80 映射容器的 8080; service 會代理 Pod 的 80
kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort

--type=NodePort:指定暴漏方式為NodePort,NodePort是外部訪問k8s集群中service的端口,可以訪問每個節點的端口,都可以訪問各個Pod。

# 查看服務
kubectl get svn# 查看服務的詳細信息
kubectl get svn -o wide

任意節點 IP:31428(端口)訪問測試,如下:

3. 動態擴容測試

擴容了多份, 所有無論訪問哪個 node 的指定端口, 都可以訪問到 tomcat6

# 擴容
kubectl scale --replicas=3 deployment tomcat6# 縮容
kubectl scale --replicas=1 deployment tomcat6

4. 刪除

流程:?創建 deployment 會管理 replicas, replicas 控制 pod 數量, 有 pod 故障會自動拉起新的 pod

# 查看所有資源
kubectl get all# 刪除部署信息
kubectl delete deployment.apps/tomcat6# 刪除服務
kubectl delete service/tomcat6

還有一個默認的service,用來監聽 443 安全連接端口。

tomcat 都不能在訪問,如下:

1.3.9 安裝默認 dashboard

1.4?入門

1.4.1 yaml & 基本使用

1.4.1.1 kubectl

1.?kubectl 文檔

https://kubernetes.io/zh/docs/reference/kubectl/overview/

2. 資源類型

命令行工具 (kubectl) | 資源類型

3. 格式化輸出

命令行工具 (kubectl) | 格式化輸出

4. 常用操作

命令行工具 (kubectl) | 常用操作

5. 命令參考

kubectl | 命令參考

1.4.1.2 yaml 語法

1. yml 模板

2. yaml 字段解析

參照官方文檔

3. yaml 輸出

(1)創建部署

# 查看創建部署的幫助信息
kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 --help# 輸出 yaml 格式的 API 對象
kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 --dry-run -o yaml

--help:查看幫助信息。

--dry-run:模擬命令的執行,但不會真正應用到 Kubernetes 集群上。

-o yaml:這個選項指定輸出格式為 YAML。這對于查看將要創建的資源定義非常有幫助。?

# 輸出 yaml 信息到指定文件 tomcat6.yaml
kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 --dry-run -o yaml > tomcat6.yaml# 查看文件
ls# 打開 tomcat6.yaml 刪除無用的信息
vi tomcat6.yaml# 應用 tomcat6.yaml 文件,創建部署 tomcat6(-f:指以文件的形式)
kubectl apply -f tomcat6.yaml# 查看 pod 信息
kubectl get pods

?tomcat6.yaml 文件信息,如下:

(2)暴露服務

同理暴露服務也可以輸出yaml,如下:

(3)Pod

# 查看所有 pod
kubectl get pods# 查看指定 pod
kubectl get pod tomcat6-5f7ccf4cb9-4tmrk# pod 的詳細信息輸出為 yamlkubectl get pod tomcat6-5f7ccf4cb9-4tmrk -o yaml# 輸出 yaml 信息到指定文件 mypod.yml
kubectl get pod tomcat6-5f7ccf4cb9-4tmrk -o yaml > mypod.yml# 修改 yaml 文件
vi mypod.yml# 應用 yaml 文件,創建 pod
kubectl apply -f mypod.yml# 查看 pod 信息
kubectl get pods

修改后的 mypod.yml 詳細信息如下:?

apiVersion: v1
kind: Pod
metadata:labels:app: tomcat6-newname: tomcat6-newnamespace: default
spec:containers:- image: tomcat:6.0.53-jre8imagePullPolicy: IfNotPresentname: tomcat6-new- image: nginximagePullPolicy: IfNotPresentname: nginx

1.4.2 Pod、Service等概念

1.4.2.1 Pod 是什么,Controller 是什么

官方文檔:Pod | Kubernetes

Pod 和 控制器

????????控制器可以為您創建多個 Pod,管理副本和上線,并在集群范圍內提供自修復能力。例如, 如果一個節點失敗, 控制器可以在不同的節點上調度一樣的替身來自動替換 Pod。包含一個或多個 Pod 的控制器一些示例包括:
Deployment
StatefulSet
DaemonSet
控制器通常使用您提供的 Pod 模板來創建它所負責的 Pod。

1.4.2.2 Deployment&Service 是什么

1.4.2.3 Service 的意義

先刪除之前的部署和 Pod,再重新部署

apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:app: tomcat6name: tomcat6
spec:replicas: 1selector:matchLabels:app: tomcat6strategy: {}template:metadata:creationTimestamp: nulllabels:app: tomcat6spec:containers:- image: tomcat:6.0.53-jre8name: tomcatresources: {}
status: {}

修改后

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: tomcat6name: tomcat6
spec:replicas: 3selector:matchLabels:app: tomcat6template:metadata:labels:app: tomcat6spec:containers:- image: tomcat:6.0.53-jre8name: tomcat

暴露

apiVersion: v1
kind: Service
metadata:creationTimestamp: nulllabels:app: tomcat6name: tomcat6
spec:ports:- port: 80protocol: TCPtargetPort: 8080selector:app: tomcat6type: NodePort
status:loadBalancer: {}

部署暴露合并

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: tomcat6name: tomcat6
spec:replicas: 3selector:matchLabels:app: tomcat6template:metadata:labels:app: tomcat6spec:containers:- image: tomcat:6.0.53-jre8name: tomcat
---
apiVersion: v1
kind: Service
metadata:labels:app: tomcat6name: tomcat6
spec:ports:- port: 80protocol: TCPtargetPort: 8080selector:app: tomcat6type: NodePort

1、 部署一個 nginx

kubectl create deployment nginx --image=nginx

2、 暴露 nginx 訪問

kubectl expose deployment nginx --port=80 --type=NodePort

統一應用訪問入口;
Service 管理一組 Pod。
防止 Pod 失聯(服務發現) 、 定義一組 Pod 的訪問策略。


現在 Service 我們使用 NodePort 的方式暴露, 這樣訪問每個節點的端口, 都可以訪問到這
個 Pod, 如果節點宕機, 就會出現問題。

1.4.2.4 labels and selectors

官方文檔:標簽和選擇算符 | Kubernetes

1.4.3 Ingress

1.4.3.1 以 yaml 的形式部署暴露應用

1. 先刪除之前的部署和 Pod,再重新部署

先刪除部署,其他相關的副本就會被自動刪掉?

2. 輸出部署 tomcat6 的 yaml,如下:

# 輸出部署 tomcat6 的yaml
kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 --dry-run -o yaml > tomcat6-deployment.yaml# 編輯 tomcat6-deployment.yaml
vi tomcat6-deployment.yaml

修改前的?tomcat6-deployment.yaml,如下:

apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:app: tomcat6name: tomcat6
spec:replicas: 1selector:matchLabels:app: tomcat6strategy: {}template:metadata:creationTimestamp: nulllabels:app: tomcat6spec:containers:- image: tomcat:6.0.53-jre8name: tomcatresources: {}
status: {}

修改后的 tomcat6-deployment.yaml,如下:

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: tomcat6name: tomcat6
spec:replicas: 3selector:matchLabels:app: tomcat6template:metadata:labels:app: tomcat6spec:containers:- image: tomcat:6.0.53-jre8name: tomcat

3. 輸出暴露 tomcat6 的yaml,如下:?

# 輸出暴露 tomcat6 的yaml
kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort --dry-run  -o yaml

yaml 具體內容,如下:?

apiVersion: v1
kind: Service
metadata:creationTimestamp: nulllabels:app: tomcat6name: tomcat6
spec:ports:- port: 80protocol: TCPtargetPort: 8080selector:app: tomcat6type: NodePort
status:loadBalancer: {}

4. 合并 tomcat 部署、 暴露的 yaml,并應用,如下:

# 編輯 tomcat6-deployment.yaml 文件
vi tomcat6-deployment.yaml# 應用 tomcat6-deployment.yaml 文件
kubectl apply -f tomcat6-deployment.yaml# 查看所有資源
kubectl get all

編輯后(合并部署和暴露)的?tomcat6-deployment.yaml 文件內容,如下:

【yaml允許多個文檔片段,用---分割】

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: tomcat6name: tomcat6
spec:replicas: 3selector:matchLabels:app: tomcat6template:metadata:labels:app: tomcat6spec:containers:- image: tomcat:6.0.53-jre8name: tomcat
---
apiVersion: v1
kind: Service
metadata:labels:app: tomcat6name: tomcat6
spec:ports:- port: 80protocol: TCPtargetPort: 8080selector:app: tomcat6type: NodePort

5. 測試,瀏覽器訪問任意節點IP:30850

希望以域名的方式訪問 tomcat ,并且能夠負載均衡,這樣的話一個節點宕機還可以通過域名訪問到另外正常運行的節點,引入下面的 Ingress

1.4.3.2 Ingress

通過 Service 發現 Pod 進行關聯。 基于域名訪問。
通過 Ingress Controller 實現 Pod 負載均衡
支持 TCP/UDP 4 層負載均衡和 HTTP 7 層負載均衡

具體步驟,如下:?

1. 部署 Ingress Controller

# 應用 ingress-controller.yaml
kubectl apply -f ingress-controller.yaml

?ingress-controller.yaml 具體內容,如下:

apiVersion: v1
kind: Namespace
metadata:name: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---kind: ConfigMap
apiVersion: v1
metadata:name: nginx-configurationnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
kind: ConfigMap
apiVersion: v1
metadata:name: tcp-servicesnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
kind: ConfigMap
apiVersion: v1
metadata:name: udp-servicesnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
apiVersion: v1
kind: ServiceAccount
metadata:name: nginx-ingress-serviceaccountnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:name: nginx-ingress-clusterrolelabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
rules:- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secretsverbs:- list- watch- apiGroups:- ""resources:- nodesverbs:- get- apiGroups:- ""resources:- servicesverbs:- get- list- watch- apiGroups:- "extensions"resources:- ingressesverbs:- get- list- watch- apiGroups:- ""resources:- eventsverbs:- create- patch- apiGroups:- "extensions"resources:- ingresses/statusverbs:- update---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:name: nginx-ingress-rolenamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
rules:- apiGroups:- ""resources:- configmaps- pods- secrets- namespacesverbs:- get- apiGroups:- ""resources:- configmapsresourceNames:# Defaults to "<election-id>-<ingress-class>"# Here: "<ingress-controller-leader>-<nginx>"# This has to be adapted if you change either parameter# when launching the nginx-ingress-controller.- "ingress-controller-leader-nginx"verbs:- get- update- apiGroups:- ""resources:- configmapsverbs:- create- apiGroups:- ""resources:- endpointsverbs:- get---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:name: nginx-ingress-role-nisa-bindingnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: nginx-ingress-role
subjects:- kind: ServiceAccountname: nginx-ingress-serviceaccountnamespace: ingress-nginx---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:name: nginx-ingress-clusterrole-nisa-bindinglabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: nginx-ingress-clusterrole
subjects:- kind: ServiceAccountname: nginx-ingress-serviceaccountnamespace: ingress-nginx---apiVersion: apps/v1
kind: DaemonSet 
metadata:name: nginx-ingress-controllernamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
spec:selector:matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxannotations:prometheus.io/port: "10254"prometheus.io/scrape: "true"spec:hostNetwork: trueserviceAccountName: nginx-ingress-serviceaccountcontainers:- name: nginx-ingress-controllerimage: siriuszg/nginx-ingress-controller:0.20.0args:- /nginx-ingress-controller- --configmap=$(POD_NAMESPACE)/nginx-configuration- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services- --udp-services-configmap=$(POD_NAMESPACE)/udp-services- --publish-service=$(POD_NAMESPACE)/ingress-nginx- --annotations-prefix=nginx.ingress.kubernetes.iosecurityContext:allowPrivilegeEscalation: truecapabilities:drop:- ALLadd:- NET_BIND_SERVICE# www-data -> 33runAsUser: 33env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceports:- name: httpcontainerPort: 80- name: httpscontainerPort: 443livenessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 10readinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 10---
apiVersion: v1
kind: Service
metadata:name: ingress-nginxnamespace: ingress-nginx
spec:#type: NodePortports:- name: httpport: 80targetPort: 80protocol: TCP- name: httpsport: 443targetPort: 443protocol: TCPselector:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx

2. 創建 Ingress 規則,并應用

vi ingress-tomcat6.yml

ingress-tomcat6.yml 具體內容,如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: web
spec:rules:- host: tomcat6.atguigu.comhttp:paths:- backend:serviceName: tomcat6servicePort: 80

注意:規則中的 serviceName對應 tomcat 暴露的name;規則中的servicePort 對應?tomcat 暴露的pod 端口,如下圖:

ingress是 Running的狀態,在應用 Ingress 規則 ingress-tomcat6.yaml?

3. 以管理員身份打開 SwitchHosts,添加端口映射

4. 測試

在瀏覽器訪問 http://tomcat6.atguigu.com/

2 KubeSphere

默認的 dashboard 沒啥用, 我們用 kubesphere 可以打通全部的 devops 鏈路。Kubesphere 集成了很多套件, 集群要求較高

https://kubesphere.io/

Kuboard 也很不錯, 集群要求不高

https://kuboard.cn/support/

2.1 簡介

????????KubeSphere 是一款面向云原生設計的開源項目, 在目前主流容器調度平臺 Kubernetes 之上構建的分布式多租戶容器管理平臺, 提供簡單易用的操作界面以及向導式操作方式, 在降低用戶使用容器調度平臺學習成本的同時, 極大降低開發、 測試、 運維的日常工作的復雜度。

2.2 安裝

2.2.1 前提條件

https://kubesphere.io/docs/v2.1/zh-CN/installation/prerequisites/

注意:上面的地址不可用,可參照下面的地址,如下。

https://kubesphere.io/zh/docs/v3.3/release/release-v210/? ?【官方文檔 3.3版本】

Release Notes - 《KubeSphere v2.1 使用手冊》 - 書棧網 · BookStack?【2.1版本】

2.2.2?安裝前提環境

2.2.2.1 安裝 helm(master 節點執行)

????????Helm 是 Kubernetes 的包管理器。 包管理器類似于我們在 Ubuntu 中使用的 apt、 Centos中使用的 yum 或者 Python 中的 pip 一樣, 能快速查找、 下載和安裝軟件包。 Helm 由客戶端組件 helm 和服務端組件 Tiller 組成, 能夠將一組 K8S 資源打包統一管理, 是查找、共享和使用為 Kubernetes 構建的軟件的最佳方式。

1. 安裝

curl -L https://git.io/get_helm.sh | bash

墻原因, 上傳我們給定的 get_helm.sh, chmod 700 然后./get_helm.sh

可能有文件格式兼容性問題, 用 vi 打開該 sh 文件, 輸入:

:set ff

回車, 顯示 fileformat=dos, 重新設置下文件格式:

:set ff=unix

保存退出:

:wq

# 上面地址被墻,這里去 github 下載 helm 壓縮包
# 下載地址:https://github.com/helm/helm/releases?page=11tar xf helm-v2.16.3-linux-amd64.tar.gz
cp linux-amd64/helm /usr/local/bin
cp linux-amd64/tiller /usr/local/bin

2. 驗證版本?

helm version

3. 創建權限(master 執行)

創建 helm-rbac.yaml,寫入如下內容

# 創建 helm-rbac.yaml 并寫入內容
vi helm-rbac.yaml# 給擁有者賦予讀、寫、執行權限
chmod 700 helm-rbac.yaml# 應用配置
kubectl apply -f helm-rbac.yaml

?helm-rbac.yaml 具體內容,如下:

apiVersion: v1
kind: ServiceAccount
metadata:name: tillernamespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: tiller
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: cluster-admin
subjects:- kind: ServiceAccountname: tillernamespace: kube-system

2.2.2.2 安裝 Tiller(master 執行)

1. 初始化

helm init --service-account=tiller --tiller-image=jessestuart/tiller:v2.16.3 --history-max 300

--tiller-image 指定鏡像, 否則會被墻。 大家使用這個鏡像比較好 jessestuart/tiller:v2.16.3
等待節點上部署的 tiller 完成即可。

(1)報錯信息,如下:

(2)報錯原因:helm 倉庫 URL 變更。

(3)解決方案,如下:

使用 --stable-repo-url參數指定新的倉庫地址

helm init --service-account=tiller --tiller-image=jessestuart/tiller:v2.16.3 --history-max 300 --stable-repo-url https://charts.helm.sh/stable

注意:這里需要耐心等待,安裝時間稍長。

驗證,如下:

tillerkubectl get pods --all-namespaces

2.2.2.3 安裝 OpenEBS(master 執行)

https://kubesphere.io/docs/v2.1/zh-CN/appendix/install-openebs/

前提條件

  • 已有 Kubernetes 集群,并安裝了 kubectl 或 Helm
  • Pod 可以被調度到集群的 master 節點(可臨時取消 master 節點的 Taint)

關于第二個前提條件,是由于安裝 OpenEBS 時它有一個初始化的 Pod 需要在 k8s-node1 節點啟動并創建 PV(Persistent Volume) 給 KubeSphere 的有狀態應用掛載。因此,若您的 k8s-node1 節點存在 Taint,建議在安裝 OpenEBS 之前手動取消 Taint,待 OpenEBS 與 KubeSphere 安裝完成后,再對 k8s-node1 打上 Taint,以下步驟供參考:

# 查看節點名稱
kubectl get pod -o wide# 確定 master 節點是否有 taint
kubectl describe node k8s-node1 | grep Taint# 取消 taint
kubectl taint nodes k8s-node1 node-role.kubernetes.io/master:NoSchedule-

安裝 OpenEBS?

?1. 創建 OpenEBS 的命名控件,OpenEBS 的相關資源將創建在這個 namespace 下:

# 創建 OpenEBS 的命名空間 openebs
kubectl create ns openebs# 查看所有命名空間
kubectl get ns

2. 安裝 OpenEBS,有以下兩種方法,可參考其一進行創建:

A. 若集群已安裝了 Helm,可通過 Helm 命令來安裝?OpenEBS:【這里使用這個】

helm install --namespace openebs --name openebs stable/openebs --version 1.5.0

B. 除此之外 還可以通過 kubectl 命令安裝:

kubectl apply -f https://openebs.github.io/charts/openebs-operator-1.5.0.yaml

3. 安裝 OpenEBS 后將自動創建 4 個StorageClass,查看創建的 StorageClass:

kubectl get sc

4. 如下 將 openebs-hostpath 設置為默認的 StorageClass:

kubectl patch storageclass openebs-hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

5. 至此,OpenEBS 的 LocalPV 已作為默認的存儲類型創建成功。由于在文檔開頭手動去掉了master 節點的 Taint,我們可以在安裝完 OpenEBS 后將 master 節點 Taint 加上,避免業務相關的工作負載調度到 master 節點搶占 master 資源:

kubectl taint nodes k8s-node1 node-role.kubernetes.io=master:NoSchedule

2.2.3 最小化安裝 kubesphere

在 Kubernetes 集群在線部署 KubeSphere

1. 若您的集群可用的資源符合 CPU > 1 Core, 可用內存 > 2 G, 可以參考以下命令開啟

kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/v2.1.1/kubesphere-minimal.yaml

2. 上面的地址無法訪問,這里使用 kubesphere-mini.yaml 文件進行安裝,如下:

# 創建 kubesphere-mini.yaml 文件
vi kubesphere-mini.yaml# 應用 kubesphere-mini.yaml 文件,安裝 kubesphere
kubectl apply -f kubesphere-mini.yaml

kubesphere-mini.yaml 具體內容,如下:

---
apiVersion: v1
kind: Namespace
metadata:name: kubesphere-system---
apiVersion: v1
data:ks-config.yaml: |---persistence:storageClass: ""etcd:monitoring: FalseendpointIps: 192.168.0.7,192.168.0.8,192.168.0.9port: 2379tlsEnable: Truecommon:mysqlVolumeSize: 20GiminioVolumeSize: 20GietcdVolumeSize: 20GiopenldapVolumeSize: 2GiredisVolumSize: 2Gimetrics_server:enabled: Falseconsole:enableMultiLogin: False  # enable/disable multi loginport: 30880monitoring:prometheusReplicas: 1prometheusMemoryRequest: 400MiprometheusVolumeSize: 20Gigrafana:enabled: Falselogging:enabled: FalseelasticsearchMasterReplicas: 1elasticsearchDataReplicas: 1logsidecarReplicas: 2elasticsearchMasterVolumeSize: 4GielasticsearchDataVolumeSize: 20GilogMaxAge: 7elkPrefix: logstashcontainersLogMountedPath: ""kibana:enabled: Falseopenpitrix:enabled: Falsedevops:enabled: FalsejenkinsMemoryLim: 2GijenkinsMemoryReq: 1500MijenkinsVolumeSize: 8GijenkinsJavaOpts_Xms: 512mjenkinsJavaOpts_Xmx: 512mjenkinsJavaOpts_MaxRAM: 2gsonarqube:enabled: FalsepostgresqlVolumeSize: 8Giservicemesh:enabled: Falsenotification:enabled: Falsealerting:enabled: False
kind: ConfigMap
metadata:name: ks-installernamespace: kubesphere-system---
apiVersion: v1
kind: ServiceAccount
metadata:name: ks-installernamespace: kubesphere-system---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:creationTimestamp: nullname: ks-installer
rules:
- apiGroups:- ""resources:- '*'verbs:- '*'
- apiGroups:- appsresources:- '*'verbs:- '*'
- apiGroups:- extensionsresources:- '*'verbs:- '*'
- apiGroups:- batchresources:- '*'verbs:- '*'
- apiGroups:- rbac.authorization.k8s.ioresources:- '*'verbs:- '*'
- apiGroups:- apiregistration.k8s.ioresources:- '*'verbs:- '*'
- apiGroups:- apiextensions.k8s.ioresources:- '*'verbs:- '*'
- apiGroups:- tenant.kubesphere.ioresources:- '*'verbs:- '*'
- apiGroups:- certificates.k8s.ioresources:- '*'verbs:- '*'
- apiGroups:- devops.kubesphere.ioresources:- '*'verbs:- '*'
- apiGroups:- monitoring.coreos.comresources:- '*'verbs:- '*'
- apiGroups:- logging.kubesphere.ioresources:- '*'verbs:- '*'
- apiGroups:- jaegertracing.ioresources:- '*'verbs:- '*'
- apiGroups:- storage.k8s.ioresources:- '*'verbs:- '*'
- apiGroups:- admissionregistration.k8s.ioresources:- '*'verbs:- '*'---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: ks-installer
subjects:
- kind: ServiceAccountname: ks-installernamespace: kubesphere-system
roleRef:kind: ClusterRolename: ks-installerapiGroup: rbac.authorization.k8s.io---
apiVersion: apps/v1
kind: Deployment
metadata:name: ks-installernamespace: kubesphere-systemlabels:app: ks-install
spec:replicas: 1selector:matchLabels:app: ks-installtemplate:metadata:labels:app: ks-installspec:serviceAccountName: ks-installercontainers:- name: installerimage: kubesphere/ks-installer:v2.1.1imagePullPolicy: "Always"

3. 查看安裝日志,請耐心等待安裝成功

kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f

打印結果:

Start installing monitoring
**************************************************
task monitoring status is successful
total: 1     completed:1
**************************************************
#####################################################
###              Welcome to KubeSphere!           ###
#####################################################Console: http://10.0.2.15:30880
Account: admin
Password: P@88w0rdNOTES:1. After logging into the console, please check themonitoring status of service components inthe "Cluster Status". If the service is notready, please wait patiently. You can startto use when all components are ready.2. Please modify the default password after login.#####################################################

注意:這里 控制臺的地址是?http://10.0.2.15:30880?,訪問 kubesphere 使用宿主機 ip 地址?http://192.168.56.100:30880?.

4. 當所有的 pod 都是 Running 狀態則說明安裝完成,瀏覽器才可以訪問地址?http://192.168.56.100:30880

kubectl get pods --all-namespaces

訪問:http://192.168.56.100:30880

Account: admin
Password: P@88w0rd

2.2.4 完整化安裝【未做】

1. 若集群可用 CPU > 8 Core 且可用內存 > 16 G,可以使用以下命令完整安裝 KubeSphere。

注意,應確保集群中有一個節點的可用內存大于 8 G。

kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/v2.1.1/kubesphere-complete-setup.yaml

2.?查看滾動刷新的安裝日志,請耐心等待安裝成功。

kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f

說明:安裝過程中若遇到問題,也可以通過以上日志命令來排查問題。?

3. 通過 kubectl get pod --all-namespaces查看 KubeSphere 相關 namespace 下所有 Pod 狀態是否為 Running。確認 Pod 都正常運行后,可使用 IP:30880訪問 KubeSphere UI 界面,默認的集群管理員賬號為 admin/P@88w0rd。

2.2.5 安裝可插拔的組件

節點擴容

????????master節點只是一個調度系統,目前不需要擴容,pod存儲都在node2、node3,所以要對node2、node3進行擴容,如下:

安裝Metrics Server

????????KubeSphere 支持用于部署的容器組(Pod)彈性伸縮程序 (HPA)。在 KubeSphere 中,Metrics Server 控制著 HPA 是否啟用。您可以根據不同類型的指標(例如 CPU 和內存使用率,以及最小和最大副本數),使用 HPA 對象對部署 (Deployment) 自動伸縮,當業務需求增加時,KubeSphere 能夠無縫地自動水平增加 Pod 數量,提高應用系統的穩定性。通過這種方式,HPA 可以幫助確保您的應用程序在不同情況下都能平穩、一致地運行。

????????關于如何使用 HPA 請參考 設置彈性伸縮,注意,Installer 默認最小化安裝因此初始安裝時并未開啟 Metrics-server 的安裝,請在使用 HPA 之前開啟 Metrics-server 的安裝,參考以下文檔。

安裝后如何啟用 Metrics Server

1.?通過修改 ks-installer 的 configmap 可以選裝組件,執行以下命令。

kubectl edit cm -n kubesphere-system ks-installer

參考如下修改 :

...devops:enabled: True # 開啟自動化部署jenkinsMemoryLim: 2GijenkinsMemoryReq: 1000Mi # jenkins初始化申請調整為1GjenkinsVolumeSize: 8GijenkinsJavaOpts_Xms: 512mjenkinsJavaOpts_Xmx: 512mjenkinsJavaOpts_MaxRAM: 2gsonarqube:enabled: False # 開啟代碼質量檢查postgresqlVolumeSize: 8Giservicemesh:enabled: Truenotification:enabled: True # 打開通知系統alerting:enabled: True # 打開告警系統
...

2.??保存退出,保存退出,參考?驗證可插拔功能組件安裝?,通過查詢 ks-installer 日志或 Pod 狀態驗證功能組件是否安裝成功。

(1)在 kubectl 中執行以下命令查看安裝日志檢查安裝過程。

開啟可插拔功能組件的安裝后,需要通過日志或 Pod 狀態驗證功能組件是否安裝成功。

查看 ks-installer 安裝過程中產生的動態日志,等待安裝成功:

kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f

當日志出現以下提示,說明開啟的組件已安裝成功。

(2)安裝成功后,可登陸控制臺,在 服務組件下查看可插拔功能組件下的所有組件是否都已經安裝啟動完畢。

3. 驗證組件的安裝?

????????除了在控制臺查看組件狀態,還可以通過 kubectl 命令確認可插拔的組件是否安裝成功。
通常情況下,當該 namespace 下的所有 Pod 狀態都為 Running,并且 Job 都為 Completed 狀態,則說明該組件安裝成功。

kubectl get pods --all-namespaces

2.3 建立多租戶系統

官方文檔:創建企業空間、項目、用戶和平臺角色

2.3.1 目的

? ? ? ? 本文檔面向初次使用 KubeSphere 的集群管理員用戶,引導新手用戶創建企業空間、創建新的角色和賬戶,然后邀請新用戶進入企業空間后,創建項目和 DevOps 工程,幫助用戶熟悉多租戶下的用戶和角色管理,快速上手?KubeSphere。

2.3.2 前提條件

? ? ? ? 已安裝?KubeSphere,并使用默認的 admin 用戶名和密碼登錄了?KubeSphere。

????????目前,平臺的資源一共有三個層級,包括 集群 (Cluster)、 企業空間 (Workspace)、 項目 (Project) 和 DevOps Project (DevOps 工程),層級關系如下圖所示,即一個集群中可以創建多個企業空間,而每個企業空間,可以創建多個項目和 DevOps工程,而集群、企業空間、項目和 DevOps工程中,默認有多個不同的內置角色。

2.3.3 集群管理員

第一步:創建角色和賬號

平臺中的 cluster-admin 角色可以為其他用戶創建賬號并分配平臺角色,平臺內置了集群層級的以下三個常用的角色,同時支持自定義新的角色。

內置角色描述
cluster-admin集群管理員,可以管理集群中所有的資源。
workspaces-manager集群中企業空間管理員,僅可創建、刪除企業空間,維護企業空間中的成員列表。
cluster-regular集群中的普通用戶,在被邀請加入企業空間之前沒有任何資源操作權限。

通過下圖可以更清楚地了解本示例的邏輯:

本示例首先新建一個角色(users-manager)?,為該角色授予賬號管理、角色管理權限,然后新建一個賬號并給這個賬號授予 users-manager 角色。

賬號名集群角色職責
user-managerusers-manager管理集群的賬戶和角色

1. 點擊 平臺管理-》平臺角色-》創建,創建一個角色用于管理所有的賬戶和角色。

2. 填寫平臺角色的基本信息。

  • 名稱:角色的名稱。
  • 描述信息:簡單描述角色擁有的權限。

3. 為創建的平臺角色進行權限設置,勾選賬戶管理、角色管理的所有權限后,點擊創建。

4.?點擊 平臺管理-》賬戶管理-》創建。

5. 填寫新用戶的基本信息,如用戶名 atguigu-hr?,角色選擇 user-manager?,其它信息可自定義,點擊確定。

6. 使用新創建的用戶 atguigu-hr 登錄。

7. 使用 atguigu-hr 賬戶登錄來創建下表中的四個賬號,ws-manager 將用于創建一個企業空間,并指定 ws-admin 作為企業空間管理員。切換 atguigu-hr 賬號登錄后在賬號管理下,新建四個賬號,創建步驟同上,參考如下信息創建。

用戶名集群角色職責
ws-managerworkspaces-manager創建企業空間
ws-admincluster-regular管理企業空間下所有的資源(本示例用于邀請新成員加入企業空間)
project-admincluster-regular創建和管理項目、DevOps工程,邀請新成員加入
project-regularcluster-regular將被?project-admin 邀請加入項目和DevOps工程,用于創建項目和工程下的工作負載、Pipeline等資源

8. 查看新建的四個賬號信息。

2.3.4 企業空間管理員

第二步:創建企業空間

企業空間 (workspace) 是 KubeSphere 實現多租戶模式的基礎,是用戶管理項目、DevOps 工程和企業成員的基本單位。

1. 使用 ws-manager 登錄 KubeSphere ,ws-manager 有權限查看和管理平臺的所有企業空間。

點擊 平臺管理-》企業空間,可見新安裝的環境只有一個系統默認的企業空間 system-workspace,用于運行 KubeSphere 平臺相關組件和服務,禁止刪除該企業空間。

點擊創建,創建新的企業空間:

2. 填寫企業空間基本信息,點擊確定。企業空間的創建者同時默認為該企業空間的管理員(workspaces-manager),擁有企業空間的最高管理權限。

  • 企業空間名稱:請盡量保持企業名稱簡短,便于用戶瀏覽和搜索,本示例是 gulimall-workspace。
  • 企業空間管理員:指定 ws-manager 為管理員,同時邀請?ws-manager 用戶進入該企業空間。
  • 描述信息:簡單介紹該企業空間。

3. 邀請成員到該企業空間,點擊 企業空間設置-》企業成員,選擇企業空間成員并賦予角色。

成員企業角色描述
ws-adminworkspace-admin企業空間管理員,可以管理企業空間下所有的資源

新創建的企業空間,默認有三個內置企業角色,如下:

4. 切換 ws-admin(企業空間gulimall-workspace的管理員)登錄,點擊 進入企業空間。

5. ws-admin可以從集群成員中邀請新成員加入當前企業空間,然后創建項目和 DevOps 工程。點擊 企業空間設置-》企業成員-》邀請成員。

這一步需要邀請在 2.3.3 的步驟6創建的兩個用戶 project-admin和 project-regular進入企業空間,且分別授予 workspace-regular和 workspace-viewer的角色,此時該企業空間一共有如下四個用戶:

用戶名企業角色職責
ws-adminworkspace-admin企業空間管理員,管理企業空間下所有的資源(本示例用于邀請新成員加入企業空間)。
project-adminworkspace-regular創建和管理項目、DevOps 工程。
project-regularworkspace-viewer企業空間的觀察者,可以查看企業空間下所有的資源信息。

2.3.5 項目和 DevOps 工程管理員

第三步:創建項目

創建工作負載、服務和 CI/CD 流水線等資源之前,需要預先創建項目和 DevOps 工程。

1. 使用 project-admin 登錄,進入 gulimall-workspace ,點擊 創建-》創建資源型項目。

2. 填寫項目的基本信息和高級設置,完成后點擊 下一步。

基本信息

  • 名稱:為項目起一個簡潔明了的名稱,便于用戶瀏覽和搜索,比如 demo-project
  • 別名:幫助您更好的區分資源,并支持中文名稱,比如 示例項目
  • 描述信息:簡單介紹該項目

高級信息

此處將默認的最大 CPU 和內存分別設置 0.5 Core和 500?Mi,后續的示例都可以在這個示例項目中完成,在項目使用過程中可根據實際情況再次編輯資源默認請求。

完成高級設置后,點擊創建。

說明:高級設置是在當前項目中配置容器默認的 CPU 和內存的請求與限額,相當于是給項目創建了一個 Kubernetes 的 LimitRange 對象,在項目中創建工作負載后填寫容器組模板時,若不填寫容器 CPU 和內存的請求與限額,則容器會被分配在高級設置的默認 CPU 和內存請求與限額值。

3. 邀請成員

project-admin 創建完項目 gulimall 后,點擊 項目成員-》邀請成員,將用戶 project-regular 邀請進gulimall 項目并賦予 operator(項目維護者權限) 角色權限,作為該項目的開發人員。

第四步:創建 DevOps工程

DevOps 提供一系列持續集成 (CI) 和持續交付 (CD) 工具,可以使 IT 和軟件開發團隊之間的流程實現自動化。在 CI/CD 工作流中,每次集成都通過自動化構建來驗證,包括編碼、發布和測試,從而幫助開發者提前發現集成錯誤,團隊也可以快速、安全、可靠地將內部軟件交付到生產環境。

1. 繼續使用 project-admin 用戶創建 DevOps 工程。點擊創建,在彈窗中選擇創建一個DevOps 工程。DevOps 工程的創建者 project-admin 將默認成為該工程的 owner,擁有?DevOps 工程的最高權限。

2. 輸入?DevOps 工程的名稱和描述信息,如下,點擊 創建。

  • 名稱:此 DevOps 項目的簡明名稱,便于用戶識別,例如?demo-devops
  • 描述信息:此 DevOps 項目的簡要介紹。

3. 點擊 DevOps 工程列表中的 gulimall-devops 進入工程,邀請成員到此工程,并賦予 maintainer 角色權限,用于工程的 Pipeline配置、憑證配置等操作。具體操作步驟如下,后續在 DevOps 工程中創建 Pipeline 和憑證等資源,都可以由 project-regular用戶登錄后進行操作。

創建工程默認有四種角色,如下:

2.4 創建 WordPress 應用并發布至 Kubernetes

官方文檔:創建并部署 WordPress

非官方文檔:快速入門 - 3. 創建 Wordpress 應用并發布至 K8s - 《KubeSphere v2.1 使用手冊》 - 書棧網 · BookStack

2.4.1 WordPress 簡介

????????WordPress 是使用 PHP 開發的博客平臺,用戶可以在支持 PHP 和 MySQL 數據庫的環境中架設屬于自己的網站。本文以創建一個?Wordpress 應用?為例,以創建 KubeSphere 應用的形式將 Wordpress 的組件(MySQL 和 Wordpress)創建后發布至 Kubernetes 中,并在集群外訪問 Wordpress 服務。

一個完整的 Wordpress 應用會包括以下 Kubernetes 對象,其中 MySQL 作為后端數據庫,Wordpress 本身作為前端提供瀏覽器訪問。

2.4.2 前提條件

???????已創建了企業空間、項目和普通用戶 project-regular 賬號(該已賬號已被邀請至示例項目),并開啟了外網訪問,請參考?多租戶管理快速入門。

2.4.3 創建密鑰

2.4.3.1 創建 MySQL 密鑰

1. 以項目普通用戶 project-regular 登錄 KubeSphere ,在當前項目下左側菜單欄的 配置中心 選擇? ?密鑰,點擊 創建

2. 填寫密鑰的基本信息,完成后點擊 下一步。

  • 名稱:作為 MySQL 容器中環境變量的名稱,可自定義,例如 mysql-secret?

  • 別名:別名可以由任意字符組成,幫助您更好的區分資源,例如 MySQL 密鑰

  • 描述信息:簡單介紹該密鑰,如?MySQL 初始密碼

3. 密鑰設置,填寫如下信息,完成后點擊 創建。

  • 類型:選擇 默認(Opaque)
  • Data:Data 鍵值對填寫 MYSQL_ROOT_PASSWORD123456(對應MySQL環境變量)

4. 可以點擊密鑰,查看密鑰的信息。

2.4.3.2 創建 WordPress 密鑰

同上,創建一個 WordPress 密鑰,Data 鍵值對填寫 WORDPRESS_DB_PASSWORD123456 。此時兩個密鑰都創建完成。

2.4.4 創建存儲卷

1. 在當前項目下左側菜單欄的 存儲卷,點擊 創建,基本信息如下。

  • 名稱:wordpress-pvc
  • 別名:Wordpress 持久化存儲卷

2. 完成后點擊 下一步,存儲類型默認 openebs-hostpath,訪問模式和存儲卷容量也可以使用默認值,點擊 下一步,直接創建即可。

3. 同樣的方法創建mysql存儲卷

2.4.5 創建應用

前置條件

????????目前 docker hub 已經不允許訪問,在添加容器鏡像無法從官網下載鏡像,這里我們使用 Docker 搭建 Harbor 私有倉庫,便于 Kubesphere 集成容器鏡像倉庫。Docker 搭建 Harbor 私有倉庫,請參考博客:Docker 搭建 Harbor 私有倉庫-CSDN博客

注意:創建一個新的虛擬機 harbor(192.168.56.103),保證集群的三個節點k8s-node1、k8s-node2、k8s-node3 都能 ping 通?harbor,并且集群的三個節點都要添加 Harbor 地址到信任列表,如下:

# 編輯 Docker 配置文件
vi /etc/docker/daemon.json# 添加內容如下{"insecure-registries": ["192.168.56.103:80"]
}# 保存
:wq# 重新加載 Docker 配置,并重啟
systemctl daemon-reload
systemctl restart docker

添加 Harbor 鏡像倉庫

1. 登錄 KubeSphere 管理控制臺,在已創建的項目中,左側菜單欄中選擇 配置中心 -> 密鑰,點擊創建。

2. 填寫鏡像倉庫的基本信息。

  • 名稱:為鏡像倉庫起一個簡潔明了的名稱,便于瀏覽和搜索。
  • 別名:幫助您更好的區分資源,并支持中文名稱。
  • 描述信息:簡單介紹鏡像倉庫的主要特性,讓用戶進一步了解該鏡像倉庫。

3. 密鑰設置,選擇類型 鏡像倉庫密鑰,填寫登錄鏡像倉庫的信息。

  • 倉庫地址:使用 Harbor 倉庫地址 192.168.56.103:80?
  • 用戶名/密碼:admin/Harbor12345。
  • 郵箱:填寫個人郵箱。

4. 點擊創建并查看結果。

2.4.5.1 添加 MySQL 后端組件?

1. 在左側菜單欄選擇 應用負載->應用,點擊部署新應用。

2. 填寫基本信息,完成后在右側點擊 添加組件

  • 應用名稱:必填,起一個簡潔明了的名稱,便于用戶瀏覽和搜索,例如填寫 wordpress-application
  • 描述信息:簡單介紹該工作負載,方便用戶進一步了解。

3. 填寫 MySQL 組件信息。

  • 名稱:mysql。
  • 組件版本:v1。
  • 別名:MySQL數據庫。
  • 負載類型:有狀態服務(有狀態副本集)。

4. 點擊添加 容器鏡像,鏡像填寫 gulimall/mysql:5.6(應指定鏡像版本號),然后回車,點擊使用默認端口。

注意:

  • DockerHub官網無法使用,這里我們使用自己私有的鏡像倉庫:192.168.56.103:80/gulimall
  • 在高級設置中確保內存限制 ≥ 1000 Mi,否則可能 MySQL 會因內存 Limit 不夠而無法啟動。

5. 下滑,勾選 環境變量,然后選擇 引用配置文件或密鑰,名稱填寫為 MYSQL_ROOT_PASSWORD ,下拉框中選擇密鑰 mysql-secret 和??MYSQL_ROOT_PASSWORD 。完成后點擊右下角 √ 。

6. 點擊 添加存儲卷模板 ,為 MySQL 創建一個 PVC 實現數據持久化。

參考下圖填寫存儲卷信息:

  • 存儲卷名稱:必填,起一個簡潔明了的名稱,便于用戶瀏覽和搜索,此處填寫 mysql-pvc
  • 存儲類型:選擇集群已有的存儲類型,如 openebs-hostpath
  • 訪問模式和容量:訪問模式默認 RWO ,容量默認 10Gi
  • 掛載路徑:存儲卷在容器內的掛載路徑,選擇 讀寫,路徑填寫 /var/lib/mysql

完成后點擊右下角 √ 。

2.4.5.2 添加 WordPress 前端組件

1. 填寫 WordPress 組件信息。

  • 名稱:wordpress。
  • 組件版本:v1。
  • 別名:WordPress 前端。
  • 負載類型:無狀態服務(部署)。

2. 點擊添加 容器鏡像,鏡像填寫 gulimall/wordpress:4.8-apache(應指定鏡像版本號),然后回車,點擊使用默認端口。

3.?下滑,勾選 環境變量,這里需要添加兩個環境變量。

  • 點擊 引用配置文件或密鑰,名稱填寫為 WORDPRESS_DB_PASSWORD,下拉選擇密鑰 wordpress-secret 和?WORDPRESS_DB_PASSWORD
  • 點擊 添加環境變量,名稱填寫為 WORDPRESS_DB_HOST,值填寫為 mysql ,對應的是上一步添加 MySQL 組件的服務名稱,否則無法連接 MySQL 數據庫。

完成后點擊右下角 √ 。

4. 點擊 添加存儲卷,選擇已有存儲卷 wordpress-pvc,訪問模式改為 讀寫,容器掛載路徑 /var/www/html完成后點擊右下角 √ 。

5. 點擊 創建。

2.4.5.3 查看應用資源

1. 在 工作負載 下查看 部署有狀態副本集 的狀態,當它們都顯示為 運行中,說明 WordPress 應用創建成功。

?2. 選擇左側導航欄中的應用負載 -> 服務。點擊?wordpress?右側的三個點后,選擇編輯外部訪問,選擇 NodePort,點擊 確定。

2.4.5.4 訪問 wordpress

訪問地址:http://192.168.56.100:31285

1. 選擇 簡體中文。

2. 注冊信息,并點擊安裝 WordPress。

3. 安裝完成,進行登錄。

  • 用戶名/電子郵箱地址:www/atguigu-wordpress@atguigu.com
  • 密碼:123456

4. 登錄成功頁面。

3 DevOps

3.1 項目開發需要考慮的維度

Dev:怎么開發?

Ops:怎么運維?

高并發:怎么承擔高并發

高可用:怎么做到高可用

3.2 什么是 DevOps

微服務,服務自治。

DevOps:Development 和 Operations 的組合

  • DevOps 看作開發(軟件工程)、技術運營和質量保障(QA)三者的交集。
  • 突出重視軟件開發人員和運維人員的溝通合作,通過自動化流程來使得軟件構建、測試、發布更加快捷、頻繁和可靠。
  • DevOps 希望做到的是軟件產品交付過程中 IT 工具鏈的打通,使得各個團隊減少時間損耗,更加高效地協同工作。專家們總結出了下面這個 DevOps 能力圖,良好的閉環可以大大增加整體的產出。

3.3 什么是 CI&CD

3.3.1 持續集成(Continuous Integration)

  • 持續集成是指軟件個人研發的部分向軟件整體部分交付,頻繁進行集成以便更快地發現其中的錯誤。“持續集成”源自于極限編程(XP),是 XP 最初的 12 種實踐之一。
  • CI 需要具備這些:
    • 全面的自動化測試。這是實踐持續集成&持續部署的基礎,同時,選擇合適的 自動化測試工具也極其重要;
    • 靈活的基礎設施。容器,虛擬機的存在讓開發人員和 QA 人員不必再大費周折;
    • 版本控制工具。如 Git,CVS,SVN 等;
    • 自動化的構建和軟件發布流程的工具。如 Jenkins,flow.ci;
    • 反饋機制。如構建/測試的失敗,可以快速地反饋到相關負責人,以盡快解決達到一個更穩定的版本。

3.3.2 持續交付(Continuous Delivery)

持續交付在持續集成的基礎上, 將集成后的代碼部署到更貼近真實運行環境的「類生產環境」 (production-like environments) 中。 持續交付優先于整個產品生命周期的軟件部署, 建立 在高水平自動化持續集成之上。

灰度發布。

持續交付和持續集成的優點非常相似:

  • 快速發布。 能夠應對業務需求, 并更快地實現軟件價值。
  • 編碼->測試->上線->交付的頻繁迭代周期縮短, 同時獲得迅速反饋;
  • 高質量的軟件發布標準。 整個交付過程標準化、 可重復、 可靠,
  • 整個交付過程進度可視化, 方便團隊人員了解項目成熟度;
  • 更先進的團隊協作方式。 從需求分析、 產品的用戶體驗到交互 設計、 開發、 測試、 運 維等角色密切協作, 相比于傳統的瀑布式軟件團隊, 更少浪費。

3.3.3 持續部署(Continuous Deployment)

持續部署是指當交付的代碼通過評審之后,自動部署到生產環境中。持續部署是持續交付的最高階段。這意味著,所有通過了一系列的自動化測試的改動都將自動部署到生產環境。它也可以被稱為“Continuous Release”。

“開發人員提交代碼,持續集成服務器獲取代碼,執行單元測試,根據測試結果決定是否部署到預演環境,如果成功部署到預演環境,進行整體驗收測試,如果測試通過,自動部署到產品環境,全程自動化高效運轉。“

持續部署主要好處是,可以相對獨立地部署新的功能,并能快速地收集真實用戶的反饋。

“You build it, you run it”,這是 Amazon 一年可以完成 5000 萬次部署, 平均每個工程師每天部署超過 50 次的核心秘籍。

下圖是由 Jams Bowman 繪制的持續交付工具鏈圖

3.3.4 落地方案

Maven+Github+Jenkins(Hudson[現由甲骨文維護]) +Docker

自動化部署

3.4 基于Sping Boot項目構建流水線

官方文檔:使用 Jenkinsfile 創建流水線

非官方文檔:快速入門 - 9. 基于Spring Boot項目構建流水線 - 《KubeSphere v2.1 使用手冊》 - 書棧網 · BookStack

????????Jenkinsfile in SCM 意為將 Jenkinsfile 文件本身作為源代碼管理 (Source Control Management) 的一部分,根據該文件內的流水線配置信息快速構建工程內的 CI/CD 功能模塊,比如階段 (Stage),步驟 (Step) 和任務 (Job)。因此,在代碼倉庫中應包含 Jenkinsfile。

3.4.1 目的

????????本示例演示如何通過 GitHub 倉庫中的 Jenkinsfile 來創建流水線,流水線共包括 8 個階段,最終將演示示例部署到 KubeSphere 集群中的開發環境和生產環境且能夠通過公網訪問。倉庫中的 dependency 分支為緩存測試用例,測試方式與 master 分支類似,對 dependency 的多次構建可體現出利用緩存可以有效的提升構建速度。

3.4.2 前提條件

  • 開啟安裝了 DevOps 功能組件,參考?安裝 DevOps 系統;
  • 本示例以 GitHub 和 DockerHub 為例,參考前確保已創建了?GitHub?和?DockerHub?賬號;
  • 已創建了企業空間和 DevOps 工程并且創建了項目普通用戶 project-regular 的賬號,若還未創建請參考?多租戶管理快速入門;
  • 使用項目管理員?project-admin?邀請項目普通用戶?project-regular?加入 DevOps 工程并授予?maintainer?角色,若還未邀請請參考?多租戶管理快速入門 - 邀請成員。
  • 參考?配置 ci 節點?為流水線選擇執行構建的節點。

3.4.3 流水線概覽

下面的流程圖簡單說明了流水線完整的工作過程:

流程說明:

  • 階段一. Checkout SCM: 拉取 GitHub 倉庫代碼
  • 階段二. Unit test: 單元測試,如果測試通過了才繼續下面的任務
  • 階段三. SonarQube analysis:sonarQube 代碼質量檢測
  • 階段四. Build & push snapshot image: 根據行為策略中所選擇分支來構建鏡像,并將 tag 為?SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER?推送至 Harbor (其中?$BUILD_NUMBER?為 pipeline 活動列表的運行序號)。
  • 階段五. Push latest image: 將 master 分支打上 tag 為 latest,并推送至 DockerHub。
  • 階段六. Deploy to dev: 將 master 分支部署到 Dev 環境,此階段需要審核。
  • 階段七. Push with tag: 生成 tag 并 release 到 GitHub,并推送到 DockerHub。
  • 階段八. Deploy to production: 將發布的 tag 部署到 Production 環境。

3.4.4 創建憑證

注意:

  • GitHub 賬號或密碼帶有 "@" 這類特殊字符,需要創建憑證前對其進行 urlencode 編碼,可通過一些?第三方網站進行轉換,然后再將轉換后的結果粘貼到對應的憑證信息中。
  • 這里需要創建的是憑證(Credential),不是密鑰(Secret)。

在?多租戶管理快速入門?中已給項目普通用戶 project-regular 授予了 maintainer 的角色,因此使用 project-regular 登錄 KubeSphere,進入已創建的 devops-demo 工程,開始創建憑證。

1、本示例代碼倉庫中的 Jenkinsfile 需要用到?DockerHub、GitHub?和?kubeconfig?(kubeconfig 用于訪問接入正在運行的 Kubernetes 集群) 等一共 3 個憑證 (credentials) ,參考?創建憑證?依次創建這三個憑證。

2、然后參考?訪問 SonarQube 并創建 Token,創建一個 Java 的 Token 并復制。

3、最后在 KubeSphere 中進入 gulimall-devops?的 DevOps 工程中,與上面步驟類似,在?憑證?下點擊?創建,創建一個類型為 秘密文本 的憑證,憑證 ID 命名為?sonar-token,密鑰為上一步復制的 token 信息,完成后點擊?確定

  • 創建 Harbor 憑證

? ? ? ? 創建一個用于 Harbor 登錄的憑證,憑證 ID 為:harbor-id,類型選擇 賬戶憑證。用戶名/密碼:admin/Harbor12345,完成后點擊 確定。

  • 創建 GitHub 憑證

????????同上,創建一個用于 GitHub 的憑證,憑證 ID 為:github-id,類型選擇 賬戶憑證,輸入您個人的 GitHub 用戶名和密碼,備注描述信息,完成后點擊 確定。

注意:github 的認證策略發生了改變,在 2021年8月13日的時候,用戶名加密碼的認證方式被去掉了,換成了 個人令牌(Personal Access Token)的校驗方式。所以我們這里使用token
創建token的具體操作步驟可以參考文檔:GIthub獲取token令牌_github token在哪里-CSDN博客

  • 創建 kubeconfig 憑證

????????在 憑證 下點擊 創建,創建一個類型為 kubeconfig 的憑證,憑證 ID 可命名為 demo-kubeconfig,完成后點擊 確定。

說明:kubeconfig 類型的憑證用于訪問接入正在運行的 Kubernetes 集群,在流水線部署步驟將用到該憑證。注意,此處的 Content 將自動獲取當前 KubeSphere 中的 kubeconfig 文件內容,若部署至當前 KubeSphere 中則無需修改,若部署至其它 Kubernetes 集群,則需要將其 kubeconfig 文件的內容粘貼至 Content 中。

  • 訪問 SonarQube 并創建 Token,創建一個 Java 的 Token 并復制。

????????KubeSphere內置SonarQube,我們通過 kubectl get svc --all-namespaces 命令,找到 SonarQube 服務,可以看到端口信息。

kubectl get svc --all-namespaces

訪問地址:http://192.168.56.100:32595

賬號:admin

密碼:admin

ded383e8a4e3deedc8efac2cd87c348b0649ff30

創建 SonarQube 憑證

3.4.5 修改 Jenkinsfile

3.4.5.1 第一步:Fork項目

登錄 GitHub,將本示例用到的 GitHub 倉庫?devops-java-sample?Fork 至您個人的 GitHub。

3.4.5.2 修改 Jenkinsfile

1. Fork 至您個人的 GitHub 后,在?根目錄?進入?Jenkinsfile-online

2. 在 GitHub UI 點擊編輯圖標,需要修改如下環境變量 (environment) 的值。

修改項含義
DOCKER_CREDENTIAL_IDdockerhub-id填寫創建憑證步驟中的 DockerHub 憑證 ID,用于登錄您的 DockerHub
GITHUB_CREDENTIAL_IDgithub-id填寫創建憑證步驟中的 GitHub 憑證 ID,用于推送 tag 到 GitHub 倉庫
KUBECONFIG_CREDENTIAL_IDdemo-kubeconfigkubeconfig 憑證 ID,用于訪問接入正在運行的 Kubernetes 集群
REGISTRYdocker.io默認為 docker.io 域名,用于鏡像的推送
DOCKERHUB_NAMESPACEyour-dockerhub-account替換為您的 DockerHub 賬號名 (它也可以是賬戶下的 Organization 名稱)
GITHUB_ACCOUNTyour-github-account替換為您的 GitHub 賬號名,例如?https://github.com/kubesphere/?則填寫?kubesphere?(它也可以是賬戶下的 Organization 名稱)
APP_NAMEdevops-java-sample應用名稱
SONAR_CREDENTIAL_IDsonar-token填寫創建憑證步驟中的 SonarQube token憑證 ID,用于代碼質量檢測

修改后的內容:

 environment {DOCKER_CREDENTIAL_ID = 'harbor-id'GITHUB_CREDENTIAL_ID = 'github-id'KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'REGISTRY = '192.168.56.103:80/gulimall'DOCKERHUB_NAMESPACE = 'admin'GITHUB_ACCOUNT = 'good0luck'APP_NAME = 'devops-java-sample'SONAR_CREDENTIAL_ID = 'sonar-token'}

注:master分支 Jenkinsfile 中 mvn命令的參數 -o,表示開啟離線模式。本示例為適應某些環境下網絡的干擾,以及避免在下載依賴時耗時太長,已事先完成相關依賴的下載,默認開啟離線模式。

3.?修改以上的環境變量后,點擊?Commit changes,將更新提交到當前的 master 分支。

3.4.6 創建項目

CI/CD 流水線會根據示例項目的 yaml 模板文件,最終將示例分別部署到 kubesphere-sample-devkubesphere-sample-prod 這兩個項目 (Namespace) 環境中,這兩個項目需要預先在控制臺依次創建,參考如下步驟創建該項目。

一個項目對應一個Namespace 。

3.4.6.1 創建第一個項目

提示:項目管理員 project-admin 賬號已在?多租戶管理快速入門?中創建。

1. 使用項目管理員 project-admin 賬號登錄 KubeSphere,在之前創建的企業空間 (gulimall-workspace) 下,點擊 項目創建,創建一個 資源型項目,作為本示例的開發環境,填寫該項目的基本信息,完成后點擊 下一步

  • 名稱:固定為 kubesphere-sample-dev,若需要修改項目名稱則需在?yaml 模板文件?中修改 namespace
  • 別名:可自定義,比如 開發環境
  • 描述信息:可簡單介紹該項目,方便用戶進一步了解

2. 本示例暫無資源請求和限制,因此高級設置中無需修改默認值,點擊 創建,項目可創建成功。

3. 邀請成員

第一個項目創建完后,還需要項目管理員 project-admin 邀請當前的項目普通用戶 project-regular 進入 kubesphere-sample-dev 項目,進入「項目設置」→「項目成員」,點擊「邀請成員」選擇邀請 project-regular 并授予 operator 角色,若對此有疑問可參考 多租戶管理快速入門 - 邀請成員。

3.4.6.2 創建第二個項目

同上,參考以上兩步創建一個名稱為 kubesphere-sample-prod 的項目作為生產環境,并邀請普通用戶 project-regular 進入 kubesphere-sample-prod 項目并授予 operator 角色。

說明:當 CI/CD 流水線后續執行成功后,在 kubesphere-sample-dev 和 kubesphere-sample-prod 項目中將看到流水線創建的部署 (Deployment) 和服務 (Service)。

3.4.7 創建流水線

3.4.7.1 第一步:填寫基本信息

1. 使用 project-regular 登錄,進入已創建的 DevOps 工程,選擇左側菜單欄的 流水線,然后點擊創建

2. 在彈出的窗口中,輸入流水線的基本信息。

  • 名稱:為創建的流水線起一個簡潔明了的名稱,便于理解和搜索
  • 描述信息:簡單介紹流水線的主要特性,幫助進一步了解流水線的作用
  • 代碼倉庫:點擊選擇代碼倉庫,代碼倉庫需已存在 Jenkinsfile

3.4.7.2 第二步:添加倉庫

1. 點擊代碼倉庫,以添加 Github 倉庫為例。

2. 點擊彈窗中的?獲取 Token。

3. 在GitHub 的 access token 頁面填寫 Token description,簡單描述該 token,如 DevOps demo,在 Select scopes 中無需任何修改,點擊 Generate token,GitHub 將生成一串字母和數字組成的 token 用于訪問當前賬戶下的 GitHub repo。

4. 復制生成的 token,在 KubeSphere Token 框中輸入該 token 然后點擊保存。

5. 驗證通過后,右側會列出此 Token 關聯用戶的所有代碼庫,選擇其中一個帶有 Jenkinsfile 的倉庫。比如此處選擇準備好的示例倉庫 devops-java-sample,點擊 選擇此倉庫,完成后點擊 下一步。

3.4.7.3 第三步:高級設置

完成代碼倉庫相關設置后,進入高級設置頁面,高級設置支持對流水線的構建記錄、行為策略、定期掃描等設置的定制化,以下對用到的相關配置作簡單釋義。

1. 分支設置中,勾選 丟棄舊的分支,此處的 保留分支的天數 和 保留分支的最大個數 默認為 -1。

說明:

分支設置的保留分支的天數和保持分支的最大個數兩個選項可以同時對分支進行作用,只要某個分支的保留天數和個數不滿足任何一個設置的條件,則將丟棄該分支。假設設置的保留天數和個數為 2 和 3,則分支的保留天數一旦超過 2 或者保留個數超過 3,則將丟棄該分支。默認兩個值為 -1,表示將會丟棄已經被刪除的分支。

丟棄舊的分支將確定何時應丟棄項目的分支記錄。分支記錄包括控制臺輸出,存檔工件以及與特定分支相關的其他元數據。保持較少的分支可以節省 Jenkins 所使用的磁盤空間,我們提供了兩個選項來確定應何時丟棄舊的分支:

  • 保留分支的天數:如果分支達到一定的天數,則丟棄分支。
  • 保留分支的個數:如果已經存在一定數量的分支,則丟棄最舊的分支。

2. 行為策略中,KubeSphere 默認添加了三種策略。由于本示例還未用到 從 Fork 倉庫中發現 PR 這條策略,此處可以刪除該策略,點擊右側刪除按鈕。

3.?默認的 腳本路徑 為 Jenkinsfile,請將其修改為?Jenkinsfile-online

注:路徑是 Jenkinsfile 在代碼倉庫的路徑,表示它在示例倉庫的根目錄,若文件位置變動則需修改其腳本路徑。

4. 在 掃描 Repo Trigger 勾選 如果沒有掃描觸發,則定期掃描,掃描時間間隔可根據團隊習慣設定,本示例設置為 5 minutes。?

說明:定期掃描是設定一個周期讓流水線周期性地掃描遠程倉庫,根據 行為策略 查看倉庫有沒有代碼更新或新的 PR。

Webhook 推送:

Webhook 是一種高效的方式可以讓流水線發現遠程倉庫的變化并自動觸發新的運行,GitHub 和 Git (如 Gitlab) 觸發 Jenkins 自動掃描應該以 Webhook 為主,以上一步在 KubeSphere 設置定期掃描為輔。在本示例中,可以通過手動運行流水線,如需設置自動掃描遠端分支并觸發運行,詳見 設置自動觸發掃描 - GitHub SCM。

5. 將 webhook推送地址 復制到Github倉庫?setting->webhook->Add webhook,填寫復制的地址到Payload URL,點擊 Add webhook 進行保存。

6.?完成高級設置后點擊?創建

3.4.7.4 第四步:運行流水線

流水線創建后,點擊瀏覽器的 刷新 按鈕,可見兩條自動觸發遠程分支后的運行記錄,分別為 master 和 dependency 分支的構建記錄。

1. 點擊右側 運行,將根據上一步的 行為策略 自動掃描代碼倉庫中的分支,在彈窗選擇需要構建流水線的 master 分支,系統將根據輸入的分支加載 Jenkinsfile-online (默認是根目錄下的 Jenkinsfile)。

2. 由于倉庫的 Jenkinsfile-online 中 TAG_NAME: defaultValue 沒有設置默認值,因此在這里的 TAG_NAME 可以輸入一個 tag 編號,比如輸入 v0.0.1。

3. 點擊 確定,將新生成一條流水線活動開始運行。

說明: tag 用于在 Github 和DockerHub 中分別生成帶有 tag 的 release 和鏡像。 注意: 在主動運行流水線以發布 release 時,TAG_NAME 不應與之前代碼倉庫中所存在的 tag 名稱重復,如果重復會導致流水線的運行失敗。

至此,流水線 已完成創建并開始運行。

注:點擊 分支 切換到分支列表,查看流水線具體是基于哪些分支運行,這里的分支則取決于上一步 行為策略 的發現分支策略。

3.4.7.5 第五步:審核流水線

為方便演示,此處默認用當前賬戶來審核,當流水線執行至 input 步驟時狀態將暫停,需要手動點擊 繼續,流水線才能繼續運行。注意,在 Jenkinsfile-online 中分別定義了三個階段 (stage) 用來部署至 Dev 環境和 Production 環境以及推送 tag,因此在流水線中依次需要對 deploy to dev, push with tag, deploy to production 這三個階段審核 3 次,若不審核或點擊 終止 則流水線將不會繼續運行。

說明:在實際的開發生產場景下,可能需要更高權限的管理員或運維人員來審核流水線和鏡像,并決定是否允許將其推送至代碼或鏡像倉庫,以及部署至開發或生產環境。Jenkinsfile 中的 input步驟支持指定用戶審核流水線,比如要指定用戶名為 project-admin 的用戶來審核,可以在 Jenkinsfile 的 input 函數中追加一個字段,如果是多個用戶則通過逗號分隔,如下所示:

···
input(id: 'release-image-with-tag', message: 'release image with tag?', submitter: 'project-admin,project-admin1')
···

3.4.8 查看流水線

流水線這里有點問題,未解決,可能是私服、網絡等問題。可參照如下網址操作:

快速入門 - 9. 基于Spring Boot項目構建流水線 - 《KubeSphere v2.1 使用手冊》 - 書棧網 · BookStack

?????????

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916006.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916006.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916006.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從零搭建 OpenCV 項目(新手向)-- 第二天 OpenCV圖像預處理(一)

目錄 一、圖像翻轉&#xff08;鏡像翻轉&#xff09; 1. 定義 2. OpenCV 函數 3. 數學表達 二、圖像仿射變換 1. 定義 2. 仿射變換的基本原理 3. OpenCV 函數 4. 圖像旋轉 5. 圖像平移 6. 圖像縮放 7. 圖像剪切 8. 為什么會出現黑色背景&#xff1f; 三、圖像色彩…

貪心算法Day6學習心得

第一道&#xff1a;738. 單調遞增的數字 - 力扣&#xff08;LeetCode&#xff09; 這道題目暴力算法肯定是最容易想到的&#xff0c;先附上暴力的代碼&#xff1a; class Solution { private:// 判斷一個數字的各位上是否是遞增bool checkNum(int num) {int max 10;while (n…

數據的評估與清洗篇---上手清理索引和列名

重命名索引和列名 在讀取數據時,如果我們發現數據的索引或者列名亂七八糟的,可以使用DataFrame的rename方法對它們進行重新命名。 df1.rename(index={...})df1.rename(columns={...}) 重命名索引 如果想改索引就把可選參數index指定為一個字典,針對索引,把要修改…

【ICML2025】時間序列|TimePro:炸裂!線性復雜度實現高效長程多元時間序列預測!

論文地址&#xff1a;https://arxiv.org/pdf/2505.20774 代碼地址&#xff1a;https://github.com/xwmaxwma/TimePro 為了更好地理解時間序列模型的理論與實現&#xff0c;推薦參考UP “ThePPP時間序列” 的教學視頻。該系列內容系統介紹了時間序列相關知識&#xff0c;并提供配…

2025真實面試試題分析-iOS客戶端開發

以下是對iOS客戶端開發工程師面試問題的分類整理、領域占比分析及高頻問題精選&#xff08;基于??85道問題&#xff0c;總出現次數118次??&#xff09;。按技術領域整合為??7大核心類別??&#xff0c;按占比排序并精選高頻問題標注優先級&#xff08;1-5&#x1f31f;&…

計算機網絡簡答題(大雪圣期末參考資料)

1、網絡性能指標/計算機網絡有哪些常用的性能指標&#xff1f;答&#xff1a;速率&#xff0c;帶寬&#xff0c;吞吐量&#xff0c;時延&#xff08;發送時延、傳播時延、處理時延、排隊時延&#xff09;&#xff0c;時延帶寬積&#xff0c;往返時間RTT和信道&#xff08;或網絡…

紅寶書單詞學習筆記 list 76-100

list 76NO.WordMeaning1staleadj. 不新鮮的&#xff1b;陳腐的2stalln. 小隔間&#xff1b;攤位&#xff1b;牲畜棚&#xff1b;v. 停頓&#xff1b;(使) 熄火&#xff1b;故意拖延3staplen. 訂書釘&#xff1b;主要產品&#xff1b;主要部分&#xff1b;主食&#xff1b;v. 用…

Vue3 學習教程,從入門到精通,Vue 3 計算屬性(Computed Properties)知識點詳解與案例代碼(15)

Vue 3 計算屬性&#xff08;Computed Properties&#xff09;知識點詳解與案例代碼 在 Vue 3 中&#xff0c;計算屬性&#xff08;Computed Properties&#xff09; 是用于基于響應式數據派生新數據的一種方式。計算屬性具有以下特點&#xff1a; 緩存性&#xff1a;只有在依賴…

2.5 PN-PTCP

Pro?net Precision Transparent Clock Protocol (PN-PTCP) PN-PTCP&#xff08;精確透明時鐘協議&#xff09;是一種專用于 Profinet 的 二層協議&#xff0c;其作用是為網絡中的設備提供高精度的時間同步。用于實現網絡設備的高精度時間同步。

WordPress與Typecho站點CloudFlare緩存優化實戰指南

文章目錄 WordPress與Typecho站點CloudFlare緩存加速全攻略 引言 一、CloudFlare緩存基礎原理 1.1 CloudFlare工作流程 1.2 緩存類型 二、基礎配置指南 2.1 CloudFlare賬戶設置 2.2 緩存配置 2.3 頁面規則設置 三、高級緩存策略 3.1 動態內容緩存 WordPress方案: Typecho方案:…

【OpenCV實現多圖像拼接】

文章目錄1 OpenCV 圖像拼接核心原理2 OpenCV 圖像拼接實現代碼方法一&#xff1a;使用 OpenCV 內置 Stitcher 類&#xff08;推薦&#xff09;方法二&#xff1a;手動實現核心步驟關鍵參數說明3 常見問題處理4 增量式圖像拼接&#xff08;Incremental Image Stitching&#xff…

haproxy 算法

一、靜態算法按照事先定義好的規則輪詢公平調度&#xff0c;不關心后端服務器的當前負載、連接數和響應速度 等&#xff0c;且無法實時修改權重(只能為0和1,不支持其它值)&#xff0c;只能靠重啟HAProxy生效。(不管后端死活&#xff09;1.1、static-rr&#xff1a;基于權重的輪…

Go 的第一類對象與閉包

1. Go 的第一類對象&#xff08;First-Class Citizens&#xff09; 什么是第一類對象&#xff1f; 第一類對象是指能夠像 普通值 一樣使用的對象&#xff0c;通常可以賦值給變量、傳遞給函數、作為函數返回值等。在很多編程語言中&#xff0c;函數本身不被視為第一類對象&#…

深度分析Android多線程編程

理解并正確運用多線程是構建高性能、流暢、響應迅速的 Android 應用的關鍵&#xff0c;但也充滿挑戰和陷阱。 核心挑戰&#xff1a;UI 線程&#xff08;主線程&#xff09;的限制 唯一性&#xff1a; Android 應用只有一個主線程&#xff0c;負責處理所有用戶交互&#xff08;觸…

uniapp在app中關于解決輸入框鍵盤彈出后遮住輸入框問題

問題描述&#xff1a; uniapp的app中&#xff0c;當表單頁面過長時&#xff0c;點擊下方的輸入框時&#xff0c;彈出鍵盤后會把輸入框給擋住&#xff0c;導致看不到輸入內容。 解決方案&#xff1a; 在page.json中&#xff0c;找到此頁面的配置&#xff0c;加上style中的softin…

二分查找----5.尋找旋轉排序數組中的最小值

題目鏈接 /** 數組在某處進行旋轉,分割為兩個獨立的遞增區間,找出數組的最小值;特殊情況:若旋轉次數是數組長度的倍數,則數組不變 特點: 常規情況: 數組被分割為兩個獨立的子區間,左半區的最小值大于右半區的最大值 依據數組長度,mid可能落在左半區也有可能落在右半區,最小值在…

Eureka-服務注冊,服務發現

在遠程調用的時候&#xff0c;我們寫的url是寫死的。 String url "<http://127.0.0.1:9090/product/>" orderInfo.getProductId();當換個機器&#xff0c;或者新增個機器&#xff0c;導致ip變換&#xff0c;從而使得 url 發生了變化&#xff0c;接著就需要去…

ubuntu24的一些小問題

截圖Keyboard -> Keyboard Shortcus -> View and customize Shortcus如上&#xff0c;可以修改默認的快捷按鍵。比如截圖按鍵可以修改。 ibus輸入法無法&#xff0c;輸入V異常問題 也是困擾了很久&#xff0c;發現是這樣的&#xff1a;https://github.com/libpinyin/ibus…

Python Locust庫詳解:從入門到分布式壓力測試實戰

一、Locust核心優勢 作為一款基于Python的開源負載測試工具&#xff0c;Locust通過協程架構實現了高效資源利用。其獨特優勢體現在&#xff1a; 純Python腳本&#xff1a;用熟悉的語言定義用戶行為&#xff0c;支持條件判斷和復雜邏輯分布式擴展&#xff1a;單節點支持數千并發…

Redis數據類型與內部編碼

在Redis中通常普遍認為&#xff0c;使用redis的能進行查詢&#xff0c;插入&#xff0c;刪除&#xff0c;修改操作都是O(1)是因為他是利用hash表實現的&#xff0c;但是&#xff0c;背后的實現不一定是一個標準的hash表&#xff0c;它內部的數據類型還會有變數&#xff0c;不過…