关于kubernetes:OpsCICDK8S-学习笔记

43次阅读

共计 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 API
etcd 键值数据库,能够作为保留 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

对外裸露服务

下面咱们是通过端口转发的形式能够在里面拜访到集群里的服务,如果想要间接把集群服务裸露进去,咱们能够应用NodePortLoadbalancer 类型的 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 集群

网友提供的:参考文档

正文完
 0