贵港网站建设培训,网站建设合同注意点,网站建设设计风格描述,网站直播间 是怎么做的文章目录一、Kubernetes#xff08;K8S#xff09;简介1、概念1.1 Kubernetes (K8S) 是什么1.2 核心特性1.3 部署方案2、Kubernetes 集群架构2.1 架构2.2 重要概念 Pod2.3 Kubernetes 组件二、Kubernetes集群安装1、安装方式介绍2、minikubute安装3、裸机搭建#xff08;Bar…
文章目录一、KubernetesK8S简介1、概念1.1 Kubernetes (K8S) 是什么1.2 核心特性1.3 部署方案2、Kubernetes 集群架构2.1 架构2.2 重要概念 Pod2.3 Kubernetes 组件二、Kubernetes集群安装1、安装方式介绍2、minikubute安装3、裸机搭建Bare Metal3.1 概念介绍3.2 集群安装3.3 踩坑之路4、快速体验5、可视化安装5.1 Kuboard v2 - kubernetes(推荐)5.2 Kubernetes Dashboard三、集群服务部署1、部署应用Demo2、常用命令详情3、概念3.1 工作负载分类3.2 存在问题四、Service1、概念2、Service简单Demo3、对外暴露服务(重要)4、多端口5、总结五、StatefulSet1、StatefulSet介绍1.1 概念1.2 特性2、部署 StatefulSet 类型的 Mongodb六、数据持久化1、概念2、hostPath 挂载示例3、高级抽象挂载3.1 概述3.2 各个层级表述3.3 本地测试七、ConfigMap Secret1、概述2、ConfigMap3、Secret4、Demo使用八、Helm 命名空间1、简介2、Helm安装3、安装MongoDb4、命名空间九、Ingress1、介绍2、使用一、KubernetesK8S简介
1、概念 官网https://kubernetes.io/zh-cn/docs/home/ 1.1 Kubernetes (K8S) 是什么
它是一个为 容器化 应用提供集群部署和管理的开源工具由 Google 开发。K8S 是负责自动化运维管理多个跨机器 Docker 程序的集群
1.2 核心特性
服务发现与负载均衡无需修改你的应用程序即可使用陌生的服务发现机制存储编排自动挂载所选存储系统包括本地存储Secret和配置管理部署更新Secrets和应用程序的配置时不必重新构建容器镜像且不必将软件堆栈配置中的秘密信息暴露出来批量执行除了服务之外Kubernetes还可以管理你的批处理和CI工作负载在期望时替换掉失效的容器水平扩缩使用一个简单的命令、一个UI或基于CPU使用情况自动对应用程序进行扩缩自动化上线和回滚Kubernetes会分步骤地将针对应用或其配置的更改上线同时监视应用程序运行状况以确保你不会同时终止所有实例自动装箱根据资源需求和其他约束自动放置容器同时避免影响可用性自我修复重新启动失败的容器在节点死亡时替换并重新调度容器杀死不响应用户定义的健康检查的容器
1.3 部署方案
传统部署方式
应用直接在物理机上部署机器资源分配不好控制出现Bug时可能机器的大部分资源被某个应用占用导致其他应用无法正常运行无法做到应用隔离
虚拟机部署
在单个物理机上运行多个虚拟机每个虚拟机都是完整独立的系统性能损耗大
容器部署
所有容器共享主机的系统轻量级的虚拟机性能损耗小资源隔离CPU和内存可按需分配例如k8s可以轻松管理百万千万台机器的集群可以为你提供集中式的管理集群机器和应用不停机的灰度更新确保高可用、高性能、高扩展
2、Kubernetes 集群架构
2.1 架构 master 主节点控制平台不需要很高性能不跑任务通常一个就行了也可以开多个主节点来提高集群可用度。 worker 工作节点可以是虚拟机或物理计算机任务都在这里跑机器性能需要好点通常都有很多个可以不断加机器扩大集群每个工作节点由主节点管理
2.2 重要概念 Pod
K8S 调度、管理的最小单位一个 Pod 可以包含一个或多个容器每个 Pod 有自己的虚拟IP。一个工作节点可以有多个 pod主节点会考量负载自动调度 pod 到哪个节点运行 2.3 Kubernetes 组件
kube-apiserver K8S 的请求入口服务。API Server 负责接收 K8S 所有请求来自 UI 界面或者 CLI 命令行工具然后API Server 根据用户的具体请求去通知其他组件干活etcd K8S 的存储服务。etcd 存储了 K8S 的关键配置和用户配置K8S 中仅 API Server 才具备读写权限其他组件必须通过 API Server 的接口才能读写数据kube-scheduler K8S 所有 Worker Node 的调度器。当用户要部署服务时Scheduler 会选择最合适的 Worker Node服务器来部署controller Manager K8S 所有 Worker Node 的监控器。Controller Manager 有很多具体的Controller Node Controller、Service Controller、Volume Controller 等。Controller 负责监控和调整在Worker Node 上部署的服务的状态比如用户要求 A 服务部署 2 个副本那么当其中一个服务挂了的时候Controller 会马上调整让 Scheduler 再选择一个 Worker Node 重新部署服务cloud-controller 与云服务商交互Kubelet Worker Node 的监视器以及与 Master Node 的通讯器。Kubelet 是 Master Node 安插在Worker Node 上的眼线它会定期向 Master Node 汇报自己 Node 上运行的服务的状态并接受来自Master Node 的指示采取调整措施。负责控制所有容器的启动停止保证节点工作正常。Kube-Proxy K8S 的网络代理。Kube-Proxy 负责 Node 在 K8S 的网络通讯、以及对外部网络流量的负载均衡Container Runtime** Worker Node 的运行环境**。即安装了容器化所需的软件环境确保容器化程序能够跑起来比如 Docker Engine运行环境 二、Kubernetes集群安装 默认已经提前安装好Dockerdocker安装可以参考docker学习笔记 1、安装方式介绍 minikube 只是一个 K8S 集群模拟器只有一个节点的集群只为测试用master 和 worker 都在一起 直接用云平台 Kubernetes (阿里/腾讯) 可视化搭建只需简单几步就可以创建好一个集群。 优点安装简单生态齐全负载均衡器、存储等都给你配套好简单操作就搞定 裸机安装Bare Metal 至少需要两台机器主节点、工作节点个一台需要自己安装 Kubernetes 组件配置会稍微麻烦点。 可以到各云厂商按时租用服务器费用低用完就销毁。 缺点配置麻烦缺少生态支持例如负载均衡器、云存储。
2、minikubute安装 官网安装https://minikube.sigs.k8s.io/docs/start/ Minikube搭建部署单机 Kubernetes minikube安装非常简单支持各种平台建议直接裸机(个人虚拟机安装一直有问题)
# 启动集群据说不加版本会报错(我还是启动不了)
minikube start --kubernetes-versionv1.23.0
# 查看节点。kubectl 是一个用来跟 K8S 集群进行交互的命令行工具
kubectl get node
# 停止集群
minikube stop
# 清空集群
minikube delete --all
# 安装集群可视化 Web UI 控制台
minikube dashboardminikube和云平台不多赘述例如腾讯云的弹性容器服务 EKS这里主要讲述逻辑集群的安装
3、裸机搭建Bare Metal k8s集群搭建参考https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/nd7yOvdY#nav_3 3.1 概念介绍
主节点需要组件
docker也可以是其他容器运行时kubectl 集群命令行交互工具kubeadm 集群初始化工具
**工作节点需要组件 **文档
docker也可以是其他容器运行时kubelet 管理 Pod 和容器确保他们健康稳定运行kube-proxy 网络代理负责网络相关的工作
3.2 集群安装
这里我基于centos7创建了三台虚拟机(2核4G网络使用nat)以下是所有节点的配置权限不够的话使用sudo提升权限
# 每个节点分别设置对应主机名
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2# 所有节点都修改 hosts
vim /etc/hosts
192.168.249.241 node1
192.168.249.242 node2
192.168.249.240 master# 所有节点关闭 SELinux
# 临时关闭
setenforce 0
# 永久关闭
sed -i --follow-symlinks s/SELINUXenforcing/SELINUXdisabled/g /etc/sysconfig/selinux
# 查看selinux状态
getenforce# k8s不需要swap分区如果安装Linux系统时创建了swap分区那么就需要禁用swap
# 临时关闭swap分区
swapoff -a
# 修改配置文件永久关闭swap分区 或者vim /etc/fstab 删除或注释掉带有swap的行
sed -ri s/.*swap.*/#/ /etc/fstab# 所有节点确保防火墙关闭确保网络通信
systemctl stop firewalld
systemctl disable firewalld# 设置时间同步
sudo yum install ntpdate -y
sudo ntpdate time.windows.com# 添加 k8s 安装源
cat EOF kubernetes.repo
[kubernetes]
nameKubernetes
baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled1
gpgcheck0
repo_gpgcheck0
gpgkeyhttps://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
mv kubernetes.repo /etc/yum.repos.d/# 添加 Docker 安装源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 安装所需组件所有节点
yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 docker-ce# 启动 kubelet、docker并设置开机启动
systemctl enable kubelet
systemctl start kubelet
systemctl enable docker
systemctl start docker# 修改 docker 配置
# kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver否则 kubelet 启动不了
cat EOF daemon.json
{exec-opts: [native.cgroupdriversystemd],registry-mirrors: [https://ud6340vz.mirror.aliyuncs.com]
}
EOF
mv daemon.json /etc/docker/
# 重启生效
systemctl daemon-reload
systemctl restart docker
在主节点master初始化集群init的文档
# 初始化集群控制台 Control plane
# 失败了可以用 sudo kubeadm reset 重置
# 这里记得加上子网分配教程不加也可以可以试试
sudo kubeadm init --image-repositoryregistry.aliyuncs.com/google_containers --pod-network-cidr 10.244.0.0/16
#sudo kubeadm init --apiserver-advertise-address192.168.249.139 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr10.96.0.0/12 --pod-network-cidr10.244.0.0/16
# 记得把 kubeadm join xxx 保存起来
# 忘记了重新获取kubeadm token create --print-join-command# 复制授权文件以便 kubectl 可以有权限访问集群
# 如果你其他节点需要访问集群需要从主节点复制这个文件过去其他节点
# 如果是普通用户
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config# 如果是root用户
export KUBECONFIG/etc/kubernetes/admin.conf# 在其他机器上创建 ~/.kube/config 文件也能通过 kubectl 访问到集群# 如果node节点添加进集群失败可以删除节点重新添加
# 要删除 node1 这个节点首先在 master 节点上依次执行以下两个命令
kubectl drain node1 --delete-local-data --force --ignore-daemonsets
kubectl delete node node1
# 执行后通过 kubectl get node 命令可以看到 node1 已被成功删除接着在 k8snode1 这个 Node 节点上执行如下命令这样该节点即完全从 k8s 集群中脱离开来之后就可以重新执行命令添加到集群
kubeadm reset
然后把工作节点加入集群只在工作节点跑
sudo kubeadm join 192.168.249.140:6443 --token 5f20z7.9rbjijmnkhpz0sj2 \--discovery-token-ca-cert-hash sha256:b6b6b1d84ca8a0711667d654e8a676c0e17703715c5b16074896eecedbf8ca01
最后安装网络插件否则 node 是 NotReady 状态主节点跑
# 查看状态
kubectl get nodes
# 网络插件用来结点通信的
# 很有可能国内网络访问不到这个资源你可以网上找找国内的源安装 flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 这里一个方法是进入该网站手动讲内容复制下来把内容保存到linux中命名kube-flannel.yml
https://github.com/flannel-io/flannel/blob/master/Documentation/kube-flannel.yml
# 执行
kubectl apply -f kube-flannel.yml
3.3 踩坑之路
首先了解一下基本的命令
# 查看所有的详细信息
kubectl get pod -A -owide
# 查看某一个容器详细运行状态-n后跟的是命名空间排查错误用
kubectl describe pod kube-flannel-ds-wclwt -n kube-flannel
# 查看日志
kubectl logs -f --tail 200 -n kube-flannel kube-flannel-ds-5bmpl
问题一
手动导入网络插件后通过查看日志发现镜像无法拉取于是手动拉取导入然后用tag打上与yml文件中的镜像一模一样的名字这里我每个结点都是这样操作按理说会自动同步过去其他结点但是每个结点都报错了所以我手动下载了当然换个国内源也可以
# 下载地址
https://github.com/flannel-io/flannel
# 比如yml中写的是docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0首先下载对应的包
docker load flanneld-v0.20.0-amd64.docker
# 查看一下
sudo docker images
# 找到对应的镜像打上对应标签
sudo docker tag quay.io/coreos/flannel:v0.20.0-amd64 docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0
问题二
手动下载后查看describe日志发现能成功拉去镜像但是容器无法启动查看logs日志发现说没有分配子网podCIDR通过kubeadm init初始化master节点时flannel网络插件需要确保初始化命令配置了podCIDR如下启动参数–pod-network-cidr172.18.0.0/16 参考k8s集群flannel部署错误异常排查pod cidr not assigned 问题三
如果你运行 kubectl describe pod/pod-name 发现 Events 中有下面这个错误networkPlugin cni failed to set up pod test-k8s-68bb74d654-mc6b9_default network: open /run/flannel/subnet.env: no such file or directory那么在每个节点创建文件/run/flannel/subnet.env写入以下内容配置后等待一会就好了用来配置每个结点的子网信息
FLANNEL_NETWORK10.244.0.0/16
FLANNEL_SUBNET10.244.0.1/24
FLANNEL_MTU1450
FLANNEL_IPMASQtrue4、快速体验
# 创建一次deployment部署
kubectl create deployment nginx --imagenginx
kubectl get deployment
kubectl get pod
# 创建service端口映射
kubectl expose deployment nginx --port80 --typeNodePortkubectl get pod,svc -o wide
# 访问Nginx地址 http://任意节点的ip:图中Nginx的对外映射端口http://192.168.249.240:30433# 删除pod和service(端口映射)
kubectl delete deployment nginx
kubectl delete svc/nginx5、可视化安装
5.1 Kuboard v2 - kubernetes(推荐) 参考安装 Kuboard v2 # 安装 Kuboard
kubectl apply -f https://kuboard.cn/install-script/kuboard.yaml
kubectl apply -f https://addons.kuboard.cn/metrics-server/0.3.7/metrics-server.yaml
# 查看运行状态
kubectl get pods -l k8s.kuboard.cn/namekuboard -n kube-system# 获取管理员token
echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep ^kuboard-user | awk {print $1}) -o go-template{{.data.token}} | base64 -d)#Kuboard Service 使用了 NodePort 的方式暴露服务NodePort 为 32567您可以按如下方式访问 Kuboard。
# http://任意一个Worker节点的IP地址:32567/5.2 Kubernetes Dashboard 参考Kubernetes Dashboard安装/部署和访问 Kubernetes 仪表板Dashboard Kubernetes Dashboard 是 Kubernetes 的官方 Web UI。使用 Kubernetes Dashboard可以
向 Kubernetes 集群部署容器化应用诊断容器化应用的问题管理集群的资源查看集群上所运行的应用程序创建、修改Kubernetes 上的资源例如 Deployment、Job、DaemonSet等展示集群上发生的错误
# 安装 Kubernetes Dashboard
kubectl apply -f https://kuboard.cn/install-script/k8s-dashboard/v2.0.0-beta5.yaml# Kubernetes Dashboard 当前只支持使用 Bearer Token登录
# 创建 ServiceAccount 和 ClusterRoleBinding
kubectl apply -f https://kuboard.cn/install-script/k8s-dashboard/auth.yaml# 获取Bearer Token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk {print $1})
# 执行代理命令
kubectl proxy
# 如需要使用 nodePort 或 Ingress 的方式访问 Kubernetes Dashboard 请配置正确的 https 证书或者使用 Firefox 浏览器并忽略 HTTPS 校验错误。
# 访问路径将上一个步骤中获得的 Token 输入到登录界面中点击 Sign in 按钮完成登录
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/三、集群服务部署
1、部署应用Demo
部署一个 nodejs web 应用源码地址Github
# 查看pod状态
kubectl get pod -owide
# 运行一个pod
kubectl run testapp --imageccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1
# 通过yaml创建k8sPod
kubectl apply -f pod.yaml
kubectl apply -f deployment.yaml
创建pod.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:# 定义容器可以多个containers:- name: test-k8s # 容器名字image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像创建deployment.yaml文件
apiVersion: apps/v1
# 定义资源的类型/角色deployment为副本控制器此处资源类型可以是Deployment、Job、Ingress、Service等
kind: Deployment
metadata:# 定义资源的名称在同一个namespace空间中必须是唯一的name: test-k8s
spec:replicas: 2# 用来查找关联的 Pod所有标签都匹配才行selector:matchLabels:app: test-k8s# 定义 Pod 相关数据template:metadata:labels:app: test-k8sspec:# 定义容器可以多个containers:- name: test-k8s # 容器名字image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像命令行弹性伸缩k8s会自动根据结点情况部署
# 命令行弹性扩容也可以在yaml中进行编写
kubectl scale deployment test-k8s --replicas3
# 修改镜像
kubectl set image deployment test-k8s test-k8sccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error
# 把集群内端口某个pod映射到节点
kubectl port-forward test-k8s-5699487f75-bg82t 8090:8080
# 在master结点测试访问这只是其中一个容器的外网不能进行访问
curl localhost:8090
2、常用命令详情
# 部署应用
kubectl apply -f app.yaml
# 查看 deployment
kubectl get deployment
# 查看 pod
kubectl get pod -o wide
# 查看 pod 详情
kubectl describe pod pod-name
# 查看 log
kubectl logs pod-name [-f]
# 进入 Pod 容器终端 -c container-name 可以指定进入哪个容器。
kubectl exec -it pod-name -- bash
# 伸缩扩展副本
kubectl scale deployment test-k8s --replicas5
# 把集群内端口映射到节点
kubectl port-forward pod-name 8090:8080
# 查看历史
kubectl rollout history deployment test-k8s
# 回到上个版本
kubectl rollout undo deployment test-k8s
# 回到指定版本
kubectl rollout undo deployment test-k8s --to-revision2
# 删除部署
kubectl delete deployment test-k8s# 更多命令
# 查看全部
kubectl get all
# 重新部署
kubectl rollout restart deployment test-k8s
# 命令修改镜像--record 表示把这个命令记录到操作历史中
kubectl set image deployment test-k8s test-k8sccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error --record
# 暂停运行暂停后对 deployment 的修改不会立刻生效恢复后才应用设置
kubectl rollout pause deployment test-k8s
# 恢复
kubectl rollout resume deployment test-k8s
# 输出到文件
kubectl get deployment test-k8s -o yaml app2.yaml
# 删除全部资源
kubectl delete all --all
3、概念 更多官网关于 Deployment 的介绍将 Pod 指定到某个节点运行nodeselector限定 CPU、内存总量文档 3.1 工作负载分类 https://kubernetes.io/zh/docs/concepts/workloads/ Deployment 适合无状态应用所有pod等价可替代 StatefulSet 有状态的应用适合数据库这种类型。 DaemonSet 在每个节点上跑一个 Pod可以用来做节点监控、节点日志收集等 Job CronJob Job 用来表达的是一次性的任务而 CronJob 会根据其时间规划反复运行。
3.2 存在问题
每次只能访问一个 pod没有负载均衡自动转发到不同 pod访问还需要端口转发Pod 重创后 IP 变了名字也变了
四、Service
1、概念 https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#headless-services Service 通过 label 关联对应的 PodServcie 生命周期不跟 Pod 绑定不会因为 Pod 重创改变 IP提供了负载均衡功能自动转发流量到不同 Pod可对集群外部提供访问端口集群内部可通过服务名字访问 2、Service简单Demo
首先创建service.yaml
apiVersion: v1
kind: Service
metadata:name: test-k8s
spec:selector:# 要和pod对应app: test-k8s# 服务默认是这个type: ClusterIPports:- port: 8080 # 本 Service 的端口targetPort: 8080 # 容器端口
然后进行访问测试
# 创建service
kubectl apply -f service.yaml
# 查看服务
kubectl get service
kubectl get svc
# 查看服务详情可以发现 Endpoints 是各个 Pod 的 IP也就是他会把流量转发到这些节点
kubectl describe svc test-k8s
# 服务的默认类型是ClusterIP只能在集群内部访问我们可以进入到 Pod 里面访问
kubectl exec -it pod-name -- bash
curl http://test-k8s:8080
# 如果要在集群外部访问可以通过端口转发实现只适合临时测试用
kubectl port-forward service/test-k8s 8888:8080
curl http://localhost:8080
3、对外暴露服务(重要)
上面我们是通过端口转发的方式可以在外面访问到集群里的服务如果想要直接把集群服务暴露出来我们可以使用NodePort 和 Loadbalancer 类型的 Service
apiVersion: v1
kind: Service
metadata:name: test-k8s
spec:selector:app: test-k8s# 默认 ClusterIP 集群内可访问NodePort 节点可访问LoadBalancer 负载均衡模式需要负载均衡器才可用type: NodePortports:- port: 8080 # 本 Service 的端口targetPort: 8080 # 容器端口nodePort: 31000 # 节点端口范围固定 30000 ~ 32767
应用配置 kubectl apply -f service.yaml在节点上我们可以 curl http://localhost:31000 或者curl http://[你的物理ip]:31000访问到应用并且是有负载均衡的网页的信息可以看到被转发到了不同的 Pod(可能有缓存)
Loadbalancer 也可以对外提供服务这需要一个负载均衡器的支持因为它需要生成一个新的 IP 对外服务否则状态就一直是 pendding这个很少用了后面我们会讲更高端的 Ingress 来代替它。
4、多端口 https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#multi-port-services 多端口时必须配置 name
apiVersion: v1
kind: Service
metadata:name: test-k8s
spec:selector:app: test-k8stype: NodePortports:- port: 8080 # 本 Service 的端口name: test-k8s # 必须配置targetPort: 8080 # 容器端口nodePort: 31000 # 节点端口范围固定 30000 ~ 32767- port: 8090name: test-othertargetPort: 8090nodePort: 32000
5、总结 ClusterIP 默认的仅在集群内可用 NodePort 暴露端口到节点提供了集群外部访问的入口端口范围固定 30000 ~ 32767 LoadBalancer 需要负载均衡器通常都需要云服务商提供裸机可以安装 METALLB 测试会额外生成一个 IP 对外服务K8S 支持的负载均衡器负载均衡器 Headless 适合数据库clusterIp 设置为 None 就变成 Headless 了不会再分配 IP后面会再讲到具体用法
五、StatefulSet
1、StatefulSet介绍
1.1 概念
StatefulSet 是用来管理有状态的应用例如数据库。 前面我们部署的应用都是不需要存储数据不需要记住状态的可以随意扩充副本每个副本都是一样的可替代的。 而像数据库、Redis 这类有状态的则不能随意扩充副本。StatefulSet 会固定每个 Pod 的名字
1.2 特性
Service 的 CLUSTER-IP 是空的Pod 名字也是固定的。Pod 创建和销毁是有序的创建是顺序的销毁是逆序的。Pod 重建不会改变名字除了IP所以不要用IP直连
2、部署 StatefulSet 类型的 Mongodb
创建statefulset和service
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mongodb
spec:serviceName: mongodbreplicas: 3selector:matchLabels:app: mongodbtemplate:metadata:labels:app: mongodbspec:containers:- name: mongoimage: mongo:4.4#IfNotPresent 仅本地没有镜像时才远程拉Always 永远都是从远程拉Never 永远只用本地镜像本地没有则报错imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:name: mongodb
spec:selector:app: mongodbtype: ClusterIP# HeadLessclusterIP: Noneports:- port: 27017targetPort: 27017
操作这里的test-k8s镜像使用了ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v3-mongo
# 扩容
kubectl scale --replicas5 statefulset mongodb
# 查看状态信息
kubectl get endpoints mongodb -o yaml# 访问时如果直接使用 Service 名字连接会随机转发请求
# 要连接指定 Pod可以这样pod-name.service-name# 运行一个临时 Pod 连接数据测试下
kubectl run mongodb-client --rm --tty -i --restartNever --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash# 访问某一个mongodb
mongo --host mongodb-0.mongodbshow dbs
use test
db.users.save({_id:shawn,name:shawn22})
db.users.find()# 查看集权状态
kubectl get all六、数据持久化
1、概念
kubernetes 集群不会为你处理数据的存储我们可以为数据库挂载一个磁盘来确保数据的安全。可以选择云存储、本地磁盘、NFS。
本地磁盘可以挂载某个节点上的目录但是这需要限定 pod 在这个节点上运行云存储不限定节点不受集群影响安全稳定需要云服务商提供裸机集群是没有的。NFS不限定节点不受集群影响
2、hostPath 挂载示例 文档https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#hostpath 把节点上的一个目录挂载到 Pod但是已经不推荐使用了该方法配置方式简单需要手动指定 Pod 跑在某个固定的节点。仅供单节点测试使用不适用于多节点集群
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mongodb
spec:replicas: 1selector:matchLabels:app: mongodbserviceName: mongodbtemplate:metadata:labels:app: mongodbspec:containers:- name: mongoimage: mongo:4.4# IfNotPresent 仅本地没有镜像时才远程拉Always 永远都是从远程拉Never 永远只用本地镜像本地没有则报错imagePullPolicy: IfNotPresentvolumeMounts:- mountPath: /data/db # 容器里面的挂载路径name: mongo-data # 卷名字必须跟下面定义的名字一致volumes:- name: mongo-data # 卷名字hostPath:path: /data/mongo-data # 节点上的路径type: DirectoryOrCreate # 指向一个目录不存在时自动创建
创建好数据后重启kubectl rollout restart statefulset mongodb发现数据还在同时进入结点可以发现数据保存在/data/db而进入该结点的宿主机发现数据映射在/data/mongo-data
3、高级抽象挂载
3.1 概述 更好的分工运维人员负责提供好存储开发人员不需要关注磁盘细节只需要写一个申请单。方便云服务商提供不同类型的配置细节不需要开发者关注只需要一个申请单。动态创建开发人员写好申请单后供应商可以根据需求自动创建所需存储卷。
3.2 各个层级表述
Storage Class (SC)
将存储卷划分为不同的种类例如SSD普通磁盘本地磁盘按需使用。文档
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: slow
provisioner: kubernetes.io/aws-ebs
parameters:type: io1iopsPerGB: 10fsType: ext4
Persistent Volume (PV)
描述卷的具体信息例如磁盘大小访问模式。文档类型Local 示例
apiVersion: v1
kind: PersistentVolume
metadata:name: mongodata
spec:capacity:storage: 2GivolumeMode: Filesystem # Filesystem文件系统 Block块accessModes:- ReadWriteOnce # 卷可以被一个节点以读写方式挂载persistentVolumeReclaimPolicy: DeletestorageClassName: local-storagelocal:path: /root/datanodeAffinity:required:# 通过 hostname 限定在某个节点创建存储卷nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- node2
Persistent Volume Claim (PVC)
对存储需求的一个申明可以理解为一个申请单系统根据这个申请单去找一个合适的 PV 还可以根据 PVC 自动创建 PV。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mongodata
spec:accessModes: [ReadWriteOnce]storageClassName: local-storageresources:requests:storage: 2Gi
3.3 本地测试
网络云服务商封装了底层只需要提交pvc申请即可成功这里我用本地进行模拟写到了一起实际可以自行分开
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mongodb
spec:replicas: 1selector:matchLabels:app: mongodbserviceName: mongodbtemplate:metadata:labels:app: mongodbspec:containers:- name: mongoimage: mongo:4.4# IfNotPresent 仅本地没有镜像时才远程拉Always 永远都是从远程拉Never 永远只用本地镜像本地没有则报错imagePullPolicy: IfNotPresentvolumeMounts:- mountPath: /data/db # 容器里面的挂载路径name: mongo-data # 卷名字必须跟下面定义的名字一致volumes:- name: mongo-data # 卷名字persistentVolumeClaim:claimName: mongodata---
apiVersion: v1
kind: Service
metadata:name: mongodb
spec:clusterIP: Noneports:- port: 27017protocol: TCPtargetPort: 27017selector:app: mongodbtype: ClusterIP
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:name: mongodata
spec:capacity:storage: 2GivolumeMode: Filesystem # Filesystem文件系统 Block块accessModes:# 卷可以被一个节点以读写方式挂载- ReadWriteOnce persistentVolumeReclaimPolicy: DeletestorageClassName: local-storagelocal:path: /root/datanodeAffinity:required:# 通过 hostname 限定在某个节点创建存储卷nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mongodata
spec:accessModes: [ReadWriteOnce]storageClassName: local-storageresources:requests:storage: 2Gi
测试
# 运行
kubectl apply -f storage.yaml
# 查看各个层信息
kubectl get pv
kubectl get sc
kubectl get pvc
kubectl get pod -owide
# 需要进入node2结点去创建一下data路径可能会报错后面mongo的数据库就挂在到了node2的/data下面七、ConfigMap Secret
1、概述 参考文档https://kubernetes.io/zh/docs/concepts/configuration/configmap/ 数据库连接地址这种可能根据部署环境变化的我们不应该写死在代码里。Kubernetes 为我们提供了 ConfigMap可以方便的配置一些变量
2、ConfigMap
创建configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: mongo-config
data:mongoHost: mongodb-0.mongodb# 应用
kubectl apply -f configmap.yaml
# 查看
kubectl get configmap mongo-config -o yaml
kubectl get configmap
3、Secret
一些重要数据例如密码、TOKEN我们可以放到 secret 中。文档配置证书。注意数据要进行 Base64 编码。Base64 工具
创建secret.yaml
apiVersion: v1
kind: Secret
metadata:name: mongo-secret
# Opaque 用户定义的任意数据更多类型介绍 https://kubernetes.io/zh/docs/concepts/configuration/secret/#secret-types
type: Opaque
data:# 数据要 base64。https://tools.fun/base64.htmlmongo-username: bW9uZ291c2Vymongo-password: bW9uZ29wYXNz
# 应用
kubectl apply -f secret.yaml
# 查看
kubectl get secret mongo-secret -o yaml
kubectl get secret
4、Demo使用
作为环境变量使用
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mongodb
spec:replicas: 3selector:matchLabels:app: mongodbserviceName: mongodbtemplate:metadata:labels:app: mongodbspec:containers:- name: mongoimage: mongo:4.4# IfNotPresent 仅本地没有镜像时才远程拉Always 永远都是从远程拉Never 永远只用本地镜像本地没有则报错imagePullPolicy: IfNotPresentenv:- name: MONGO_INITDB_ROOT_USERNAMEvalueFrom:secretKeyRef:name: mongo-secretkey: mongo-username- name: MONGO_INITDB_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mongo-secretkey: mongo-password# Secret 的所有数据定义为容器的环境变量Secret 中的键名称为 Pod 中的环境变量名称# envFrom:# - secretRef:# name: mongo-secret
---
apiVersion: v1
kind: Service
metadata:name: mongodb
spec:selector:app: mongodbtype: ClusterIP# HeadLessclusterIP: Noneports:- port: 27017targetPort: 27017
挂载为文件更适合证书文件挂载后会在容器中对应路径生成文件一个 key 一个文件内容就是 value文档
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: mypodimage: redisvolumeMounts:- name: foomountPath: /etc/fooreadOnly: truevolumes:- name: foosecret:secretName: mysecret
进行测试test-k8s的镜像更换ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v4-configmap
kubectl run mongodb-client --rm --tty -i --restartNever --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash
mongo --host mongodb-0.mongodb -u mongouser -p mongopass
show dbs
# 外部访问需要端口转发八、Helm 命名空间
1、简介 Helm官网https://helm.sh/zh/ 包搜索https://artifacthub.io/ Helm类似 npmpipdocker hub 可以理解为是一个软件库可以方便快速的为我们的集群安装一些第三方软件。使用 Helm 我们可以非常方便的就搭建出来 MongoDB / MySQL 副本集群YAML 文件别人都给我们写好了直接使用
2、Helm安装 安装文档https://helm.sh/zh/docs/intro/install/ # 脚本安装不过可能会失败
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 手动进行安装
wget https://get.helm.sh/helm-v3.10.1-linux-amd64.tar.gz
tar -zxvf helm-v3.10.1-linux-amd64.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm
helm --help
3、安装MongoDb
# 安装
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-mongo bitnami/mongodb# 指定密码和架构
helm install my-mongo bitnami/mongodb --set architecturereplicaset,auth.rootPasswordmongopass# 删除
helm ls
helm delete my-mongo# 查看密码
kubectl get secret my-mongo-mongodb -o json
kubectl get secret my-mongo-mongodb -o yaml secret.yaml# 临时运行一个包含 mongo client 的 debian 系统
kubectl run mongodb-client --rm --tty -i --restartNever --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash# 进去 mongodb
mongo --host my-mongo-mongodb -u root -p mongopass# 也可以转发集群里的端口到宿主机访问 mongodb
kubectl port-forward svc/my-mongo-mongodb 27017:27018
4、命名空间 如果一个集群中部署了多个应用所有应用都在一起就不太好管理也可以导致名字冲突等。我们可以使用 namespace 把应用划分到不同的命名空间跟代码里的 namespace 是一个概念只是为了划分空间 # 创建命名空间
kubectl create namespace testapp
# 部署应用到指定的命名空间
kubectl apply -f app.yml --namespace testapp
# 查询
kubectl get pod --namespace kube-system
# 查询命名空间
kubectl get ns
可以用 kubens 快速切换 namespace首先进行下载安装
wget https://github.com/ahmetb/kubectx/releases/download/v0.9.4/kubens_v0.9.4_linux_x86_64.tar.gz
tar -zxvf kubens_v0.9.4_linux_x86_64.tar.gz
sudo mv kubens /usr/local/bin/kubens
# 查看所有命名空间
kubens
# 切换命名空间
kubens kube-system
# 回到上个命名空间
kubens -
# 切换集群
# kubectx minikube
九、Ingress
1、介绍 Ingress 为外部访问集群提供了一个 统一 入口避免了对外暴露集群端口功能类似 Nginx可以根据域名、路径把请求转发到不同的 Service。可以配置 https **跟 LoadBalancer 有什么区别**LoadBalancer 需要对外暴露端口不安全无法根据域名、路径转发流量到不同 Service多个 Service 则需要开多个 LoadBalancer功能单一无法配置 https 2、使用 文档Ingress 要使用 Ingress需要一个负载均衡器 Ingress Controller如果是裸机bare metal) 搭建的集群你需要自己安装一个负载均衡插件可以安装 METALLB如果是云服务商会自动给你配置否则你的外部 IP 会是 pending状态无法使用。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: simple-example
spec:ingressClassName: nginxrules:- host: tools.funhttp:paths:- path: /easydocpathType: Prefixbackend:service:name: service1port:number: 4200- path: /svnbucketpathType: Prefixbackend:service:name: service2port:number: 8080 参考文档
https://www.bilibili.com/video/BV1Tg411P7EB
https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/9EX8Cp45
https://kuboard.cn/install/install-k8s.html