ubuntu部署k8s(亲测好用)

ubuntu部署k8s(亲测好用)

前言

本文介绍如何在ubuntu上部署k8s集群,大致可以分为如下几个步骤:

(1)修改ubuntu配置

(2)安装docker

(3)安装kubeadm、kubectl以及kubelet

(4)初始化master节点

(5)将slave节点加入网络

主机名    主机ip                                      版本                   CPU 内存

k8s-95isee-master-1   172.17.131.4(阿里云主私网IP)        Ubuntu server 18.04       2核 1G

k8s-95isee-node-1      192.168.56.21   Ubuntu server 18.04     2核 1G

在master1上部署管理节点,在node1上部署工作节点。服务器配置上,k8s 要求 CPU 最低为 2 核,不然在安装过程中会报错,虽然这个错误可以避免,但是为了稳定起见还是把虚拟机的配置成它想要的,至于内存 k8s 没有硬性要求。

一. 修改 ubuntu 配置

首先,k8s 要求我们的 ubuntu 进行一些符合它要求的配置。很简单,包括以下两步:关闭 Swap 内存,这一步两台主机都需要进行配置。

修改主机名称

查看主机名

# hostname

修改 /etc/hostname

# vi /etc/hostname

修改 /etc/hosts

/etc/hosts 存放的是域名与 ip 的对应关系,虽然这一步不是必须选项,但建议在修改主机名之后同步修改该文件。

# vi /etc/hosts

重启系统

# reboot

关闭 swap 内存

这个swap其实可以类比成 windows 上的虚拟内存,它可以让服务器在内存吃满的情况下可以保持低效运行,而不是直接卡死。但是 k8s 的较新版本都要求关闭swap。

# swapoff -a         # 临时关闭

# sed -ri 's/.*swap.*/#&/' /etc/fstab    # 永久关闭

确定当前没有开启 Swap

在终端使用命令 free -m 查看输出结果

可以看到最后一行是0 0 0,则表示当前没有开启。

开启必要端口

(3)将网桥的ip4流量转接到iptables

# cat > /etc/sysctl.d/k8s.conf << EOF

net.bridge.bridge-nf-call-ip6tables = 1

net.bridge.bridge-nf-call-iptables = 1

EOF

# sysctl --system  # 使流量转接生效

针对阿里云ecs服务器,需要配置 iptables 转发 IP ,使云服务器网络互通

由于初始化时删除了 --apiserver-advertise-address 参数,返回的节点加入集群命令为内网IP,但几个云服务器内网不互通,所以我们需要使用 iptables 进行 IP 转发,将主节点公网IP转发至内网IP,由于node节点加入集群的命令是内网IP,因此还需要配置 node 节点将主节点的内网IP转发至主节点的公网IP。

# 在主节点 master

sudo iptables -t nat -A OUTPUT -d <主节点公网IP> -j DNAT --to-destination <主节点私有IP>

sudo iptables -t nat -A OUTPUT -d 8.130.50.100 -j DNAT --to-destination 172.17.131.4

# 在 node 节点上

  1. sudo iptables -t nat -A OUTPUT -d <主节点私有IP> -j DNAT --to-destination <主节点公网IP>
  2. sudo iptables -t nat -A OUTPUT -d 172.17.131.4 -j DNAT --to-destination 8.130.50.100
  3. 开机生效利用工具:/etc/init.d/iptables-persistent。

安装工具:如果没有,需要安装:

# apt update

# apt-get install iptables-persistent

iptables-persistent是一个开机启动脚本,在/etc/init.d/目录下。查看可知,保存文件是在:/etc/iptables/rules.v4或/etc/iptables/rules.v6

# apt update

安装 docker

docker 是 k8s 的基础,在安装完成之后也需要修改一些配置来适配 k8s ,所以本章分为 docker 的安装 与 docker 的配置 两部分。如果你已经安装并使用了一段时间的 docker 了话,建议使用docker -v查看已安装的 docker 版本,并在 k8s 官网上查询适合该版本的 k8s 进行安装。这一步两台主机都需要进行安装。

docker 的安装

docker 在 ubuntu 的安装上真是再简单不过了,执行如下命令即可,在安装之前请记得把镜像源切换到国内。

# sudo apt install docker.io

等安装完成之后使用docker -v来验证 docker是否可用。

# docker -v

Docker version 20.10.12, build 20.10.12-0ubuntu2~20.04.1

docker 的配置

安装完成之后需要进行一些配置,包括切换docker下载源为国内镜像站 以及 修改cgroups。

