k8s 是 Googlo 开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序的平台。
第 1 章 k8s 基础
1.1 k8s 特性
- 服务发现和负载均衡:k8s 可以负载均衡并分配网络流量使部署稳定
- 存储编排:k8s 允许自动挂载选择的存储系统
- 自动部署和回滚:使用 k8s 描述已部署容器
- 自动完成装箱计算:k8s 允许指定每个容器所需 CPU 和内存(RAM)
- 自我修复:k8s 重新启动失败容器、替换容器、杀死不响应容器,并且在准备好服务之前不通告给客户端
- 密钥和配置管理:允许存储和管理敏感信息,例如密码,OAuth 令牌和 SSH 令牌
1.2 k8s 组件架构(⭐)
1.2.1 Control Plane (控制平面,总部)
-
controller-manager(决策者):在主节点上运行控制器。每个控制器都是一个单独的进程, 为了降低复杂性它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器包括:
- 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应
- 任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
- 端点控制器(Endpoints Controller): 填充端点对象(即加入 Service 与 Pod)
- 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和访问令牌
-
apiserver(秘书部):提供了资源操作的唯一入口,公开了 k8s API,并提供认证、授权、访问控制、API 注册和服务发现等机制
-
etcd(资料库):k8s 默认的存储系统
-
scheduler(调度者):负责监视新创建的、未指定运行节点的 Pods,选择节点让 Pod 在上面运行
1.2.2 Node (节点,工厂)
- kubelet(厂长):集群中每个节点上运行的代理服务进程,对 Pod 进行创建、调度和维护
- kube-proxy(看门大爷):集群中每个节点上运行的网络代理,负责为Pod 提供服务和负载均衡功能
- docker(车间):提供容器运行环境
1.3 k8s 容器组和工作负载
1.3.1 Namespace 名称空间
Namespace 用来对集群资源进行隔离划分,只隔离资源不隔离网络。
# 获取名称空间
kubectl get ns
# 创建名称空间
kubectl create ns <namespace-name>
# 删除名称空间
kubectl delete ns <namespace-name>
1.3.2 Pod 容器组
k8s 为了管理容器,在 docker 容器上又封装了一层容器组 Pod。Pod 是 k8s 中应用的最小单元,包含一个或多个容器。Pod 中的容器共享同一个 IP 地址和命名空间,共享相同的存储卷和主机资源。
Pod 的状态有:
- pending:容器组已被节点接受,但由于网络原因还未运行起来
- running:容器组已经被调度到节点,并且所有的容器都已经启动。至少有一个容器处于运行或重启状态
- succeeded:所有容器都正常退出
- failed:所有容器都意外中断
Pod 常用命令有:
# 使用命令创建一个 Pod
kubectl run <pod-name> --image=<image-name> [-n <namespace-name>]
# 使用 yaml 创建一个 Pod
kubectl apply -f <pod-name>.yaml
# 查看 Pod
kubectl get pod -A
# 持续监控 Pod
kubectl get pods -w
# 查看 Pod 具体状态
kubectl describe pod <pod-name>
# 查看 Pod 日志
kubectl logs <pod-name> [-c container-name]
# 进入 Pod 中容器终端
kubectl exec -it <pod-name> -c <container-name> /bin/bash
# 删除 Pod
kubectl delete <Pod名称>
1.3.3 工作负载
在 Kubernetes 中,我们一般不直接创建 Pod,而是通过工作负载如 Deployment、StatefulSet、DaemonSet、Job, 为 Pod 提供水平伸缩,版本更新,故障恢复等能力。
Deployment ,使 Pod 拥有多副本,自愈,扩缩容等能力。deployment 命令有:
# 创建 deployment
kubectl create deploy <deploy-name> --image=[image-name]
# 查看创建的 deployment
kubectl get deploy
# 彻底删除 deployment
kubectl delete deploy <deploy-name>
# deployment 创建 3 份
kubectl create deploy <deploy-name> --image=nginx --replicas=3
# deployment 扩容到 5 份
kubectl scale deploy/<deploy-name> --replicas=5
# deployment 缩容到 2 份
kubectl scale deploy/<deploy-name> --replicas=2
# 滚动更新镜像
kubectl set image deploy/<deploy-name> [image-name]=[image-name]:[image-tag] --record
# 查看部署的镜像版本
kubectl get deploy/<deploy-name> -oyaml|grep image
# 查看版本历史纪录
kubectl rollout history deploy/<deploy-name>
# 回退到指定版本
kubectl rollout undo deploy/<deploy-name> --to-revision=<revision-num>
# 回退到上个版本:
kubectl rollout undo deploy/<deploy-name>
1.4 k8s 服务抽象
1.4.1 Service 服务访问
Service 是 Pod 的网络服务发现与负载均衡的实现。
# 集群内暴露 ClusterIP
kubectl expose deploy [deploy-name] --port=<service-port> --target-port=<pod-port> --type=ClusterIP
# 集群外暴露 NodePort
kubectl expose deploy [deploy-name] --port=<service-port> --target-port=<pod-port> --type=NodePort
# 查看所有服务
kubectl get svc
1.4.2 Ingress 统一网关入口
Ingress 是 Service 的统一网关入口,底层实际上就是反向代理 nginx,通过域名、路径匹配规则指向不同的 Service:
1.5 k8s 存储抽象
1.5.1 nfs 存储系统
我们知道 Docker 中保存容器数据的方法是挂载数据卷。但是在 k8s 中,如果我们 3 号机器上的某个 Pod 节点(黑色)宕机,根据故障转移 k8s 在 2 号机器再启动该节点。但是原来 3 号机器挂载的目录无法转移到 2 号机器上,造成数据存储丢失。
k8s 使用存储层统一管理所有 Pod 挂载的目录。 以 nfs 存储层为例,它在某个机器下创建 /nfs/data 目录用于挂载数据,在其他机器中都存在备份目录 /bak/data。只要 Pod 在一台机器上挂载了数据,该数据都会同步到其他机器上,这就叫做存储抽象。
1.5.2 PV & PVC 目录挂载
PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置
PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷规格
k8s 使用 PV & PVC 方式进行数据挂载。Pod 想要挂载多大的空间,先使用 PVC 申请 PV 空间。如果 Pod 被删除,PVC 随之被删除,对应的 PV 空间也被回收。
1.6 k8s 配置管理
1.6.1 ConfigMap 服务配置文件挂载
ConfigMap 可以抽取应用配置,并且可以自动更新,被多个 Pod 共享,非常适合配置文件类的数据挂载:
# 定义了一个名为 my-config 的 ConfigMap 对象,并定义了两个 properties 文件
apiversion: v1
kind: ConfigMap
metadata:
name: my-config
data:
database.properties:
database.url=jdbc:mysql://127.0.0.1:3306/test
database.username=root
database.password=root
server.properties:
server.port=8080
server.timeout=300
1.6.2 Secret 服务敏感配置文件
Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥,将这些信息放在 Secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活:
# 定义了一个名为 my-secret 的 Secret 对象,并定义了 username 和 password
apiversion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
stringData:
username: admin
password: admin
1.7 k8s 资源 yaml 文件(声明式 api)
-
apiVersion 定义 api 版本,一般是 apps/v1
-
kind 定义资源类别,有 Pod、Deployment、Job、Service、Ingress 等
-
metadata 资源元数据
- name 定义资源名称
- namespace 定义资源所在命名空间
- labels 定义资源拥有的标签
-
spec 定义资源所需的参数属性
- replicas 定义副本数量
- selector
-
status 定义当前资源在 k8s 中的实际状态
第 2 章 k8s 集群上安装 KubeSphere
master 节点要求 2CPU 4G,硬盘 20G;node 节点要求 4CPU 8G,硬盘 40G。
2.1 安装 k8s 集群
2.1.1 安装 Docker
在每台机器上复制以下命令(registry-mirrors 换成自己的阿里云镜像加速地址):
sudo yum remove docker*
sudo yum install -y yum-utils
# 配置 docker 的 yum 地址
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 docker20.10.7 版本
sudo yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io-1.4.6
# 启动 & 开机启动 docker
systemctl enable docker --now
# docker 加速配置
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://3li81rlf.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2.1.2 安装 Kubernetes
每个机器配置自己的 hostname:
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2
在每台机器上复制以下命令:
# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# 关闭 swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
# 允许 iptables 检查桥接流量
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
2.1.3 安装 kubelet、kubeadm、kubectl
在每台机器上复制以下命令(master ip 换成自己的):
# 配置 k8s 的 yum 源地址
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 安装 kubelet,kubeadm,kubectl
sudo yum install -y kubelet-1.20.9 kubeadm-1.20.9 kubectl-1.20.9
# 启动 kubelet
sudo systemctl enable --now kubelet
# 所有机器配置 master 域名
echo "172.31.0.94 k8s-master" >> /etc/hosts
2.1.4 初始化 master
在 master 上执行以下命令(master ip 换成自己的):
kubeadm init \
--apiserver-advertise-address=172.31.0.94 \
--control-plane-endpoint=k8s-master \
--image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \
--kubernetes-version v1.20.9 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=192.168.0.0/16
显示最后 5 行内容进行复制:
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join k8s-master:6443 --token atka7l.z8l1mr0tl0fbvqwn \
--discovery-token-ca-cert-hash sha256:f168da9b17ea3e87e2c05a96da68e9f0827ad2f2267e87ef524c7d632122b3e3
在 master 上继续执行:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
在 master 上安装 Calico 网络插件(注意 k8s 的版本 1.20.9 对应 calico 版本 3.20):
curl https://docs.projectcalico.org/archive/v3.20/manifests/calico.yaml -O
kubectl apply -f calico.yaml
2.1.5 worker node 加入集群
将 master 中的 /etc/kubernetes/admin.conf 文件拷贝到 node 相同目录下。然后在两个 node 下执行命令:
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
将之间复制的最后 5 行内容打开,在两个 node 上执行 kubeadm join 开头的命令:
kubeadm join k8s-master:6443 --token atka7l.z8l1mr0tl0fbvqwn \
--discovery-token-ca-cert-hash sha256:f168da9b17ea3e87e2c05a96da68e9f0827ad2f2267e87ef524c7d632122b3e3
使用 kubectl get nodes 命令查看(大概需要 3-5 分钟):
2.1.6 nfs-storage
配置默认存储
在每个机器上执行:
yum install -y nfs-utils
在 master 上执行,安装 nfs-server:
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
mkdir -p /nfs/data
systemctl enable rpcbind
systemctl enable nfs-server
systemctl start rpcbind
systemctl start nfs-server
exportfs -r
exportfs
在两个 node 上执行,配置 nfs-client(换成自己的 master ip):
showmount -e 172.31.0.94
mkdir -p /nfs/data
mount -t nfs 172.31.0.94:/nfs/data /nfs/data
在 master 根目录 vi sc.yaml,复制以下 yaml 命令(注意两处 ip 地址改为自己 master 的 ip):
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "true"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 172.31.0.94 ## 指定自己 nfs 服务器地址
- name: NFS_PATH
value: /nfs/data
volumes:
- name: nfs-client-root
nfs:
server: 172.31.0.94 ## 指定自己 nfs 服务器地址
path: /nfs/data
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
kubectl apply -f sc.yaml
kubectl get sc
这里我们需要在 master 上 vim /etc/kubernetes/manifests/kube-apiserver.yaml,添加以下几行:
- --feature-gates=RemoveSelfLink=false
- --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --service-account-issuer=api
- --service-account-api-audiences=api,vault,factors
2.1.7 metrics-server
集群指标监控组件
在 master 根目录下 vi metrics.yaml,复制以下内容:
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: system:aggregated-metrics-reader
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- pods
- nodes
- nodes/stats
- namespaces
- configmaps
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
k8s-app: metrics-server
spec:
containers:
- args:
- --cert-dir=/tmp
- --kubelet-insecure-tls
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/metrics-server:v0.4.3
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: https
scheme: HTTPS
periodSeconds: 10
name: metrics-server
ports:
- containerPort: 4443
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /readyz
port: https
scheme: HTTPS
periodSeconds: 10
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- mountPath: /tmp
name: tmp-dir
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
serviceAccountName: metrics-server
volumes:
- emptyDir: {}
name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
labels:
k8s-app: metrics-server
name: v1beta1.metrics.k8s.io
spec:
group: metrics.k8s.io
groupPriorityMinimum: 100
insecureSkipTLSVerify: true
service:
name: metrics-server
namespace: kube-system
version: v1beta1
versionPriority: 100
kubectl apply -f metrics.yaml
# 等待半分钟
kubectl top nodes
kubectl top pods -A
2.2 安装 KubeSphere 平台(v3.1.1)
- Kubernetes 版本必须为:v1.20.x、v1.21.x、* v1.22.x、* v1.23.x 和 * v1.24.x
- 确保您的机器满足最低硬件要求:CPU > 1 核,内存 > 2 GB
- 在安装之前,需要配置 Kubernetes 集群中的默认存储类型
2.2.1 部署 KubeSphere
在 master 上:
yum install -y wget
wget https://github.com/kubesphere/ks-installer/releases/download/v3.1.1/kubesphere-installer.yaml
wget https://github.com/kubesphere/ks-installer/releases/download/v3.1.1/cluster-configuration.yaml
2.2.2 修改 cluster-configuration.yaml
---
apiVersion: installer.kubesphere.io/v1alpha1
kind: ClusterConfiguration
metadata:
name: ks-installer
namespace: kubesphere-system
labels:
version: v3.1.1
spec:
persistence:
storageClass: ""
authentication:
jwtSecret: ""
local_registry: ""
etcd:
monitoring: true
endpointIps: 172.31.0.94
port: 2379
tlsEnable: true
common:
redis:
enabled: true
openldap:
enabled: true
minioVolumeSize: 20Gi
openldapVolumeSize: 2Gi
redisVolumSize: 2Gi
monitoring:
# type: external
endpoint: http://prometheus-operated.kubesphere-monitoring-system.svc:9090
es:
# elasticsearchMasterReplicas: 1
# elasticsearchDataReplicas: 1
elasticsearchMasterVolumeSize: 4Gi
elasticsearchDataVolumeSize: 20Gi
logMaxAge: 7
elkPrefix: logstash
basicAuth:
enabled: false
username: ""
password: ""
externalElasticsearchUrl: ""
externalElasticsearchPort: ""
console:
enableMultiLogin: true
port: 30880
alerting:
enabled: true
auditing:
enabled: true
devops:
enabled: true
jenkinsMemoryLim: 2Gi
jenkinsMemoryReq: 1500Mi
jenkinsVolumeSize: 8Gi
jenkinsJavaOpts_Xms: 512m
jenkinsJavaOpts_Xmx: 512m
jenkinsJavaOpts_MaxRAM: 2g
events:
enabled: true
ruler:
enabled: true
replicas: 2
logging:
enabled: true
logsidecar:
enabled: true
replicas: 2
metrics_server:
enabled: false
monitoring:
storageClass: ""
# prometheusReplicas: 1
prometheusMemoryRequest: 400Mi
prometheusVolumeSize: 20Gi
multicluster:
clusterRole: none
network:
networkpolicy:
enabled: true
ippool:
type: calico
topology:
type: none
openpitrix:
store:
enabled: true
servicemesh:
enabled: true
kubeedge:
enabled: false
cloudCore:
nodeSelector: {"node-role.kubernetes.io/worker": ""}
tolerations: []
cloudhubPort: "10000"
cloudhubQuicPort: "10001"
cloudhubHttpsPort: "10002"
cloudstreamPort: "10003"
tunnelPort: "10004"
cloudHub:
advertiseAddress:
- ""
nodeLimit: "100"
service:
cloudhubNodePort: "30000"
cloudhubQuicNodePort: "30001"
cloudhubHttpsNodePort: "30002"
cloudstreamNodePort: "30003"
tunnelNodePort: "30004"
edgeWatcher:
nodeSelector: {"node-role.kubernetes.io/worker": ""}
tolerations: []
edgeWatcherAgent:
nodeSelector: {"node-role.kubernetes.io/worker": ""}
tolerations: []
kubectl apply -f kubesphere-installer.yaml
kubectl apply -f cluster-configuration.yaml
需要 5-10 分钟安装成功,使用以下命令查看安装进程:
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f
# 解决 etcd 监控证书找不到问题
kubectl -n kubesphere-monitoring-system create secret generic kube-etcd-client-certs --from-file=etcd-client-ca.crt=/etc/kubernetes/pki/etcd/ca.crt --from-file=etcd-client.crt=/etc/kubernetes/pki/apiserver-etcd-client.crt --from-file=etcd-client.key=/etc/kubernetes/pki/apiserver-etcd-client.key
kubectl get pod -A
# 查看每个 Pod 具体状态,如果是在 Pulling image 就只能等待
kubectl describe pod -n [NAMESPACE] [NAME]
2.2.3 访问 KubeSphere
拿机器的公网 IP:30880 访问 KubeSphere 网页,使用默认账户和密码登录访问 KubeSphere 网页:
2.2.4 安装后启用可插拔组件
- 点击左上角的「平台管理」 ,然后选择「集群管理」。
- 点击「自定义资源 CRD」,然后在搜索栏中输入 clusterconfiguration
- 在资源列表中,点击 ks-installer 右侧的三个点,然后选择「编辑配置文件」
- 在该配置文件中,将所需组件 enabled 的 false 更改为 true,以启用要安装的组件。完成后点击「更新」
- 等待组件安装成功,登录 KubeSphere 控制台,在「服务组件」中可以查看不同组件的状态
| 配置项 | 功能组件 | 描述 |
|---|---|---|
| alerting | 告警系统 | 使用户能够自定义告警策略,及时向接收器发送告警信息 |
| auditing | 审计日志系统 | 记录了平台上不同租户的活动 |
| devops | DevOps 系统 | 基于 Jenkins 提供开箱即用的 CI/CD 功能,提供一站式 DevOps 方案,内置 Jenkins 流水线与 B2I & S2I |
| events | 事件系统 | 导出、过滤和警告多租户 Kubernetes 集群中的 Kubernetes 事件 |
| logging | 日志系统 | 在统一的控制台中提供灵活的日志查询、收集和管理功能 |
| metrics_server | HPA | 根据设定指标对 Pod 数量进行动态伸缩,使运行在上面的服务对指标的变化有一定的自适应能力 |
| networkpolicy | 网络策略 | 可以在同一个集群内部之间设置网络策略 |
| notification | 通知系统 | 允许用户将警告信息发送出来的告警通知到电子邮件、企业微信和 Slack |
| openpitrix | 应用商店 | 基于 Helm 的应用程序商店,允许用户管理应用整个生命周期 |
| servicemesh | 服务网格 (基于 Istio) | 支持灰度发布、流量拓扑、流量治理、流量跟踪 |
2.3 使用 minikube 安装 k8s
minikube 是本地 k8s,专门用于 k8s 的学习和开发。
2.3.1 Linux 安装
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
2.3.2 使用 docker 启动
minikube start --force --driver=docker
2.3.3 设置交互
alias kubectl="minikube kubectl --"
第 3 章 KubeSphere 实战
3.1 多租户系统实战
多租户系统包含集群、企业空间、项目三部分。
3.1.1 添加用户
- 创建用户管理员
使用平台管理员 platform-admin 身份访问 KubeSphere ****网页。点击「平台管理」->「访问控制」->「账户管理」->「创建」一个用户管理员:hr-zhang
- 创建企业空间管理员
使用 hr-zhang 账户登录网页,点击「账户管理」->「创建」一个企业空间管理员:boss-li
- 创建企业空间
使用 boss-li 账户来登录网页,点击「企业空间」->「创建」多个企业空间:wuhan、shenzhen 等
- 人员入职
使用 hr-zhang 账户登录网页,点击「账户管理」->「创建」多个平台用户:
- 分部管理员
使用 boss-li 账户登录网页,点击「武汉分部」->「企业空间设置」->「企业成员」->「邀请成员」,邀请 wuhan-boss,赋予其武汉管理员的角色:
点击「深圳分部」->「企业空间设置」->「企业成员」->「邀请成员」,邀请 shenzhen-boss,赋予其深圳管理员的角色:
3.1.2 邀请人员进入企业空间
使用 wuhan-boss 账户登录网页,点击「企业空间设置」->「企业成员」->「邀请成员」,邀请所有开发人员赋予其企业空间普通成员的角色:
3.1.3 邀请成员进入项目
使用 pm-wang 账户登录网页,点击「项目管理」->「创建」多个项目:
点击「edu」->「项目设置」->「项目成员」邀请成员进入项目:
3.2 部署中间件
【应用部署三要素】
- 应用的工作负载(部署方式):Deployment(无状态部署)、StatefulSet(有状态副本集)、DaemonSet(守护进程集)
- 应用的存储(数据挂载):存储卷(PVC)、配置集(ConfigMap)
- 应用的服务(可访问性):集群内(ClusterIP)、集群外(NodePort)
3.2.1 添加应用仓库
使用企业空间管理员 wuhan-boss 登录,点击「应用管理」->「应用仓库」-> 「添加仓库」:
3.2.2 部署 zookeeper
使用开发人员 dev-zhao 账户登录网页,选择 edu 项目,点击「应用负载」->「应用」->「部署新应用」->「来自应用模板」->「bitnami」,搜索 zookeeper 进行部署,系统自动为我们创建好了两个服务访问,我们将有外网访问的访问方式设置为 NodePort:
3.2.3 部署 mysql
点击「应用商店」->「mysql」->「部署」->「下一步」->「部署」,系统自动为我们创建好了两个服务访问,我们将有外网访问的访问方式设置为 NodePort:
出于安全性考虑,登录 mysql 的密码(账户 root)在「配置中心」的「密钥」下显示:
我们将该密钥通过 Base64 解码得到我们的密码,此时我们在集群外通过 k8s 集群任意节点公网 ip、NodePort 服务端口号、以及 root 密码连接 k8s 集群内部的 mysql: