1.什么是Kubernetes?
K8s(Kubernetes)是一个开源容器编排工具,用于自动部署、扩展和管理容器化应用。它可以帮助我们管理由成百上千个容器组成的应用程序,也可以帮助们在不同的环境中(例如,物理机、虚拟机、云环境或者混合的部署环境)管理这些应用程序。
K8s 最初由 Google 开发,它在 Google 的大规模容器编排系统(Borg)的基础上演化而来。Borg是谷歌内部的大规模集群管理系统,负责对谷歌内部很多核心服务的调度和管理,Borg的目的是让用户能够不必操心资源管理的问题,让他们专注于自己的核心业务,并且做到跨多个数据中心的资源利用率最大化。它现在由 Cloud Native Computing Foundation (CNCF) 管理,并且已经成为了 CNCF 的顶级项目。
总之,K8s 的主要作用是解决容器化应用程序的编排和管理问题,从而帮助开发人员更轻松地构建和维护分布式系统。
2.kubernetes 组件简介
2.1 kube-apiserver
API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作,提供了k8s各类资源对象的增删改查及watch等HTTP Rest接口,这些对象包括pods、services、replicationcontrollers等。API Server为REST操作提供服务,并为集群的共享状态提供前端,所有其他组件都通过该前端进行交互。通常我们可以通过命令行工具kubectl来与Kubernetes API Server交互,它们之间的接口是REST调用。kube-apiserver端口默认值是6443,可通过启动参数“--secure-port”来修改默认值,默认监听IP为0.0.0.0及本机所有IP,可通过启动参数“--bind-address”设置监听指定的内网IP。
Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。
简言之,kube-apiserver是集群管理的API入口,是资源配额控制的入口,提供了完备的集群安全机制。打一个比较生动的比喻:是Kubernetes的唯一一个操作控制入口,即任何命令,任何操作都只能通过kube-apiserver来下发。
2.2 kube-scheduler
kube-scheduler 是控制平面的组件, 负责监视新创建的、未指定运行节点的 Pods, 并选择节点来让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
2.3 kube-controller-manager
kube-controller-manager是控制平面的组件, 负责运行控制器进程。从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。
这些控制器包括:
节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
端点分片控制器(EndpointSlice controller):填充端点分片(EndpointSlice)对象(以提供 Service 和 Pod 之间的链接)。
服务账号控制器(ServiceAccount controller):为新的命名空间创建默认的服务账号(ServiceAccount)。
2.4 kube-proxy
kube-proxy 是集群中每个节点上所运行的网络代理, 实现 Kubernetes 服务 概念的一部分。kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。
2.5 kubelet
kubelet会在集群中每个节点上运行,它保证容器都运行在 Pod中。kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
2.6 kubectl
kubectl 作为客户端CLI工具,可以让用户通过命令行对 Kubernetes集群进行操作。kubectl在$HOME/.kube目录中查找一个名为config的配置文件。可以通过设置KUBECONFIG环境变量或设置--kubeconfig参数来指定其它kubeconfig文件。
2.7 etcd
etcd 是Core0S公司开发目前是Kubernetes默认使用的key-value数据存储系统,用于保存kubernetes的所有集群数据,etcd支持分布式集群功能,生产环境使用时需要为etcd数据提供定期备份机制。
2.8 DNS
尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。
2.9 Dashboard
Dashboard是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除。
3.安装
安装虚拟机环境:ubuntu-22.04,可连接外网
3.1 Containerd安装
3.1.1 Containerd简介
containerd是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性。containerd可以在宿主机中管理完整的容器生命周期,包括容器镜像的传输和存储、容器的执行和管理、存储和网络等。
PS:自k8s 1.23版本之后,已经不支持docker了,所以本文后面的都是已containerd为主。
3.1.2 Containerd的apt安装
1)验证仓库版本:apt-cache madison containerd
2)安装containerd:
a)使用命令直接安装:apt install containerd=1.6.12-0ubuntu1~22.04.1
①验证安装之后的环境,使用命令:whereis runc、whereis containerd、runc -v、 containerd -v
②修改配置文件:
查看配置文件:containerd --help | grep config
创建默认配置文件目录:mkdir /etc/containerd/
查看默认配置: containerd config default
如果需要修改配置文件,可将配置文件重定向: containerd config default > /etc/containerd/config.toml
重定向之后,需重启配置文件: systemctl restart containerd.service
为解决后续出现的下载阻塞问题,可先修改镜像下载地址,将图1位置地址改为图2地址(此处地址修改为任何可下载的地址)
b)二进制安装:
①网络畅通的前提下,可以直接下载:wget:https://github.com/containerd/containerd/releases/download/v1.6.20/containerd-1.6.20-linux-amd64.tar.gz
②网络不那么畅通的前提下,可以手动在github上下载之后,拷贝到虚拟机上,下载地址:https://github.com/kubernetes-sigs/cri-tools/releases/
下载完成之后,直接解压,解压命令:tar xvf containerd-1.6.20-linux-amd64.tar.gz
copy⼆进制:cp bin/* /usr/local/bin/
验证containerd执⾏结果:containerd -v
创建service⽂件:vim /lib/systemd/system/containerd.service
编辑配置文件:mkdir /etc/containerd
重定向文件:containerd config default > /etc/containerd/config.toml
修改镜像地址:vim /etc/containerd/config.toml (同使用apt安装)
部署runc:wget:https://github.com/opencontainers/runc/releases/download/v1.1.5/runc.amd64,chmod a+x runc.amd64,mv runc.amd64 /usr/bin/runc
3.2 安装nerdctl
3.2.1 nerdctl简介
nerdctl是一个较新的containerd工具,兼容Docker命令行工具,比ctr覆盖更全面,另外还支持docker-compose(不包括swarm)以及一些可选的高级特性。本次学习主要以nerdctl为主。
3.2.2 安装nerdctl
a)下载:wget https://github.com/containerd/nerdctl/releases/download/v1.3.0/nerdctl-1.3.0-linux amd64.tar.gz
b)解压在特定的某文件夹下:tar xvf nerdctl-1.3.0-linux-amd64.tar.gz -C /usr/local/bin/
c)查看版本: nerdctl version
d)nerdctl配置⽂件:
创建文件:mkdir /etc/nerdctl/
编辑文件:vim /etc/nerdctl/nerdctl.toml
3.3 安装CNI
3.3.1 CNI简介
容器网络,它定义了一套接口标准,提供了规范文档以及一些标准实现。采用CNI规范来设置容器网络的容器平台不需要关注网络的设置的细节,只需要按CNI规范来调用CNI接口即可实现网络的设置。简言之,就是一个网络接口,用于给容器配置网络信息。
3.3.2 安装
a)下载命令:wget:https://github.com/containernetworking/plugins/releases/download/v1.2.0/cni-plugins linux-amd64-v1.2.0.tgz
b)解压到指定目录:tar xvf cni-plugins-linux-amd64-v1.2.0.tgz -C /opt/cni/bin/
完成之后测试网络:nerdctl run -d -p 80:80 --name=nginx-web1 --restart=always nginx
访问宿主机的80端口:
c)创建Tomcat测试容器并指定端⼝:
nerdctl run -d -p 8080:8080 --name=tomcat-web1 --restart=always tomcat:7.0.88-alpine
d)创建MySQL测试容器并指定端⼝
nerdctl run -t -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=MySQL127336 -d mysql:5.6.39
测试远程连接MySQL
apt install mariadb-client,mysql -uroot -pMySQL127336 -h192.168.0.130
3.4 安装kubeadm基础环境
a)安装运⾏
二进制安装:tar xvf runtime-docker20.10.19-containerd1.6.20-binary-install.tar.gz
执行脚本:bash runtime-install.sh containerd
Ubuntu 2204在/etc/containerd/config.toml的这个位置必须改为true
b)安装kubeadm、kubectl、kubelet
apt-get update && apt-get install -y apt-transport-https -y
apt install kubeadm=1.26.3-00 kubelet=1.26.3-00 kubectl=1.26.3-00
导入Key:curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
更新源文件:cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
> deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
> EOF
更新源之后,apt-get update && apt-cache madison kubeadm
c)下载kubenetes镜像
安装指定版本(Master和node都需要装):kubeadm config images list --kubenetes-version v1.26.3
编辑下载镜像源文件和下载版本:vim images-down.sh
#!/bin/bash
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.26.3
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller manager:v1.26.3
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.26.3
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.26.3
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.6-0
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.9.3
执行脚本:bash images-down.sh
d) 内核参数优化(Master和node都需要):cat /etc/sysctl.conf
net.ipv4.ip_forward=1 #启用路由转发功能
vm.max_map_count=262144
kernel.pid_max=4194303
fs.file-max=1000000
net.ipv4.tcp_max_tw_buckets=6000
net.netfilter.nf_conntrack_max=2097152
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1 #使用内核支持对网桥的检查
vm.swappiness=0
内核模块开机挂载:vim /etc/modules-load.d/modules.conf
ip_vs
ip_vs_lc
ip_vs_lblc
ip_vs_lblcr
ip_vs_rr
ip_vs_wrr
ip_vs_sh
ip_vs_dh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
ip_tables
ip_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
xt_set
br_netfilter
nf_conntrack
overlay
优化最大文件数:vim /etc/security/limits.conf
root soft core unlimited
root hard core unlimited
root soft nofile 1000000
root hard nofile 1000000
root soft nproc 1000000
root hard nproc 1000000
root hard memlock 32000
root soft memlock 32000
root soft msgqueue 8192000
root hard msgqueue 8192000
优化之后重启:reboot
验证服务器模块: lsmod | grep br_netfilter
关闭交换分区:
sudo swapoff -a #临时生效
sudo sed -i '/ swap / s/^(.*)$/#1/g' /etc/fstab #永久生效
确认是否关闭交换分区:free -m
3.5 kubernetes集群初始化
3.5.1 命令行
kubeadm init --apiserver-advertise-address=192.168.0.130(此处IP为需要配置的虚拟机IP--一般为主机IP) --apiserver-bind-port=6443 --kubernetes-version=v1.26.3 --pod-network-cidr=10.100.0.0/16 --service-cidr=10.200.0.0/16 --service-dns-domain=cluster.local --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --ignore-preflight-errors=swap(最后一句是忽略分区报错)
完成初始化如截图所示:
按照初始化,配置文件:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
添加新节点命令:kubeadm join 192.168.0.130:6443 --token 0ghyae.5r70wd5n6ddptvbj \ --discovery-token-ca-cert-hash sha256:abdea63c8074a01706ccc50d7545e462ab0cdd6e15779921f385d4927ed55978
当出现如下图所示的时候,就说明节点加入成功了。
如果有报错,可查看日志:tail /var/log/syslog
3.5.2 基于initial文件初始化推荐:
将默认配置输出至文件:kubeadm config print init-defaults > kubeadm-init.yaml
修改初始化后的文件:vim kubeadm-init.yaml
此处修改IP为本地虚拟机IP,并指定配置
指定kubelet使用systemd
kind: kubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1betal
cgroupDriver: systemd
指定KubeProxy使用ipvs
apiVersion: kubeproxy.config.k8s.io/v1alphal
kind: KubeProxyConfiguration
mode: ipvs
3.6 部署网络组件
3.6.1 安装flannel
下载flannel的yml文件:https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml,下载之后修改网络地址。
3.6.2 安装calico
同flannel,也得先下载对应的yml文件,下载之后修改网络地址,这个网络地址也是Master初始化的网络地址以及子网数量。
配置本机默认网卡(可通过ip addr查看本机网卡):
执行命令:kubectl apply -f calico-ipip_ubuntu2004-k8s-1.26.x.yaml
验证环境是否可用:kubeclt get pod -A
部署nginx
验证完成:
部署tomcat并验证: