安装原生Kubernetes单机/集群版

发表于 2022-12-30

这里介绍安装原生Kubernetes单机/集群版的方法,非Minikube、非Kind、非Colima等指令; 使用的是原生kubelet、kubeadm来部署Kubernetes。

kubeadm是Kubernetes官方提供的快速安装集群的工具,伴随着Kubernetes的版本发布进行更新。

环境准备

Linux

如果你有一台Linux环境,并且具备4C以上的CPU、8G以上的内存,并且安装了CentOS7或Ubuntu 20.XX以上版本的操作系统,那么就可以看下一章节了。

M1 MacBook

使用multipass软件

Windows

可以使用VirtualBox + Vagrant 来搭建一个Kubernetes集群环境。模拟 master1+worker2的3节点环境。

安装软件

分别安装 VirtualboxValgrant

截止到今天2023.04.07,virtualbox和vagrant对arm64的支持还非常不完善,对x86的支持比较好。

导入镜像

由于国内的网络环境体验比较差,需要手工下载box镜像并导入到vagrant系统中。

先写一个简单的Vagrantfile:

1Vagrant.configure("2") do |config|
2  config.vm.box = "generic/centos8"
3
4  config.vm.define "master" do |vb|
5    vb.vm.hostname = "master-node"
6    vm.vm.network "private_network", ip: "192.168.33.100"
7  end
8end

执行 vagrant up 会自动下载box镜像,如果碰到网络环境不好的话,会卡在下载步骤。这时候就需要手动拷贝提示的URL并下载,然后导入:

导入需要使用 metadata.json:

 1{
 2    "name": "generic/centos8",
 3    "versions": [{
 4        "version": "4.2.14",
 5        "providers": [{
 6            "name": "virtualbox",
 7            "url": "file:///D:/Downloads/fe15bfbf-d39d-4ee6-99cb-9624fa4be44f"
 8        }]
 9    }]
10}

执行指令: vagrant box add ./metadata.json 即可完成镜像的导入。

编写 Vagrantfile

此文件实现了 master1+worker2的环境:

 1IP_NW="192.168.33."
 2IP_START=100
 3
 4Vagrant.configure("2") do |config|
 5  config.vm.box = "generic/centos8"
 6  
 7  config.vm.provider "virtualbox" do |vb|
 8    vb.memory = 4096
 9    vb.cpus = 2
10	vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
11  end
12  
13  config.vm.provision "shell", inline: <<-SHELL
14	  echo "$IP_NW$((IP_START)) master-node" >> /etc/hosts
15	  echo "$IP_NW$((IP_START+1)) worker-node01" >> /etc/hosts
16	  echo "$IP_NW$((IP_START+2)) worker-node02" >> /etc/hosts
17  SHELL
18  
19  config.vm.define "master" do |vb|
20    vb.vm.hostname = "master-node"
21    vb.vm.network "private_network", ip: IP_NW + "#{IP_START}"
22  end
23
24  (1..2).each do |i|
25	config.vm.define "node0#{i}" do |node|
26		node.vm.hostname = "worker-node0#{i}"
27		node.vm.network "private_network", ip: IP_NW + "#{IP_START + i}"
28	end
29  end 
30  
31end

安装完成后可以使用 vagrant ssh-config 获取ssh 配置信息。

更改为root登录

1$ vagrant ssh master-node
2$ sudo -s
3$ sh -c 'cd /root && \
4  mkdir -p .ssh && \
5  chmod 0700 .ssh && \
6  cp -af /home/vagrant/.ssh/authorized_keys .ssh/ && \
7  chown root:root .ssh/authorized_keys'

清理Vagrant环境

如果vagrant 没有启动成功,那么清理的话分为以下几步:

更新kernel

如果使用的宿主机是CentOS7,则需要更新Kernel到较新的版本,如果是CentOS8则无需更新。

 1# 导入ElRepo库的gpg密钥
 2$ rpm -import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
 3# 添加ElRepo的repo配置
 4$ yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
 5# $ yum install -y https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm
 6# $ yum install -y https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm
 7
 8
 9# 列出可用的内核版本
10$ yum --disablerepo='*' --enablerepo=elrepo-kernel list available 
11# 安装lt支持的版本, lt= long-term
12$ yum --enablerepo=elrepo-kernel install -y kernel-ml
13
14# CentOS8 直接Reboot即生效
15# CentOS7 需要手动调整顺序: 如下
16
17# 查看当前内核版本及启动顺序
18$ awk -F\' '$1=="menuentry " {print i++ " : " $2}' /boot/grub2/grub.cfg
190 : CentOS Linux (5.4.108-1.el7.elrepo.x86_64) 7 (Core)
201 : CentOS Linux (3.10.0-1160.11.1.el7.x86_64) 7 (Core)
212 : CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core)
223 : CentOS Linux (0-rescue-20210128140208453518997635111697) 7 (Core)
23
24# 设置内核默认启动顺序,若无此命令则安装 grub2-pc 包
25$ grub2-set-default 0
26
27# 重启系统
28$ reboot 

如果elrepo.org的地址比较和谐,那么可以设置HTTP代理,编辑 /etc/yum.conf,增加一行: proxy=http://10.226.133.174:8888

更新HostName

如果非Vagrant环境的话, 需要手动配置Hostname,这里配置宿主机的hostnamemaster-node

由于Kubernetes使用Hostname来进行配置主机,所以这里配置宿主机的hostnamemaster-node

1$ echo 'master-node' > /etc/hostname
2$ hostname master-node
3$ echo '127.0.0.1 master-node' >> /etc/hosts
4
5# 如果有多台Node设备,则需要将Node设备的Hostname设置到/etc/hosts中

设置SSH免密访问

master-node 上创建SSH密钥,并同步到所有Node主机

1$ ssh-keygen -t rsa
2$ ssh-copy-id -i /root/.ssh/id_rsa.pub master-node
3
4# 如果有多台Node设备,则需要将ssh密钥拷贝到所有的Node主机上

关闭交换分区

1$ swapoff -a && \
2  sed -ri 's/.*swap.*/#&/' /etc/fstab && \
3  sysctl -w vm.swappiness=0

CentOS关闭防火墙

1$ systemctl stop firewalld && systemctl disable firewalld

配置网络转发及网桥设置

 1
 2# For Ubuntu
 3$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
 4overlay
 5br_netfilter
 6EOF
 7
 8$ modprobe overlay br_netfilter
 9
10
11# For CentOS
12$ ...
13
14
15$ cat > /etc/sysctl.d/k8s.conf << EOF
16net.bridge.bridge-nf-call-ip6tables = 1
17net.bridge.bridge-nf-call-iptables = 1
18net.ipv4.ip_forward = 1
19net.ipv6.conf.default.forwarding = 1
20vm.swappiness = 0
21EOF
22
23$ sysctl -p /etc/sysctl.d/k8s.conf

安装IPSet&IPVS

1$ apt install -y ipset ipvsadm

安装容器管理工具(kubernetes -1.23)

截止到目前(2022.12.30),kubernetes 1.26版本不再支持docker作为其容器管理工具, 所以这里选择安装1.23版本的Kubernetes,可以支持使用docker作为容器管理工具。

安装docker-ce,详细步骤点击:

执行命令: systemctl enable docker,随系统启动

设置docker配置(kubernetes -1.23)

需要修改docker的cgroup driver 为systemd, 同时storage driver为overlay2 也是overlay2需要高版本kernel的支持。

1$ cat /etc/docker/daemon.json
2{
3  "exec-opts": ["native.cgroupdriver=systemd"],
4  "storage-driver": "overlay2",
5  "registry-mirrors": ["https://registry.docker-cn.com"]
6}
7
8$ service docker restart

docker设置代理

1$ mkdir -p /etc/systemd/system/docker.service.d
2$ cat > /etc/systemd/system/docker.service.d/http-proxy.conf << EOF
3[Service]
4Environment="HTTP_PROXY=http://10.226.133.174:8888"
5Environment="HTTPS_PROXY=http://10.226.133.174:8888"
6Environment="NO_PROXY=localhost,127.0.0.1"
7EOF
8$ systemctl daemon-reload && systemctl restart docker 
9$ systemctl show --property=Environment docker

安装containerd(kubernetes 1.24+)

1$ apt install -y containerd

修改containerd的配置(kubernetes 1.24+)

1$ mkdir  -p /etc/containerd && \
2  containerd config default > /etc/containerd/config.toml && \
3  sed -i 's@SystemdCgroup = false@SystemdCgroup = true@' /etc/containerd/config.toml && \
4  systemctl daemon-reload && systemctl enable containerd && systemctl start containerd

安装Kubernetes工具

需要安装的工具包括:

由于国内环境,这里采用aliyun的源进行安装指定1.23.15-0版本

阿里云Kubernetes镜像配置方法

Debian/Ubuntu

1$ apt-get update && apt-get install -y apt-transport-https
2$ curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - 
3$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
4deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
5EOF
6$ apt-get update
7$ apt-get install -y kubelet=1.23.15-00 kubeadm=1.23.15-00 kubectl=1.23.15-00
8$ systemctl enable kubelet && systemctl start kubelet

CentOS/RHEL/Fedora

 1$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo
 2[kubernetes]
 3name=Kubernetes
 4baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
 5enabled=1
 6gpgcheck=1
 7repo_gpgcheck=1
 8gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
 9EOF
10$ setenforce 0
11$ yum install -y kubelet-1.23.15-0 kubeadm-1.23.15-0 kubectl-1.23.15-0
12$ systemctl enable kubelet && systemctl start kubelet

初始化集群

安装集群

 1# 使用docker作为容器管理工具,需指定1.23版本,同时指定aliyun镜像仓库
 2$ kubeadm init --apiserver-advertise-address=10.226.193.7 \
 3    --image-repository registry.aliyuncs.com/google_containers \
 4    --kubernetes-version=v1.23.15 \
 5    --service-cidr=10.96.0.0/12 \
 6    --pod-network-cidr=10.244.0.0/16 \
 7    --v=5
 8# --apiserver-advertise-address: kube-apiserver对外侦听的地址;由于kubeadm默认使用eth0的地址作为侦听地址,在某些情况下不适用
 9# --image-repository: 由于一些不可描述的原因,国内无法下载kubernetes的容器镜像,这里使用阿里云的镜像仓库
