简述
Kubernetes(简称 K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序
关键特性
- 自动化部署和回滚:Kubernetes 可以自动化地部署和回滚应用程序,确保应用程序始终处于预期的状态。
- 服务发现和负载均衡:Kubernetes 提供内置的服务发现和负载均衡功能,确保流量自动分配到健康的容器实例。
- 存储编排:Kubernetes 支持挂载本地存储、云存储和网络存储等多种存储系统。
- 自我修复:Kubernetes 可以自动重启失败的容器、替换被杀死的容器、以及在节点不可用时重新调度容器。
- 水平扩展:Kubernetes 可以根据需求自动扩展或缩减容器实例的数量。
主要组件
- Master 节点:
- API Server:处理 REST 操作,提供集群的统一入口。
- etcd:分布式键值存储,用于存储集群的所有数据。
- Controller Manager:负责执行集群的控制逻辑,管理不同的控制器。
- Scheduler:调度器,负责将容器调度到合适的节点上运行。
- 工作节点(Node):
- Kubelet:运行在每个节点上,负责管理容器的生命周期。
- Kube-proxy:负责网络代理和负载均衡。
- 容器运行时:如 Docker 或 containerd,用于实际运行容器。从1.24版本之后不再使用docker作为运行时。
基本概念
- Pod:Kubernetes 中的最小部署单元,一个 Pod 可以包含一个或多个容器。
- Service:定义了一组 Pod 的访问策略,提供负载均衡和服务发现。
- Deployment:用于声明应用的期望状态,负责管理 Pod 的创建和更新。
- Namespace:用于将集群资源划分为逻辑上的组,以便不同的项目或团队使用。
搭建
环境准备
可以多节点部署,也可单节点部署。需要注意的是单节点部署要删除污点,否则无法部署应用
主机名 | IP地址 |
---|---|
master | 192.168.11.122 |
node | 192.168.11.127 |
1、禁用防火墙、selinux、swap
# 禁用防火墙
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# 禁用selinux
sudo sed -i 's/enforcing/disabled/' /etc/selinux/config #永久禁用
sudo setenforce 0 # 临时禁用
# 禁用swap
sudo swapoff -a # 临时禁用
sudo sed -ri 's/.*swap.*/#&/' /etc/fstab #永久禁用
2、将桥接的IPv4流量传递到iptables的链
以下为一条命令,可直接复制执行
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1 # 开启路由转发
net.bridge.bridge-nf-call-ip6tables = 1 # 开启桥流量监控
net.bridge.bridge-nf-call-iptables = 1 # 开启桥流量监控
EOF
# 生效
sudo sysctl --system
3、apt 切换国内源
Ubuntu 22.04换国内源 清华源 阿里源 中科大源 163源_ubuntu22阿里源-CSDN博客
系统版本:ubuntu22.04
其他版本可自行搜索,不同版本对应不同的代号
cat > /etc/apt/sources.list << EOF
# 清华源
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# 阿里源
deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
EOF
换源后,更新
apt-get update
4、时间同步
以下有两种方式,可任选其一
- 安装chrony
## 安装chrony
sudo apt-get update
sudo apt-get install chrony -y
## 启用并启动Chrony服务
sudo systemctl enable chrony
sudo systemctl start chrony
## 检查chrony状态,看时间是否同步
sudo chronyc tracking
- 安装ntpd
# 安装ntpd
sudo apt-get update
sudo apt-get install ntp
# 启动并启用 ntpd 服务
sudo systemctl start ntp
sudo systemctl enable ntp
# 检查 ntpd 状态
ntpq -p
更换时区
# 查看当前时区
timedatectl status
# 列出可用时区
timedatectl list-timezones
# 过滤时区列表
timedatectl list-timezones | grep Asia
# 更改时区
sudo timedatectl set-timezone Asia/Shanghai
# 验证时区更改
timedatectl status
安装k8s组件(所有节点)
- kubeadm:用来初始化k8s集群的指令。
- kubelet:在集群的每个节点上用来启动 Pod 和容器等。
- kubectl:用来与k8s集群通信的命令行工具,查看、创建、更新和删除各种资源。
官网:安装kubeadm、kubelet和kubectl
方式一:apt安装
1、更新 apt 包索引,安装k8s需要的依赖包
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
- ca-certificates 是 Linux 系统中一个非常重要的软件包,它包含了一系列的数字证书,这些证书用于验证 HTTPS 连接的安全性
- apt-transport-https 是一个 APT (Advanced Packaging Tool) 的传输层插件,它允许 APT 通过 HTTPS 协议来获取软件包。
2、下载用于 k8s 软件包仓库的公共签名密钥
如果 /etc/apt/keyrings
目录不存在
sudo mkdir -p -m 755 /etc/apt/keyrings
所有仓库都使用相同的签名密钥,因此你可以忽略URL中的版本:
sudo curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
3、添加 k8s apt 的源列表
-
注意版本
Kubernetes 1.31
; 对于其他 Kubernetes 版本,则需要更改
-
此操作会覆盖
/etc/apt/sources.list.d/kubernetes.list
中现存的所有配置 -
添加之后,直接install不指定版本会默认安装设置的源列表中1.31所有版本中的最新版
sudo echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
4、更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
执行成功后,可以看到相关依赖安装成功和安装的版本号
若想安装指定版本,可查询kubelet、kubeadm、kubectl可安装版本的列表
sudo apt-cache madison kubeadm
sudo apt-cache madison kubelet
sudo apt-cache madison kubectl
方式二:二进制包安装
二进制包地址(注意版本和架构替换),可自行下载或使用curl,wget等工具
地址: https://dl.k8s.io/release/版本/bin/linux/系统架构(amd64或arm64)/(kubeadm,kubelet,kubectl)
我这里使用最新版本,amd64架构
1、kubectl二进制包
https://dl.k8s.io/release/v1.31.3/bin/linux/amd64/kubectl
2、kubeadm二进制包
https://dl.k8s.io/release/v1.31.3/bin/linux/amd64/kubeadm
3、kubelet二进制包
https://dl.k8s.io/release/v1.31.3/bin/linux/amd64/kubelet
4、赋权并配置全局可执行
二进制包下载完成后,是执行文件,赋权
chmod +x kubeadm
chmod +x kubectl
chmod +x kubelet
配置全局可执行
cp kubeadm kubectl kubelet /usr/bin/
5、配置kubelet.service
vim /etc/systemd/system/kubelet.service
修改ExecStart为自己的kubelet的安装目录
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/bin/kubelet # 注意修改为kubelet执行文件所在目录
Restart=always
StartLimitInterval=0
RestartSec=10
[Install]
WantedBy=multi-user.target
设置kubelet开机自启动
sudo systemctl enable kubelet
以上为所有节点的配置,下面进行对master节点的单独配置
配置与初始化(master节点)
1、配置容器运行时(master节点)
官网:Container Runtimes
安装containerd
若安装了docker,可跳过containerd等安装,直接对containerd进行配置,若未安装过可以使用以下方式安装
下载containerd 二进制文件
- amd64(x86_64)版本
sudo wget https://github.com/containerd/containerd/releases/download/v1.6.12/containerd-1.6.12-linux-amd64.tar.gz
- arch64(arm64)版本
sudo wget https://github.com/containerd/containerd/releases/download/v1.6.12/containerd-1.6.12-linux-arm64.tar.gz
解压并安装
- amd64(x86_64)版本
sudo tar -xvf containerd-1.6.12-linux-amd64.tar.gz
- arch64(arm64)版本
sudo tar -xvf containerd-1.6.12-linux-arm64.tar.gz
将解压后的二进制文件内容移动到 /usr/local/bin 目录
sudo mv bin/* /usr/local/bin/
创建 containerd 的 systemd 服务文件containerd.service,执行一下命令写入配置
cat > /etc/systemd/system/containerd.service << EOF
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStart=/usr/local/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
EOF
至此,containerd安装完成,下面进行配置
配置containerd
创建配置文件
sudo mkdir -p /etc/containerd
生成容器运行时的默认配置,写入/etc/containerd/config.toml
sudo containerd config default > /etc/containerd/config.toml
进入配置文件,按ESC,输入"/<关键字>"查询内容
sudo vi /etc/containerd/config.toml
-
按ESC,进入命令模式。输入"/sandbox_image",找到位置后按Enter选中,按i进入插入模式,修改sandbox_image镜像为国内镜像,这里用的阿里云。若配置了代理可不用切换国内源,直接访问k8s镜像源拉取
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.10"
-
按ESC,输入"/SystemdCgroup"查询,修改
SystemdCgroup = true
,使用 systemd 作为容器的 cgroup 驱动程序 -
修改完成后按ESC,输入:wq保存退出
重启containerd,并设置开机自启sudo systemctl daemon-reload sudo systemctl restart containerd sudo systemctl enable containerd
2、配置cgroup驱动(master节点)
官网:配置cgroup驱动
方式一:输出默认配置文件,写入kubeadm-config.yaml中
sudo kubeadm config print init-defaults > kubeadm-config.yaml
配置详解:
kind: InitConfiguration(初始化过程的配置)
localAPIEndpoint.advertiseAddress:设置控制平面节点的广播地址,通常是节点的 IP 地址。
bootstrapTokens 用于配置集群的引导令牌(Bootstrap
Tokens)。在集群初始化时,允许新的节点加入集群。引导令牌是一种短期的、一次性的令牌,通常用于在集群初始化和节点加入过程中进行身份验证。
nodeRegistration.name:设置主节点名称。
nodeRegistration.criSocket:如果你使用的是containerd 而不是 Docker,设置为 “/run/containerd/containerd.sock”。
kind: ClusterConfiguration(集群的配置)
kubernetesVersion:指定 Kubernetes 版本,例如"v1.30.1"。
controlPlaneEndpoint:如果你有高可用性(HA)集群,设置控制平面通信的共享端点,例如 “master节点IP:6443”。
networking.podSubnet:指定 Pod网络的子网范围,例如 “10.244.0.0/16”
controllerManager 和 scheduler: 分别包含了控制器管理器和调度器的额外设置。
etcd:包含了etcd(Kubernetes的后端存储)的配置,可以是本地的也可以是外部的。
imageRepository:如果你使用自定义镜像仓库,设置镜像仓库地址,例如registry.aliyuncs.com/google_containers。
增加KubeletConfiguration的配置,设置cgroup驱动为systemd
在1.22及以上版本中,不设置cgroupDriver会默认为systemd,低版本注意修改。
--- # 分隔
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd # 使用 systemd 作为cgroup 驱动程序
修改配置文件
通过/<关键词>搜索 更改默认配置中的localAPIEndpoint.advertiseAddress
地址为节点ip、更改节点名称、切换镜像源为阿里源、指定 Pod 网络的 CIDR地址范围
localAPIEndpoint:
advertiseAddress: 192.168.11.122 # 主节点的IP
nodeRegistration:
name: master # 主节点的hostname
imageRepository: registry.aliyuncs.com/google_containers
networking:
podSubnet: 10.244.0.0/16 # 指定 Pod 网络的 CIDR(Classless Inter-Domain Routing)地址范围
方式二:最简配置,创建kubeadm-config.yaml,写入以下配置
以下配置版本为1.31。若安装的其他版本可以通过sudo kubeadm config print init-defaults
命令,将kubeadm.k8s.io/v1beta4
改为其输出的内容中对应的版本即可
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: stable
controlPlaneEndpoint: "192.168.11.122:6443" # master节点IP:6443
networking:
podSubnet: "10.244.0.0/16"
imageRepository: registry.aliyuncs.com/google_containers
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
3、初始化master节点
在kubeadm-config.yaml文件所在目录执行命令
sudo kubeadm init --config kubeadm-config.yaml
集群创建成功,执行提示命令,创建集群配置文件,开始使用集群
需要注意的是:
直接执行export KUBECONFIG=/etc/kubernetes/admin.conf
命令是有时效性的,关闭终端立即失效 ,所以也可在root用户执行命令创建配置文件
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
或者将export KUBECONFIG=/etc/kubernetes/admin.conf
放入shell配置文件~/.bashrc或~/.zshrc
中
稍等30s执行命令查看节点
kubectl get nodes
这个过程中可能遇到的问题 :【解决】k8s使用kubeadm初始化集群失败问题整理
工作节点加入集群(node节点)
主节点初始化集群成功后,会提示工作节点的加入命令,复制到工作节点执行即可(此处替换自己的)
kubeadm join 192.168.11.122:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:036843071148c8f7700062c2438b35c86b0dc5754011829b5cf83bb9379d88fa
此命令为集群初始化时生成的,toke有效期有限,后面加入集群,可执行以下命令:
1、在master节点获取 Join 命令
首先,你需要从集群的master节点
获取 kubeadm join 命令。执行以下命令来获取:
kubeadm token create --print-join-command
这将输出一个 kubeadm join 命令
kubeadm join 192.168.11.122:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
2、在工作节点上运行 输出的Join 命令
在node工作节点
上运行控制台输入的Join 命令,等待执行完成
3、验证节点是否加入集群
在主节点上运行以下命令,验证工作节点是否成功加入集群:
kubectl get nodes
能够看到新加入的节点出现在节点列表中
至此,集群创建并加入工作节点成功,接下来继续在master节点安装部署需要的组件
安装网络插件flannel
下载地址: kube-flannel.yml
可直接下载到本机,复制到远程
scp 本地文件路径 user@ip:远程路径
或者使用wget、curl等工具下载
sudo wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
下载完成后,部署到集群
kubectl apply -f kube-flannel.yml
等待flannel拉取必要组件镜像并完成初始化,查看所有组件的状态,必须全部Running才行
kubectl get pods --all-namespaces
这个过程中可能遇到的问题 :【解决】k8s使用flannel网络插件的问题整理
初始化PV、PVC
创建pv.yaml配置文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: "/mnt/data"
pvc.yaml配置文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: example-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: manual
部署pv和pvc
kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
验证pv和pvc
kubectl get pv
kubectl get pvc
在 Kubernetes (K8s) 中,持久卷 (Persistent Volume, PV) 和持久卷声明 (Persistent Volume Claim, PVC) 是用于管理持久存储的资源。
它们的主要目的是为容器化应用提供持久化存储,以便在 Pod重启或重新调度时数据不会丢失。
安装 ingress
来自: https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.1/deploy/static/provider/cloud/deploy.yaml
注意上面内容的ingress.yaml 复制下来后,需要设定 ingress 的外部地址:
按ESC进入命令模式,输入/kind: Service
搜索,按Enter后,N查找下一个,找到Service 中name为ingress-nginx-controller的配置项,在该配置的最下方加入:
externalIPs:
- 服务器ip
部署ingress
kubectl apply -f ingress.yaml
创建默认的 ingressCllass 配置文件ingress-class.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
部署 ingressClass
kubectl apply -f ingress-class.yaml
删除污点
如果是单节点部署,需要删除污点,否则无法部署运行应用 pod
kubectl taint nodes --all node-role.kubernetes.io/master-
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
部署安装应用
示例
编写my-dockerfile-nginx.yaml
文件
此文件主要是定义了一个 K8s 服务(Service)和一个部署(Deployment),用于运行一个基于 Nginx 的应用
apiVersion: v1
kind: Service
metadata:
name: my-dockerfile-nginx
spec:
ports:
- port: 8081 # 对外暴露的端口
targetPort: 80 # Nginx 内部监听的端口
nodePort: 31111 # NodePort访问端口
type: NodePort # NodePort类型的Service,可以通过Node的IP和NodePort访问到Service
selector:
app: my-dockerfile-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-dockerfile-nginx
labels:
app: my-dockerfile-nginx
spec:
replicas: 1 # 副本数
selector: # 选择器,用于选择replicas生效的Pod
matchLabels:
app: my-dockerfile-nginx
template:
metadata:
labels:
app: my-dockerfile-nginx
spec:
containers:
- name: my-dockerfile-nginx
image: liuhp6903/my-dockerfile-nginx:latest # 应用的镜像
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
部署到集群
kubectl apply -f my-dockerfile-nginx.yaml -n <指定namespace>
不指定命名空间,会部署到默认命名空间
等待pod创建并running,可以通过节点IP:nodePort在外部进行访问