Kubernetes自学系列
第一篇 【自学Kubernetes一 ● 安装 】
Kubernetes基础
一.Kubernetes是什么?
Kubernetes(也被称为K8s)是一个开源的容器编排系统,用于自动化应用容器的部署、扩展和管理。它提供了声明式配置和自动化,使得系统更加健壮,可以更好地处理复杂的、分布式的系统。它是Google基于十多年的运行生产负载经验而设计的,并由Cloud Native Computing Foundation(CNCF)维护。
主要特性:
1.服务发现和负载均衡:Kubernetes 可以使用 DNS 名称或自己的 IP 地址暴露容器,如果流量过大,Kubernetes 可以负载均衡和分发网络流量,以保证部署稳定。
2.存储编排:Kubernetes 允许你自动挂载你选择的存储系统,比如本地存储、公共云提供商等。
3.自动部署和回滚:你可以描述你期望的部署状态,Kubernetes 可以将实际状态改变为期望状态。例如,你可以自动化 Kubernetes 来创建新的容器,删除现有的容器,采取所有的必要操作以达到你的期望状态。
4.自我修复:Kubernetes 可以重新启动失败的容器,替换容器,杀死不响应用户定义的健康检查的容器,直到它们准备好为用户提供服务。
5.密钥和配置管理:Kubernetes 可以存储和管理敏感信息,如密码、OAuth 令牌和 ssh 密钥。你可以在不重建镜像的情况下部署和更新密钥和应用配置。
总的来说,Kubernetes 可以提供一个平台,使得你可以更容易地管理、维护和扩展复杂的应用系统。
二.Kubernetes 核心组件:
Kubernetes的核心组件主要包括以下几个部分:
- Master节点组件:Master节点(也被称为控制平面)的组件是提供集群的全局控制。Master节点负责集群的全局决策(例如调度),以及检测和响应集群事件(例如,当副本控制器的副本数量不足时,启动新的副本)。
kube-apiserver:Kubernetes API服务器是集群的前端,提供了REST接口,所有的管理工具和Kubernetes组件都会与API服务器进行交互。
etcd:etcd是一个分布式的、一致性的键值存储,用于保存Kubernetes集群的所有数据。kube-scheduler:根据工作负载的资源需求、硬件/软件/策略约束、亲和性和反亲和性规格、数据位置、工作负载间的干扰和截止日期等因素,负责在集群中选择最优节点来运行未调度的Pods。
kube-controller-manager:运行控制器,这些控制器包括节点控制器、副本控制器、端点控制器、服务帐户和令牌控制器等。
cloud-controller-manager:运行云提供商特定的控制器循环。
- Node节点组件:Node节点是Kubernetes中的工作机器,这些机器可以是物理机或虚拟机。每个Node都需要运行Kubelet、Kube-proxy以及容器运行时,如Docker。
kubelet:负责维护Pods的生命周期,执行如启动、停止容器等操作。
kube-proxy:在每个Node上运行的网络代理,维护Node上的网络规则。
Container Runtime:容器运行时负责运行容器,例如Docker、containerd、CRI-O等。
以上就是Kubernetes的主要组件,它们共同工作,提供了一个强大、灵活和可扩展的容器编排平台。
三.Kubernetes 的安装:
官网安装部署:
首先看看官网地址,提供了各个操作系统的二进制文件以供安装,下载地址
官网推荐的最低部署机器配置:
内存:每台机器 2 GB以上
CPU:2个以上
按照官网的教程 使用kubeadm引导集群:
kubeadm是一个工具,它提供了kubeadm init
和kubeadm join
两个命令作为快速创建kubernetes集群的最佳实践
kubeadm init
用于启动集群的控制平面节点。
kubeadm join
用于将新节点加入到已有的集群中。
kubeadm帮助用户在虚拟机、物理服务器或在云上初始化和配置Kubernetes集群的主节点和工作节点。它不是一个部署工具,但它做了初始化集群的基础工作。
kubeadm的主要功能包括:
初始化主节点:创建一个Kubernetes控制平面节点。
sudo kubeadm init --apiserver-advertise-address=<your-ip-address> --pod-network-cidr=<network-cidr>
加入节点:将一个Kubernetes工作节点加入到集群中。
sudo kubeadm join <master-node-ip>:<master-node-port> --token <token> --discovery-token-ca-cert-hash <hash>
升级集群:将Kubernetes集群升级到新的版本。
sudo kubeadm upgrade apply v<new-version>
配置节点:在节点上配置Kubernetes和运行时设置。
创建令牌:为kubeadm join创建令牌。
sudo kubeadm token create
列出令牌:
sudo kubeadm token list
删除令牌:
sudo kubeadm token delete <token>
重置当前的 Kubernetes 集群:
sudo kubeadm reset
以CentOS9为例,跟着官网的教程一步步安装:
1.安装容器运行时:
Kubernetes 依赖于容器运行时,所以先安装容器运行时,我选择的是Containerd
官方安装运行时教程
Containerd入门说明
第一步下载Containerd文件并解压:下载地址(根据自己的操作系统选择合适的文件下载)
wget https://github.com/containerd/containerd/releases/download/v1.7.16/containerd-1.7.16-linux-amd64.tar.gz
sudo tar Cxzvf /usr/local containerd-1.7.16-linux-amd64.tar.gz
第二步,以服务运行Containerd
,下载服务文件到指定目录 /usr/local/lib/systemd/system/
wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
加载服务将Containerd
添加到开机启动并立刻运行
sudo systemctl daemon-reload
sudo systemctl enable --now containerd
查看服务状态
sudo systemctl status containerd
以下输出代表启动成功 (active (running)
)
Loaded: loaded (/usr/local/lib/systemd/system/containerd.service;
enabled; preset: disabled)
Active: active (running) since Sun 2024-04-28 15:15:39 HKT; 19h ago
Docs: https://containerd.io
Process: 76720 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS) Main PID: 76721 (containerd)
Tasks: 264
Memory: 1.0G
CPU: 11min 833ms
CGroup: /system.slice/containerd.service
第三步下载并安装runc
:
runc
是一个基础的、低级别的工具,用于创建和运行容器,直接管理容器的生命周期,它是许多更高级别的容器平台的基础
wget https://github.com/opencontainers/runc/releases/download/v1.2.0-rc.1/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
查看版本
runc --version
以下输出代表安装成功
runc version 1.1.12
commit: v1.1.12-0-g51d5e94
spec: 1.0.2-dev
go:go1.21.9
libseccomp: 2.5.2
第四步安装CNI
插件:
CNI
插件是实现容器网络的关键组件,它提供了一种标准的、插件化的方式来配置和管理容器的网络
wget https://github.com/containernetworking/plugins/releases/download/v1.4.1/cni-plugins-linux-amd64-v1.4.1.tgz
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.4.1.tgz
第五步修改配置文件 /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
让
runc
和Kubernetes
共享同一个cgroup
视图,这样Kubernetes
就可以准确地跟踪和限制Pod
的资源使用。如果runc
和Kubernetes
使用不同的cgroup
驱动程序,那么Kubernetes
可能无法准确地跟踪和限制Pod
的资源使用。
cgroup是Linux内核的一项功能,可以限制、记录和隔离进程组使用的物理资源(如CPU、内存、磁盘I/O等)
官方说 如果你的发行版 使用的是 cgroup v2,建议使用 cgroup 驱动程序
注意⚠️这里有个坑:
如果你和我一样 傻傻的将这段配置复制进去,你就会发现你的Kubernetes API服务
每过几分钟异常崩溃重启,崩溃之前用的好好的,
然后怀疑人生,五年前的一位老哥花了一周找解决方案,提出这个解决方案的人花了几个小时,而我花了一个小时
恭喜看到这里的你不用踩坑
我得到具体解决方案的帖子(五年前)
就是先生成默认配置到配置文件,然后修改项SystemdCgroup = true
修改完成后重启Containerd
服务
sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
OK,到此容器运行时准备完毕
2.安装kubeadm引导集群:
第一步将 SELinux 设置为permissive
模式(这是允许容器访问主机文件系统所必需的):
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
第二步2.添加 Kubernetes yum存储库(因为我是CentOS9,不同系统请看官网教程)
存储库定义中的参数exclude可确保与 Kubernetes 相关的包在运行时不会升级,yum update因为升级 Kubernetes
必须遵循特殊的过程。请注意,此存储库仅包含适用于 Kubernetes 1.30 的软件包
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
第三步安装最新的 kubelet
、kubeadm
和 kubectl
:
kubeadm:引导集群的命令。
kubelet:在集群中的所有机器上运行的组件,并执行诸如启动 Pod 和容器之类的操作。
kubectl:与集群对话的命令行实用程序。
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
添加到开机启动并立即启用 kubelet 服务
sudo systemctl enable --now kubelet
查看状态
sudo systemctl status kubelet
以下输出说明安装启动成功
kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since Sun 2024-04-28 15:15:39 HKT; 20h ago
Docs: https://kubernetes.io/docs/ Main PID: 76884 (kubelet)
Tasks: 15 (limit: 76140)
Memory: 49.8M
CPU: 23min 48.904s
CGroup: /system.slice/kubelet.service
第四步尝试使用kubeadm初始化控制主节点
sudo kubeadm init --apiserver-advertise-address=xxx.xxx.xxx.xxx --pod-network-cidr=10.244.0.0/16
Flannel
是一个为Kubernetes
提供网络功能的插件,它允许Pod
跨越不同的节点进行通信。Flannel
为每个节点分配一个子网,Pod的IP地址就从这个子网中分配。
10.244.0.0/16 是网络插件Flannel
的默认的网络地址范围,如果使用Flannel
可以不用修改
第五步指定 kubectl 命令使用的 kubeconfig
文件的位置(kubeconfig
文件包含了连接到 Kubernetes
集群和进行身份验证的信息。kubectl
命令需要这个文件来找到并连接到你的 Kubernetes
集群)
非root用户使用:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
sudo chown $(whoami):$(whoami) /etc/kubernetes/admin.conf
root用户使用:
crictl config --set runtime-endpoint=unix:///run/containerd/containerd.sock
vi ~/.bashrc
export KUBECONFIG=/etc/kubernetes/admin.conf
source ~/.bashrc
指定ENDPOINT 否则会有⚠️警告 默认端点已被废弃之类的
export CRI_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock
发现没有效果 还是会有警告
使用这个命令设置即可
crictl config --set runtime-endpoint=unix:///run/containerd/containerd.sock
WARN[0000] runtime connect using default endpoints:
[unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock
unix:///var/run/cri-dockerd.sock]. As the default settings are now
deprecated, you should set the endpoint instead. WARN[0000] image
connect using default endpoints:
[unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock
unix:///var/run/cri-dockerd.sock]. As the default settings are now
deprecated, you should set the endpoint instead.
第六步安装网络插件我用的是Flannel
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
到此Kubernetes 安装完成你可以部署新节点,服务应用程序了
常用命令:
检查集群状态:kubectl get nodes
获取pod (k8s的最小部署单元)kubectl get pods
Kubernetes应用配置文件命令: kubectl apply -f xxx.yml
Kubernetes 删除配置文件中定义的资源(注意,某些资源不会被删除)kubectl delete -f filename.yaml
获取StatefulSet 工作负载对象(用于管理有状态的应用)kubectl get statefulsets
进入pod容器内部 kubectl exec -it podname -- /bin/bash
获取 详情 kubectl describe 资源类型 pod name
查看日志 kubectl logs podname
查看kubelet日志:
journalctl -u kubelet --since "1 hour ago"
journalctl -u kubelet | tail -n 20
查看API服务状态
sudo crictl ps | grep kube-apiserver
修改配置后重启
kubectl apply -f filename.yml
kubectl rollout restart statefulset appname
四.踩坑指南:
1.Kubernetes 默认不支持在启用了交换空间的系统上运行
所以Kubernetes 在初始化之前有两个解决方案:
1.禁用交换空间。使用以下命令来禁用交换空间:
sudo swapoff -a
然后,编辑 /etc/fstab 文件,注释掉与 swap 相关的行,以防止在重启后交换空间被再次启用。
2.设置 --fail-swap-on 标志为 false。这将允许 kubelet 在启用了交换空间的系统上运行,但是这可能会影响 Kubernetes 的性能。你可以在 kubelet 的配置文件中添加这个标志。具体的步骤可以参考官网如何编辑 kubelet 配置文件的指南。
2.如果 /etc/kubernetes/admin.conf 文件失效或丢失,
可以在 Kubernetes 主节点上重新生成一个。以下是步骤:
1.首先,需要在主节点上以 root 用户身份运行以下命令,获取 Kubernetes API 服务器的证书和密钥:
cd /etc/kubernetes/pki
ls | grep -E 'apiserver.*'
应该能看到 apiserver.crt 和 apiserver.key 这两个文件。
2.然后,用 kubectl config
命令来创建一个新的 kubeconfig
文件。需要替换以下命令中的 为你的 Kubernetes 主节点的 IP 地址:
sudo kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://xxx.xxx.xxx.xxx:6443 \
--kubeconfig=admin.conf
sudo kubectl config set-credentials admin \
--client-certificate=/etc/kubernetes/pki/apiserver.crt \
--client-key=/etc/kubernetes/pki/apiserver.key \
--embed-certs=true \
--kubeconfig=admin.conf
sudo kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin \
--kubeconfig=admin.conf
sudo kubectl config use-context kubernetes --kubeconfig=admin.conf
这些命令将创建一个名为 admin.conf
的新 kubeconfig
文件,将它复制到 /etc/kubernetes/admin.conf
。
最后,更改新 kubeconfig
文件的所有权和权限,以便 kubelet
服务可以读取它:
sudo chown root:root admin.conf
sudo chmod 600 admin.conf
sudo mv admin.conf /etc/kubernetes/