这个cgroups是啥呢,你可以把它理解成一个进程隔离工具,docker就是用它来实现容器的隔离的。docker 默认使用的是cgroupfs,而 k8s 也用到了一个进程隔离工具systemd,如果使用两个隔离组的话可能会引起异常,所以我们要把 docker 的也改成systemd。

这两者都是在/etc/docker/daemon.json里修改的,所以我们一起配置了就好了,首先执行下述命令编辑daemon.json:

# sudo vi /etc/docker/daemon.json

打开后输入以下内容:

{

"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"],

"exec-opts":["native.cgroupdriver=systemd"]

}

然后:wq保存后重启 docker:

# sudo systemctl daemon-reload

# sudo systemctl restart docker

然后就可以通过docker info | grep Cgroup来查看修改后的 docker cgroup 状态,发现变为systemd即为修改成功。

# docker info | grep Cgroup

三. 安装 k8s

安装完了 docker 就可以下载 k8s 的三个主要组件kubelet、kubeadm以及kubectl了。这一步两台主机都需要进行安装。先来简单介绍一下这三者:

kubelet: k8s 的核心服务

kubeadm: 这个是用于快速安装 k8s 的一个集成工具,我们在master1和node1上的 k8s 部署都将使用它来完成。

kubectl: k8s 的命令行工具,部署完成之后后续的操作都要用它来执行

其实这三个的下载很简单,直接用apt-get就好了,但是因为某些原因,它们的下载地址不存在了。所以我们需要用国内的镜像站来下载,也很简单,依次执行下面五条命令即可:

# 使得 apt 支持 ssl 传输

# apt-get update && apt-get install -y apt-transport-https

# 下载 gpg 密钥

# curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -

# 添加 k8s 镜像源

# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list

deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main

EOF

# 更新源列表

# apt-get update

# 下载 kubectl,kubeadm以及 kubelet(注意:不要安装最新版1.24.2)

# apt-get install -y kubelet=1.23.0-00 kubeadm=1.23.0-00 kubectl=1.23.0-00

直接在/etc/apt/sources.list里添加https://mirrors.aliyun.com/kubernetes/apt/是不行的,因为这个阿里镜像站使用的ssl进行传输的,所以要先安装apt-transport-https并下载镜像站的密钥才可以进行下载。

四. 安装 master 节点

下载完成后就要迎来重头戏了,初始化master节点,这一章节只需要在管理节点上配置即可,大致可以分为如下几步:

(1)初始化master节点

(3)配置kubectl工具

(4)初始化 master 节点

  1. 初始化master节点

使用kubeadm的init命令就可以轻松的完成初始化,不过需要携带几个参数,如下。先不要直接复制执行,将赋值给--apiserver-advertise-address参数的 ip 地址修改为自己的master主机地址,然后再执行。

# kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.23.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all

这里介绍一下一些常用参数的含义:

--apiserver-advertise-address: k8s 中的主要服务apiserver的部署地址,填自己的管理节点 ip

--image-repository: 拉取的 docker 镜像源,因为初始化的时候kubeadm会去拉 k8s 的很多组件来进行部署,所以需要指定国内镜像源,下不然会拉取不到镜像。

--pod-network-cidr: 这个是 k8s 采用的节点网络,因为我们将要使用flannel作为 k8s 的网络,所以这里填10.244.0.0/16就好

--kubernetes-version: 这个是用来指定你要部署的 k8s 版本的,一般不用填,不过如果初始化过程中出现了因为版本不对导致的安装错误的话,可以用这个参数手动指定。

--ignore-preflight-errors: 忽略初始化时遇到的错误,比如说我想忽略 cpu 数量不够 2 核引起的错误,就可以用--ignore-preflight-errors=CpuNum。错误名称在初始化错误时会给出来。

当你看到如下字样是,就说明初始化成功了,请把最后那行以kubeadm join开头的命令复制下来,之后安装工作节点时要用到的。

如果你不慎遗失了该命令,可以在master节点上重新生成新的token

# kubeadm token create --print-join-command

kubeadm join 172.17.131.4:6443 --token z9c9nm.35ot5viwzecw460j --discovery-token-ca-cert-hash sha256:327304db0ffd615d7a1db3fedd4bbe411b6fb879aa0a51cc9ddd3c255dce5176

  1. 配置 kubectl 工具(仅在master上进行)

执行下面命令,会出现错误。

# kubectl get nodes

The connection to the server localhost:8080 was refused - did you specify the right host or port?

因为需要预先配置。