10# --kubernetes-version=v1.23.15: 指定安装kubernetes的版本,1.23版本是支持docker作为容器支持的

如果需要支持IPv6,可在cidr中增加IPv6的地址段:

1kubeadm init --apiserver-advertise-address=192.168.64.6 \
2    --image-repository registry.aliyuncs.com/google_containers \
3    --kubernetes-version=v1.23.15 \
4    --service-cidr=10.96.0.0/12,2001:db8:41:1::/112 \
5    --pod-network-cidr=10.244.0.0/16,2001:db8:42:0::/56 \
6    --v=5

多Master部署

如果需要支持多Master部署,那么需要首先修改集群的kubeadm-config,增加:controlPlaneEndpoint: 192.168.64.6:6443

1    kind: ClusterConfiguration
2    kubernetesVersion: v1.23.15
3    controlPlaneEndpoint: 192.168.64.6:6443

然后在第二台Master上部署证书

1$ scp /etc/kubernetes/pki/sa.* /etc/kubernetes/pki/ca.* /etc/kubernetes/pki/front-proxy-ca.* master02:/etc/kubernetes/pki/
2$ scp /etc/kubernetes/pki/etcd/ca.* master02:/etc/kubernetes/pki/etcd/

获取join token:

1$ kubeadm token create --print-join-command

在第二台master上执行Join命令

1$ kubeadm join 192.168.64.6:6443 --token xxx \
2    --discovery-token-ca-cert-hash sha256:xxxx \
3    --control-plane 

初始化网络插件

安装好集群后,使用kubectl get node 查看节点状态,会显示NotReady,这是由于集群还没有初始化网络。 这里安装flannel网络模块:

1$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

如果需要更改Flannel默认使用的网卡,修改kube-flannel.yaml:

1containers:
2  - name: kube-flannel
3    image: quay.io/coreos/flannel:v0.10.0-amd64
4    command:
5    - /opt/bin/flanneld
6    args:
7    - --ip-masq
8    - --kube-subnet-mgr
9    - --iface=eth0

注意,截止到2023.05.06,flannel对IPv6的支持不太好,请用calico来配置网络。

calico官方地址

下边是一份支持IPv6的CustomResource描述:

 1spec:
 2  # Configures Calico networking.
 3  calicoNetwork:
 4    # Note: The ipPools section cannot be modified post-install.
 5    ipPools:
 6      - blockSize: 26
 7        cidr: 10.244.0.0/16
 8        encapsulation: IPIP
 9        natOutgoing: Enabled
10        nodeSelector: all()
11      - blockSize: 122
12        cidr: 2001:db8:42:0::/56
13        encapsulation: None
14        natOutgoing: Enabled
15        nodeSelector: all()

取消主节点不可调度限制

由于是单机版,所以需要去掉主节点的NoSchedule的taint标记,否则的话安装Pod会无法找到可用的Node节点而失败。

1$ kubectl taint nodes master-node node-role.kubernetes.io/master:NoSchedule-

提前导入镜像

如果创建多Node节点的集群,可以使用提前导入镜像的方式,使用以下脚本,将镜像上传到docker.com作为中转:

使用脚本 k8s-outside.sh,从国外站点拉取最新镜像,上传到dockerhub

 1#!/bin/bash
 2
 3repo=ir0cn
 4#repo=quay.io/xxfe
 5#repo=registry.cn-hangzhou.aliyuncs.com/xxfe
 6
 7images=$(kubeadm config images list --kubernetes-version=v1.23.15 2>/dev/null | awk '{print $1}')
 8
 9for imageName in  ${images[@]}; do
10    docker pull $imageName || exit -1
11    newImageName=$(echo $imageName | awk -F/ '{print $NF}' | sed 's@:@__@')
12    docker tag $imageName $repo/google_containers:$newImageName || exit -1
13    docker push $repo/google_containers:$newImageName || exit -1
14done

使用脚本 k8s-inside.sh,从dockerhub拉取镜像并改名,每台机器均需执行

 1#!/bin/bash
 2
 3repo=ir0cn
 4#repo=quay.io/xxfe
 5#repo=registry.cn-hangzhou.aliyuncs.com/xxfe
 6
 7images=$(kubeadm config images list --kubernetes-version=v1.23.15 2>/dev/null | awk '{print $1}')
 8
 9for imageName in ${images[@]}; do
10    newImageName=$(echo $imageName | awk -F/ '{print $NF}' | sed 's@:@__@')
11    docker pull $repo/google_containers:$newImageName || exit -1
12    docker tag $repo/google_containers:$newImageName $imageName
13    docker rmi $repo/google_containers:$newImageName
14done

重置集群

1kubeadm reset
2rm -rf /etc/kubernetes /etc/cni/net.d
3iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

上一篇 My First Post 下一篇 监控Linux文件被进程篡改