共计 18697 个字符,预计需要花费 47 分钟才能阅读完成。
📚Kubernetes(K8S)简介
课程内容
- 介绍下什么是 kubernetes,什么时候须要 kubernetes,以及它的组成架构。
- 用 3 种不同的形式教大家如何装置 kubernetes 集群。包含 minikube,云平台搭建,裸机搭建(3 台服务器)。
- 通过一个 demo 我的项目演示如何部署我的项目到集群中,怎么对外裸露服务端口
- 怎么部署数据库这种有状态的利用,以及如何数据长久化
- 集群中配置文件和密码文件的应用
- 怎么应用 Helm 利用商店疾速装置第三方利用
- 怎么应用 Ingress 对外提供服务
指标:学完课程,对 kubernetes 有一个全面的意识,可能轻松应答各种集群部署工作。
Kubernetes (K8S) 是什么
它是一个为 容器化 利用提供集群部署和治理的开源工具,由 Google 开发。
Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。Google 在 2014 年开源了 Kubernetes 我的项目
次要个性:
- 高可用,不宕机,主动劫难复原
- 灰度更新,不影响业务失常运行
- 一键回滚到历史版本
- 不便的伸缩扩大(利用伸缩,机器加减)、提供负载平衡
- 有一个欠缺的生态
学习课程前提
相熟 Docker 的根本应用,如果你还不理解 Docker,先看视频 Docker 疾速上手
相熟 Linux 操作系统
不同的利用部署计划
传统部署形式:
利用间接在物理机上部署,机器资源分配不好管制,呈现 Bug 时,可能机器的大部分资源被某个利用占用,导致其余利用无奈失常运行,无奈做到利用隔离。
虚拟机部署
在单个物理机上运行多个虚拟机,每个虚拟机都是残缺独立的零碎,性能损耗大。
容器部署
所有容器共享主机的零碎,轻量级的虚拟机,性能损耗小,资源隔离,CPU 和内存可按需分配
什么时候须要 Kubernetes
当你的利用只是跑在一台机器,间接一个 docker + docker-compose 就够了,不便轻松;
当你的利用须要跑在 3,4 台机器上,你仍旧能够每台机器独自配置运行环境 + 负载均衡器;
当你利用拜访数一直减少,机器逐步减少到十几台、上百台、上千台时,每次加机器、软件更新、版本回滚,都会变得十分麻烦、痛不欲生,再也不能好好的摸鱼了,人生节约在那些没技术含量的重复性工作上。
这时候,Kubernetes 就能够一展身手了,让你轻松治理百万千万台机器的集群。“谈笑间,樯橹灰飞烟灭”,享受着一手掌控所有,年薪百万不可企及。
Kubernetes 能够为你提供集中式的治理集群机器和利用,加机器、版本升级、版本回滚,那都是一个命令就搞定的事,不停机的灰度更新,确保高可用、高性能、高扩大。
Kubernetes 集群架构
master
主节点,管制平台,不须要很高性能,不跑工作,通常一个就行了,也能够开多个主节点来进步集群可用度。
worker
工作节点,能够是虚拟机或物理计算机,工作都在这里跑,机器性能须要好点;通常都有很多个,能够一直加机器扩充集群;每个工作节点由主节点治理
重要概念 Pod
豆荚,K8S 调度、治理的最小单位,一个 Pod 能够蕴含一个或多个容器,每个 Pod 有本人的虚构 IP。一个工作节点能够有多个 pod,主节点会考量负载主动调度 pod 到哪个节点运行。
Kubernetes 组件
kube-apiserver
API 服务器,公开了 Kubernetes APIetcd
键值数据库,能够作为保留 Kubernetes 所有集群数据的后盾数据库kube-scheduler
调度 Pod 到哪个节点运行kube-controller
集群控制器cloud-controller
与云服务商交互
如果你想要理解更多 K8S 组成细节,主节点、工作节点别离有哪些程序,各有什么作用,能够查看 官网具体介绍
💽装置 Kubernetes 集群
装置形式介绍
- minikube
只是一个 K8S 集群模拟器,只有一个节点的集群,只为测试用,master 和 worker 都在一起 - 间接用云平台 Kubernetes
可视化搭建,只需简略几步就能够创立好一个集群。
长处:安装简单,生态齐全,负载均衡器、存储等都给你配套好,简略操作就搞定 - 裸机装置(Bare Metal)
至多须要两台机器(主节点、工作节点个一台),须要本人装置 Kubernetes 组件,配置会略微麻烦点。
能够到各云厂商按时租用服务器,费用低,用完就销毁。
毛病:配置麻烦,短少生态反对,例如负载均衡器、云存储。
minikube
装置非常简单,反对各种平台,装置办法
须要提前装置好 Docker
# 启动集群
minikube start
# 查看节点。kubectl 是一个用来跟 K8S 集群进行交互的命令行工具
kubectl get node
# 进行集群
minikube stop
# 清空集群
minikube delete --all
# 装置集群可视化 Web UI 控制台
minikube dashboard
云平台搭建
- 腾讯云 TKE(控制台搜寻容器)
- 登录阿里云控制台 – 产品搜寻 Kubernetes
裸机搭建(Bare Metal)
主节点须要组件
- docker(也能够是其余容器运行时)
- kubectl 集群命令行交互工具
-
kubeadm 集群初始化工具
工作节点须要组件 文档
- docker(也能够是其余容器运行时)
- kubelet 治理 Pod 和容器,确保他们衰弱稳固运行。
- kube-proxy 网络代理,负责网络相干的工作
开始装置
你也能够试下 这个我的项目,用脚本疾速搭建 K8S 裸机集群
当然,为了更好的了解,你应该先手动搭建一次
# 每个节点别离设置对应主机名
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2
# 所有节点都批改 hosts
vim /etc/hosts
172.16.32.2 node1
172.16.32.6 node2
172.16.0.4 master
# 所有节点敞开 SELinux
setenforce 0
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
w 所有节点确保防火墙敞开
systemctl stop firewalld
systemctl disable firewalld
增加装置源(所有节点)
# 增加 k8s 装置源
cat <<EOF > kubernetes.repo
[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
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
留神,据学员反馈,1.24 以上的版本会报错,跟教程有差别,所以倡议大家指定版本号装置,版本号确保跟老师的一样
启动 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.cgroupdriver=systemd"],
"registry-mirrors": ["https://ud6340vz.mirror.aliyuncs.com"]
}
EOF
mv daemon.json /etc/docker/
# 重启失效
systemctl daemon-reload
systemctl restart docker
用 kubeadm 初始化集群(仅在主节点跑),
# 初始化集群控制台 Control plane
# 失败了能够用 kubeadm reset 重置
kubeadm init --image-repository=registry.aliyuncs.com/google_containers
# 记得把 kubeadm join xxx 保存起来
# 遗记了从新获取:kubeadm token create --print-join-command
# 复制受权文件,以便 kubectl 能够有权限拜访集群
# 如果你其余节点须要拜访集群,须要从主节点复制这个文件过来其余节点
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 在其余机器上创立 ~/.kube/config 文件也能通过 kubectl 拜访到集群
有趣味理解 kubeadm init 具体做了什么的,能够 查看文档
把工作节点退出集群(只在工作节点跑)
kubeadm join 172.16.32.10:6443 --token xxx --discovery-token-ca-cert-hash xxx
装置网络插件,否则 node 是 NotReady 状态(主节点跑)
# 很有可能国内网络拜访不到这个资源,你能够网上找找国内的源装置 flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
查看节点,要在主节点查看(其余节点有装置 kubectl 也能够查看)
装置形式介绍
- minikube
只是一个 K8S 集群模拟器,只有一个节点的集群,只为测试用,master 和 worker 都在一起 - 间接用云平台 Kubernetes
可视化搭建,只需简略几步就能够创立好一个集群。
长处:安装简单,生态齐全,负载均衡器、存储等都给你配套好,简略操作就搞定 - 裸机装置(Bare Metal)
至多须要两台机器(主节点、工作节点个一台),须要本人装置 Kubernetes 组件,配置会略微麻烦点。
能够到各云厂商按时租用服务器,费用低,用完就销毁。
毛病:配置麻烦,短少生态反对,例如负载均衡器、云存储。
本文档课件需配套 视频 一起学习
minikube
装置非常简单,反对各种平台,装置办法
须要提前装置好 Docker
# 启动集群
minikube start
# 查看节点。kubectl 是一个用来跟 K8S 集群进行交互的命令行工具
kubectl get node
# 进行集群
minikube stop
# 清空集群
minikube delete --all
# 装置集群可视化 Web UI 控制台
minikube dashboard
云平台搭建
- 腾讯云 TKE(控制台搜寻容器)
- 登录阿里云控制台 – 产品搜寻 Kubernetes
裸机搭建(Bare Metal)
主节点须要组件
- docker(也能够是其余容器运行时)
- kubectl 集群命令行交互工具
-
kubeadm 集群初始化工具
工作节点须要组件 文档
- docker(也能够是其余容器运行时)
- kubelet 治理 Pod 和容器,确保他们衰弱稳固运行。
- kube-proxy 网络代理,负责网络相干的工作
开始装置
你也能够试下 这个我的项目,用脚本疾速搭建 K8S 裸机集群
当然,为了更好的了解,你应该先手动搭建一次
# 每个节点别离设置对应主机名
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2
# 所有节点都批改 hosts
vim /etc/hosts
172.16.32.2 node1
172.16.32.6 node2
172.16.0.4 master
# 所有节点敞开 SELinux
setenforce 0
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
所有节点确保防火墙敞开
systemctl stop firewalld
systemctl disable firewalld
增加装置源(所有节点)
# 增加 k8s 装置源
cat <<EOF > kubernetes.repo
[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
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
留神,据学员反馈,1.24 以上的版本会报错,跟教程有差别,所以倡议大家指定版本号装置,版本号确保跟老师的一样
启动 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.cgroupdriver=systemd"],
"registry-mirrors": ["https://ud6340vz.mirror.aliyuncs.com"]
}
EOF
mv daemon.json /etc/docker/
# 重启失效
systemctl daemon-reload
systemctl restart docker
用 kubeadm 初始化集群(仅在主节点跑),
# 初始化集群控制台 Control plane
# 失败了能够用 kubeadm reset 重置
kubeadm init --image-repository=registry.aliyuncs.com/google_containers
# 记得把 kubeadm join xxx 保存起来
# 遗记了从新获取:kubeadm token create --print-join-command
# 复制受权文件,以便 kubectl 能够有权限拜访集群
# 如果你其余节点须要拜访集群,须要从主节点复制这个文件过来其余节点
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 在其余机器上创立 ~/.kube/config 文件也能通过 kubectl 拜访到集群
有趣味理解 kubeadm init 具体做了什么的,能够 查看文档
把工作节点退出集群(只在工作节点跑)
kubeadm join 172.16.32.10:6443 --token xxx --discovery-token-ca-cert-hash xxx
装置网络插件,否则 node 是 NotReady 状态(主节点跑)
# 很有可能国内网络拜访不到这个资源,你能够网上找找国内的源装置 flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
查看节点,要在主节点查看(其余节点有装置 kubectl 也能够查看)
🏭部署利用到集群中
部署利用 YAML 文件
间接命令运行
kubectl run testapp --image=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1
Pod
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
# 定义容器,能够多个
containers:
- name: test-k8s # 容器名字
image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
# 部署名字
name: test-k8s
spec:
replicas: 2
# 用来查找关联的 Pod,所有标签都匹配才行
selector:
matchLabels:
app: test-k8s
# 定义 Pod 相干数据
template:
metadata:
labels:
app: test-k8s
spec:
# 定义容器,能够多个
containers:
- name: test-k8s # 容器名字
image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
Deployment 通过 label 关联起来 Pods
部署利用演示
部署一个 nodejs web 利用,源码地址:Github
# 部署利用
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
# 进入 Pod 容器终端,-c container-name 能够指定进入哪个容器。kubectl exec -it pod-name -- bash
# 伸缩扩大正本
kubectl scale deployment test-k8s --replicas=5
# 把集群内端口映射到节点
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-revision=2
# 删除部署
kubectl delete deployment test-k8s
Pod 报错解决
如果你运行 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_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
更多命令
# 查看全副
kubectl get all
# 重新部署
kubectl rollout restart deployment test-k8s
# 命令批改镜像,--record 示意把这个命令记录到操作历史中
kubectl set image deployment test-k8s test-k8s=ccr.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
更多官网对于 Deployment 的介绍
将 Pod 指定到某个节点运行:nodeselector
限定 CPU、内存总量:文档
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
工作负载分类
- Deployment
适宜无状态利用,所有 pod 等价,可代替 - StatefulSet
有状态的利用,适宜数据库这种类型。 - DaemonSet
在每个节点上跑一个 Pod,能够用来做节点监控、节点日志收集等 - Job & CronJob
Job 用来表白的是一次性的工作,而 CronJob 会依据其工夫布局重复运行。
文档
现存问题
- 每次只能拜访一个 pod,没有负载平衡主动转发到不同 pod
- 拜访还须要端口转发
- Pod 重创后 IP 变了,名字也变了
下节咱们解说如何解决。
🎭Service
个性
- Service 通过 label 关联对应的 Pod
- Servcie 生命周期不跟 Pod 绑定,不会因为 Pod 重创扭转 IP
- 提供了负载平衡性能,主动转发流量到不同 Pod
- 可对集群内部提供拜访端口
- 集群外部可通过服务名字拜访
创立 Service
创立 一个 Service,通过标签 test-k8s
跟对应的 Pod 关联上 service.yaml
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: ClusterIP
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
利用配置 kubectl apply -f service.yaml
查看服务 kubectl get svc
查看服务详情 kubectl describe svc test-k8s
,能够发现 Endpoints 是各个 Pod 的 IP,也就是他会把流量转发到这些节点。
服务的默认类型是ClusterIP
,只能在集群外部拜访,咱们能够进入到 Pod 外面拜访:kubectl exec -it pod-name -- bash
curl http://test-k8s:8080
如果要在集群内部拜访,能够通过端口转发实现(只适宜长期测试用):kubectl port-forward service/test-k8s 8888:8080
如果你用 minikube,也能够这样
minikube service test-k8s
对外裸露服务
下面咱们是通过端口转发的形式能够在里面拜访到集群里的服务,如果想要间接把集群服务裸露进去,咱们能够应用NodePort
和 Loadbalancer
类型的 Service
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默认 ClusterIP 集群内可拜访,NodePort 节点可拜访,LoadBalancer 负载平衡模式(须要负载均衡器才可用)type: NodePort
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
nodePort: 31000 # 节点端口,范畴固定 30000 ~ 32767
利用配置 kubectl apply -f service.yaml
在节点上,咱们能够 curl http://localhost:31000/hello/easydoc
拜访到利用
并且是有负载平衡的,网页的信息能够看到被转发到了不同的 Pod
hello easydoc
IP lo172.17.0.8, hostname: test-k8s-68bb74d654-962lh
如果你是用 minikube,因为是模仿集群,你的电脑并不是节点,节点是 minikube 模仿进去的,所以你并不能间接在电脑上拜访到服务
Loadbalancer
也能够对外提供服务,这须要一个负载均衡器的反对,因为它须要生成一个新的 IP 对外服务,否则状态就始终是 pendding,这个很少用了,前面咱们会讲更高端的 Ingress 来代替它。
多端口
多端口时必须配置 name,文档
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
name: test-k8s # 必须配置
targetPort: 8080 # 容器端口
nodePort: 31000 # 节点端口,范畴固定 30000 ~ 32767
- port: 8090
name: test-other
targetPort: 8090
nodePort: 32000
总结
ClusterIP
默认的,仅在集群内可用
NodePort
裸露端口到节点,提供了集群内部拜访的入口
端口范畴固定 30000 ~ 32767
LoadBalancer
须要负载均衡器(通常都须要云服务商提供,裸机能够装置 METALLB 测试)
会额定生成一个 IP 对外服务
K8S 反对的负载均衡器:负载均衡器
Headless
适宜数据库
clusterIp 设置为 None 就变成 Headless 了,不会再调配 IP,前面会再讲到具体用法
官网文档
🥙StatefulSet
什么是 StatefulSet
StatefulSet 是用来治理有状态的利用,例如数据库。
后面咱们部署的利用,都是不须要存储数据,不须要记住状态的,能够随便裁减正本,每个正本都是一样的,可代替的。
而像数据库、Redis 这类有状态的,则不能随便裁减正本。
StatefulSet 会固定每个 Pod 的名字
部署 StatefulSet 类型的 Mongodb
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: mongodb
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才近程拉,Always 永远都是从近程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess
clusterIP: None
ports:
- port: 27017
targetPort: 27017
kubectl apply -f mongo.yaml
StatefulSet 个性
- Service 的
CLUSTER-IP
是空的,Pod 名字也是固定的。 - Pod 创立和销毁是有序的,创立是程序的,销毁是逆序的。
- Pod 重建不会扭转名字,除了 IP,所以不要用 IP 直连
Endpoints 会多一个 hostname
拜访时,如果间接应用 Service 名字连贯,会随机转发申请
要连贯指定 Pod,能够这样 pod-name.service-name
运行一个长期 Pod 连贯数据测试下kubectl run mongodb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash
Web 利用连贯 Mongodb
在集群外部,咱们能够通过服务名字拜访到不同的服务
指定连贯第一个:mongodb-0.mongodb
问题
pod 重建后,数据库的内容失落了
下节,咱们解说如何解决这个问题。
🍤数据长久化
介绍
kubernetes 集群不会为你解决数据的存储,咱们能够为数据库挂载一个磁盘来确保数据的平安。
你能够抉择云存储、本地磁盘、NFS。
- 本地磁盘:能够挂载某个节点上的目录,然而这须要限定 pod 在这个节点上运行
- 云存储:不限定节点,不受集群影响,平安稳固;须要云服务商提供,裸机集群是没有的。
- NFS:不限定节点,不受集群影响
hostPath 挂载示例
把节点上的一个目录挂载到 Pod,然而曾经不举荐应用了,文档
配置形式简略,须要手动指定 Pod 跑在某个固定的节点。
仅供单节点测试应用;不适用于多节点集群。
minikube 提供了 hostPath 存储,文档
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
serviceName: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才近程拉,Always 永远都是从近程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data/db # 容器外面的挂载门路
name: mongo-data # 卷名字,必须跟上面定义的名字统一
volumes:
- name: mongo-data # 卷名字
hostPath:
path: /data/mongo-data # 节点上的门路
type: DirectoryOrCreate # 指向一个目录,不存在时主动创立
更高级的形象
Storage Class (SC)
将存储卷划分为不同的品种,例如:SSD,一般磁盘,本地磁盘,按需应用。文档
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "10"
fsType: ext4
Persistent Volume (PV)
形容卷的具体信息,例如磁盘大小,拜访模式。文档,类型,Local 示例
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodata
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem # Filesystem(文件系统)Block(块)accessModes:
- ReadWriteOnce # 卷能够被一个节点以读写形式挂载
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /root/data
nodeAffinity:
required:
# 通过 hostname 限定在某个节点创立存储卷
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
Persistent Volume Claim (PVC)
对存储需要的一个申明,能够了解为一个申请单,零碎依据这个申请单去找一个适合的 PV
还能够依据 PVC 主动创立 PV。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodata
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-storage"
resources:
requests:
storage: 2Gi
为什么要这么多层形象
- 更好的分工,运维人员负责提供好存储,开发人员不须要关注磁盘细节,只须要写一个申请单。
- 不便云服务商提供不同类型的,配置细节不须要开发者关注,只须要一个申请单。
- 动态创建,开发人员写好申请单后,供应商能够依据需要主动创立所需存储卷。
腾讯云示例
本地磁盘示例
不反对动态创建,须要提前创立好
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
image: mongo:5.0
imagePullPolicy: IfNotPresent
name: mongo
volumeMounts:
- mountPath: /data/db
name: mongo-data
volumes:
- name: mongo-data
persistentVolumeClaim:
claimName: mongodata
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
clusterIP: None
ports:
- port: 27017
protocol: TCP
targetPort: 27017
selector:
app: mongodb
type: 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: 2Gi
volumeMode: Filesystem # Filesystem(文件系统)Block(块)accessModes:
- ReadWriteOnce # 卷能够被一个节点以读写形式挂载
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /root/data
nodeAffinity:
required:
# 通过 hostname 限定在某个节点创立存储卷
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodata
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-storage"
resources:
requests:
storage: 2Gi
问题
以后数据库的连贯地址是写死在代码里的,另外还有数据库的明码须要配置。
下节,咱们解说如何解决。
📑ConfigMap & Secret
ConfigMap
数据库连贯地址,这种可能依据部署环境变动的,咱们不应该写死在代码里。
Kubernetes 为咱们提供了 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
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.html
mongo-username: bW9uZ291c2Vy
mongo-password: bW9uZ29wYXNz
# 利用
kubectl apply -f secret.yaml
# 查看
kubectl get secret mongo-secret -o yaml
应用办法
作为环境变量应用
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才近程拉,Always 永远都是从近程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
# Secret 的所有数据定义为容器的环境变量,Secret 中的键名称为 Pod 中的环境变量名称
# envFrom:
# - secretRef:
# name: mongo-secret
挂载为文件(更适宜证书文件)
挂载后,会在容器中对应门路生成文件,一个 key 一个文件,内容就是 value,文档
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
🍓Helm & 命名空间
介绍
Helm
相似 npm,pip,docker hub, 能够了解为是一个软件库,能够不便疾速的为咱们的集群装置一些第三方软件。
应用 Helm 咱们能够十分不便的就搭建进去 MongoDB / MySQL 正本集群,YAML 文件他人都给咱们写好了,间接应用。官网,利用核心
装置 Helm
装置 文档curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
装置 MongoDB 示例
# 装置
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-mongo bitnami/mongodb
# 指定明码和架构
helm install my-mongo bitnami/mongodb --set architecture="replicaset",auth.rootPassword="mongopass"
# 删除
helm ls
heml 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 --restart='Never' --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
命名空间
如果一个集群中部署了多个利用,所有利用都在一起,就不太好治理,也能够导致名字抵触等。
咱们能够应用 namespace 把利用划分到不同的命名空间,跟代码里的 namespace 是一个概念,只是为了划分空间。
# 创立命名空间
kubectl create namespace testapp
# 部署利用到指定的命名空间
kubectl apply -f app.yml --namespace testapp
# 查问
kubectl get pod --namespace kube-system
能够用 kubens 疾速切换 namespace
# 切换命名空间
kubens kube-system
# 回到上个命名空间
kubens -
# 切换集群
kubectx minikube
✈️Ingress
介绍
Ingress 为内部拜访集群提供了一个 对立 入口,防止了对外裸露集群端口;
性能相似 Nginx,能够依据域名、门路把申请转发到不同的 Service。
能够配置 https
跟 LoadBalancer 有什么区别?
LoadBalancer 须要对外裸露端口,不平安;
无奈依据域名、门路转发流量到不同 Service,多个 Service 则须要开多个 LoadBalancer;
性能繁多,无奈配置 https
应用
要应用 Ingress,须要一个负载均衡器 + Ingress Controller
如果是裸机(bare metal) 搭建的集群,你须要本人装置一个负载平衡插件,能够装置 METALLB
如果是云服务商,会主动给你配置,否则你的内部 IP 会是“pending”状态,无奈应用。
文档:Ingress
Minikube 中部署 Ingress Controller:nginx
Helm 装置:Nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-example
spec:
ingressClassName: nginx
rules:
- host: tools.fun
http:
paths:
- path: /easydoc
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
- path: /svnbucket
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080
腾讯云配置 Ingress 演示
🎉其余补充
kubernetes 能够治理大量的容器化利用,不便的进行伸缩扩大集群,随时回退版本。
kubernetes 须要云厂商的反对才是残缺的,好在以后各大云厂商都曾经提供了 k8s 集群服务,生态很欠缺,十分不便。
咱们本人搭建的叫裸机,用来做测试、学习很好,能够把本人淘汰的电脑用起来搭建出一个集群玩玩。
WEB 可视化治理集群
如果你感觉命令行治理集群太麻烦,你能够用 Helm 疾速搭建一个 kubernetes-dashboard,这样你就有了一个 WEB 界面,能够可视化的进行一些操作和治理。
如果是 minikube 更加简略,一个命令 minikube dashboard
就好了。
数据库更好的做法
数据库这种有状态的利用,更好的做法是间接应用云厂商提供的数据库,运行会更加稳固,也有欠缺的数据备份。
用脚本搭建集群
Github 上有用户曾经把裸机搭建须要做的工作写成了脚本,一个脚本就帮你初始化好集群工作:kainstall
公网搭建 K8S 集群
网友提供的:参考文档