kubernetes(Jenkins、kubernetes核心、K8s实战-KubeSphere、)

文章目录

  • [1. Jenkins](#1. Jenkins)
    • [1.1. 概述](#1.1. 概述)
      • [1.1.1. 简单部署](#1.1.1. 简单部署)
      • [1.1.2. 自动化部署](#1.1.2. 自动化部署)
      • [1.1.3. DevOps概述](#1.1.3. DevOps概述)
      • [1.1.4. CI/CD概述](#1.1.4. CI/CD概述)
    • [1.2. jenkins介绍及安装](#1.2. jenkins介绍及安装)
      • [1.2.1. 安装](#1.2.1. 安装)
      • [1.2.2. 解锁jenkins](#1.2.2. 解锁jenkins)
      • [1.2.3. 安装推荐插件](#1.2.3. 安装推荐插件)
      • [1.2.4. 创建管理员用户](#1.2.4. 创建管理员用户)
      • [1.2.5. 升级jenkins版本](#1.2.5. 升级jenkins版本)
      • [1.2.6. 安装额外插件blue ocean](#1.2.6. 安装额外插件blue ocean)
      • [1.2.7. jenkins界面说明](#1.2.7. jenkins界面说明)
    • [1.3. 入门案例](#1.3. 入门案例)
      • [1.3.1. 自由风格任务](#1.3.1. 自由风格任务)
      • [1.3.2. 流水线任务Pipeline](#1.3.2. 流水线任务Pipeline)
      • [1.3.3. 并行化任务](#1.3.3. 并行化任务)
    • [1.4. 部署项目](#1.4. 部署项目)
      • [1.4.1. 在项目中添加流水线文件](#1.4.1. 在项目中添加流水线文件)
      • [1.4.2. 拉取项目并指定流水线文件](#1.4.2. 拉取项目并指定流水线文件)
      • [1.4.3. 编写流水线查看当前位置](#1.4.3. 编写流水线查看当前位置)
      • [1.4.4. 使用jenkins-docker部署](#1.4.4. 使用jenkins-docker部署)
        • [1. 安装jenkins的docker插件](#1. 安装jenkins的docker插件)
        • [2. 下载maven镜像并生成java包](#2. 下载maven镜像并生成java包)
        • [3. 制作docker镜像并完成部署](#3. 制作docker镜像并完成部署)
        • [4. 完整的jenkinsfile内容](#4. 完整的jenkinsfile内容)
  • [2. kubernetes核心](#2. kubernetes核心)
    • [2.1. 为什么要k8s](#2.1. 为什么要k8s)
      • [2.1.1. 项目部署的问题](#2.1.1. 项目部署的问题)
      • [2.1.2. k8s有什么用](#2.1.2. k8s有什么用)
    • [2.2. 架构组件(了解)](#2.2. 架构组件(了解))
      • [2.2.1. 控制平面组件(Master)](#2.2.1. 控制平面组件(Master))
      • [2.2.2. 节点组件(Node)](#2.2.2. 节点组件(Node))
      • [2.2.3. 工作流程](#2.2.3. 工作流程)
    • [2.3. k8s安装](#2.3. k8s安装)
      • [2.3.1. 环境要求](#2.3.1. 环境要求)
      • [2.3.2. 基础环境](#2.3.2. 基础环境)
      • [2.3.3. 统一下载k8s镜像](#2.3.3. 统一下载k8s镜像)
      • [2.3.4. 克隆出三台虚拟机修改ip和主机名](#2.3.4. 克隆出三台虚拟机修改ip和主机名)
      • [2.3.5. 主节点安装](#2.3.5. 主节点安装)
      • [2.3.6. 添加工作节点](#2.3.6. 添加工作节点)
      • [2.3.7. k8s挂了如何启动](#2.3.7. k8s挂了如何启动)
      • [2.3.8. 安装dashboard](#2.3.8. 安装dashboard)
    • [2.4. 名称空间(namespace)](#2.4. 名称空间(namespace))
      • [2.4.1. 命令行](#2.4.1. 命令行)
      • [2.4.2. yaml语法](#2.4.2. yaml语法)
    • [2.5. Pod](#2.5. Pod)
      • [2.5.1. 命令行](#2.5.1. 命令行)
      • [2.5.2. yaml语法](#2.5.2. yaml语法)
      • [2.5.3. Pod应用访问测试](#2.5.3. Pod应用访问测试)
      • [2.5.4. pause容器作用](#2.5.4. pause容器作用)
    • [2.6. 工作负载](#2.6. 工作负载)
      • [2.6.1. Deployment无状态负载](#2.6.1. Deployment无状态负载)
      • [2.6.2. StatefulSet有状态负载](#2.6.2. StatefulSet有状态负载)
      • [2.6.3. DaemonSet守护负载](#2.6.3. DaemonSet守护负载)
      • [2.6.4. ReplicaSet副本](#2.6.4. ReplicaSet副本)
      • [2.6.5. Labels标签](#2.6.5. Labels标签)
    • [2.7. Service](#2.7. Service)
      • [2.7.1. ClusterIP](#2.7.1. ClusterIP)
      • [2.7.2. NodePort](#2.7.2. NodePort)
      • [2.7.3. 通过label进行负载均衡](#2.7.3. 通过label进行负载均衡)
    • [2.8. Ingress网关](#2.8. Ingress网关)
      • [2.8.1. 下载安装](#2.8.1. 下载安装)
      • [2.8.2. 使用案例](#2.8.2. 使用案例)
    • [2.9. 存储卷(Volume)](#2.9. 存储卷(Volume))
      • [2.9.1. PV&PVC](#2.9.1. PV&PVC)
      • [2.9.2. 制备PV](#2.9.2. 制备PV)
      • [2.9.3. PVC声明及绑定](#2.9.3. PVC声明及绑定)
      • [2.9.4. Pod使用PVC](#2.9.4. Pod使用PVC)
    • [2.10. 配置](#2.10. 配置)
      • [2.10.1. ConfigMap](#2.10.1. ConfigMap)
        • [1. 初始化CM](#1. 初始化CM)
        • [2. 在Pod中使用CM](#2. 在Pod中使用CM)
        • [3. 演示动态同步](#3. 演示动态同步)
      • [2.10.2. Secret](#2.10.2. Secret)
    • [2.11. 小结](#2.11. 小结)
  • [3. K8s实战-KubeSphere](#3. K8s实战-KubeSphere)
    • [3.1. K8s生态](#3.1. K8s生态)
    • [3.2. helm](#3.2. helm)
    • [3.3. KubeSphere](#3.3. KubeSphere)
      • [3.3.1. 安装](#3.3.1. 安装)
      • [3.3.2. Console界面说明](#3.3.2. Console界面说明)
      • [3.3.3. 部署一个nginx](#3.3.3. 部署一个nginx)
        • [1. 持久卷声明](#1. 持久卷声明)
        • [2. nginx部署](#2. nginx部署)
        • [3. 日常维护](#3. 日常维护)
        • [4. 通过kubectl访问](#4. 通过kubectl访问)
        • [5. 通过service暴露](#5. 通过service暴露)
        • [6. 应用路由](#6. 应用路由)
      • [3.3.4. 多租户](#3.3.4. 多租户)
      • [3.3.5. 部署WordPress](#3.3.5. 部署WordPress)
        • [1. 创建密钥(secret)](#1. 创建密钥(secret))
        • [2. 创建持久卷声明](#2. 创建持久卷声明)
        • [3. 搭建MySQL服务](#3. 搭建MySQL服务)
        • [4. 搭建wd应用服务](#4. 搭建wd应用服务)
        • [5. 对外暴露wd服务](#5. 对外暴露wd服务)
        • [6. 路由规则及网关](#6. 路由规则及网关)
      • [3.3.6. MySQL扩展](#3.3.6. MySQL扩展)

1. Jenkins

Jenkins是一个开源的、可扩展的持续集成、交付、部署(软件/代码的编译、打包、部署)的基于web界面的平台。通过Jenkins可以实现自动化的持续集成和持续部署。

官网:https://www.jenkins.io/

中文官网:https://www.jenkins.io/zh/

官方文档:https://jenkins.io/zh/doc/

1.1. 概述

1.1.1. 简单部署

手动部署

shell 复制代码
nohup java -jar -Xmx500m -Xms500m -XX:+HeapDumpOnOutOfMemoryError xxx.jar >xxx.log 2>&1 & 
# 1:表示stdout标准输出 2:表示stderr标准错误 &:等效于标准输出
# 2>&1,意思是错误输出等同于标准输出。把标准输出和错误输出全部导入日志xxx.log里。

创建没有任务的容器 不停止

sh 复制代码
docker run -d  --name 容器名称  -p 端口号:端口号 镜像名称  sleep infinity

1.1.2. 自动化部署

部署过程的每一个步骤都自动化,可以带来包括效能在内的显著的好处。你可以手工做这些事情,但是很耗时。二者的生产率差异真的很大。

一般部署过程涉及到应用、环境和部署流程主要的模型。

自动应用部署也改进了软件的总体质量。在整个生命周期(包括部署在内)都使用好的工具,能够把人的干预最小化,质量就可预测。

1.1.3. DevOps概述

DevOps:Development和Operations的组合词,它是一种重视 软件开发人员(Dev)IT运维技术人员(Ops) 之间沟通合作的文化、运动或惯例。

​ 在最开始的编程工作中,开发人员就是运维人员。随着软件开发复杂度不断增加,技术团队角色逐渐 增多(如开发工程师、运维工程师、测试工程师等),这种情况就导致组织里充斥着「部门墙」,大家 都自行其是,形成了一种天然壁垒。在非DevOps开发运维中,开发员创建代码,在他们自己的系统上对其进行测试,通过QA【质量保证部门】运行并将其推送到运行维护操作中。由于运维(Ops)团队无法承受对其系统进行频繁更改,因此新代码通常并不兼容。因此运维将代码发回给开发员而他们必须又得从头开发,然后循环往复给两个团队带来了相互隔离的现象,为此,没有太多关于是什么原因导致代码不兼容的交流而带来各司其职不负责任的结果。

​ DevOps专注于消除开发与运维团队之间的这种隔阂,从而在不影响质量的情况下促进更快的交付。 DevOps消除了将开发和运维团队限制在孤岛中的情况。DevOps也是一种开发哲学理念,它使整个团队和组织的工作变得更轻松。DevOps还需要协作才能成功而不仅是开发和运维,QA和安全团队通常也需要将自己集成到其中,以实现快速交付完美的软件产品。

1.1.4. CI/CD概述

CI/CD是DevOps把理论变为现实的核心有效方法与方案。是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。

CI/CD 的核心概念:

  1. 持续集成(CI,Continuous Integration):对应开发生命周期的后期阶段,保证代码质量、降低测试成本。

    开发人员将会频繁地向主干提交代码。这些新提交的代码在最终合并到主干前,需要经过编译和自动化测试流进行验证。持续集成过程中很重视自动化测试验证结果,以保障所有的提交在合并主线之后的质量问题,对可能出现的一些问题进行预警。

  2. 持续部署(CD,Continuous Deployment):每一处提交都会自动触发发布流,所有的变更都会被自动部署到生产环境中。

    在CD环境中,通过自动化的构建、测试和部署循环来快速交付高质量的产品。某种程度上代表了一个开发团队工程化的程度,任何修改通过了所有已有的工作流就会直接和客户见面,只有当一个修改在工作流中构建失败才能阻止它部署到产品线。

    加速了与客户的反馈循环,但是会给团队带来压力,因为不再有"发布日"了。开发人员的修改在提交的几分钟后就上线了。

  3. 持续交付(CD,Continuous Delivery):让软件的构建、测试与释出变得更快以及更频繁。

    它可以让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以释出的状况。

整个CI/CD的过程完全可以实现自动化,开发人员只需要将代码推送到远程仓库,后期的所有阶段都可以靠自动化完成。

1.2. jenkins介绍及安装

1.2.1. 安装

sh 复制代码
# 创建数据及配置目录
mkdir -p /opt/jenkins

# 运行jenkins容器
docker run -d -u root --name jenkins \
	-p 8080:8080 -p 50000:50000 \
	-v /opt/jenkins/conf/:/var/jenkins_home \
	-v /etc/localtime:/etc/localtime \
	-v /opt/jenkins/data:/data \
	-v /var/run/docker.sock:/var/run/docker.sock \
  	-v $(which docker):/usr/bin/docker \
	--restart=always \
	jenkins/jenkins

# 修改插件源
cd /opt/jenkins/conf
vim hudson.model.UpdateCenter.xml
# 将文件中的url地址改成:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

# 重启jenkins容器
docker restart jenkins

浏览器访问:http://你的虚拟机ip地址:8080/

1.2.2. 解锁jenkins

根据提示到对应的映射目录下查看解锁密码:cat /opt/jenkins/conf/secrets/initialAdminPassword

1.2.3. 安装推荐插件

选择 安装推荐的插件 ,很有可能显示下载失败!

直接先跳过

1.2.4. 创建管理员用户

开始使用jenkins!

1.2.5. 升级jenkins版本

点击 Manage Jenkins ,可以看到插件安装失败的原因是jenkins版本太低导致的。

滚动条往下拉,可以看到:

点击自动升级jenkins版本!

升级完成后,点击重启,重启成功之后,重新登录到jenkins,可以看到插件都正常了

1.2.6. 安装额外插件blue ocean

blue ocean 插件为例演示额外插件的安装:该插件是构建任务的ui页面


1.2.7. jenkins界面说明

Jenkins主界面:

我的视图:展示的是当前用于对jenkins可操作的权限

blue Occean:查看构建历史的漂亮界面

1.3. 入门案例

1.3.1. 自由风格任务

  1. 创建自由风格的构建任务

  2. 指定构建过程要执行的操作

  3. 保存好之后,打开blue ocean菜单,执行任务

  4. 点击历史记录可以看到执行效果:

1.3.2. 流水线任务Pipeline

之前采用Jenkins的自由风格构建的项目,每个步骤流程都要通过不同的方式设置,并且构建过程中整体流程是不可见的,无法确认每个流程花费的时间,并且问题不方便定位问题。

Jenkins的Pipeline可以让项目的发布整体流程可视化,明确执行的阶段,可以快速的定位问题。并且整个项目的生命周期可以通过一个Jenkinsfile文件管理,而且Jenkinsfile文件是可以放在项目中维护。

接下来,创建一个流水线任务,并指定流水线任务脚本:

还可以查看流水线语法,流水线语法如下:

json 复制代码
pipeline {  //开始一个流水线
    agent any  //任何代理都可以执行这个流水线(集群【主+从jenkin[代理节点]】)

    stages {  //阶段s
        stage('拉取代码') { //每个阶段
            steps { //步骤
                echo '拉取代码完成'
                sh 'pwd'
            }
        }
        stage('编译构建') { 
            steps {
                echo '编译构建'
                sh 'ls /'
            }
        }
        stage('单元测试') {
            steps {
                echo '单元测试'
            }
        }

        stage('制作镜像') {
            steps {
                echo '制作镜像'
            }
        }
        stage('发布部署') {
            steps {
                echo '发布部署'
            }
        }
    }
}

运行效果:

1.3.3. 并行化任务

groovy 复制代码
stage('代码质量分析') { //每个阶段
    parallel{
        stage('Branch A'){
            steps {
                echo '代码质量分析--商品'
                sh 'echo'
            }
        }
        stage('Branch B'){
            steps {
                echo '代码质量分析--订单'
                sh 'echo'
            }
        }
    }
}
stage('单元测试') { //每个阶段
    parallel{
        stage('Branch A'){
            steps {
                echo '单元测试--商品接口'
            }
        }
        stage('Branch B') {
            steps {
                echo '单元测试--订单接口'
            }
        }
    }

}

执行效果:

1.4. 部署项目

1.4.1. 在项目中添加流水线文件

在项目中创建deploy文件夹,并添加jenkinsfile文件,添加内容,推送到git远程仓库。

文件内容如下:

json 复制代码
pipeline {
    agent any
    stages {
        stage('test') {
            steps {
                echo 'hello'
            }
        }
    }
}

1.4.2. 拉取项目并指定流水线文件

创建流水线任务:

保存并执行流水线任务。

1.4.3. 编写流水线查看当前位置

修改jenkinsfile脚本,并推送到远程仓库

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('拉取code') {
            //查看当前所在的位置
            steps {
                sh 'pwd'
                sh 'ls -l'
            }
        }
    }
}

重新执行jenkins任务,效果如下:

1.4.4. 使用jenkins-docker部署

1. 安装jenkins的docker插件

安装完成之后重启,只要在系统管理最后看到docker代表安装成功:

流水线语法中也多了:

2. 下载maven镜像并生成java包

在项目的deploy目录下创建settings.xml文件,文件内容如下:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <localRepository>/mvn/repository</localRepository>
    <mirrors>
        <mirror>
            <id>nexus-aliyun</id>
            <mirrorOf>central</mirrorOf>
            <name>Nexus aliyun</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
        </mirror>
    </mirrors>
    <profiles>
        <profile>
            <id>jdk-17</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>17</jdk>
            </activation>
            <properties>
                <maven.compiler.source>17</maven.compiler.source>
                <maven.compiler.target>17</maven.compiler.target>
                <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
            </properties>
        </profile>
    </profiles>
</settings>

在项目jenkinsfile中添加以下阶段,然后提交到远程仓库

groovy 复制代码
stage('项目打包') {
    steps {
        //步骤  mvn clean package
        sh 'echo 项目正在打包'
        //下载maven镜像  并指定将容器下载的jar包挂载到本地/mvn/repository目录下
        withDockerContainer(args: '-v /mvn/repository:/mvn/repository', image: 'maven:3.8.5-openjdk-17') {
            //在maven中运行以下命令
            sh 'mvn -v'
            sh 'ls -l'
            //-s "settings.xml"指定maven使用 settings.xml配置文件
            // 跳过测试打包项目
            sh 'mvn -s "deploy/settings.xml" clean package  -DskipTest' 
            sh 'ls -l target'
        }
    }
}

执行jenkins任务,生成jar包:第一次执行需要下载maven依赖,可能需要很长时间

3. 制作docker镜像并完成部署

在项目deploy下创建Dockerfile:

dockerfile 复制代码
# 基于openjdk:17镜像创建新镜像
FROM openjdk:17
# 镜像作者
MAINTAINER atguigu
COPY target/*.jar /demo.jar
# 声明需要暴露的端口
EXPOSE 10010
# 执行命令运行jar包(也可以使用RUN)
ENTRYPOINT ["java" ,"-jar" ,"/demo.jar"]

语法说明:基于上面的Dockerfile和打好的target目录下的jar包执行以下命令可以创建镜像

docker build -f Dockerfile -t='demo:v1.0' .

jenkinsfile添加下面参数化脚本:

groovy 复制代码
parameters { //参数化构建
    string(name: 'verNo', defaultValue: 'v1.0', description: '输入此次发布版本?')
}

jenkinsfile添加下面阶段:

groovy 复制代码
stage('制作镜像') {
    steps {
        sh 'echo 项目正在部署'
        sh 'ls -al'
        sh 'ls -al target'
        sh "docker build -f deploy/Dockerfile -t demo:${params.verNo} ."
        sh 'docker images|grep demo'
    }
}
stage('项目部署') {
    steps {
        sh 'echo 项目正在部署'
        sh "docker run -p 10010:10010 --restart=always -d --name demo demo:${params.verNo}"
    }
}

运行jenkins任务,完成部署:

在虚拟机中查看容器:

4. 完整的jenkinsfile内容
groovy 复制代码
pipeline {
    agent any

    parameters { //参数化构建
        string(name: 'verNo', defaultValue: 'v1.0', description: '输入此次发布版本?')
    }

    stages {
        stage('拉取code后当前所在位置') {
            steps {
                sh "pwd"
                sh "ls -l"
            }
        }
        stage('项目打包') {
            steps {
                //步骤  mvn clean package
                sh 'echo 项目正在打包'
                //下载maven镜像  并指定将容器下载的jar包挂载到本地/mvn/repository目录下
                withDockerContainer(args: '-v /mvn/repository:/mvn/repository', image: 'maven:3.8.5-openjdk-17') {
                    //在maven中运行以下命令
                    sh 'mvn -v'
                    sh 'ls -l'
                    //-s "settings.xml"指定maven使用 settings.xml配置文件
                    // 跳过测试打包项目
                    sh 'mvn -s "deploy/settings.xml" clean package  -DskipTest'
                    sh 'ls -l target'
                }
            }
        }
        stage('制作镜像') {
            steps {
                sh 'echo 项目正在部署'
                sh 'ls -al'
                sh 'ls -al target'
                sh "docker build -f deploy/Dockerfile -t demo:${params.verNo} ."
                sh 'docker images|grep demo'
            }
        }
        stage('项目部署') {
            steps {
                sh 'echo 项目正在部署'
                sh "docker run -p 10010:10010 --restart=always -d --name demo demo:${params.verNo}"
            }
        }
    }
}

2. kubernetes核心

Kubernetes,也称为K8s,是一个用于自动化容器化应用程序部署、扩展和管理的开源系统。

它将组成应用程序的容器分组为逻辑单元(Pod),以便于管理和发现。Kubernetes建立在谷歌15年的生产工作负载运行经验之上,并结合了社区中最好的想法和实践。

2.1. 为什么要k8s

2.1.1. 项目部署的问题

传统部署方式带来的问题:

  1. 操作繁琐,特别是服务器较多的情况下

  2. 难以合理的分配服务器资源,包括:内存、硬盘、CPU、GPU等

  3. 权限分配问题:不同的服务器和服务,不同用户需要不同的权限

  4. 无法弹性伸缩:用户的访问量具有不可预测性的特点,如何实时根据用户访问量实时调整资源

  5. 健康监测:需要不同的检测工具、引入不同的手段监控不同类型的应用

  6. 复杂的网络拓扑图:域名分配、网关集群、微服务、中间件,他们的关系错综复杂

    。。。。

总之,传统的部署方式存在一系列的难题。

2.1.2. k8s有什么用

Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在k8s中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。

K8s的作用包括:

  1. 自动化部署和管理容器化应用程序:K8s可以帮助开发团队快速、自动地部署和管理容器化应用程序,减少手动操作的工作量。

  2. 横向扩展和弹性伸缩:K8s可以根据应用程序的负载情况,自动扩展或收缩容器实例的数量,实现弹性伸缩,提高应用程序的可伸缩性。

  3. 服务发现和负载均衡:K8s提供了内置的服务发现和负载均衡功能,可以自动管理应用程序之间的通信和负载均衡,简化了微服务架构的部署和管理。

  4. 自动完成装箱计算:K8s允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,K8s可以做出更好的决策来管理容器的资源。

  5. 自我修复:K8s重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并确保没有停机时间。

  6. 灵活的扩展:K8s提供了丰富的插件和扩展机制,可以与各种外部系统和工具进行集成。无论是监控系统、日志收集工具还是自动化运维平台,都可以与K8s紧密配合,实现更高级的功能和管理能力。

  7. 开源生态:K8s是一个开源项目,拥有庞大的社区支持。我们可以从社区中获得丰富的资源和经验分享,解决问题时也能够快速找到帮助和支持。

  8. 密钥与配置管理:K8s允许你存储和管理敏感信息,例如密码、OAuth令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

总的来说,K8s可以帮助开发团队更高效地部署和管理容器化应用程序,提高应用程序的可靠性、可伸缩性和性能。

2.2. 架构组件(了解)

一个kubernetes集群主要是由N个控制节点(master)、N个**工作节点(node)**构成,每个节点上都会安装不同的组件。

2.2.1. 控制平面组件(Master)

英文:Control Plane Components

控制平面组件对集群作出全局决策(例如:调度),以及检测和响应集群事件(例如:当部署的副本不满足时启动新的pod)。

控制平面组件可以在集群中的任何机器上运行。但是,为了简单起见,设置脚本通常在同一台机器上启动所有控制平面组件,并且不要在此机器上运行用户容器。

控制平面组件主要包括:

  1. kube-apiserver:API server是控制平面的前端,用于暴漏k8s API。kube-apiserver是Kubernetes API server的主要实现,采用水平化设计(通过部署多个实例进行伸缩,并在这些实例之间平衡流量)

  2. etcd:兼具一致性和高可用性的键值数据库,用于保存 Kubernetes 所有集群数据的备份数据库。如果您的Kubernetes集群使用etcd作为其备份存储,请确保您有数据备份计划。

  3. kube-scheduler:用于监视新创建的没有指定节点的Pod,并选择节点供其运行。

    调度决策考虑的因素包括单机和集群的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。

  4. kube-controller-manager:运行控制器管理器。从逻辑上讲,每个控制器都是一个单独的进程,但为了降低复杂性,它们都被编译成一个二进制文件,并在一个进程中运行。

    这些控制器包括:

    • 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应
    • 任务控制器(Job controller): 监测一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
    • 端点切片控制器(Endpoints Controller): 填充端点切片(Endpoints)对象(即加入 Service 与 Pod)
    • 服务帐户控制器(ServiceAccount controller): 为新的命名空间创建默认帐户
  5. cloud-controller-manager :云控制器管理器,一个嵌入云特定控制逻辑的组件。云控制器管理器允许您将集群链接到云提供商的API,并将与该云平台交互的组件仅与自己集群交互的组件分离。如果您在自己的场地上运行K8s,或者在自己电脑内的学习环境中运行,则集群不需要云控制器管理器。

    与运行控制器管理器一样,云控制器管理器将几个逻辑独立的控制循环组合成一个二进制文件,作为一个进程运行。

    下面的控制器都包含对云平台驱动的依赖:

    • 节点控制器(Node Controller): 用于检查云供应商,以确定节点在停止响应后是否已在云中删除
    • 路由控制器(Route Controller): 用于在底层云基础设施中设置路由
    • 服务控制器(Service Controller): 用于创建、更新和删除云提供商负载均衡器

2.2.2. 节点组件(Node)

节点组件在每个节点上运行,维护运行的pod并提供Kubernetes运行时环境。

  1. kubelet:在群集中每个节点上运行的代理。它确保容器在Pod中运行。

    kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。

  2. kube-proxy:是在集群中的每个节点上运行的网络代理。维护节点上的网络规则,允许通过集群内外的网络会话与Pods进行网络通信。

2.2.3. 工作流程

新应用部署流程:

  1. Controller Manager 把这次应用部署详细信息(用哪个镜像、启动几个容器、容器名、CPU、内存最大限制多少...)交给 API Server

  2. API Server把数据保存到 etcd

  3. Scheduler 找 API Server 要到 etcd 中最新要部署的应用信息

  4. Scheduler 进行资源调度计算,算出应用应该合适的部署到哪个 Node

  5. Scheduler 把这次调度计算结果 交给 API Server,让他保存到 etcd

  6. Kubelet 和 API Server 保持长链接的监听状态

  7. API Server 上次保存了调度信息后,会通知具体Node节点的 Kubelet

  8. Kubelet 收到这次应用部署信息, Kubelet 按照要求,先下载镜像、然后启动容器

  9. 启动的应用的 IP 信息 注册到 Kube-Proxy;其他Node 的 kube-proxy同步数据

  10. Kubelet要监控自己Node的每个应用状态。 如果应用故障由 Kubelet进行重启

k8s应用自愈的处理过程:

2.3. k8s安装

k8s官方提供了多种部署方式。

学习环境部署方式包括:

  • kind:可以让您在本地计算机上运行Kubernetes。此工具要求您安装Docker或Podman。
  • minikube:类似于kind,minikube是一个可以让您在本地运行Kubernetes的工具。minikube在您的个人计算机(包括Windows、macOS和Linux PC)上运行一个单节点(all-in-one)或多节点的本地Kubernetes集群,以便您可以试用Kubernete,或用于日常开发工作。
  • kubeadm:创建和管理Kubernetes集群。它执行必要的操作,以便以用户友好的方式启动并运行最小可行、安全的集群。

生产环境部署方式包括:

  • kubeadmin
  • kops(Kubernetes Operations)用于创建、升级和管理生产级、高可用的 Kubernetes 集群,是建立并运行生产级 Kubernetes 集群的最简单方法。文档地址:https://kops.sigs.k8s.io/
  • Kubespray:支持生产环境的集群维护,通过Ansible来管理部署动作,提供了多种参数来满足定制化的需求。文档地址:https://kubespray.io/#/

kubectl:Kubernetes命令行工具,允许您针对Kubernete集群运行命令。您可以使用kubectl来部署应用程序、检查和管理集群资源以及查看日志。

kubelet:在集群中所有机器上运行的组件,用于启动pod和容器及健康监测。

为了更好的了解和学习k8s,咱们先使用kubeadmin来安装k8s v1.23.x,v1.24开始k8s不再直接支持docker(需要cri-docker插件)

2.3.1. 环境要求

服务器要求:

  1. 兼容的Linux主机。Kubernetes项目为基于Debian和Red Hat的Linux发行版以及那些没有包管理器的发行版提供了通用说明。

  2. 每台机器至少2 GB RAM

  3. 2核及以上CPU

  4. 集群中相关服务器可以网络互通

  5. 关闭防火墙

  6. 安装docker

    sh 复制代码
    # 安装docker:如已安装,则可略过。。。。
    yum -y install docker-ce
    # 设置开机启动   启动docker
    systemctl enable docker
    systemctl start docker

2.3.2. 基础环境

sh 复制代码
# 关闭防火墙
systemctl stop firewalld 
systemctl disable firewalld 

# 将 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

# 安装kubelet、kubeadm、kubectl
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
exclude=kubelet kubeadm kubectl
EOF

# 安装并使kubelet自动重启
sudo yum install -y kubelet-1.23.17 kubeadm-1.23.17 kubectl-1.23.17 --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
# 通过命令行可以看到kubelet每隔几秒钟就会重启,陷入了一个等待 kubeadm 指令的死循环
systemctl status kubelet
journalctl -u kubelet

kubelet 每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环。

2.3.3. 统一下载k8s镜像

sh 复制代码
# 查看k8s组件的镜像列表及版本
kubeadm config images list
# 如果需要下载指定版本
kubeadm config images list --kubernetes-version 1.23.17

# 拉取相关镜像
kubeadm config images pull
# 由于国内墙的问题会导致拉取失败

制作k8s拉取镜像的脚本:

sh 复制代码
vim pull_k8s_images.sh

内容如下:

sh 复制代码
#!/bin/bash

KUBE_VERSION=v1.23.17
KUBE_PAUSE_VERSION=3.6
ETCD_VERSION=3.5.6-0
DNS_VERSION=v1.8.6

GCR_URL=k8s.gcr.io
# 阿里云第三方用户上传的镜像,镜像比较多
# 或者使用:registry.cn-hangzhou.aliyuncs.com/google_containers
DOCKERHUB_URL=registry.cn-hangzhou.aliyuncs.com/google_containers

images=(
kube-proxy:${KUBE_VERSION}
kube-scheduler:${KUBE_VERSION}
kube-controller-manager:${KUBE_VERSION}
kube-apiserver:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd:${ETCD_VERSION}
coredns:${DNS_VERSION}
)

for imageName in ${images[@]} ; do
  docker pull $DOCKERHUB_URL/$imageName
done

执行脚本:

sh 复制代码
# 授予执行权限
chmod +x ./pull_k8s_images.sh
# 执行
./pull_k8s_images.sh

2.3.4. 克隆出三台虚拟机修改ip和主机名

点击"克隆" --> "下一页" --> "下一页" --> 选择"创建完整克隆"点击"下一页" --> 录入"虚拟机名称",点击完成。

逐个启动每一台虚拟机,修改网卡的ip地址:三台虚拟机我这里采用的是100、101、102

vim /etc/sysconfig/network-scripts/ifcfg-ens33

逐个修改主机名:我这里分别设置为node-1、node-2、node-3

sh 复制代码
hostnamectl set-hostname node-1
# 最后重启
reboot

2.3.5. 主节点安装

下面操作只在master节点操作,本地已经有需要的依赖了,但是仍然会去拉取镜像。而如果把image-repository参数加上则可以跳过,直接使用已存在的镜像

sh 复制代码
# 在所有节点上添加master域名映射,前面是master节点的ip,后面是域名建议写节点名
echo "192.168.30.100  cluster-endpoint" >> /etc/hosts

kubeadm init \
	--kubernetes-version=v1.23.17 \
	--control-plane-endpoint=cluster-endpoint \
	--pod-network-cidr=172.32.0.0/16 \
	--service-cidr=10.96.0.0/16 \
	--apiserver-advertise-address=192.168.30.100 \
	--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers

#注意:三个ip不重叠
# --control-plane-endpoint和master域名一致

执行成功,会出现以下提示:最好把提示信息复制出来

sh 复制代码
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:  1.用户及权限配置

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:   2.网络
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:	3.添加主节点

  kubeadm join cluster-endpoint:6443 --token jl2h8m.9l6xs4m4vd3ioxad \
	--discovery-token-ca-cert-hash sha256:9ab4f4878e7ab9153b08bb241f7486fd75da2500fbf425e9c0431363e097177d \
	--control-plane 

Then you can join any number of worker nodes by running the following on each as root:  4.添加工作节点

kubeadm join cluster-endpoint:6443 --token jl2h8m.9l6xs4m4vd3ioxad \
	--discovery-token-ca-cert-hash sha256:9ab4f4878e7ab9153b08bb241f7486fd75da2500fbf425e9c0431363e097177d 

按照提示,完成一下操作:

  1. 添加用户权限:

    sh 复制代码
    # 添加配置并赋予权限
    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
    # 以上操作完成,查看集群下的节点列表
    kubectl get nodes
  2. 配置pod网络:

    参照地址:https://kubernetes.io/docs/concepts/cluster-administration/addons/

    sh 复制代码
    # 下载calico组件到当前目录
    curl https://docs.projectcalico.org/v3.20/manifests/calico.yaml -O
    # 修改calico.yaml配置文件,打开注释并配置ip地址,要和第一步中的--pod-network-cidr=172.32.0.0/16一致
    # 可以/192.168进行搜索
    vim calico.yaml
    # 应用calico组件:bubectl apply -f 使用指定的yaml配置文件部署应用
    kubectl apply -f calico.yaml
    # 查看运行中的应用,类似于docker ps
    kubectl get pod -A


    几分钟之后全部处于running状态,说明都已经初始化成功了。主节点状态也处于ready状态了:

2.3.6. 添加工作节点

直接复制《主节点安装》章节中,初始化k8s时的提示命令行,在工作节点上执行:

sh 复制代码
# 添加主节点
kubeadm join cluster-endpoint:6443 --token jl2h8m.9l6xs4m4vd3ioxad \
--discovery-token-ca-cert-hash sha256:9ab4f4878e7ab9153b08bb241f7486fd75da2500fbf425e9c0431363e097177d \
--control-plane 

# 添加工作节点
kubeadm join cluster-endpoint:6443 --token jl2h8m.9l6xs4m4vd3ioxad \
--discovery-token-ca-cert-hash sha256:9ab4f4878e7ab9153b08bb241f7486fd75da2500fbf425e9c0431363e097177d 
    
# 生成新令牌
kubeadm token create --print-join-command

添加工作节点:

按照上图最后的提示,在主节点上执行:kubectl get nodes查看,可能需要等待一分钟才会由NotReady进入Ready状态

2.3.7. k8s挂了如何启动

k8s集群挂了如何启动:通过kubelet,本质就是一个系统服务

sh 复制代码
systemctl enable  kubelet --now
# 或者
systemctl start kubelet

2.3.8. 安装dashboard

sh 复制代码
# 部署dashboard客户端。如果拒绝连接,可以先下载下来,再上传到linux。或者使用vi指令,把内容copy进去。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
# 查看应用安装状态
kubectl get pod -A

# 设置访问端口  type: ClusterIP 改为 type: NodePort
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
# 查看端口号
kubectl get svc -A |grep kubernetes-dashboard

# 创建用户
kubectl create serviceaccount dashboard-admin -n kube-system
# 用户授权
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
# 获取访问令牌
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

具体执行细节如下:

可能需要等待几分钟。

设置端口号:

查看端口号:

设置好端口号之后,访问测试

浏览器不允许访问:可以使用火狐浏览器

生成访问token:

把token复制到浏览器即可访问

2.4. 名称空间(namespace)

名称空间,用来对集群资源进行隔离划分。默认只隔离资源,不隔离网络

2.4.1. 命令行

sh 复制代码
# 创建名称空间:ns 也可以写全称 namespace
kubectl create ns helloworld
# 删除名称空间
kubectl delete ns helloworld
# 查看名称空间
kubectl get ns

2.4.2. yaml语法

sh 复制代码
# 查看语法
[root@node-1 ~]# kubectl create ns helloworld -oyaml 
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2024-03-27T03:47:07Z"
  labels:
    kubernetes.io/metadata.name: helloworld
  name: helloworld
  resourceVersion: "5499"
  uid: a14cbaef-2e48-4805-88ab-fda742e3f89f
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
  
# 基于yaml创建名称空间
vim helloworld.yaml
# 内容如下:
apiVersion: v1 # 固定写法,k8s版本
kind: Namespace # 资源类型
metadata:
  name: helloworld # 资源名称
  
# 创建应用
kubectl apply -f helloworld.yaml
# 删除应用
kubectl delete -f helloworld.yaml

dashboard客户端效果:

2.5. Pod

pod是k8s中最小的可部署单元,一个pod是一组一个或者多个共享存储或者网络资源的容器。简而言之,pod是一组容器(一个pause容器和多个应用容器),而容器单指一个容器(docker)。

Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个:

  • 可以以它为依据,评估整个Pod的健康状态
  • 可以在根容器上设置ip地址,其他容器都用此ip(Pod ip),以实现Pod内部的网络通信

同一个pod不能有两个端口号相同的容器。例如:一个pod中部署两个nginx,除非自己制作一个nginx镜像把端口号改掉,否则就会端口号冲突,导致第二个容器启动失败。

2.5.1. 命令行

sh 复制代码
# 查看帮助
kubectl run --help

# 创建一个包含nginx容器的pod,默认名称空间是default
kubectl run mynginx --image=nginx
# 在指定名称空间下创建pod
kubectl run mynginx --image=nginx -n helloworld

# 查看default名称空间的Pod
kubectl get pod
# 在指定名称空间下查看pod
kubectl get pod -n helloworld
# 查看所有名称空间的pod
kubectl get pods -A

# 查看一个pod的具体信息
kubectl describe pod 你自己的Pod名字
# 删除,删除多个以空格分割
kubectl delete pod Pod名字

# 进入pod,如果一个pod只有一个容器-c {container} 可省略
kubectl exec {podname} -n {namespace} -c {container} -- bash

2.5.2. yaml语法

yml语法提示:

sh 复制代码
kubectl explain pod.spec.containers

查看yaml语法:

sh 复制代码
[root@node-1 ~]# kubectl run mynginx --image=nginx -n hello-world --dry-run=client -oyaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: mynginx
  name: mynginx
  namespace: hello-world
spec:
  containers:
  - image: nginx
    name: mynginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

# 根据这个模板就可以自己写一个yaml文件了
vi pod.yaml
# 内容如下:
apiVersion: v1
kind: Pod
metadata:
  name: myapp
  namespace: helloworld
spec:
  containers:
  - image: nginx
    name: nginx
  - image: tomcat
    name: tomcat
  restartPolicy: Always
status: {}

2.5.3. Pod应用访问测试

访问测试:

  1. 虚拟机中通过 pod的ip+容器内应用的port 访问pod内的某个容器应用
  2. Pod内的容器之间可以通过 localhost:port 或者 Pod的ip:port 相互访问
  3. 不同Pod之间通过 pod的ip:port 相互访问
  4. 宿主机的浏览器无法访问Pod内的应用

虚拟机内可以访问pod容器中的nginx:

在同一个pod内的不同容器中,可以通过localhost相互访问:

不同pod之间,可以通过ip地址进行访问

2.5.4. pause容器作用

管理并监控pod中的容器,并提供自愈能力

如果杀掉docker中的nginx容器,pause容器会自动帮我们创建新的nginx容器

2.6. 工作负载

您的应用程序作为Pods中的容器运行;然而,管理单个Pod将是一项艰巨的工作。工作负载是比Pod更高的抽象级别,然后Kubernete控制平面根据您定义的工作负载对象,自动管理Pod对象。

用于管理工作负载的内置API包括:

  1. Deployment:适合管理集群上的无状态应用程序工作负载,其中部署中的任何Pod都是可以根据需要互换的。这是在集群上运行应用程序的最常见方式。
  2. StatefulSet:用来管理有状态应用的工作负载, 并为 Pod 提供持久存储和持久标识符。如果StatefulSet中的一个Pod出现故障,K8s会制作一个新的Pod连接到同一持久存储卷。
  3. DaemonSet:可以在集群中的每个节点上运行DaemonSets(及其pod)。当有节点加入集群时, 也会为他们新增一个 Pod ; 当有节点从集群移除时,这些 Pod 也会被回收;删除 DaemonSet 将会删除它创建的所有 Pod。

您可以使用Job或CronJob来定义运行定时任务。一个Job代表一个一次性任务,一个CronJob代表一个可以重复执行的任务。

2.6.1. Deployment无状态负载

sh 复制代码
# 通过deployment初始化pod:多副本及自愈能力
kubectl create deployment my-dep --image=nginx[ --replicas=3]
# 查看Deployment负载
kubectl get deploy -A
# 删除工作负载
kubectl delete deploy my-dep

# 扩缩容
kubectl scale --replicas=5 deployment/my-dep

# 滚动更新
kubectl set image deployment/my-dep nginx=nginx:1.16.1
# 查看滚动更新状态
kubectl rollout status deployment/my-dep

# 查看历史记录
kubectl rollout history deployment/my-dep
# 查看某个历史详情
kubectl rollout history deployment/my-dep --revision=2
# 回滚(回到上次)
kubectl rollout undo deployment/my-dep
# 回滚(回到指定版本)
kubectl rollout undo deployment/my-dep --to-revision=2
  1. 测试多副本及自愈能力

  2. 扩缩容

  3. 滚动更新、灰度发布:

    找一个不存在的nginx版本更新试试(无限循环滚动更新,需要版本回退解决该问题)

  4. 版本回退

yaml语法:

sh 复制代码
[root@node-1 ~]# kubectl create deploy my-dep --image=nginx -n hello-world --replicas=3 --dry-run=client -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: my-dep
  name: my-dep
  namespace: hello-world
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-dep
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-dep
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

2.6.2. StatefulSet有状态负载

sh 复制代码
# statefulSet不支持命令行创建,必须通过脚本初始化,脚本官方案例如下:
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # 必须匹配 .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # 默认值是 1
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: nginx # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

2.6.3. DaemonSet守护负载

sh 复制代码
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # 这些容忍度设置是为了让该守护进程集在控制平面节点上运行
      # 如果你不希望自己的控制平面节点运行 Pod,可以删除它们
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      # 可能需要设置较高的优先级类以确保 DaemonSet Pod 可以抢占正在运行的 Pod
      # priorityClassName: important
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

2.6.4. ReplicaSet副本

ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。

例如灰度发布(滚动更新)时,会创建新的一组pod替换调用旧的一组pod,每一组pod就是一个ReplicaSet,如图:

ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet, 除非你需要自定义更新业务流程或根本不需要更新。

这实际上意味着,你可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment,并在 spec 部分定义你的应用。

2.6.5. Labels标签

为什么需要标签?

在pod发生故障以后,对应pod会被对应的控制器重启或重建,一个pod重建以后,对应的ip地址和名称都是会发生变化的,所以靠ip地址和名称关联pod是不行的;那靠什么关联pod呢?在k8s上是使用的标签和标签选择器的机制实现资源和资源间相互关联的。

标签是什么?有什么用?

所谓标签就是指一个键值数据,在k8s上任何资源都可以拥有标签。有了标签以后,我们后续就可以根据标签来管理对应的资源;一个资源可以拥有多个标签,同时一个标签也可以附加给多个资源;我们可以理解为标签就是用来逻辑的对资源进行分组,拥有相同标签的资源为一组;标签的作用是方便用户管理资源;比如在k8s上运行了几百个pod,我们想要管理功能相同的pod,就可以把具有相似功能的pod附加同一个标签,然后要管理这些pod的时,直接指定拥有指定标签的pod即可。

sh 复制代码
# 查看所有pod的标签
kubectl get pod -A --show-labels
# 查看一个pod的标签
kubectl get pod mynginx --show-labels

# 给pod添加标签
kubectl label pod mynginx app=nginx
# 更新标签:加上--overwrite参数修改标签
kubectl label pod mynginx app=nginx2 --overwrite
# 删除标签
kubectl label po mynginx app-

# 根据标签查看pod列表,多个标签以逗号分割
kubectl get pod -A -l app=my-dep

2.7. Service

Kubernetes 中 Service 是 将运行在一个或一组 Pod上的网络应用程序公开为网络服务的方法。每个 Service 对象定义端点的一个逻辑集合(通常这些端点就是 Pod)以及如何访问到这些 Pod 的策略。简而言之,就是pod的服务发现及负载均衡

现有问题:每个Pod都有自己的唯一Ip,且在集群内任意节点,任意Pod都能通过这个ip访问。写死对方Pod IP

  1. 一个Pod不能处理大量请求
  2. 对方宕机导致IP不通

2.7.1. ClusterIP

sh 复制代码
# 默认就是ClusterIP
kubectl expose deployment my-dep --port=8000 --target-port=80
# 完整写法如下:
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP

在web控制台打开nginx pod的控制台,修改nginx的默认页内容:

查看my-dep对外暴露服务的ip地址及端口号,然后访问效果如下:

上述方式,可以pod之间访问,也可以虚拟机访问pod

**域名访问:**只能pod之间访问

  1. 同一个名称空间下,访问my-dep:svc名:端口号svc名.名称空间:端口号

    创建deploy:kubectl create deploy my-tom --image=tomcat

    在web页面中的tomcat pod中访问my-dep:

    sh 复制代码
    root@my-tom-67ccb9cd95-dkftn:/usr/local/tomcat# curl my-dep:8000
    22222
    root@my-tom-67ccb9cd95-dkftn:/usr/local/tomcat# curl my-dep:8000
    33333
    root@my-tom-67ccb9cd95-dkftn:/usr/local/tomcat# curl my-dep:8000
    22222
    root@my-tom-67ccb9cd95-dkftn:/usr/local/tomcat# curl my-dep.default:8000
    11111
    root@my-tom-67ccb9cd95-dkftn:/usr/local/tomcat# curl my-dep.default:8000
    22222
    root@my-tom-67ccb9cd95-dkftn:/usr/local/tomcat# curl my-dep.default:8000
    33333
  2. 不同名称空间,访问my-dep:svc名.名称空间:端口号

    在helloworld中创建deploy:kubectl create deploy my-tom --image=tomcat -n helloworld

    sh 复制代码
    root@my-tom-67ccb9cd95-fwwvp:/usr/local/tomcat# curl my-dep:8000
    curl: (6) Could not resolve host: my-dep   # 不加名称空间无法访问
    root@my-tom-67ccb9cd95-fwwvp:/usr/local/tomcat# curl my-dep.default:8000
    33333
    root@my-tom-67ccb9cd95-fwwvp:/usr/local/tomcat# curl my-dep.default:8000
    22222
    root@my-tom-67ccb9cd95-fwwvp:/usr/local/tomcat# curl my-dep.default:8000
    33333
    root@my-tom-67ccb9cd95-fwwvp:/usr/local/tomcat# curl my-dep.default:8000
    11111

2.7.2. NodePort

这种模式允许在外部浏览器中通过虚拟机ip访问,同时也包含了ClusterIP能力

sh 复制代码
# 可以先删除my-dep服务再如下声明一次:kubectl delete svc my-dep
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort
# 或者把ClusterIP模式的服务直接改成NodePort模式
kubectl edit svc my-dep

# 查看svc服务
kubectl get svc
kubectl describe svc 

把红框中的ClusterIP改成NodePort即可

保存完成之后:

然后就可以通过:虚拟机ip:port进行访问了

可以修改端口号,修改方式同上(和修改type: NodePort一样)

注意:NodePort范围在 30000-32767 之间

原理:

2.7.3. 通过label进行负载均衡

也可以通过labels进行负载均衡:

给my-dep下的前两个pod添加标签:author=lxf

编写my-dep的选择器:

sh 复制代码
[root@k8s yaml]# curl 10.96.171.39:8000
2222222
[root@k8s yaml]# curl 10.96.171.39:8000
111111
[root@k8s yaml]# curl 10.96.171.39:8000
2222222

2.8. Ingress网关

Ingress对象是从集群外部到集群内服务的HTTP和HTTPS路由,由Ingress上定义的路由规则控制。

为了使Ingress资源正常工作,集群必须有一个正在运行的Ingress Controller,与其他k8s资源不同,Ingress Controller不是通过集群自动启动的,需要根据需要选择适合自己的Ingress Controller进行安装,Kubernetes作为一个项目支持和维护AWS、GCE和nginx等Ingress Controller。这里我们选择nginx

官网地址:https://kubernetes.github.io/ingress-nginx/

2.8.1. 下载安装

Supported Ingress-NGINX version k8s supported version Nginx Version Helm Chart Version
🔄 v1.10.0 1.29, 1.28, 1.27, 1.26 1.25.3 4.10.0*
🔄 v1.9.6 1.29, 1.28, 1.27, 1.26, 1.25 1.21.6 4.9.1*
🔄 v1.9.5 1.28, 1.27, 1.26, 1.25 1.21.6 4.9.0*
🔄 v1.9.4 1.28, 1.27, 1.26, 1.25 1.21.6 4.8.3
🔄 v1.9.3 1.28, 1.27, 1.26, 1.25 1.21.6 4.8.*
🔄 v1.9.1 1.28, 1.27, 1.26, 1.25 1.21.6 4.8.*
🔄 v1.9.0 1.28, 1.27, 1.26, 1.25 1.21.6 4.8.*
v1.8.4 1.27, 1.26, 1.25, 1.24 1.21.6 4.7.*
v1.7.1 1.27, 1.26, 1.25, 1.24 1.21.6 4.6.*
v1.6.4 1.26, 1.25, 1.24, 1.23 1.21.6 4.5.*
v1.5.1 1.25, 1.24, 1.23 1.21.6 4.4.*
v1.4.0 1.25, 1.24, 1.23, 1.22 1.19.10† 4.3.0
v1.3.1 1.24, 1.23, 1.22, 1.21, 1.20 1.19.10† 4.2.5
sh 复制代码
# 下载ingress的yaml文件,如果下载不了,可以使用浏览器访问下载,或者使用下面的内容
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml

# 注意:需要将image值分别改为:
# dyrnq/ingress-nginx-controller:v1.5.1
# dyrnq/kube-webhook-certgen:v20220916-gd32f8c343
# dyrnq/kube-webhook-certgen:v20220916-gd32f8c343
vi deploy.yaml

kubectl apply -f deploy.yaml
kubectl get pod,svc -n ingress-nginx

效果如下:

把Load

2.8.2. 使用案例

实现如下效果:

具体操作:

sh 复制代码
# 启动两个nginx
kubectl create deploy nginx-service --image=nginx --replicas=2
# 启动两个tomcat
kubectl create deploy tomcat-service --image=tomcat --replicas=2
# 一个nginx service
kubectl expose deploy nginx-service --port=8000 --target-port=80
# 一个tomcat service
kubectl expose deploy tomcat-service --port=9000 --target-port=8080
# 创建ingress路由规则
kubectl create ingress ing-rule --class=nginx --rule="nginx.atguigu.com/=nginx-service:8000" --rule="tomcat.atguigu.com/=tomcat-service:9000"

最终效果如下:

访问效果:

2.9. 存储卷(Volume)

容器中的文件在磁盘上是临时存放的,这给在容器中运行较重要的应用带来一些问题。 当容器崩溃或停止时会出现一个问题。此时容器状态未保存, 因此在容器生命周期内创建或修改的所有文件都将丢失。 在崩溃期间,kubelet 会以干净的状态重新启动容器。 当多个容器在一个 Pod 中运行并且需要共享文件时,会出现另一个问题。 K8s卷抽象解决了这两个问题。

K8s支持多种类型的卷。Pod可以同时使用任意的卷类型,临时卷(Ephemeral volume,之前使用的)和Pod生命周期一样,持久卷不会随着Pod的结束而销毁,在Pod重新启动时会保留数据。

2.9.1. PV&PVC

  • PersistentVolume(PV)是群集中由管理员提供或使用存储类动态提供的一块存储。它是集群中的资源,就像节点是集群资源一样。

  • PersistentVolumeClaim(PVC)是用户对存储的请求。它类似于Pod。PVC可以声明所需特定大小和访问模式的卷。

PV是集群中的资源,PVC是对这些资源的请求。Pod消耗节点资源,PVC消耗PV资源。群集管理员需要能够提供各种不同于大小和访问模式的持久卷

PVC 申领与 PV 卷之间的绑定是一种一对一的映射,一旦二者绑定到一起,控制面板总是将该 PV 卷绑定到这一 PVC

2.9.2. 制备PV

PV 卷的制备有两种方式:静态制备或动态制备。

  • 静态制备:集群管理员创建若干 PV 卷。这些卷对象带有真实存储的细节信息, 并且对集群用户可用(可见)。PV 卷对象存在于 Kubernetes API 中,可供用户消费(使用)。
  • 动态制备:如果管理员所创建的所有静态 PV 卷都无法与用户的 PersistentVolumeClaim 匹配, 集群可以尝试为该 PVC 申领动态制备一个存储卷。动态制备需要配置存储类( StorageClass)

这里采用静态制备,使我们在一定程度上了解PV及PVC的工作机制:

  1. 在node-2节点上创建3个目录:

    sh 复制代码
    mkdir -p /opt/k8s/data/01
    mkdir -p /opt/k8s/data/02
    mkdir -p /opt/k8s/data/03
  2. 编写yaml文件,制备PV:

    sh 复制代码
    vi pv.yaml
    kubectl apply -f pv.yaml

    内容如下:

    yaml 复制代码
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv01-100m
    spec:
      capacity:
        storage: 100M  # 1.5G=1.5*1000M  1.5Gi=1.5*1024M
      accessModes:
        - ReadWriteMany
      storageClassName: local-storage
      local:
        path: /opt/k8s/data/01
      nodeAffinity: # 亲和度,pod会和pv创建在同一个节点
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - node-2
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv02-200m
    spec:
      capacity:
        storage: 200M
      accessModes:
        - ReadWriteMany
      storageClassName: local-storage
      local:
        path: /opt/k8s/data/02
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - node-2
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv03-300m
    spec:
      capacity:
        storage: 300M
      accessModes:
        - ReadWriteMany
      storageClassName: local-storage
      local:
        path: /opt/k8s/data/03
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - node-2
  3. 制备完成之后:

    sh 复制代码
    [root@node-1 ~]# kubectl get pv
    NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS    REASON   AGE
    pv01-100m   100M       RWX            Retain           Available           local-storage            16s
    pv02-200m   200M       RWX            Retain           Available           local-storage            16s
    pv03-300m   300M       RWX            Retain           Available           local-storage            16s

2.9.3. PVC声明及绑定

sh 复制代码
# 创建pvc.yaml
vi pvc.yaml
kubectl apply -f pvc.yaml
# 查看pvc
kubectl get pvc,pv

内容如下:

yaml 复制代码
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 150Mi  # 如果多个PV满足,则取最小的一个PV
  storageClassName: local-storage

效果如下:

pv的几种状态:

  • Available:可用状态,还没有被绑定

  • Bound: 已经被人绑定,只有指定的pvc可以使用

  • Released:有pvc绑定过了,但是pvc没了。这个PV别人用不了

    代表以前有数据存在过的痕迹,K8s不会自行把这个删除,需要人工确认,进行数据备份,并重新恢复Available

    去这个pv真正所在的目录。把他的数据备份出来,再把这个PV变为available(先删再创建)。

2.9.4. Pod使用PVC

sh 复制代码
vi pod-pvc.yaml
kubectl apply -f pod-pvc.yaml

内容如下:

yaml 复制代码
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: pod-pvc
  name: pod-pvc
spec:
  serviceName: pod-pvc
  replicas: 1
  selector:
    matchLabels:
      app: pod-pvc
  template:
    metadata:
      labels:
        app: pod-pvc
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          persistentVolumeClaim:
            claimName: nginx-pvc

到node-2服务器上的/opt/k8s/data/02目录,随便加个文件,访问效果如下:

sh 复制代码
[root@node-2 ~]# cd /opt/k8s/data/02
[root@node-2 02]# echo "hello world......" > 1.txt

2.10. 配置

2.10.1. ConfigMap

ConfigMap是一个API对象,用于将非机密数据存储在键-值对中。Pod可以将ConfigMaps用作环境变量、命令行参数或卷中的配置文件。它使特定环境中的配置与容器解耦,以便您的应用程序易于移植。当 ConfigMap 被更新时,所投射的键(pod中的配置)最终也会被更新,从而为pod提供热更新的能力。

注意:

  1. ConfigMap不提供保密或加密功能。如果要存储的数据是机密的,请使用Secret或者第三方工具
  2. ConfigMap不是为保存大块数据而设计的,存储在ConfigMap中的数据不能超过1 MiB
  3. 和其他 Kubernetes 对象都有一个 spec 不同的是,ConfigMap 使用 databinaryData 字段。这些字段能够接收键-值对作为其取值。databinaryData 字段都是可选的
  4. 可以在Pod中使用ConfigMap,但是Pod和ConfigMap必须位于同一命名空间中。
1. 初始化CM
sh 复制代码
# 查看帮助
kubectl create cm --help
# 其中有一条基础提示:path/to/bar是配置目录
kubectl create configmap my-config --from-file=path/to/bar

# 创建一个conf目录,并添加两个conf配置文件
mkdir conf
# 内容参照nginx的默认的/etc/nginx/conf.d/default.conf配置文件
vi default.conf  
# 随便加些注释内容:# sdfsfdslfsdddddddddddd
vi test.conf
cd ..

# 执行命令创建cm
kubectl create configmap my-config --from-file=conf/
# 查看cm
kubectl get cm
# 查看cm配置内容
kubectl get cm my-config -oyaml

最终结果如下:

yaml 复制代码
apiVersion: v1
data:
  default.conf: |
    server {
        listen       80;
        listen  [::]:80;
        server_name  localhost;

        #access_log  /var/log/nginx/host.access.log  main;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }
  test.conf: |
    # sdfsfdslfsdddddddddddd
kind: ConfigMap
metadata:
  creationTimestamp: "2024-03-31T14:06:29Z"
  name: my-config
  namespace: default
  resourceVersion: "121992"
  uid: e89f9747-6465-4020-9809-799b56b909ed
2. 在Pod中使用CM
sh 复制代码
# 创建pod-cm.yaml配置文件
vi pod-cm.yaml
# 执行
kubectl apply -f pod-cm.yaml

内容如下:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - name: nginx-conf
      mountPath: /etc/nginx/conf.d
  volumes:
  - name: nginx-conf
    configMap:
      name: my-config
status: {}

效果如下:

3. 演示动态同步

在cm中修改了配置内容,pod中的配置文件内容会自行同步

修改my-config内容:

sh 复制代码
kubectl edit cm my-config

在pod-cm中查看nginx对应的配置文件也跟着同步了:可能需要一两分钟

2.10.2. Secret

Secret 对象类型与ConfigMaps类似,但专门用于保存敏感数据。例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod的定义或者 容器镜像中来说更加安全和灵活。

由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。

  1. 声明Secret

    sh 复制代码
    kubectl create secret docker-registry lxf-docker \
    --docker-username=joedy23@163.com \
    --docker-password=lxf123456 \
    --docker-email=666666@qq.com
  2. 在pod中使用secret:

    yaml 复制代码
    apiVersion: v1
    kind: Pod
    metadata:
      name: private-nginx
    spec:
      containers:
      - name: private-nginx
        image: lxf/guignginx:v1.0
      imagePullSecrets:
      - name: lxf-docker

    拉取镜像时,使用第一步配置的密钥

  3. 查看secret:

    sh 复制代码
    kubectl get secret lxf-docker -oyaml

2.11. 小结

k8s部署应用需要考虑三要素:

另外,大型应用的应用监控(Prometheus、Grafana)也是不可或缺的

k8s核心概念:

  1. namespace:名称空间,环境隔离(资源),网络互通

  2. Pod:一组容器,使用容器具备自愈

  3. 工作负载:Deployment(无状态的工作负载),statefulSet(有状态的工作负载 配合pv和pvc使用)

    使pod具备自愈能力,使pod具备伸缩性

  4. service服务:使工作负载统一对外提供访问入口,使工作负载中的资源具备负载均衡能力

  5. ingress网关:使k8s应用统一对外暴露,提供service服务的路由能力

  6. pv和pvc:提供底层的存储支持。

  7. ConfigMap:提供统一配置能力

3. K8s实战-KubeSphere

3.1. K8s生态

CNCF:全称Cloud Native Computing Foundation(云原生计算基金会),成立于2015年12月11日,是一个开源软件基金会,它致力于云原生(Cloud Native)技术的普及和可持续发展。

CNCF是开源的、与供应商无关的云原生计算中心,托管Kubernetes和Prometheus等项目,使云原生通用且可持续。

3.2. helm

官方网站:https://helm.sh/zh/

3.3. KubeSphere

官网:https://kubesphere.io/zh

文档:https://kubesphere.io/zh/docs/v3.4/introduction/what-is-kubesphere/

3.3.1. 安装

多节点参照文档:https://kubesphere.io/zh/docs/v3.4/installing-on-linux/introduction/multioverview/

sh 复制代码
# 三个机器设置不一样的名字
hostnamectl set-hostname node1
hostnamectl set-hostname node2
hostnamectl set-hostname node3

# 安装依赖:所有节点都要执行
yum install -y socat conntrack ebtables ipset

# 在主节点上执行以下指令,如果在线下载不成功,可以离线下载好,上传到特定目录
export KKZONE=cn
curl -sfL https://get-kk.kubesphere.io | VERSION=v3.0.10 sh -
chmod +x kk

# 初始化集群配置文件 
./kk create config --with-kubesphere
# 在当前目录下你会看到有一个 config-sample.yaml 文件
# 修改集群文件:指定好三台机器的ip、账号密码、master节点、工作节点; 

# 安装集群
./kk create cluster -f config-sample.yaml
# 此时需要较长时间下载相关组件 
# 整个安装过程可能需要 10 到 20 分钟,具体取决于您的计算机和网络环境。

#查看安装结果:包括dashboard访问地址、用户名及密码。
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f

离线下载:https://github.com/kubesphere/kubekey/releases

下载好直接解压即可使用。

安装成功之后:

此时通过上图中的Console地址就可以浏览器访问了:

额外说明:

  • ebtables: ebtables 是一个用于以太网桥的过滤器,它允许在 Linux 内核中操作以太网桥的数据包过滤规则。它可以用于控制网络流量、设置网络策略等。
  • socat: socat 是一个功能强大的网络工具,用于建立各种类型的连接,如 TCP、UDP、UNIX 套接字等。它可以用于端口转发、代理、网络调试等任务。
  • ipset: ipset 是一个用于管理 IP 地址集合的工具。它允许你创建和操作 IP 地址的集合,提供高效的 IP 地址匹配和过滤功能。ipset 可以用于防火墙配置、访问控制列表等。
  • conntrack: conntrack 是一个连接跟踪工具,用于在 Linux 内核中跟踪网络连接的状态。它可以用于查看和操作活动连接、连接跟踪表等。conntrack 在网络安全和网络分析中很有用。
  • chrony 是一个用于计算机时间同步的工具,它提供了精确的时钟同步和时间调整功能。在安装k8s时安装时间同步服务,切换时区为亚洲、上海,而不是UTC。

3.3.2. Console界面说明

点击左上角,弹出功能切换页面,包括:集群管理、访问控制、平台设置

集群管理菜单说明:

3.3.3. 部署一个nginx

1. 持久卷声明

先创建一个持久卷,以便于将来挂载到nginx:

填写基本信息:pvc名称及名称空间

存储设置:存储类(只有local)、访问模式(只有ReadWriteOnce)、卷容量(1Gi)

最后一步:高级设置,直接跳过完成创建!

2. nginx部署

选择:应用负载 --> 工作负载 --> 部署 --> 创建

依次完成:基本信息、容器组设置、存储设置、高级设置

  1. 基本信息:设置deployment名称及名称空间

  2. 容器组设置:容器组副本数、选择容器镜像(镜像、cpu、内存、容器名、端口等等)

  3. 存储设置:持久卷及挂载路径

  4. 高级设置:选择节点(可以略过,自动分配节点)

  5. 点击创建按钮,完成创建:

    稍等一会儿,即可完成创建

3. 日常维护

在工作负载列表中找到刚刚创建的nginx-deploy:

点击进去:

可以编辑yaml文件,重新指定nginx镜像(演示滚动更新、版本回退)

4. 通过kubectl访问

随便访问一个pod:

5. 通过service暴露

基本信息:录入服务名称、名称空间

服务设置:内部访问模式(虚拟ip地址)、指定工作负载(在弹出框中选择nginx-deploy)

最终效果如下:

高级设置:勾选外部访问(NodePort、LoadBalancer),最后点击创建

可以分别在kubectl 和 浏览器中进行访问测试!

6. 应用路由

3.3.4. 多租户

KubeSphere 的多租户系统分三个层级,即集群、企业空间和项目。KubeSphere 中的项目等同于 Kubernetes 的命名空间。

您可以在一个 KubeSphere 集群中创建多个企业空间,每个企业空间下可以创建多个项目。

您需要创建一个新的企业空间进行操作,而不是使用系统企业空间,系统企业空间中运行着系统资源,绝大部分仅供查看。出于安全考虑,强烈建议给不同的租户授予不同的权限在企业空间中进行协作。

KubeSphere 为每个级别默认设有多个内置角色。此外,您还可以创建拥有自定义权限的角色。KubeSphere 多层次结构适用于具有不同团队或组织以及每个团队中需要不同角色的企业用户。

演示案例:

  1. 使用平台管理员账户admin登录控制台,添加用户并指定密码:

    • 添加企业管理员,例如:boss

    • 添加普通用户,例如:zh3、li4、wang5、zhao6

  2. 使用企业管理员账户boss登录控制台,添加企业并指定管理员,邀请每个企业的普通用户:

    • 添加企业并指定管理员(默认就是boss),例如:北京分公司、上海分公司、西安分公司

    • 选择一个企业,给每个企业邀请用户并分别赋予一定的权限。如下:boss和每个公司的admin都可以给这个公司邀请新人

  3. 使用公司管理员账户登录控制台,添加项目(名称空间),给项目添加成员并授予权限

三层权限设计最终如下:

接下来,可以分别使用不同的用户,查看自己的功能列表

3.3.5. 部署WordPress

1. 创建密钥(secret)

需要创建两个密钥:MySQL密钥 和 WordPress密钥

以MySQL为例如下:

填好之后,下一步:选择文本形式

完成创建如下:

可以点进去查看密钥:

2. 创建持久卷声明

需要创建一个PVC:wd-pvc。因为将来我们会为mysql创建有状态的工作负载,创建过程中就会让我们创建mysql-pvc

3. 搭建MySQL服务

创建mysql的有状态工作负载(会自动创建对应的pvc及service,并为mysql服务分配访问域名)

录入基本信息:名称

录入容器组设置:容器副本数量、然后点击添加容器

下图中的DATABASE应该是MYSQL_DATABASE,或者后续再去创建这个库。

存储设置:添加持久卷声明

添加持久卷声明如下:

选择好之后,略过高级设置,点击直接创建即可!

最后效果如下:创建了工作负载

同时创建了对应的service

也创建了持久卷声明:

4. 搭建wd应用服务

创建服务:服务 --> 创建 --> 无状态服务

下拉:

下拉:

下拉:下述参数设置请参照dockerhub中docker部署的参数设置

下一步:

略过高级设置,直接点击创建即可,等待一会儿。

5. 对外暴露wd服务
6. 路由规则及网关

创建应用路由:

下一步、略过高级设置,完成创建

最后需要启用网关

在hosts文件中配置好域名就可以通过域名访问啦!!!!!!!

3.3.6. MySQL扩展

  1. 演示扩缩容

  2. 演示mysql的内部访问:

  1. 演示mysql的外部访问:需要创建自定义服务,允许外部访问

最终效果

相关推荐
只会copy的搬运工33 分钟前
Jenkins 持续集成部署——Jenkins实战与运维(1)
运维·ci/cd·jenkins
catoop41 分钟前
K8s 无头服务(Headless Service)
云原生·容器·kubernetes
liuxuzxx2 小时前
1.24.1-Istio安装
kubernetes·istio·service mesh
测试杂货铺2 小时前
如何用postman做接口自动化测试及完美的可视化报告?
自动化测试·软件测试·测试工具·职场和发展·jenkins·压力测试·postman
道一云黑板报3 小时前
Flink集群批作业实践:七析BI批作业执行
大数据·分布式·数据分析·flink·kubernetes
运维小文3 小时前
K8S中的PV、PVC介绍和使用
docker·云原生·容器·kubernetes·存储
ζั͡山 ั͡有扶苏 ั͡✾4 小时前
Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)
云原生·容器·kubernetes
Hadoop_Liang4 小时前
Kubernetes ConfigMap的创建与使用
云原生·容器·kubernetes
科马5 小时前
【Jenkins】持久化
java·运维·jenkins
编程、小哥哥7 小时前
在 Docker 中部署 Jenkins,并完成项目的构建和发布
servlet·docker·jenkins