Mac OS(10.13.6)使用 vagrant+VirtualBox +centos7搭建k8s集群步骤
环境准备工作
- 下载VirtualBox 地址:https://www.virtualbox.org/ 下载最新安装包 6.1 ,安装环境很简单,根据步骤下一步即可
- 下载vagrant 地址:https://www.vagrantup.com/ 下载最新安装包 Vagrant 2.2.9 ,安装环境很简单,根据步骤下一步即可
- 下载centos7 box https://download.csdn.net/download/xia296/12740338 使用命令vagrant box add centos7 box文件路径,增加本地box
- 安装 kubeadm,使用 kubeadm 开启k8s集群,需要环境如下:
- docker-ce安装
- kubelet和kubectl
使用vagrant 创建3个centos7 虚拟机网络配置及其他配置基础
新增vagrant 本地box,以防止远程下载操作系统;
#创建本地box vagrant box add centos7 /Users/summer/Downloads/centos-7.0-x86_64.box #查询本地box vagrant box list
新建一个vagrant 配置文件
Vagrantfile
批量创建3个虚拟机Vagrant.configure("2") do |config| (1..3).each do |i| config.vm.define "k8s-node#{i}" do |node| # 设置虚拟机的Box node.vm.box = "centos7" # 设置虚拟机的主机名 node.vm.hostname="k8s-node#{i}" # 设置虚拟机的IP node.vm.network "private_network", ip: "192.168.56.#{99+i}", netmask: "255.255.255.0" # 设置主机与虚拟机的共享目录 # node.vm.synced_folder "~/Documents/vagrant/share", "/home/vagrant/share" # VirtaulBox相关配置 node.vm.provider "virtualbox" do |v| # 设置虚拟机的名称 v.name = "k8s-node#{i}" # 设置虚拟机的内存大小 v.memory = 2048 # 设置虚拟机的CPU个数 v.cpus = 2 end end end end
运行vagrant up命令,运行后会帮我们自动创建k8s-node1、k8s-node2、k8s-node3 虚拟机
vagrant up
设置自定义nat网络,防止公用一个IP;
由于vagrant 帮我们创建的只能通过ssh访问,我们需要开启账号密码访问权限,以便可以使用其他客户端工具访问,这里以k8s-node1为例,其他虚拟机类似(非必须,测试我的版本默认已经开启了yes);
#进入k8s-node1 vagrant ssh k8s-node1 #切换root访问权限,密码默认为vagrant su root #修改sshd_config,找到 PasswordAuthentication no 改为yes即可,最新版本创建的时候可以忽略,默认则是yes vi /etc/ssh/sshd_config #重启sshd服务 service sshd restart
设置Linux环境(三个虚拟机都要执行)
为了测试方便,关闭所有虚拟机的防火墙
systemctl stop firewalld systemctl disable firewalld
关闭selinux 安全策略(此处可以省略,我测试默认是关闭的)
#查看selinux cat /etc/selinux/config #SELINUX=disabled SELINUX=disabled #如没有禁止,可以使用如下命令快速禁止 sed -i 's/enforcing/disabled' /etc/selinux/config #全局禁止配置 setenforce 0
关闭swap
#查看是否禁止了swap cat /etc/fstab #可以查看到是开启的,如需要禁止注释掉此行即可 /dev/mapper/centos-swap swap swap defaults 0 0 #临时的禁止 swapoff -a #执行此命令,可以注释掉分区交换行 sed -ri 's/.*swap.*/#&/' /etc/fstab #验证,swap必须为0 free -g
添加主机名与IP对于关系
#通过hostname查看主机名,我这里使用vagrant创建时就指定了,如果你没使用vagrant,则可以使用hostnamectl set-hostname<newhostname> 指定新的hostname; hostname #添加本地主机映射 vim /etc/hosts 10.0.2.15 k8s-node1 10.0.2.4 k8s-node2 10.0.2.5 k8s-node3
将桥接的IPv4流量传递到iptables的链(防止统计流量指标不准确)
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 --system
所有虚拟机安装docker、kubeadm、kubelet和kubectl
配置yum源(可选)
#1、配置yum源base repo为阿里云的yum源
cd /etc/yum.repos.d
mv CentOS-Base.repo CentOS-Base.repo.bak
mv epel.repo epel.repo.bak
curl https://mirrors.aliyun.com/repo/Centos-7.repo -o CentOS-Base.repo
sed -i 's/gpgcheck=1/gpgcheck=0/g' /etc/yum.repos.d/CentOS-Base.repo
curl https://mirrors.aliyun.com/repo/epel-7.repo -o epel.repo
#2、配置kubernetes源为阿里的yum源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
#配置yum说明
#baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 Kubernetes源设为阿里
#gpgcheck=0:表示对从这个源下载的rpm包不进行校验
#repo_gpgcheck=0:某些安全性配置文件会在 /etc/yum.conf 内全面启用 repo_gpgcheck,以便能检验软件库的中继数据的加密签署
#如果gpgcheck设为1,会进行校验,就会报错如下,所以这里设为0
#3、update cache 更新缓存
yum clean all && yum makecache && yum repolist
docker 安装
安装docker之前,清理系统之前的docker
sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
安装docker-ce 之前需安装所需的包。yum-utils提供了yum-config-manager 效用,并device-mapper-persistent-data和lvm2由需要 devicemapper存储驱动程序。
sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
设置稳定的存储库。
#官方库有点慢,我们可以使用国内镜像库 sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo #设置阿里云库 sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker及配置docker加速
国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
- 网易:**https://hub-mirror.c.163.com/**
- 阿里云:https://<你的ID>.mirror.aliyuncs.com
- 七牛云加速器:**https://reg-mirror.qiniu.com**
当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。
阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了,更多阿里云服务器docker一键部署见帮助手册
#安装docker-ce cli sudo yum install -y docker-ce docker-ce-cli containerd.io #复制以下配置加速 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://pee6w651.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
设置docker开机自启动
sudo systemctl enable docker
安装kubeadm、kubelet和kubectl
Kubelet负责与其他节点集群通信,并进行本节点Pod和容器生命周期的管理。
Kubeadm是Kubernetes的自动化部署工具,降低了部署难度,提高效率。
Kubectl是Kubernetes集群管理工具。
#配置kubernetes源为阿里的yum源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 将 SELinux 设置为 permissive 模式(相当于将其禁用),这里我上面已经设置过了,所以不需要设置;
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
#开始安装
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
#设置开机自启动kubelet
systemctl enable --now kubelet
#查看k8s版本
kubeadm version
请注意:
通过运行命令
setenforce 0
和sed ...
将 SELinux 设置为 permissive 模式可以有效的将其禁用。 这是允许容器访问主机文件系统所必须的,例如正常使用 pod 网络。 您必须这么做,直到 kubelet 做出升级支持 SELinux 为止。一些 RHEL/CentOS 7 的用户曾经遇到过问题:由于 iptables 被绕过而导致流量无法正确路由的问题。您应该确保 在
sysctl
配置中的net.bridge.bridge-nf-call-iptables
被设置为 1。cat <<EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sysctl --system
确保在此步骤之前已加载了
br_netfilter
模块。这可以通过运行lsmod | grep br_netfilter
来完成。要显示加载它,请调用modprobe br_netfilter
。
kubelet 现在每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环。
在控制平面节点上配置 kubelet 使用的 cgroup 驱动程序
使用 docker 时,kubeadm 会自动为其检测 cgroup 驱动并在运行时对 /var/lib/kubelet/kubeadm-flags.env
文件进行配置。
如果您使用不同的 CRI,您需要使用 cgroup-driver
值修改 /etc/default/kubelet
文件(对于 CentOS、RHEL、Fedora,修改 /etc/sysconfig/kubelet
文件),像这样:
KUBELET_EXTRA_ARGS=--cgroup-driver=<value>
这个文件将由 kubeadm init
和 kubeadm join
使用以获取额外的用户自定义的 kubelet 参数。
请注意,您只需要在您的 cgroup 驱动程序不是 cgroupfs
时这么做,因为它已经是 kubelet 中的默认值。
需要重新启动 kubelet:
systemctl daemon-reload
systemctl restart kubelet
自动检测其他容器运行时的 cgroup 驱动,例如在进程中工作的 CRI-O 和 containerd。
查看kubernetes 镜像并初始化 (master node都要执行)
开始初始化集群之前可以使用kubeadm config images list
查看一下初始化需要哪些镜像,可以先通过kubeadm config images pull
手动在各个节点上拉取所k8s需要的docker镜像,master节点初始化或者node节点加入集群时,会用到这些镜像
如果不先执行kubeadm config images pull
拉取镜像,其实在master节点执行kubeadm init
或者node节点执行 kubeadm join
命令时,也会先拉取镜像。
kubeadm config images list
W0823 16:09:49.820989 7970 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
#以下是所需要的镜像
k8s.gcr.io/kube-apiserver:v1.18.8
k8s.gcr.io/kube-controller-manager:v1.18.8
k8s.gcr.io/kube-scheduler:v1.18.8
k8s.gcr.io/kube-proxy:v1.18.8
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.7
初始化kubeadm与之对应的命令为kubeadm reset(1.18.8版本忽略这一步)
kubeadm init --kubernetes-version v1.18.8 \ --apiserver-advertise-address=10.0.2.15 \ --service-cidr=10.1.0.0/16 \ --pod-network-cidr=10.244.0.0/16 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
参数说明:
–kubernetes-version: 用于指定k8s版本; –apiserver-advertise-address:用于指定kube-apiserver监听的ip地址,就是 master本机IP地址。 –pod-network-cidr:用于指定Pod的网络范围,它的值取决于你在下一步选择的哪个网络插件,比如我在本文中使用的是Calico网络,需要指定为192.168.0.0/16 –service-cidr:用于指定SVC的网络范围; –image-repository: 指定阿里云镜像仓库地址,这一步很关键,由于kubeadm 默认从官网k8s.grc.io下载所需镜像,国内无法访问,因此需要通过–image-repository指定阿里云镜像仓库地址,注意在发文的时候阿里云仓库中最新版本为1.17,所以通过这个镜像地址无法拉取1.18.8版本;
手动下载docker镜像,编写master_images.sh(master节点所需镜像下载)、node_images.sh(node节点所需镜像下载)
master_images.sh 脚本内容如下:
#!/bin/bash images=( kube-apiserver:v1.18.8 kube-proxy:v1.18.8 kube-controller-manager:v1.18.8 kube-scheduler:v1.18.8 coredns:1.6.7 etcd:3.4.3-0 pause:3.2 ) for imageName in ${images[@]} ; do docker pull gotok8s/$imageName docker tag gotok8s/$imageName k8s.gcr.io/$imageName docker rmi gotok8s/$imageName done
node_images.sh 脚本内容如下:
#!/bin/bash images=( kube-proxy:v1.18.8 pause:3.2 ) for imageName in ${images[@]} ; do docker pull gotok8s/$imageName docker tag gotok8s/$imageName k8s.gcr.io/$imageName docker rmi gotok8s/$imageName #docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName # docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName done
初始化配置文件
#初始化配置文件 kubeadm config print init-defaults > kubeadm.yaml #编辑配置文件 vim kubeadm.yaml apiVersion: kubeadm.k8s.io/v1beta2 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdef ttl: 24h0m0s usages: - signing - authentication kind: InitConfiguration localAPIEndpoint: advertiseAddress: 10.0.2.15 # 修改为本机ip地址,多块网卡可以指定具体ip bindPort: 6443 nodeRegistration: criSocket: /var/run/dockershim.sock name: master1 taints: - effect: NoSchedule key: node-role.kubernetes.io/master --- apiServer: timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta2 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {} dns: type: CoreDNS etcd: local: dataDir: /var/lib/etcd imageRepository: k8s.gcr.io kind: ClusterConfiguration kubernetesVersion: v1.18.8 # 修改为最新版本 networking: dnsDomain: cluster.local serviceSubnet: 10.1.0.0/16 # service网段 podSubnet: 10.244.0.0/16 # pod网段,需与网络插件网段一致 scheduler: {} --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs # 开启ipvs #指定初始化配置文件执行 kubeadm init --config=kubeadm.yaml #看到如下信息代表初始化成功,然后根据提示操作即可 Your Kubernetes control-plane has initialized successfully! #要开始使用群集,您需要以常规用户身份运行以下操作: To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config #现在应该将pod网络部署到集群。 You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ #待网络配置好后,在子节点执行如下命令,子节点则加入到集群中; Then you can join any number of worker nodes by running the following on each as root: kubeadm join 10.0.2.15:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:763142fb1596ffa79b631210b801e0b0764c23666a01f37f5224a853c8777a93
至此我们master节点已经初步完成,执行命令kubectl get nodes 查看集群节点状态可以发现master状态是NotReady,因为此时还没有安装网络组件,下面我们来安装网络组件;
安装pod网络组件(flannel网络组件为例)
#下载flannel网络组件配置文件 wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml #安装网络组件 kubectl apply -f kube-flannel.yml #卸载网络组件 kubectl delete -f kube-flannel.yml
命令查看有多少pods
#查看默认名称空间下的pods kubectl get pods #查看名称空间 kubectl get ns #查看所有名称空间下的pods kubectl get pods --all-namespaces #查看运行节点 [root@k8s-node1 k8s]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-node1 Ready master 3h59m v1.18.8 #主节点运行正常 k8s-node2 Ready <none> 4m25s v1.18.8 #从节点运行正常,如果为NotReady,我们耐心等待加载即可; k8s-node3 Ready <none> 4m23s v1.18.8 #从节点运行正常
常见问题
- 如启动vagrant up 出现如下错误,不要慌,这个是你的虚拟网卡驱动没初始化好
There was an error while executing VBoxManage, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.
Command: ["hostonlyif", "create"]
Stderr: 0%...
Progress state: NS_ERROR_FAILURE
VBoxManage: error: Failed to create the host-only adapter
VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component HostNetworkInterfaceWrap, interface IHostNetworkInterface
VBoxManage: error: Context: "RTEXITCODE handleCreate(HandlerArg *)" at line 95 of file VBoxManageHostonly.cpp
执行以下命令即可
sudo "/Library/Application Support/VirtualBox/LaunchDaemons/VirtualBoxStartup.sh" restart
注意:执行命令可能一些会不成功,你需要进入设置->安全和隐私->常规,并在“允许应用程序...”下批准Oracle,Inc.的请求。
修改Docker Cgroup Driver为systemd,如果不修改则在后续添加Worker节点时可能会遇到“detected cgroupfs as ths Docker driver.xx”的报错信息,并配置Docker本地镜像库;
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/"
cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors":[ "https://1nj0zren.mirror.aliyuncs.com", "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", "http://f1361db2.m.daocloud.io", "https://registry.docker-cn.com" ] } EOF #以下为常用命令 #重新加载daemon.json配置 systemctl daemon-reload #重启docker服务 或start docker systemctl restart docker #设置Kubelet开启开机自启动 systemctl enable kubelet #启动Kubelet服务 systemctl start kubelet #重启kubelet服务 systemctl restart kubelet #查看kubectl健康状态 kubectl get cs
发现controller-manager和scheduler状态是不健康
如果节点都处于Ready后,实际上该状态是不影响的。因为kubeadm v1.18.6及以后的版本,是默认不开启controller-manager的10252和scheduler的10251端口的,一般10251和10252是监听在http上面,不需要证书认证,属于不安全的端口。
可以将/etc/kubernetes/manifests/kube-controller-manager.yaml、/etc/kubernetes/manifests/kube-scheduler.yaml中–port=0注释掉,再次kubect get cs组件状态,这时都是ok了。
[root@k8s-node1 k8s]# kubectl get cs NAME STATUS MESSAGE ERROR controller-manager Healthy ok scheduler Healthy ok etcd-0 Healthy {"health":"true"}
worker节点加入集群后,一直处于NotReady状态,我们通过监控pod进度查看
#监控pod状态 watch kubectl get pods -n kube-system -o wide #指定pod查看详细信息 kubectl describe pod coredns-66bff467f8-8pksf --namespace=kube-system #coredns-66bff467f8-8pksf是你的pod name