大数据分析与挖掘
¶

07. Docker and Kubernetes
¶

主讲人:丁平尖

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 容器。
    • 你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,
    • 而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。
  • 学习文档:
    • https://docs.docker.com/manuals/
    • https://yeasy.gitbook.io/docker_practice

跟普通虚拟机的对比¶

特性 普通虚拟机 Docker
跨平台 通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行 支持的系统非常多,各类 Windows 和 Linux 都支持
性能 性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了 性能好,只虚拟软件所需运行环境,最大化减少没用的配置
自动化 需要手动安装所有东西 一个命令就可以自动部署好所需环境
稳定性 稳定性不高,不同系统差异大 稳定性好,不同系统都一样部署方式

Docker 部署的优势¶

  • 打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
  • 分发:你可以把你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装
  • 部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一模一样的运行环境,不管是在 Windows/Mac/Linux。

Docker 通常用来做什么¶

  • 应用分发、部署,方便传播给他人安装。特别是开源软件和提供私有部署的应用
  • 快速安装测试/学习软件,用完就丢(类似小程序),不把时间浪费在安装软件上。
  • 多个版本软件共存,不污染系统,例如 Python2、Python3,Redis4.0,Redis5.0
  • Docker 可以用于部署大数据处理框架,如 Hadoop 和 Spark,简化集群的配置和管理。

重要概念:镜像、容器¶

  • 镜像:可以理解为软件安装包,可以方便的进行传播和安装。
  • 容器:软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。

镜像加速源¶

  • registry-mirrors: 镜像加速器列表,拉取镜像时会优先使用这些镜像源,加速下载。

image.png

直接安装的缺点¶

  • 安装麻烦,可能有各种依赖,运行报错。例如:WordPress,ElasticSearch,Redis
  • 可能对 Windows 并不友好,运行有各种兼容问题,软件只支持 Linux 上跑
  • 不方便安装多版本软件,不能共存。
  • 电脑安装了一堆软件,拖慢电脑速度。
  • 不同系统和硬件,安装方式不一样

Docker 安装的优点¶

  • 一个命令就可以安装好,快速方便
  • 有大量的镜像,可直接使用
  • 没有系统兼容问题,Linux 专享软件也照样跑
  • 支持软件多版本共存
  • 用完就丢,不拖慢电脑速度
  • 不同系统和硬件,只要安装好 Docker 其他都一样了,一个命令搞定所有

Docker安装WordPress¶

WordPress 是一个流行的开源内容管理系统(CMS),可快速搭建网站和博客

image.png

案例: 安装 WordPress 并配置数据库¶

  • Docker:管理单个镜像/容器(build/run/exec)。
  • Docker Compose:管理多容器应用(组合、链接、统一启动/停止)。
  • Example compose.yaml for 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

image.png

更多相关命令¶

  • 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

image-2.png

minikube操作¶

  • 启动集群
minikube start
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

minikube部署应用程序¶

  • 应用程序现在可以在http://localhost:7080/%E4%B8%8A%E4%BD%BF%E7%94%A8

image.png

Kubernetes 扩展¶

image.png

腾讯云容器服务TKE(Tencent Kubernetes Engine)¶

  • 腾讯云容器服务 TKE(Tencent Kubernetes Engine)是腾讯云提供的托管式 Kubernetes 服务,旨在简化容器化应用的部署和管理。

https://cloud.tencent.com/product/tke

腾讯云容器服务TKE(Tencent Kubernetes Engine)¶

image-2.png

裸机安装Kubernetes集群¶

image.png

裸机安装Kubernetes集群¶

image.png

租用腾讯云服务器CVM(Cloud Virtual Machine)¶

image.png

租用腾讯云服务器CVM(Cloud Virtual Machine)¶

image-2.png

远程连接云服务器¶

image.png

远程连接云服务器¶

image.png

组件¶

  • 主节点需要组件
    • 容器运行时(如docker) 负责运行容器的软件
    • kubectl 集群命令行交互工具
    • kubeadm 集群初始化工具
  • 工作节点需要组件 (https://kubernetes.io/zh-cn/docs/concepts/overview/components/#node-components)
    • 容器运行时(如docker) 负责运行容器的软件
    • kubelet 管理 Pod 和容器,确保他们健康稳定运行。
    • kube-proxy 网络代理,负责网络相关的工作

开始安装¶

  • 脚本搭建: https://github.com/lework/kainstall
  • 手动搭建
  1. 每个节点分别设置对应主机名
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2
  1. 所有节点都修改 hosts
vim /etc/hosts
# 修改 hosts 文件,添加以下内容
172.19.0.14 node1
172.19.0.4 node2
172.19.0.17 master
  1. 所有节点关闭 SELinux
# SELinux 常见于 RHEL/CentOS/Fedora 等发行版;对安全很有帮助,但会导致服务访问被拒
# 关闭 SELinux
setenforce 0
# 修改 SELinux 配置文件,将其设置为禁用
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
  1. 所有节点防火墙关闭
systemctl stop firewalld   # 停止防火墙服务  
systemctl disable firewalld   # 禁用防火墙服务,开机不自启
  1. 配置 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
  1. 为所有节点安装组件
# 安装 kubelet、kubectl、kubeadm 和 Docker 组件(指定版本)
yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 docker-ce
  1. 启动 kubelet、docker,并设置开机启动(所有节点)
systemctl enable kubelet        # 设置 kubelet 服务开机自启,保证节点重启后自动启动
systemctl start kubelet         # 启动 kubelet 服务,负责管理 Kubernetes 节点上的 Pod 和容器
systemctl enable docker         # 设置 Docker 服务开机自启,保证节点重启后自动启动
systemctl start docker          # 启动 Docker 服务,提供容器运行环境
  1. 修改 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
  1. 用 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
  1. 把工作节点加入集群(只在工作节点跑)
# 用 kubeadm join 命令将工作节点加入 Kubernetes 集群,需替换为实际的 join 命令
kubeadm join 172.19.0.17:6443 --token m8usq6.6dou8eqq1g2f7zrd  --discovery-token-ca-cert-hash sha256:41e144f9a7cfeacf64eeace0ec7318d6768755a586cdd011ccd9a8ac7c84ced4
  1. 安装网络插件,否则 node 是 NotReady 状态(主节点跑)
# 为 Kubernetes 集群安装 Flannel 网络插件,确保各节点网络互通。
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  1. 查看节点状态
# 查看节点状态
kubectl get nodes