# mkdir -p $HOME/.kube

# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

# sudo chown $(id -u):$(id -g) $HOME/.kube/config

# echo 'export KUBECONFIG=$HOME/.kube/config' >> $HOME/.bashrc

# source ~/.bashrc

如果在初始化过程中出现了任何Error导致初始化终止了,使用kubeadm reset重置之后再重新进行初始化。

  1. 部署 flannel 网络

flannel是什么?它是一个专门为 k8s 设置的网络规划服务,可以让集群中的不同节点主机创建的 docker 容器都具有全集群唯一的虚拟IP地址。想要部署flannel的话直接执行下述命令即可:

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

如果被墙,可以直接保存下列文件进行安装

# kubectl apply -f kube-flannel.yaml

输出如下内容即为安装完成:

clusterrole.rbac.authorization.k8s.io/flannel created

clusterrolebinding.rbac.authorization.k8s.io/flannel created

serviceaccount/flannel created

configmap/kube-flannel-cfg created

daemonset.extensions/kube-flannel-ds-amd64 created

daemonset.extensions/kube-flannel-ds-arm64 created

daemonset.extensions/kube-flannel-ds-arm created

daemonset.extensions/kube-flannel-ds-ppc64le created

daemonset.extensions/kube-flannel-ds-s390x created

至此,k8s 管理节点部署完成。

五. 将 slave 节点加入网络

首先需要重复步骤 1 ~ 3 来安装 docker 、k8s 以及修改服务器配置,之后执行从步骤 4 中保存的命令即可完成加入,注意,这条命令每个人的都不一样,不要直接复制执行:

  1. 配置文件处理(仅在node上进行)

mkdir -p $HOME/.kube

复制master节点的 /etc/kubernetes/admin.conf 到 node节点 $HOME/.kube/config

sudo  $(id -u):$(id -g) $HOME/.kube/config

echo 'export KUBECONFIG=$HOME/.kube/config' >> $HOME/.bashrc

source ~/.bashrc

  1. 加入节点:

# kubeadm join 172.17.131.4:6443 --token decqn7.lwcygbjmzof0xny3 --discovery-token-ca-cert-hash sha256:8f0e8d2c04e38c7aa291d8b47be2bd8a5127bf1071263e01bdd5602ab331a01d

待控制台中输出以下内容后即为加入成功:

This node has joined the cluster:

* Certificate signing request was sent to apiserver and a response was received.

* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.

随后登录master1查看已加入节点状态,可以看到node1已加入,并且状态均为就绪。至此,k8s 搭建完成:

root@master1:~# kubectl get nodes

NAME STATUS ROLES AGE VERSION

master1 Ready master 145m v1.15.0

node1 Ready <none> 87m v1.15.0

修改 kubelet 默认地址

访问kubelet配置文件:

sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

在最后一行ExecStart 之前 添加如下内容:

Environment="KUBELET_EXTRA_ARGS=--node-ip=172.17.131.4"

重启kubelet:

systemctl stop kubelet.service && \

systemctl daemon-reload && \

systemctl start kubelet.service

至此修改完成,更多信息详见 kubectl logs、exec、port-forward 执行失败问题解决 。

修改 flannel 的默认网卡

编辑flannel配置文件

sudo kubectl edit daemonset kube-flannel-ds-amd64 -n kube-system

找到spec.template.spec.containers.args字段并添加--iface=网卡名,例如我的网卡是enp0s8:

- args:

- --ip-masq

- --kube-subnet-mgr

# 添加到这里

- --iface=enp0s8

:wq保存修改后输入以下内容删除所有 flannel,k8s 会自动重建:

kubectl delete pod -n kube-system -l app=flannel

至此修改完成,更多内容请见 解决k8s无法通过svc访问其他节点pod的问题 。

问题解决:

(1)cni.go:240] "Unable to update cni config" err="no networks found in /etc/cni/net.d"

node节点

mkdir -p /etc/cni/net.d

从master复制/etc/cni/net.d/10-flannel.conflist到node的/etc/cni/net.d/10-flannel.conflist

systemctl daemon-reload

systemctl restart kubelet

(2)manager.go:610] "Failed to read data from checkpoint" checkpoint="kubelet_internal_checkpoint" err="checkpoint is not found"

从master复制/etc/cni/net.d/10-flannel.conflist到node的/etc/cni/net.d/10-flannel.conflist

systemctl restart kubelet

从master复制/etc/systemd/system/kubelet.service.d/10-kubeadm.conf到node的/etc/systemd/system/kubelet.service.d/10-kubeadm.con

systemctl daemon-reload

systemctl restart kubelet

(3)Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")

当执行kubectl get nodes等命令时,所有的命令都会打印出错误:Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of “crypto/rsa: verification error” while trying to verify candidate authority certificate “kubernetes”)

(4)/root/.kube/config证书认证错误,使用正确证书,可能是kubeadm reset证书未删除

解决办法

删除原来的证书及缓存文件

解决办法

(5)重新安装k8s的方法:

删除节点

# kubectl delete node iz8vbaed97osn3phw7pmoqz

# rm -rf  /root/.kube/*

# kubeadm reset

# systemctl restart docker

# kubeadm init --apiserver-advertise-address=172.17.131.4 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.23.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all

# mkdir -p $HOME/.kube

# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

# sudo chown $(id -u):$(id -g) $HOME/.kube/config

(6)如果主机重新初始化,节点也要重新加入,$HOME/.kube/config要重新复制

kubelet[120917]: E0711 10:51:44.857104  120917 kubelet.go:1711] "Failed creating a mirror pod for" err="pods \"kube-scheduler-iz0jl3zpei8ypnyf5t4o4pz\" already exists" p

重启docker服务

systemctl restart docker

(7)node出错

[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp 127.0.0.1:10248: connect: connection refused.

解决方法:(该解决方案对Docker的version 20.10.17, build 100c701有效,其它版本未测试)

# 添加以下内容

vim /etc/docker/daemon.json

{

"exec-opts": ["native.cgroupdriver=systemd"]

}

# 重启

systemctl restart docker

# 重新初始化

kubeadm reset # 先重置

(8)解决ContainerCreating

root@k8s-95isee-master-1:/opt# kubectl get pod -A

NAMESPACE              NAME                                          READY   STATUS              RESTARTS   AGE

kube-system            coredns-6d8c4cb4d-29chr                       0/1     ContainerCreating   0          16h

kube-system            coredns-6d8c4cb4d-hj64k                       0/1     ContainerCreating   0          16h

kube-system            etcd-k8s-95isee-master-1                      1/1     Running             1          16h

kube-system            kube-apiserver-k8s-95isee-master-1            1/1     Running             2          16h

kube-system            kube-controller-manager-k8s-95isee-master-1   1/1     Running             2          16h

kube-system            kube-proxy-ksd8z                              1/1     Running             0          16h

kube-system            kube-proxy-qmdwl                              1/1     Running             0          16h

kube-system            kube-proxy-szsnw                              0/1     ContainerCreating   0          16h

kube-system            kube-scheduler-k8s-95isee-master-1            1/1     Running             2          16h

kubernetes-dashboard   dashboard-metrics-scraper-799d786dbf-vc2xt    0/1     ContainerCreating   0          64m

kubernetes-dashboard   kubernetes-dashboard-fb8648fd9-k9cjs          0/1     ContainerCreating   0          64m

root@k8s-95isee-master-1:/opt# kubectl describe pods -n kube-system coredns-6d8c4cb4d-29chr

Warning  FailedCreatePodSandBox  4m1s (x53908 over 16h)  kubelet  (combined from similar events): Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "904ed4366fb15aa96c4848b9c0e032e4a845963c8cbcd70e4058e69ea445531a" network for pod "coredns-6d8c4cb4d-29chr": networkPlugin cni failed to set up pod "coredns-6d8c4cb4d-29chr_kube-system" network: open /run/flannel/subnet.env: no such file or directory

(9)查看指定路径下是否存在subnet.env文件,不存在则创建此文件,写入如下内容,可以解决。

/run/flannel/subnet.env的内容:

FLANNEL_NETWORK=10.244.0.0/16

FLANNEL_SUBNET=10.224.0.1/24

FLANNEL_MTU=1450

FLANNEL_IPMASQ=true

每个节点都要有此文件,在master节点创建好之后,复制到worker节点。然后重新创建 pod,正常了。

(10)问题描述:在单机版k8s上部署应用后,发现Pod的状态一直处于pending状态,

于是 kubectl describe pods 查看了下发现:

Warning  FailedScheduling  20s (x9 over 8m36s)  default-scheduler  0/1 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.

意思是   1个节点有pod不能容忍的污点{node-role.kubernetes.io/master:}

原因:当创建单机版的 k8s 时,这个时候 master 节点是默认不允许调度 pod

解决:执行命令:

# kubectl taint nodes --all node-role.kubernetes.io/master-

master 标记为可调度即可

参考

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值