首页 > 其他分享 >K8S入门

K8S入门

时间:2023-04-10 19:56:55浏览次数:44  
标签:kubectl K8S 入门 集群 test k8s 节点 name

原文链接:https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/9EX8Cp45

一、简介

容器化应用提供集群部署和管理的开源工具,Google开发
主要特性:

  • 高可用,不宕机,自动灾难恢复
  • 灰度更新,不影响业务正常运转
  • 一键回滚到历史版本
  • 方便的伸缩扩展(应用伸缩,机器加减)、提供负载均衡
  • 有一个完善的生态

需要熟悉docker和linux的基本使用

1、不同的应用部署方案

传统部署方式:

应用直接在物理机上部署,机器资源分配不好控制,出现Bug时,可能机器的大部分资源被某个应用占用,导致其他应用无法正常运行,无法做到应用隔离

虚拟机部署:

在单个物理机上运行多个虚拟机,每个虚拟机都是完整独立的系统,性能损耗大

容器部署:

所有容器共享主机的系统,轻量级的虚拟机,性能损耗小,资源隔离,CPU和内存可按需分配

2、什么时候需要K8S

Kubernets可以提供集中式的管理集群机器和应用,加机器、版本升级、版本回归都是一个命令搞定的事,不停机上的灰度更新,确保高可用、高性能、高扩展

Kubernets集群架构

master

主节点,控制平台,不需要很高性能,不跑任务,通常一个就行了,也可以开多个主节点来提高集群可用度

worker

工作节点,可以是虚拟机或物理计算机,任务都在这里跑,机器性能需要好点,通常有很多个,可以不断加机器扩大集群,每个工作节点由主节点管理

重要概念Pod

豆荚,K8S调度、管理的最小单位,一个Pod可以包含一个或多个容器,每个Pod有自己的虚拟IP,一个工作节点可以有多个pod,主节点会考量负载自动调度pod到哪个节点运行

Kube-apiserver:API服务器,公开了Kubernets API
etcd键值数据库:可以作为保存Kubernetes所以集群数据的后台数据库
kube-scheduler:调度Pod到哪个节点运行
kube-controller:集群控制器
cloud-controller:与云服务商交互

二、安装Kubernetes集群

安装方式介绍

  • minikube

只是一个K8S集群模拟器,只有一个节点的集群,只为测试用,master和worker都在一起

  • 直接用云平台Kubernetes

可视化搭建,只需简单几步就可以创建好一个集群
优点:安装简单,生态齐全,负载均衡器,存储等都给你配置好,简单操作就搞定

  • 逻辑安装(Bare Metal)

至少需要两台机器(主节点、工作节点一台),需要自己按照Kubernetes组件,配置会稍微麻烦点
可以到各个云厂商按时租用服务器,费用低,用完就销毁
缺点:配置麻烦,缺少生态支持,例如负载均衡器、云存储

miniKube

Minikube是一种轻量化的Kubernetes集群,是Kubernetes社区为了帮助开发者和学习者能够更好学习和体验k8s功能而推出的,借助个人PC的虚拟化环境就可以实现Kubernetes的快速构建启动。目前已支持在macOS、Linux、Windows平台上利用各类本地虚拟化环境作为驱动运行。
按照方法参考文档:

https://minikube.sigs.k8s.io/docs/start/

注意!需要先安装好docker
可以用exe进行安装,也可以用命令行安装

安装完可以启动集群

# 启动集群
minikube start
# 查看节点。kubectl 是一个用来跟 K8S 集群进行交互的命令行工具
kubectl get node
# 停止集群
minikube stop
# 清空集群
minikube delete --all
# 安装集群可视化 Web UI 控制台
minikube dashboard

docker里面设置镜像

添加国内镜像

{
    "experimental": false,
    "debug": true,
    "registry-mirrors": [
        "https://xxxxxx.mirror.aliyuncs.com",
        "http://hub-mirror.c.163.com"
    ]
}

安装完成minikube之后,用命令行启动minikube start
启动成功会看到

kubectl get node 查看节点

逻辑搭建

在腾讯云里面的容器服务,去买服务器,可以选最低配,master节点是腾讯云托管的,配置worker节点就行

主节点需要组件
  • docker(也可以是其他容器运行时)
  • kubectl 集群命令行交互工具
  • kubeadm 集群初始化工具
