江湖夜雨十年灯

ubuntu 下安装 k8s

李二花 / 2020-03-10


关键词:ubuntu, k8s

ubuntu 下安装 k8s

安装 k8s 准备工作

准备工作

我们先假设以下的情况成立。

机器:有2-3台物理机或虚拟机 系统:Ubuntu 18.04 以上且已换好国内的源 如果以上基本不成立,本篇文章到此结束,谢谢观看…

安装Docker

我也不需要介绍各种情况了,直接登上机器,创建一个shell脚本,例如叫install_docker.sh,一把梭代码如下。

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates 
curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get -y install docker-ce docker-ce-cli containerd.io

然后执行sh install_docker.sh,等待命令跑完,验证docker是否安装好即可。直接敲docker + 回车。

安装Kubernetes

同理,新建一个shell脚本,例如install_k8s.sh。一把梭代码如下。

sudo curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get install -y kubelet kubeadm kubectl --allow-unauthenticated

需要注意的是, sudo curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - 可能会失败,因为墙的原因,因此,我们需要在可以下载到的地方提前下载好,然后 scp 到机器,然后使用 sudo apt-key add apt-key.gpg 即可。

另外安装时还有连不上的情况, 换国内的源

sudo apt-get update
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main
EOF
sudo apt-get install -y kubelet kubeadm kubectl --allow-unauthenticated

然后执行sh install_k8s.sh,等待命令跑完,验证k8s是否安装好即可。直接敲kubectl + 回车。

关闭Swap

先给出一把梭,不要耽误了正在安装的老铁。为什么要关闭后面再说。

暂时关闭 直接使用命令 sudo swapoff -a,但是重启之后会生效。会导致 k8s 无法正常运行。 永久关闭 建议一劳永逸,sudo vim /etc/fstab 将有 swap.img 那行注释掉,保存即可。

那么,swap是啥呢?它是系统的交换分区,你可以理解为虚拟内存。当系统内存不足的时候,会将一部分硬盘空间虚拟成内存使用。

初始化Master节点

到这,准备工作就完成了,可以开始安装K8S的master节点了,登上要作为 master 节点的机器。

设置HostName

老规矩,先上命令,再说为什么要设置。


自定义修改了主机名,在之后查看集群内节点时,每个节点的名字就不会显示K8S自动生成的名字,便于查看和记忆。例如,在其他的 Node 节点你可以将 master-node 改为 slave-node-1 或worker-node-2

### Master 节点配置 cgroup driver

#### 方法一

修改 kubelet 配置 `/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf`

Note: This dropin only works with kubeadm and kubelet v1.11+

[Service] CPUAccounting=true MemoryAccounting=true Environment=“KUBELETKUBECONFIGARGS=–bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf –kubeconfig=/etc/kubernetes/kubelet.conf –cgroup-driver=systemd” #配置在这里cgroup-driver=systemd Environment=“KUBELETCONFIGARGS=–config=/var/lib/kubelet/config.yaml”

This is a file that “kubeadm init” and “kubeadm join” generates at runtime, populating the KUBELETKUBEADMARGS variable dynamically

EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env

This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use

the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELETEXTRAARGS should be sourced from this file.

EnvironmentFile=-/etc/sysconfig/kubelet ExecStart= ExecStart=/usr/bin/kubelet $KUBELETKUBECONFIGARGS $KUBELETCONFIGARGS $KUBELETKUBEADMARGS $KUBELETEXTRAARGS


#### 方法二

https://kubernetes.io/docs/setup/production-environment/container-runtimes/

### 初始化 master 节点

初始化过程会访问墙外网站,如果 init 不能顺利执行,请配置全局代理或者用下面的脚本提前跑好:

#!/bin/bash

images=( kube-apiserver:v1.20.1 kube-controller-manager:v1.20.1 kube-scheduler:v1.20.1 kube-proxy:v1.20.1 pause:3.2 etcd:3.4.13-0 coredns:1.7.0 )

for imageName in ${images[@]} ; do docker pull registry.cn-hangzhou.aliyuncs.com/googlecontainers/$imageName docker tag registry.cn-hangzhou.aliyuncs.com/googlecontainers/$imageName k8s.gcr.io/$imageName docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName done


然后执行

`sudo kubeadm init --apiserver-advertise-address=192.168.56.200 --pod-network-cidr=10.244.0.0/16`

- apiserver-advertise-address=192.168.56.200 绑定 apiserver 到 master 节点的 Host-Only 适配器的地址,默认是绑到 NAT 的地址上,这样其他机器是永远也访问不到的。

- pod-network-cidr=10.244.0.0/16 指定 pod 网络地址空间,我们使用 flannel 组件必须使用这个空间。

