一、前言
本篇是Kubernetes第二篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战。
Kubernetes系列文章:
二、Kubernetes搭建方式介绍和对比
Minikube
Minikube是一种可以在本地轻松运行Kubernetes的工具。Minikube在笔记本电脑的VM中运行单节点Kubernetes集群,供希望尝试Kubernetes或日常开发的用户测试使用。特点是不能启动生产集群,没有高可用性的单节点机器。
Kubeadm
Kubeadm是Kubernetes 1.4开始新增的特性,Kubeadm 是一个提供了 kubeadm init 和 kubeadm join 的工具, 作为创建 Kubernetes 集群的 “快捷途径” 的最佳实践。Kubeadm 通过执行必要的操作来启动和运行最小可用集群。 按照设计,它只关注启动引导,而非配置机器。同样的, 安装各种 “锦上添花” 的扩展,例如 Kubernetes Dashboard、 监控方案、以及特定云平台的扩展,都不在讨论范围内。Kubeadm是一种把 kubelet 直接运行在宿主机上,然后使用容器部署其他的 Kubernetes 组件的方案。
Kind
Kind 是 Kubernetes in Docker 的简写,是一个使用 Docker 容器作为 Nodes,在本地创建和运行 Kubernetes 群集的工具。适用于在本机创建 Kubernetes 群集环境进行开发和测试。Kind 使用kubeadm创建和启动群集节点,使用 containerd 作为容器运行时。
二进制包
二进制包就是在官网下载相关的组件的二进制包,相对于上面两种快速搭建集群的方式,其实就是相当于用程序脚本帮我们装好了集群,前两者属于自动部署,简化部署操作,自动部署屏蔽了很多细节,使得对各个模块感知很少,遇到问题很难排查,如果手动安装,对Kubernetes理解也会更全面。二进制包目前生产环境的主流搭建方式,已在生产环境验证,kubeadm也可以搭建生产环境。
三、使用Kubeadm搭建Kubernetes学习环境习
环境
这里我简单说下我为啥选择Kubeadm作为自己搭建集群工具,Kind、Minikube实在是太简单,根本让我们感觉不到一点困难,Kubeadm可以让我们适当体验Kubernetes搭建过程,去理解一些组件之间的交互,二进制才是我们终极目标,我只是刚开始不想让大家被安装就抹灭了学习Kubernetes的兴趣。
配置说明
在搭建K8S集群时,推荐在阿里云或腾讯云采购如下配置(当然也可以使用自己虚机):
- 至少2台2C2G的服务器,最好2C4G或者8G,2G的话内存单存Kubernetes就会占用一般,后面不太方便大家做实验,我采用的2台2C4G阿里云机器;
- 系统的话大家采用CentOS 7.X 或 CentOS 8.X的版本,这里我采用8.2的版本;
搭建前准备工作
注意:我这里采用的Kubernetes1.21.2和Docker 20.10.7的版本,大家注意下版本问题。
查看Linux版本
#所有机器都进行检查 cat /etc/redhat-release
修改hostname
#这里强烈建议修改hostname,这样子在集群列表查询的时候很很明确 #修改hostname hostnamectl set-hostname demo-master-1 #检查是否修改成功 hostname #设置hostname解析 类似windows的host解析 echo "127.0.0.1 $(hostname)" >> /etc/hosts
查看网络
#查看内网ip地址 找到eth0 ip add #使用ping命令保证每个节点都是IP地址必须可以互通 ping #关闭防火墙 systemctl stop firewalld systemctl disable firewalld
image.png
Docker安装
可以参考我的这篇博文;
安装 kubeadm、kubelet 和 kubectl
- 配置配置Kubernetes的yum源;
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
- 如果存在旧版本首先卸载旧版本,安装kubelet、kubeadm、kubectl,如果非Master可以不安装kubectl;
#卸载Kubernetes yum remove -y kubelet kubeadm kubectl #安装 yum install -y kubelet-1.21.2 kubeadm-1.21.2 kubectl-1.21.2 #非master可以采用以下命令 yum install -y kubelet-1.21.2 kubeadm-1.21.2
- 关闭Swap,这里简单聊下Kubernetes为什么会关闭Swap?Swap Space是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者是他们的组合。简单点说,当系统物理内存吃紧时,Linux会将内存中不常访问的数据保存到Swap上,这样系统就有更多的物理内存为各个进程服务,而当系统需要访问Swap上存储的内容时,再将Swap上的数据加载到内存中。Kubernetes关闭Swap一个是性能问题,开启Swap会严重影响性能(包括内存和I/O);另一个是管理问题,开启Swap后通过Cgroups设置的内存上限就会失效,如果不关闭Kubernetes运行会出现错误, 即使安装成功了,node重启后也会出现kubernetes server运行错误;
swapoff -a yes | cp /etc/fstab /etc/fstab_bak cat /etc/fstab_bak |grep -v swap > /etc/fstab
- 关闭SeLinux,也简单聊一下为什么关闭SeLinux?SELinux(Secure Enhanced Linux)安全增强的Linux是美国国家安全局NSA针对计算机基础结构安全开发的一个全新的Linux安全策略机制。SELinux可以允许系统管理员更加灵活的来定义安全策略。SELinux是一个内核级别的安全机制,从Linux2.6内核之后就将SELinux集成在了内核当中,因为SELinux是内核级别的,所以我们对于其配置文件的修改都是需要重新启动操作系统才能生效的。现在主流发现的Linux版本里面都集成了SELinux机制,CentOS/RHEL都会默认开启SELinux机制。这里为什么建议大家关闭SeLinux,我相信不是专门的运维可能懂这个的人也不多,所以为了防止大家遇到一些奇怪的问题,就把它关闭吧;
setenforce 0 sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
- 将Docker的Cgroup Driver 修改为systemd并且更改Docker为国内的镜像加速器,不然在为Kubernetes集群添加节点时会报错;
#修改docker/daemon.json cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "registry-mirrors":[ "https://kfwkfulq.mirror.aliyuncs.com", "https://2lqq34jg.mirror.aliyuncs.com", "https://pee6w651.mirror.aliyuncs.com", "http://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn", "https://registry.docker-cn.com" ] } EOF mkdir -p /etc/systemd/system/docker.service.d
- 设置网络配置相关的参数;
#增加配置 cat <<EOF > /etc/sysctl.d/ k8s.confnet.ipv4.ip_forward=1 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF #加载 sysctl --system
- 重启docker,并设置开机启动kubelet;
# 重启docker,并启动 kubelet systemctl daemon-reloadsy stemctl restart docker systemctl enable kubelet && systemctl start kubelet
初始化Master
- 配置Host相关内容;
#只在master节点执行 export MASTER_IP=172.21.122.230 #替换为自己hostName export APISERVER_NAME=demo-master-1 #设置Kubernetes容器组所在的网段 export POD_SUBNET=10.100.0.0/16echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
- 配置kubeadm-config.xml相关参数,可以参考该文章,具体学习下参数含义;
#删除默认是版本 rm -f ./kubeadm-config.yaml #编辑kubeadm-config cat <<EOF > ./kubeadm-config.yaml #api的版本 apiVersion: kubeadm.k8s.io/v1beta2 #配置的种类 kind: ClusterConfiguration #版本 kubernetesVersion: v1.21.2 #镜像拉取地址 imageRepository: registry.aliyuncs.com/google_containers #api默认绑定的端口 controlPlaneEndpoint: "${APISERVER_NAME}:6443" #自定义的网络 networking: serviceSubnet: "10.96.0.0/16" podSubnet: "${POD_SUBNET}" dnsDomain: "cluster.local" EOF
- 初始化初始化Master节点,成功以后大致信息如下图;
kubeadm init --config=kubeadm-config.yaml --upload-certs
- image.png如果出现以下错误,说明安装过kubeadm,使用以下命令进行初始化:
kubeadm reset -f
- image.png
- 配置kubectl;
rm -rf /root/.kube/ mkdir /root/.kube/ cp -i /etc/kubernetes/admin.conf /root/.kube/config
- 检查节点初始化的情况;
#查看各个组件执行的情况 watch kubectl get pod -n kube-system -o wide #查看Master节点情况 kubectl get nodes -o wide
安装网络插件
这里我选择了Flannel作为我的网络插件;
export POD_SUBNET=10.100.0.0/16 kubectl apply -f https://kuboard.cn/install-script/v1.21.x/calico-operator.yaml wget https://kuboard.cn/install-script/flannel/flannel-v0.14.0.yaml sed -i "s#10.244.0.0/16#${POD_SUBNET}#" flannel-v0.14.0.yaml kubectl apply -f ./flannel-v0.14.0.yaml
初始化Work节点
- 在Master节点上获取join参数;
kubeadm token create --print-join-command
- 配置Work节点的host信息;
# 替换为master节点IP export MASTER_IP=172.21.122.230 # 替换为Master节点hostName export APISERVER_NAME=demo-master-1 echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
- 初始化Work节点,执行Master节点上获取到的Join参数;
image.png
- 在Master上检查初始化结果;
kubectl get nodes -o wide
image.png
恭喜你,至此安装完成!
四、实战
这个案例就简单创建一个运行着Nginx的Pod,体验一把Kubernetes的使用,此外建议大家再开始学习阶段不要去使用一些图形化工具,先把一些命令整体去了解一下,以后在使用图形化界面。
- 创建一个nginx-deployment.yaml文件,这里大家可以使用vscode去编辑,然后同步到服务器上,应该vscode也可以直接同步到服务器上,具体怎么配置大家自行百度,编写如下内容:
#api版本 apiVersion: apps/v1 #指定资源的角色 kind: Deployment #元数据名称 metadata: name: nginx-deployment #指定该资源的内容详情 spec: #选择器 selector: matchLabels: app: nginx #Pod的定义 template: metadata: labels: app: nginx #指定该资源的内容 spec: containers: #容器名称 - name: nginx #镜像版本 image: nginx:latest #资源的限制 resources: limits: memory: "128Mi" cpu: "500m" #暴露的端口 ports: - containerPort: 80
- 在Master上运行该资源;
kubectl create -f nginx-deployment.yaml
- 检查资源是否创建成功,这里我通过标签选择器进行查看,所以跟-l的参数;
kubectl get pods -l app=nginx
image.png
- 查看Pod的整个详情;
#后面跟着具体的pod名称 kubectl describe pod nginx-deployment-7dc45fbd74-5bh2z