工作节点需要组件
  • docker(也可以是其他容器运行时)
  • kubelet 管理 Pod 和 容器,确保他们健康稳定运行
  • kube-proxy 网络代理,负责网络相关的工作
安装服务器及配置

创建两台服务器之后,再创建一个CVM服务器
安装好五台服务器之后

用Xshell连接到上面的三个主机

# 每个节点分别设置对应主机名
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2
# 所有节点都修改 hosts,内网ip
vim /etc/hosts
10.0.0.13 node1
10.0.0.2 node2
10.0.0.9 master

配置好之后,ping node1 (node2,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

启动 kubelet、docker,并设置开机启动(所有节点)

systemctl enable kubelet
systemctl start kubelet
systemctl enable docker
systemctl start docker

下面这部分内容可能有错误!有错的话按照下面的解决方案执行!!!!!!!

原文连接:https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/nd7yOvdY

修改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 访问到集群

注意在kubeamd init哪里可能会报错:

安装 Docker 软件
注意: lz在这里安装的最新版本docker,但由于新版本k8s已经弃用docker,所以需要安装对应版本的docker,lz是在这里安装的最新版本,然后再降低docker到可用版本。安装一定要保证docker的版本相同否则可能会出现如下报错,可以通过yum downgrade --setopt=obsoletes=0 -y docker-ce-\({version} docker-ce-selinux-\){version} containerd.io实现降级,或者参考Docker高版本降级到指定版本

把工作节点加入集群(只在工作节点跑)

kubeadm join 172.16.32.10:6443 --token xxx --discovery-token-ca-cert-hash xxx

上面的两个分割线之间可能出问题,可能会报docker版本高什么的,最终kubeadm init会报错
如果报错,可以重新按照这个配置一下:

https://www.cnblogs.com/oaoa/p/17301550.html

成功的话会生成这个,一定要保存起来,可以让其他节点加入集群

kubeadm join 10.0.0.9:6443 --token 7bq4lz.qj7e6fp72t0ydis4 --discovery-token-ca-cert-hash sha256:51b258c57b80b8c7bd9e6c372a50fd208f0af8aeea33f546b53da4b71d630692 

其他节点加入之后,可以在master上面查看节点
kubectl get node

安装网络插件,否则node是NotReady状态(主节点跑)

# 很有可能国内网络访问不到这个资源,你可以网上找找国内的源安装 flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# 如果上面的插件安装失败,可以选用 Weave,下面的命令二选一就可以了。
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
kubectl apply -f http://static.corecore.cn/weave.v2.8.1.yaml

# 更多其他网路插件查看下面介绍,自行网上找 yaml 安装
https://blog.csdn.net/ChaITSimpleLove/article/details/117809007

请注意,flannel 插件安装不上(因为网络问题),这样会导致后面名字访问服务用不了,
大家可以改用 weave 或者使用香港服务器或者寻找国内的源安装

安装完过一会就会变成ready状态

三、部署应用到集群中

首先要确定docker里面的miniKube是启动状态

在命令行里面运行

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 # 镜像

可以在一个地方建一个pod.yaml文件,在yaml文件中写入上面的内容,然后转到那个目录下执行
kubectl apply -f .\pod.yaml
kubectl get pod

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 # 镜像

建一个app.yaml文件,在yaml文件中写入上面的内容,然后转到那个目录下执行
kubectl apply -f .\app.yaml
kubectl get pod -o wide 可以看到每个节点的id

Deployment 通过 label 关联起来 Pods

# 部署应用
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

在xshell里面master主机
vim app.yaml
把deployment里的内容复制进去,可以先i,然后设置成:set paste来防止格式混乱,然后esc :wq退出

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

将 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,通过表亲test-k8s跟对应的Pod关联上
    service.yaml
apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s    # 和pod的label对应起来
  type: ClusterIP
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口

本地主机上的重新部署一下

kubectl get all
kubectl delete all --all  # 把之前部署的全部清除
kubectl apply -f ./app.yaml # 重新部署一下
kubectl apply -f ./service.yaml
kubectl get pod 
kubectl get service
kubectl get svc # 查看服务还可以用这个缩写

应用配置 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,后面会再讲到具体用法
官网文档

五、StatefuSet

什么是 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     # 要和pod对应上
  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     # 指向一个目录,不存在时自动创建

可以往数据库里面写一条测试
然后重启数据库
kubectl rollout restart statefulset mongodb
kubectl delete statefulset mongodb

更高级的抽象

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
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 --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 演示

标签:kubectl,K8S,入门,集群,test,k8s,节点,name
From: https://www.cnblogs.com/oaoa/p/17304111.html

相关文章

  • ASP.NET Core MVC 从入门到精通之接化发(二)
    随着技术的发展,ASP.NETCoreMVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NETCoreMVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NETCoreMVC系统开发的人员。 经过前两篇文章的讲解,初步了解ASP.NETCor......
  • 前端学习 node 快速入门 系列 —— 项目版权格式化
    其他章节请看:前端学习node快速入门系列项目版权格式化需求替换整个项目的版权信息,替换文件为.c和.h结尾。分析版权信息通常都在文件开头,通过是否有copyright来判断是替换版权还是新增版权实现通过node读取文件,过滤出.c、.h文件,然后用正则判断是替换版权还......
  • 小程序入门4—钉钉群机器人消息通知和钉钉工作通知
    前言在消息通知这块,钉钉可谓是玩出了花,比如工作通知、群机器人通知,还有那万恶的Ding一下。钉钉的通知不仅花样多,而且大部分渠道都支持自定义,也即可以自定义设置发送时间、发送内容,并且还支持多种样式的消息如文本、卡片、Markdown等。这篇文章我主要介绍一下常用的两类:钉钉群机......
  • Kubeadm在线安装k8s_超详细
     生产环境可以采取这种方式安装k8sv1.23.17,版本兼容很好,你的支持就是我最大的动力。服务器要求:建议最小硬件配置:2核CPU、2G内存、20G硬盘服务器最好可以访问外网,会有从网上拉取镜像需求,如果服务器不能上网,需要提前下载对应镜像并导入节点软件环境:操作系统:centos7.9_x64(mini......
  • ctfshow web入门 sql注入 171-175
    171-175同属无过滤绕过(并未对sql语句过滤,仅对查询结果过滤)重点:1、了解万能密码2、了解sql语句中字符串函数3、了解备份功能(导入/导出数据)4、蚁剑如何连接数据库web171$sql="selectusername,passwordfromuserwhereusername!='flag'andid=......
  • 56、K8S-监控机制-Prometheus-配置解析、标签管理
    Kubernetes学习目录1、配置文件1.1、配置简介1.1.1、简介Prometheus可以通过命令行或者配置文件的方式对服务进行配置。一般情况下,命令行方式一般用于不可变的系统参数配置,例如存储位置、要保留在磁盘和内存中的数据量等;配置文件用于定义与数据动态获取相关的配置选项和文件......
  • Java入门5(多态)
    多态编译时的多态:方法重载运行时的多态:动态绑定多态的三大前提类之间要有继承关系要出现方法重写父类的引用指向了子类的对象测试样例//定义Person类publicclassPerson{publicStringname;publicStringsex;publicintage;publicPerson(St......
  • 快速入门
    MPP数据库是指“大规模并行处理”(MassivelyParallelProcessing)数据库,是一种用于处理大规模数据的数据库系统。它可以处理非常大的数据集并提供快速的数据访问和处理能力。核心思想是将大型数据集分解成小的数据块,并在多个计算节点上并行处理这些块。使用共享存储架构,其中多个......
  • ST入门笔记3
    ST自动控制灯模式//之前是手动的[要求]自动模式切换5s自动[配件]m1减模式不用了只需m0m2开始停止[讲解]添加定时器(条件D0=1,tc0,50)TS定时器当前值**时间继电器一定要放在if或case语句外侧,否则就会每跑一次被清零[代码](*M0启动*)IFLDP(1,M0)THEN D0:=D0+1;END_IF;(*M2stop......
  • k8s 会把自己的ca.pem 注入到 /var/run/secrets/kubernetes.io/serviceaccount/ 目录
     k8s会把自己的ca.pem注入到/var/run/secrets/kubernetes.io/serviceaccount/目录下 生成三个文件lrwxrwxrwx1rootroot13Dec1201:56ca.crt->..data/ca.crtlrwxrwxrwx1rootroot16Dec1201:56namespace->..data/namespacelrwxrwxrwx1rootroot12D......