kubeadm 的完整参考手册 kubeadm reference guide

推荐保存最后输出的 join 命令到文件(以免忘记或找不到了),方便添加节点到集群。如果忘了也找不到输出了,网上有方法生成哈希值,请自行查找。

这里碰到的问题是第一次因为 docker cgroup 的原因失败了,因此又重新执行,导致了如下错误,解决办法也在下面了: 

[init] Using Kubernetes version: v1.20.1 [preflight] Running pre-flight checks [WARNING SystemVerification]: this Docker version is not on the list of validated versions: 20.10.1. Latest validated version: 19.03 error execution phase preflight: [preflight] Some fatal errors occurred: [ERROR FileAvailable–etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists [ERROR FileAvailable–etc-kubernetes-manifests-kube-controller-manager.yaml]: /etc/kubernetes/manifests/kube-controller-manager.yaml already exists [ERROR FileAvailable–etc-kubernetes-manifests-kube-scheduler.yaml]: /etc/kubernetes/manifests/kube-scheduler.yaml already exists [ERROR FileAvailable–etc-kubernetes-manifests-etcd.yaml]: /etc/kubernetes/manifests/etcd.yaml already exists [ERROR Port-10250]: Port 10250 is in use [ERROR DirAvailable–var-lib-etcd]: /var/lib/etcd is not empty [preflight] If you know what you are doing, you can make a check non-fatal with --ignore-preflight-errors=... To see the stack trace of this error execute with –v=5 or higher


解决方法: `use "kubeadm reset" and reinitialize the kubeadm using "kubeadm init"`

地址: https://github.com/kubernetes/kubeadm/issues/1616

配置 kubectl 访问集群

non-root user

mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config


测试配置

kubectl cluster-info # 有正常输出即可


### 安装 flannel 网络

#### 安装与配置

flannel 默认的监听接口是 NAT 适配器的接口,我们需要的是 Host-Only 适配器的接口,所以需要修改 kube-flannel.yml 文件

这个值金额搞好像 也是下载不了的,还是需要复制他

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

给 /opt/bin/flanneld 命令添加 --iface="enp0s8" 参数 # enp0s8 是 Host-Only 适配器对应的接口

kubectl apply -f kube-flannel.yml


#### 测试是否 OK

kubectl get pods –all-nam espaces -o wide # 稍等一会,下载镜像需要一定时间,�最后应该显示 flannel pods 是 Running 状态, kube-dns 也是 Running 状态



## 增加其他节点

在节点上执行 kubeadm init 最后输出的 join 命令

kubeadm join –token : –discovery-token-ca-cert-hash sha256:


一旦遇到状态是 notReady 的情况大概率是拉镜像被强了,因此需要在 node 机器上使用脚本提前把镜像拉好,脚本在本文的上面。

然后在 master 节点如下做:

fupeng@master-node:~$ kubectl get node NAME STATUS ROLES AGE VERSION master-node Ready control-plane,master 11m v1.20.1 worker-node-03 Ready 21s v1.20.1 fupeng@master-node:~$ kubectl get pods –all-namespaces -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system coredns-74ff55c5b-lfjxj 11 Running 0 11m 10.244.0.3 master-node kube-system coredns-74ff55c5b-mkn4h 11 Running 0 11m 10.244.0.2 master-node kube-system etcd-master-node 11 Running 0 11m 10.0.2.15 master-node kube-system kube-apiserver-master-node 11 Running 0 11m 10.0.2.15 master-node kube-system kube-controller-manager-master-node 11 Running 0 11m 10.0.2.15 master-node kube-system kube-flannel-ds-9hmr5 11 Running 0 23s 10.0.2.15 worker-node-03 kube-system kube-flannel-ds-v4vft 11 Running 0 4m37s 10.0.2.15 master-node kube-system kube-proxy-2trdt 11 Running 0 11m 10.0.2.15 master-node kube-system kube-proxy-z5bgv 11 Running 0 23s 10.0.2.15 worker-node-03 kube-system kube-scheduler-master-node 11 Running 0 11m 10.0.2.15 master-node ```


参考:


  1. 如果不是ready状态, 查看日志, 看原因

journalctl -f -u kubelet.service

  1. 如果任一 Pod 状态不为 Running,请运行以下命令:

$ kubectl describe pod yourPodName -n kube-system

  1. 为了从 aws-node 和 kube-proxy Pod 日志中获取其他信息,请运行以下命令:

$ kubectl logs yourPodName -n kube-system

  1. 在node上执行kubeadm reset 可以断开node, 然后重新join
  2. 在master上执行kubeadm reset后可以重新init