本地VMWare环境搭建1.28版本K8S
环境规划
k8s环境规划
podSubnet(pod网段) 10.244.0.0/16
serviceSubnet(service网段): 10.96.0.0/12
实验环境规划
操作系统:centos7.9
配置: 1Gib内存/8vCPU/20G硬盘
网络:NAT模式
| K8S集群角色 | IP | 主机名 | 安装的组件 |
|---|---|---|---|
| 控制节点 | 192.168.40.180 | master-1 | apiserver、controller-manager、scheduler、kubelet、etcd、kube-proxy、容器运行时、calico |
| 工作节点 | 192.168.40.181 | node-1 | Kube-proxy、calico、coredns、容器运行时、kubelet |
| 工作节点 | 192.168.40.182 | node-2 | Kube-proxy、calico、coredns、容器运行时、kubelet |
虚拟机准备
配置VMware虚拟机
- 安装VMware
- 下载CentOS7镜像
- 配置VMWare虚拟机,使用NAT模式。
- 安装CentOS系统
配置CentOS虚拟机网络
-
新搭建出来的虚拟机默认没有IP,需要先修改配置文件加一个IP
-
vmware-编辑-虚拟机网络编辑器,先把网段和子网掩码设置好:

- 修改网卡配置文件
vi /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static #static表示静态ip地址
IPADDR=192.168.40.180 #ip地址,需要跟自己电脑所在网段一致
NETMASK=255.255.255.0
GATEWAY=192.168.40.2
DNS1=192.168.40.2
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33 #网卡名字,跟DEVICE名字保持一致即可
DEVICE=ens33 #网卡设备名,ip addr可看到自己的这个网卡设备名
ONBOOT=yes #开机自启动网络,必须是yes
关闭Selinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
reboot
SSH连接
- VSCod直接配置ssh host文件用内网IP登录。
免密登录
-
客户端ssh-keygen生成公钥
-
把公钥复制到服务器端
mkdir -p ~/.ssh/
touch ~/.ssh/authorized_keys
vi ~/.ssh/authorized_keys
#将公钥值复制进去
- 编辑ssh配置文件
sudo vim /etc/ssh/sshd_config
#PubkeyAuthentication yes注释去掉,才可以使用公钥验证
- 重启ssh服务
systemctl restart sshd.service
- VsCode的ssh配置文件中加入公钥位置
Host 192.168.40.180
HostName 192.168.40.180
User root
IdentityFile /C:/Users/hangx/.ssh/id_rsa
克隆两台工作节点
-
虚拟机关机-右键克隆出两台新机器
-
修改两台机器网卡配置文件,配置静态IP
vi /etc/sysconfig/network-scripts/ifcfg-ens33
#IP修改成192.168.40.181,192.168.40.182
配置k8s环境准备
替换阿里云repo源
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum makecache
替换阿里云的epel源
yum install -y wget
wget -O /etc/yum.repos.d/epel-7.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
升级系统到centos7.9
yum update -y
配置主机名
hostnamectl set-hostname master-1 && bash
hostnamectl set-hostname node-1 && bash
hostnamectl set-hostname node-2 && bash
配置hosts文件
vim /etc/hosts
192.168.40.180 master-1
192.168.40.181 node-1
192.168.40.182 node-2
tee -a /etc/hosts <<'EOF'
172.16.183.75 master1
172.16.183.76 node1
EOF
配置主机间无密码登录
ssh-keygen
ssh-copy-id master-1
ssh-copy-id node-1
ssh-copy-id node-2
关闭交换分区
swapoff -a
vim /etc/fstab
#/dev/mapper/centos-swap swap swap defaults 0 0
配置阿里云repo源
- 配置基础repo源
#备份基础repo源
mkdir /root/repo.bak
cd /etc/yum.repos.d/
mv * /root/repo.bak/
#课件里面的阿里云的repo源
#把CentOS-Base.repo和epel.repo文件上传到master1主机的/etc/yum.repos.d/目录下
chmod o+w /etc/yum.repos.d
- 配置阿里云docker的repo源
yum install yum-utils -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#会把阿里云的docker源的配置给拉下来。
- 配置安装k8s组件的阿里云repo源
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF
安装基础软件包
yum install -y device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack telnet ipvsadm openssh-clients
yum install如果出现报错:GPG key retrieval failed: [Errno 14] curl#37 - "Couldn't open file /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7"
意思是,yum源开启了GPG校验,需要在/etc/pki/rpm-gpg目录下存在对应安装文件的公钥文件,才能完成校验。
可以关闭掉校验:
sed -i 's/pgcheck=1/pgcheck=0/g' /etc/yum.repos.d/epel.repo
配置时间同步
#安装ntpdate命令
yum install ntpdate -y
#跟网络时间做同步
ntpdate cn.pool.ntp.org
#把时间同步做成计划任务
crontab -e
* */1 * * * /usr/sbin/ntpdate cn.pool.ntp.org
#重启crond服务
service crond restart
禁用firewalld
systemctl stop firewalld && systemctl disable firewalld
修改内核参数-开路由转发
modprobe br_netfilter
echo "modprobe br_netfilter" >> /etc/profile
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf
安装K8S组件
安装配置containerd
yum install containerd.io-1.6.6 -y #1.27也是用这个版本
#生成 containerd 的配置文件:
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
#修改配置文件,1.26和1.27配置一样
#SystemdCgroup = true表示containerd驱动用systemd,在 Kubernetes 中,容器运行时需要与宿主机的 cgroup 和 namespace 进行交互,以管理容器的资源。
#对于 cgroup 的驱动程序,Docker 和 Containerd 默认都使用的是 cgroupfs。#systemd-cgroup 则是 Systemd 对 cgroup 的一个实现。
#相比 cgroupfs,systemd-cgroup 在资源隔离方面提供了更好的性能和更多的特性。例如,systemd-cgroup 可以使用更多的内存压缩算法,以便更有效地使用内存。此外,systemd-cgroup 还提供了更好的 cgroup 监控和控制机制,可以更精确地调整容器的资源使用量。总之,使用 systemd-cgroup 作为容器运行时的 cgroup 驱动程序,可以提高 Kubernetes 集群中容器的资源管理效率,从而提升整个集群的性能。
#将sandbox_image设置为阿里云镜像仓库中的pause:3.7,在 Kubernetes 中,每个 Pod 中都有一个 pause 容器,这个容器不会运行任何应用,只是简单地 sleep。它的作用是为了保证 Pod 中所有的容器共享同一个网络命名空间和 IPC 命名空间。pause 容器会在 Pod 的初始化过程中首先启动,然后为 Pod 中的其他容器创建对应的网络和 IPC 命名空间,并且在其他容器启动之前保持运行状态,以保证其他容器可以加入到共享的命名空间中。
#简单来说,pause 容器就是一个占位符,它为 Pod 中的其他容器提供了一个共享的环境,使它们可以共享同一个网络和 IPC 命名空间。这也是 Kubernetes 实现容器间通信和网络隔离的重要机制之一。
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
vim /etc/containerd/config.toml
sandbox_image = "k8s.gcr.io/pause:3.6" ==> sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"
#配置 containerd 开机启动,并启动 containerd
systemctl enable containerd --now
#修改/etc/crictl.yaml文件,指定k8s的运行时和拉取镜像都使用containerd
#这个文件是 crictl 工具的配置文件,用于指定与 containerd 交互的相关设置:
#指定unix:///run/containerd/containerd.sock 是为了告诉 crictl 使用 Unix 域套接字的方式来连接 containerd 的 API。containerd 提供了一个 socket 文件 /run/containerd/containerd.sock,crictl 通过连接该 socket 文件,可以与 containerd 进行通信,管理容器和镜像等操作。
#runtime-endpoint:指定 containerd 的运行时接口地址:crictl 可以与 containerd 通信来管理容器生命周期和资源隔离。
#image-endpoint:指定 containerd 的镜像接口地址:以便 crictl 可以与 containerd 通信来管理镜像的拉取和推送。
#timeout:指定 crictl 等待 containerd 响应的最大时间,避免出现无响应的情况。
#debug:开启或关闭 crictl 的调试模式,方便排查问题。
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
systemctl restart containerd
#配置containerd镜像加速器,k8s所有节点均按照以下配置:
mkdir /etc/containerd/certs.d/docker.io/ -p
tee -a /etc/containerd/certs.d/docker.io/hosts.toml <<'EOF'
[host."https://docker.m.daocloud.io"]
capabilities = ["pull"]
EOF
vim /etc/containerd/config.toml
config_path = "" ==> config_path = "/etc/containerd/certs.d"
#保存退出
systemctl restart containerd
ctr和crictl区别
背景:在部署k8s的过程中,经常要对镜像进行操作(拉取、删除、查看等)
问题:使用过程中会发现ctr和crictl有很多相同功能,也有些不同,那区别到底在哪里?
说明:
ctr是containerd自带的CLI命令行工具,crictl是k8s中CRI(容器运行时接口)的客户端,k8s使用该客户端和containerd进行交互;
cat /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
pull-image-on-create: false
disable-pull-on-run: false
2.ctr和crictl命令具体区别如下,也可以--help查看。
- crictl缺少对具体镜像的管理能力,可能是k8s层面镜像管理可以由用户自行控制,能配置pod里面容器的统一镜像仓库,镜像的管理可以有habor等插件进行处理。
![]()
(注:docker save -o打包的镜像,用ctr -n=k8s.io images import可以解压出来)
安装配置docker
#docker也要安装,docker跟containerd不冲突,安装docker是为了能基于dockerfile构建镜像
yum install docker-ce -y
systemctl enable docker --now
#配置docker镜像加速器,k8s所有节点均按照以下配置
tee /etc/docker/daemon.json <<'EOF'
{
"registry-mirrors":["https://docker.m.daocloud.io"]
}
EOF
#重启docker:
systemctl daemon-reload && systemctl restart docker && systemctl status docker
k8s舍弃dockershim
background: Dockershim FAQ
- Kubernetes 的早期版本仅适用于特定的容器运行时:Docker Engine。后来,Kubernetes 增加了对使用其他容器运行时的支持。创建 CRI 标准是为了和许多不同的容器运行时之间交互操作。
- Docker Engine 没有实现(CRI)接口,因此 Kubernetes 项目创建了特殊代码来帮助过渡,并使 dockershim 代码成为 Kubernetes 的一部分。dockershim 代码一直是一个临时解决方案(因此得名:shim)。事实上,维护 dockershim 已经成为 Kubernetes 维护者的沉重负担。
- 此外,在较新的 CRI 运行时中实现了与 dockershim 不兼容的功能,例如 cgroups v2 和用户命名空间。 从 Kubernetes 中移除 dockershim 允许在这些领域进行进一步的开发。
- 舍弃dockershim,但是docker技术还是有用的,因为要用dockerfile和docker build做镜像。这个功能是其他容器运行时没有的。
舍弃dockershim带来的优势:
- 调用链上看 - 用containerd更高效
- 用dockerd作为容器运行时:kubelet --> dockershim --> dockerd --> containerd
用containerd作为容器运行时:kubelet --> CRI pulgin (containerd进程内) --> containerd
资源利用率上看 - 用containerd更精简
- Docker不是一个纯粹的容器运行时,具有大量其他功能
containerd和docker作为容器运行时的区别
- 拉取镜像时:
#containerd需要写明完整镜像路径
ctr -n=k8s.io images pull docker.io/library/centos:latest
#docker拉镜像可以简写
docker pull centos
安装k8s软件包
yum install -y kubelet-1.28.1 kubeadm-1.28.1 kubectl-1.28.1
systemctl enable kubelet
初始化集群
- 设置容器运行时
crictl config runtime-endpoint unix:///run/containerd/containerd.sock
#这个在先前/etc/crictl.yaml中已经配置过了
- 使用kubeadm初始化k8s集群
#在控制节点上
cd /root/
kubeadm config print init-defaults > kubeadm.yaml
#根据我们自己的需求修改配置,比如修改 imageRepository 的值,kube-proxy 的模式为 ipvs,需要注意的是由于我们使用的containerd作为运行时,所以在初始化节点的时候需要指定cgroupDriver为systemd
- kubeadm.yaml配置文件如下:
tee kubeadm.yaml << 'EOF'
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.40.180 #控制节点的ip
bindPort: 6443
nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock ##指定containerd容器运行时
imagePullPolicy: IfNotPresent
name: master-1 #控制节点主机名
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers #registry.k8s.io #这是kubeadm安装控制节点组件时用的镜像源
kind: ClusterConfiguration
kubernetesVersion: 1.28.1 #这里的版本要和kubeadm\kubectl\kubelet的版本一致
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16 #指定pod网段
serviceSubnet: 10.96.0.0/12
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
EOF
- 初始化集群
kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification
#配置kubectl的配置文件config,相当于对kubectl进行授权,这样kubectl命令可以使用这个证书对k8s集群进行管理
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#1. 设置kubectl的alias为k:
whereis kubectl # kubectl: /usr/bin/kubectl
echo "alias k=/usr/bin/kubectl">>/etc/profile
source /etc/profile
#2. 设置alias的自动补全:
source <(kubectl completion bash | sed 's/kubectl/k/g')
#3. 解决每次启动k都会失效,要重新刷新环境变量(source /etc/profile)的问题:在~/.bashrc文件中添加以下代码:source /etc/profile
echo "source /etc/profile" >> ~/.bashrc
#4. 给alias k也配置补全
tee -a ~/.bashrc <<'EOF'
alias k='kubectl'
complete -o default -F __start_kubectl k
source <(kubectl completion bash)
EOF
##使命令生效
source ~/.bashrc
#安装了zsh的环境,把上面放到~/.zshrc中
echo "source /etc/profile" >> ~/.zshrc
~/.bashrc是一个在 Linux 系统中的 shell 脚本,当用户打开新的 bash shell 时,它会被自动执行。这个文件通常用于定义环境变量,别名,函数等,以便在打开新的 bash shell 时自动设置这些值。例如,如果你想要为所有的 bash shell 设置一个环境变量
JAVA_HOME,你可以在~/.bashrc文件中添加以下行:
export JAVA_HOME=/path/to/java
注意,
~/.bashrc文件是针对单个用户的。如果你想要为系统中的所有用户设置环境变量或别名,你应该编辑/etc/bash.bashrc或/etc/profile文件。
- 扩容工作节点
kubeadm token create --print-join-command
#在node-01上加参数 --ignore-preflight-errors=SystemVerification
#工作节点打标签
kubectl label nodes node2 node-role.kubernetes.io/work=worker
mkdir -p $HOME/.kube
#master-01的kubectl的config文件拷到node1上
scp $HOME/.kube/config node-1:/root/.kube/
安装calico
#上传了Caclio.yaml
kubectl apply -f calico.yaml
#在线下载地址为:https://docs.projectcalico.org/manifests/calico.yaml
#修改calico配置
#- name: CLUSTER_TYPE
# value: "k8s,bgp"
# 上面这一段的下面添加:(指定calico从ens33跨节点通信,不指定的话,会走lo的IP,没办法跨节点通信,也就没办法给pod划分IP)
- name: IP_AUTODETECTION_METHOD
value: "interface=ens33"
#验证calico功能
kubectl run busybox --image docker.io/library/busybox:1.28 --image-pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh
#ping外网
ping www.baidu.com
#nslookup svc
nslookup kubernetes.default.svc.cluster.local