Kubernetes (K8S) 是什么¶
- Kubernetes 是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。
- Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。
- 它最初由 Google 开发,现在由云原生计算基金会(Cloud Native Computing Foundation, CNCF)维护。
- Kubernetes 提供了一套强大的工具和功能,使开发人员和运维人员能够更轻松地管理复杂的容器化应用程序。
- 主要功能包括:
- 自动化部署:Kubernetes 可以自动部署容器化应用程序,并确保它们在集群中运行。
- 扩展和缩减:根据需求,Kubernetes 可以自动扩展或缩减应用程序的实例数量。
- 负载均衡:Kubernetes 提供内置的负载均衡功能,以确保流量均匀分布到各个容器实例。
- 自愈能力:如果某个容器或节点出现故障,Kubernetes 会自动重新调度和恢复应用程序。
- 服务发现和配置管理:Kubernetes 提供服务发现机制,使容器能够相互通信,并支持配置管理以简化应用程序的配置过程。
什么时候需要 Kubernetes¶
- 当你的应用只是跑在一台机器,直接一个 docker + docker-compose 就够了,方便轻松;
- 当你的应用需要跑在 3,4 台机器上,你依旧可以每台机器单独配置运行环境 + 负载均衡器(Standalone Master);
- 当你应用访问数不断增加,机器逐渐增加到十几台、上百台、上千台时,每次加机器、软件更新、版本回滚,都会变得非常麻烦、痛不欲生。
- Kubernetes 可以提供集中式的管理集群机器和应用,加机器、版本升级、版本回滚,那都是一个命令就搞定的事,不停机的灰度更新,确保高可用、高性能、高扩展。
学习前提:Docker¶
- 在学习 Kubernetes 之前,建议先了解 Docker 和 Linux 的基础知识。
- Docker 是什么?
- Docker 是一种流行的容器化平台,用于创建、部署和管理容器化应用程序。Kubernetes 主要用于编排和管理 Docker 容器。
- 你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,
- 而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。
- 学习文档:
跟普通虚拟机的对比¶
| 特性 | 普通虚拟机 | Docker |
|---|---|---|
| 跨平台 | 通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行 | 支持的系统非常多,各类 Windows 和 Linux 都支持 |
| 性能 | 性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了 | 性能好,只虚拟软件所需运行环境,最大化减少没用的配置 |
| 自动化 | 需要手动安装所有东西 | 一个命令就可以自动部署好所需环境 |
| 稳定性 | 稳定性不高,不同系统差异大 | 稳定性好,不同系统都一样部署方式 |
Docker 部署的优势¶
- 打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
- 分发:你可以把你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装
- 部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一模一样的运行环境,不管是在 Windows/Mac/Linux。
Docker 通常用来做什么¶
- 应用分发、部署,方便传播给他人安装。特别是开源软件和提供私有部署的应用
- 快速安装测试/学习软件,用完就丢(类似小程序),不把时间浪费在安装软件上。
- 多个版本软件共存,不污染系统,例如 Python2、Python3,Redis4.0,Redis5.0
- Docker 可以用于部署大数据处理框架,如 Hadoop 和 Spark,简化集群的配置和管理。
重要概念:镜像、容器¶
- 镜像:可以理解为软件安装包,可以方便的进行传播和安装。
- 容器:软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。
直接安装的缺点¶
- 安装麻烦,可能有各种依赖,运行报错。例如:WordPress,ElasticSearch,Redis
- 可能对 Windows 并不友好,运行有各种兼容问题,软件只支持 Linux 上跑
- 不方便安装多版本软件,不能共存。
- 电脑安装了一堆软件,拖慢电脑速度。
- 不同系统和硬件,安装方式不一样
Docker 安装的优点¶
- 一个命令就可以安装好,快速方便
- 有大量的镜像,可直接使用
- 没有系统兼容问题,Linux 专享软件也照样跑
- 支持软件多版本共存
- 用完就丢,不拖慢电脑速度
- 不同系统和硬件,只要安装好 Docker 其他都一样了,一个命令搞定所有
案例: 安装 WordPress 并配置数据库¶
- Docker:管理单个镜像/容器(build/run/exec)。
- Docker Compose:管理多容器应用(组合、链接、统一启动/停止)。
- Example
compose.yamlfor wordpress
compose.yaml 示例¶
# 说明:此 Compose 文件用于在本地以 Docker 容器运行 WordPress + MySQL 环境。
# 结构概览:
# - services: 定义两个服务:wordpress(Web 应用)和 db(MySQL 数据库)。
# - volumes: 使用命名卷来持久化 WordPress 文件和 MySQL 数据库数据。
services: # 定义服务集合
wordpress: # WordPress 服务
image: wordpress # 使用官方 wordpress 镜像(PHP + Apache)
restart: always # 容器异常退出时自动重启
ports: # 端口映射列表
- 8080:80 # 将主机 8080 映射到容器 80(访问 http://localhost:8080/)
environment: # 环境变量:数据库连接信息
WORDPRESS_DB_HOST: db # 数据库主机(Compose 服务名)
WORDPRESS_DB_USER: exampleuser # WordPress 数据库用户名
WORDPRESS_DB_PASSWORD: examplepass # WordPress 数据库密码(注意生产环境不要明文)
WORDPRESS_DB_NAME: exampledb # WordPress 使用的数据库名
volumes: # 挂载卷:持久化网站文件
- wordpress:/var/www/html # 将命名卷 wordpress 挂载到 /var/www/html
db: # MySQL 数据库服务
image: mysql:8.0 # 使用 MySQL 8.0 官方镜像
restart: always # 容器异常退出时自动重启
environment: # MySQL 环境变量
MYSQL_DATABASE: exampledb # 启动时创建的数据库名,应与 WORDPRESS_DB_NAME 一致
MYSQL_USER: exampleuser # 创建的非 root 用户
MYSQL_PASSWORD: examplepass # 非 root 用户的密码(注意生产环境不要明文)
MYSQL_RANDOM_ROOT_PASSWORD: '1' # 随机生成 root 密码('1' 或 'true')
volumes: # 持久化数据库数据
- db:/var/lib/mysql # 将命名卷 db 挂载到 /var/lib/mysql
volumes: # 定义命名卷
wordpress: # WordPress 内容卷
db: # 数据库数据卷
wordpress: # WordPress 服务
image: wordpress # 使用官方 wordpress 镜像(PHP + Apache)
restart: always # 容器异常退出时自动重启
ports: # 端口映射列表
- 8080:80 # 将主机 8080 映射到容器 80(访问 http://localhost:8080/)
environment: # 环境变量:数据库连接信息
WORDPRESS_DB_HOST: db # 数据库主机(Compose 服务名)
WORDPRESS_DB_USER: exampleuser # WordPress 数据库用户名
WORDPRESS_DB_PASSWORD: examplepass # WordPress 数据库密码(注意生产环境不要明文)
WORDPRESS_DB_NAME: exampledb # WordPress 使用的数据库名
volumes: # 挂载卷:持久化网站文件
- wordpress:/var/www/html # 将命名卷 wordpress 挂载到 /var/www/html
db: # MySQL 数据库服务
image: mysql:8.0 # 使用 MySQL 8.0 官方镜像
restart: always # 容器异常退出时自动重启
environment: # MySQL 环境变量
MYSQL_DATABASE: exampledb # 启动时创建的数据库名,应与 WORDPRESS_DB_NAME 一致
MYSQL_USER: exampleuser # 创建的非 root 用户
MYSQL_PASSWORD: examplepass # 非 root 用户的密码(注意生产环境不要明文)
MYSQL_RANDOM_ROOT_PASSWORD: '1' # 随机生成 root 密码('1' 或 'true')
volumes: # 持久化数据库数据
- db:/var/lib/mysql # 将命名卷 db 挂载到 /var/lib/mysql
运行WordPress¶
- Run docker compose up, wait for it to initialize completely,
- and visit http://localhost:8080
更多相关命令¶
docker ps查看当前运行中的容器docker images查看镜像列表docker rm container-id删除指定 id 的容器docker stop/start container-id停止/启动指定 id 的容器docker rmi image-id删除指定 id 的镜像docker volume ls查看 volume 列表docker network ls查看网络列表
Kubernetes 基本概念¶
节点(Node):一个节点是一个运行 Kubernetes 中的主机。
容器组(Pod):一个 Pod 对应于由若干容器组成的一个容器组,同个组内的容器共享一个存储卷(volume)。
web 界面(ux):用户可以通过 web 界面操作 Kubernetes。
命令行操作(cli):kubectl命令。
minikube¶
- Minikube 是一个工具,可以在本地计算机上快速运行一个单节点的 Kubernetes 集群,适合学习和测试 Kubernetes。
- 安装文档:https://minikube.sigs.k8s.io/docs/start/?arch=%2Fwindows%2Fx86-64%2Fstable%2F.exe+download
In [ ]:
!kubectl get nodes
NAME STATUS ROLES AGE VERSION minikube Ready control-plane 133m v1.34.0 minikube-m02 NotReady <none> 17m v1.34.0
In [11]:
!minikube node add --worker
* 将节点 m03 作为 [worker] 添加到集群 minikube * 在集群中 "minikube" 启动节点 "minikube-m03" worker * 正在拉取基础镜像 v0.0.48 ... * 正在验证 Kubernetes 组件... * 已成功将 m03 添加到 minikube!
! 从 Minikube 的 container 内部连接到 https://registry.k8s.io/ 失败 * 要获取新的外部镜像,可能需要配置代理:https://minikube.sigs.k8s.io/docs/reference/networking/proxy/ ! The image 'gcr.io/k8s-minikube/storage-provisioner:v5' was not found; unable to add it to cache. ! The image 'registry.k8s.io/etcd:3.6.4-0' was not found; unable to add it to cache. ! The image 'registry.k8s.io/coredns/coredns:v1.12.1' was not found; unable to add it to cache. ! The image 'registry.k8s.io/kube-controller-manager:v1.34.0' was not found; unable to add it to cache. ! The image 'registry.k8s.io/kube-scheduler:v1.34.0' was not found; unable to add it to cache. ! The image 'registry.k8s.io/kube-apiserver:v1.34.0' was not found; unable to add it to cache. ! The image 'registry.k8s.io/kube-proxy:v1.34.0' was not found; unable to add it to cache. ! The image 'registry.k8s.io/pause:3.10.1' was not found; unable to add it to cache.
In [13]:
!kubectl get nodes
NAME STATUS ROLES AGE VERSION minikube Ready control-plane 3h22m v1.34.0 minikube-m02 Ready <none> 87m v1.34.0 minikube-m03 Ready <none> 34s v1.34.0
In [14]:
!minikube node delete minikube-m03
!kubectl get nodes
* 正在从集群 minikube 中删除节点 minikube-m03 * 正在停止节点 "minikube-m03" ... * 正在通过 SSH 关闭“minikube-m03”… * 正在删除 docker 中的“minikube-m03”… * 节点 minikube-m03 已成功删除。 NAME STATUS ROLES AGE VERSION minikube Ready control-plane 3h23m v1.34.0 minikube-m02 Ready <none> 87m v1.34.0
In [ ]:
!minikube stop
* 正在停止节点 "minikube-m02" ... * 正在通过 SSH 关闭“minikube-m02”… * 正在停止节点 "minikube" ... * 正在通过 SSH 关闭“minikube”… * 2 个节点已停止。
minikube部署应用程序¶
- 创建示例部署并将其公开在端口 8080 上:
# 创建名为 hello-minikube 的部署,使用 kicbase/echo-server:1.0 镜像
kubectl create deployment hello-minikube --image=kicbase/echo-server:1.0
# 将部署暴露为 NodePort 服务,端口为 8080
kubectl expose deployment hello-minikube --type=NodePort --port=8080
- 这可能需要一点时间,但当您运行以下命令时,您的部署将很快显示出来:
- 访问此服务的最简单方法是让 minikube 为您启动 Web 浏览器:
# 查看 hello-minikube 服务的详细信息,包括分配的端口
kubectl get services hello-minikube
# 自动在浏览器打开服务页面,方便访问和测试
minikube service hello-minikube
- 或者,使用 kubectl 转发端口:
kubectl port-forward service/hello-minikube 7080:8080
Kubernetes 扩展¶
腾讯云容器服务TKE(Tencent Kubernetes Engine)¶
- 腾讯云容器服务 TKE(Tencent Kubernetes Engine)是腾讯云提供的托管式 Kubernetes 服务,旨在简化容器化应用的部署和管理。
腾讯云容器服务TKE(Tencent Kubernetes Engine)¶
裸机安装Kubernetes集群¶
裸机安装Kubernetes集群¶
租用腾讯云服务器CVM(Cloud Virtual Machine)¶
租用腾讯云服务器CVM(Cloud Virtual Machine)¶
远程连接云服务器¶
远程连接云服务器¶
组件¶
- 主节点需要组件
- 容器运行时(如docker) 负责运行容器的软件
- kubectl 集群命令行交互工具
- kubeadm 集群初始化工具
- 工作节点需要组件 (https://kubernetes.io/zh-cn/docs/concepts/overview/components/#node-components)
- 容器运行时(如docker) 负责运行容器的软件
- kubelet 管理 Pod 和容器,确保他们健康稳定运行。
- kube-proxy 网络代理,负责网络相关的工作
开始安装¶
- 脚本搭建: https://github.com/lework/kainstall
- 手动搭建
- 每个节点分别设置对应主机名
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2
- 所有节点都修改 hosts
vim /etc/hosts
# 修改 hosts 文件,添加以下内容
172.19.0.14 node1
172.19.0.4 node2
172.19.0.17 master
- 所有节点关闭 SELinux
# SELinux 常见于 RHEL/CentOS/Fedora 等发行版;对安全很有帮助,但会导致服务访问被拒
# 关闭 SELinux
setenforce 0
# 修改 SELinux 配置文件,将其设置为禁用
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
- 所有节点防火墙关闭
systemctl stop firewalld # 停止防火墙服务
systemctl disable firewalld # 禁用防火墙服务,开机不自启
- 配置 Kubernetes YUM 源(阿里云镜像)
以下命令将阿里云的 Kubernetes YUM 源配置到 CentOS 7 系统,便于后续安装 Kubernetes 相关组件。
# 创建 Kubernetes YUM 源配置文件(使用阿里云镜像)
cat <<EOF > kubernetes.repo # 创建一个新的 Kubernetes YUM 源配置文件
[kubernetes] # 仓库名称
name=Kubernetes # 仓库描述
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 # 阿里云镜像源地址
enabled=1 # 启用该仓库
gpgcheck=0 # 关闭 GPG 校验
repo_gpgcheck=0 # 关闭仓库 GPG 校验
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg # GPG 公钥地址(可选)
EOF
mv kubernetes.repo /etc/yum.repos.d/ # 移动配置文件到 yum 源目录
# 添加 Docker YUM 源(阿里云镜像)以便安装 Docker
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
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/
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 为所有节点安装组件
# 安装 kubelet、kubectl、kubeadm 和 Docker 组件(指定版本)
yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 docker-ce
- 启动 kubelet、docker,并设置开机启动(所有节点)
systemctl enable kubelet # 设置 kubelet 服务开机自启,保证节点重启后自动启动
systemctl start kubelet # 启动 kubelet 服务,负责管理 Kubernetes 节点上的 Pod 和容器
systemctl enable docker # 设置 Docker 服务开机自启,保证节点重启后自动启动
systemctl start docker # 启动 Docker 服务,提供容器运行环境
- 修改 docker 配置(所有节点)
# kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver,否则 kubelet 启动不了
cat <<EOF > daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"], # 设置 cgroupdriver 为 systemd,Kubernetes 推荐
"registry-mirrors": ["https://ud6340vz.mirror.aliyuncs.com"] # 配置 Docker 镜像加速器,提高拉取速度
}
EOF
mv daemon.json /etc/docker/ # 将配置文件移动到 Docker 配置目录
# 重启生效
systemctl daemon-reload # 重新加载 systemd 管理的所有服务配置,确保新配置生效
systemctl restart docker # 重启 Docker 服务,使配置更改立即生效
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 重置
# 初始化 Kubernetes 控制平面(仅主节点执行),指定镜像仓库为阿里云镜像,加速拉取所需镜像
kubeadm init --image-repository=registry.aliyuncs.com/google_containers
# 记得把 kubeadm join xxx 保存起来
# 忘记了重新获取:kubeadm token create --print-join-command
# 复制授权文件,以便 kubectl 可以有权限访问集群
# 如果你其他节点需要访问集群,需要从主节点复制这个文件过去其他节点
# 创建 .kube 目录(如果不存在),用于存放 kubeconfig 配置文件
mkdir -p $HOME/.kube
# 复制 Kubernetes 管理员配置文件到当前用户的 .kube 目录
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# 修改配置文件的所有者为当前用户,确保 kubectl 有权限访问
chown $(id -u):$(id -g) $HOME/.kube/config
- 把工作节点加入集群(只在工作节点跑)
# 用 kubeadm join 命令将工作节点加入 Kubernetes 集群,需替换为实际的 join 命令
kubeadm join 172.19.0.17:6443 --token m8usq6.6dou8eqq1g2f7zrd --discovery-token-ca-cert-hash sha256:41e144f9a7cfeacf64eeace0ec7318d6768755a586cdd011ccd9a8ac7c84ced4
- 安装网络插件,否则 node 是 NotReady 状态(主节点跑)
# 为 Kubernetes 集群安装 Flannel 网络插件,确保各节点网络互通。
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
- 查看节点状态
# 查看节点状态
kubectl get nodes