Kubernetes 概述
Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。
容器化部署的优势
应用程序经历了 传统部署 > 虚拟化部署 > 容器部署。容器化部署的优势:
- 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
- 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性), 提供可靠且频繁的容器镜像构建和部署。
- 关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时, 从而将应用程序与基础架构分离。
- 可观察性:不仅可以显示 OS 级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
- 跨开发、测试和生产的环境一致性:在笔记本计算机上也可以和在云中运行一样的应用程序。
- 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
- 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
- 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
- 资源隔离:可预测的应用程序性能。
- 资源利用:高效率和高密度。
容器是打包和运行应用程序的好方式。在生产环境中, 你需要管理运行着应用程序的容器,并确保服务不会下线。 例如,如果一个容器发生故障,则你需要启动另一个容器。 如果此行为交由给系统处理,是不是会更容易一些?这就是 Kubernetes 要来做的事情!Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移你的应用、提供部署模式等。
Kubernetes 能做什么
Kubernetes 为你提供:
服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
自动完成装箱计算
你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。 你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。
自我修复
Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。
密钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
Kubernetes 不做什么
Kubernetes:
- 不限制支持的应用程序类型。 Kubernetes 旨在支持极其多种多样的工作负载,包括无状态、有状态和数据处理工作负载。 如果应用程序可以在容器中运行,那么它应该可以在 Kubernetes 上很好地运行。
- 不部署源代码,也不构建你的应用程序。 持续集成(CI)、交付和部署(CI/CD)工作流取决于组织的文化和偏好以及技术要求。
- 不提供应用程序级别的服务作为内置服务,例如中间件(例如消息中间件)、 数据处理框架(例如 Spark)、数据库(例如 MySQL)、缓存、集群存储系统 (例如 Ceph)。这样的组件可以在 Kubernetes 上运行,并且/或者可以由运行在 Kubernetes 上的应用程序通过可移植机制(例如开放服务代理)来访问。
- **不是日志记录、监视或警报的解决方案。 **它集成了一些功能作为概念证明,并提供了收集和导出指标的机制。
- 不提供也不要求配置用的语言、系统(例如 jsonnet),它提供了声明性 API, 该声明性 API 可以由任意形式的声明性规范所构成。
- 不提供也不采用任何全面的机器配置、维护、管理或自我修复系统。
- 此外,Kubernetes 不仅仅是一个编排系统,实际上它消除了编排的需要。 编排的技术定义是执行已定义的工作流程:首先执行 A,然后执行 B,再执行 C。 而 Kubernetes 包含了一组独立可组合的控制过程,可以持续地将当前状态驱动到所提供的预期状态。 你不需要在乎如何从 A 移动到 C,也不需要集中控制,这使得系统更易于使用且功能更强大、 系统更健壮,更为弹性和可扩展。
Kubernetes 安装
关闭 Debian 交换分区
先准备3台虚拟机,关闭交换分区(一个是性能问题,开启swap会严重影响性能(包括内存和I/O);另一个是管理问题,开启swap后通过cgroups设置的内存上限就会失效。有的时候可用内存很多也会swap,这时候关闭是为了避免swap带来的性能问题)。
- 编辑 /etc/fstab 文件,注释掉 swap 分区
- 修改 systemd 相关配置
# 查看与 swap 分区相关的 systemd 项
sudo systemctl --type swap --all
# 关闭相关项,保证重启之后 swap 分区不会被重新挂载
sudo systemctl mask dev-xxx.swap
参考:Debian 11 关闭 swap 遇到的问题和解决方案 - CSDN
修改 /etc/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"ip-forward": true,
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
}
添加软件源并安装(所有节点都要操作)
sudo apt-get update && apt-get install -y apt-transport-https
sudo curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
sudo cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
sudo apt update
sudo apt install -y kubelet=1.23.0-00 kubeadm=1.23.0-00 kubectl=1.23.0-00
初始化(仅在 Master 节点操作)
# --apiserver-advertise-address: apiserver监听的IP地址
# --control-plane-endpoint: 控制平面的IP或域名
# --pod-network-cidr: 指定pod网络可以使用的IP地址段
# --service-cidr: 指定service的虚拟网络IP段
# --token-ttl: 令牌过期时间,默认24小时,0表示永不过期。生产环境中最好设置一定的过期时间
kubeadm init \
--apiserver-advertise-address=192.168.31.150 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.23.0 \
--control-plane-endpoint 192.168.31.150 \
--service-cidr=10.100.0.0/16 \
--token-ttl 0 \
--pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
开机自启动 master
sudo systemctl enable kubelet
查看 kubelet 节点信息
sudo kubectl get nodes
# 只能看到 master 节点,状态为 NotReady
NAME STATUS ROLES AGE VERSION
satur01 NotReady control-plane,master 2d3h v1.23.0
加入节点
- 在工作节点执行初始化完成后的提示操作(注意替换为实际的提示操作)
# 获取 token
sudo kubeadm token list
-- bes778.t843utru84j9mxnw
# 获取 sha
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
-- 1ec9fabfa84ef1f3f3a4c024720632b6af1d3085fcaa80fd4608792051f431f9
--sha256:1ec9fabfa84ef1f3f3a4c024720632b6af1d3085fcaa80fd4608792051f431f9
sudo kubeadm join 192.168.31.150:6443 --token bes778.t843utru84j9mxnw --discovery-token-ca-cert-hash sha256:1ec9fabfa84ef1f3f3a4c024720632b6af1d3085fcaa80fd4608792051f431f9
- 查看节点列表
sudo kubectl get nodes
# 因为网络插件没装,所以NotReady
kubectl get componentstatus
kubectl get cs
kubectl get pods -n kube-system
安装Flannel网络插件(需要上github下载flanneld)
# 访问https://github.com/flannel-io/flannel#deploying-flannel-manually下载flanneld
# 将下载后的flanneld二进制文件放到/opt/bin目录,没可执行权限的话记得授权
# 执行以下命令,kube-flannel.yml内容见“附录 -> kube-flannel.yml”
sudo kubectl apply -f kube-flannel.yml
# 安装完成后再执行一遍kubectl get nodes,查看状态是否为Ready
安装 calico
获取 calico.yaml 到 /opt/k8s 下 : calico.yaml 并修改 docker.io 为 calico,使用 grep image calico.yaml
查看并下载镜像。
再查看应该没有 Pending 状态的容器
kubectl get pods -n kube-system