架构规划

k8s至少需要一个master和一个node才能组成一个可用集群。

我们有三台服务器,ip和身份规划如下: 
192.168.0.145master node 
192.168.0.145 node 
192.168.0.145 node

192.168.0.145即作master节点又作node节点。

三台服务器都是CentOS7系统。

设置主机名

分别使用hostname命令把主机名称设置为k8s,k8s1,k8s2

hostname k8s

hostname k8s1

hostname k8s2

然后编辑对应关系,使用命令

vi /etc/hosts

输入如下:

192.168.0.145    k8s

192.168.0.146    k8s1

192.168.0.147    k8s2

 使用kubeadm安装Kubernetes

注意以下命令,非root用户需要sudo权限带sudo执行相关命令。

Root用户去掉sudo执行。

关闭防火墙

如果各个主机启用了防火墙,需要开放Kubernetes各个组件所需要的端口,可以查看Installing kubeadm中的”Check required ports”一节。 这里简单起见在各节点禁用防火墙:

sudo systemctl stop firewalld.service   #停止firewall

sudo systemctl disable firewalld.service #禁止firewall开机启动

sudo firewall-cmd --state             #查看防火墙状态

禁用SELINUX

sudo setenforce 0

sudo vi /etc/selinux/config

#SELINUX修改为disabled

SELINUX=disabled

创建/etc/sysctl.d/k8s.conf文件

sudo vi /etc/sysctl.d/k8s.conf

添加如下内容:

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

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

是修改生效,执行

sudo sysctl -p /etc/sysctl.d/k8s.conf

遇到错误:

error: "net.bridge.bridge-nf-call-ip6tables" is an unknown key

error: "net.bridge.bridge-nf-call-iptables" is an unknown key

解决方法:

sudo modprobe bridge

sudo lsmod | grep bridge

sudo sysctl -p /etc/sysctl.d/k8s.conf

可能遇到问题

–sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: 没有那个文件或目录 报错

[root@localhost ~]# sysctl -p /etc/sysctl.d/k8s.conf

sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: 没有那个文件或目录

sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: 没有那个文件或目录

解决方法:

modprobe br_netfilter

ls /proc/sys/net/bridge

sudo sysctl -p /etc/sysctl.d/k8s.conf

安装Docker

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

查看当前的Docker版本: 
使用命令

sudo yum list docker-ce.x86_64  --showduplicates |sort -r

输出如下:

[zzq@localhost ~]$ sudo yum list docker-ce.x86_64  --showduplicates |sort -r

 * updates: mirrors.aliyun.com

Loading mirror speeds from cached hostfile

Loaded plugins: fastestmirror, priorities

 * extras: mirrors.aliyun.com

 * elrepo: mirrors.tuna.tsinghua.edu.cn

docker-ce.x86_64            18.03.1.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            18.03.0.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.12.1.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.12.0.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.09.1.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.09.0.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.06.2.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.06.1.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.06.0.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.03.2.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.03.1.ce-1.el7.centos             docker-ce-stable

docker-ce.x86_64            17.03.0.ce-1.el7.centos             docker-ce-stable

 * base: mirrors.aliyun.com

Available Packages

[zzq@localhost ~]$

Kubernetes 1.8已经针对Docker的1.11.2, 1.12.6, 1.13.1和17.03等版本做了验证。 因此我们这里在各节点安装docker的17.03.2版本。 
使用命令如下:

sudo yum makecache fast

以及

sudo yum install -y --setopt=obsoletes=0 \

  docker-ce-17.03.2.ce-1.el7.centos \

  docker-ce-selinux-17.03.2.ce-1.el7.centos

可能遇到的问题

获取 GPG 密钥失败:[Errno 12] Timeout on https://download.docker.com/linux/centos/gpg: (28, 'Operation timed out after 30002 milliseconds with 0 out of 0 bytes received')

解决方法 
一般超时原因都是网络问题,需要检查网络以及能够直接访问到这个资源比如使用命令:

curl -l https://download.docker.com/linux/centos/gpg

启动和停止Docker

Centos7

sudo systemctl start docker

Docker从1.13版本开始调整了默认的防火墙规则,禁用了iptables filter表中FOWARD链,这样会引起Kubernetes集群中跨Node的Pod无法通信,在各个Docker节点执行下面的命令:

sudo iptables -P FORWARD ACCEPT

同时在docker的systemd unit文件中以ExecStartPost加入允许访问的代码,使用命令如下:

# 为docker服务创建一个systemd插件目录

mkdir -p /etc/systemd/system/docker.service.d

# 创建一个/etc/systemd/system/docker.service.d/port.conf配置文件

vi /etc/systemd/system/docker.service.d/port.conf

输入以下内容,保存退出:

ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT

重启docker服务

systemctl daemon-reload

systemctl restart docker

安装Kubeadm和kubelet

下面在各节点安装kubeadm和kubelet,编辑资源库

vi   /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

使用阿里云镜像地址

执行以下命令

Yum makecache fast

Yum install -y kubelet kubeadm kubectl

安装完成

调整启动方式

kubelet的启动环境变量要与docker的cgroup-driver驱动一样。

查看docker的cgroup-driver驱动 
使用命令

docker info

或者

docker info | grep -i cgroup

输出如下:

Cgroup Driver: cgroupfs

默认值为cgroupfs,yum安装kubelet,kubeadm时生成10-kubeadm.conf文件中可能将这个参数值改成了systemd。

查看kubelet的配置文件,其中包含如下内容: 
使用命令

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

或者

cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf|grep "cgroup-driver"

如果没找到则默认的cgroupfs,不需要修改。

如果输出如下则需要修改成一致的方式,即可以修改10-kubeadm.conf中的也可以修改docker的。

KUBELET_CGROUP_ARGS=--cgroup-driver=systemd

我们这里修改各节点docker的cgroup driver使其和kubelet一致

即修改或创建/etc/docker/daemon.json 
使用命令

vi /etc/docker/daemon.json

加入下面的内容:

{

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

}

重启docker:

systemctl restart docker

systemctl status docker

处理swap

Kubernetes 1.8开始要求关闭系统的Swap,如果不关闭,默认配置下kubelet将无法启动。 
可以通过kubelet的启动参数–fail-swap-on=false更改这个限制。

方式一关闭swap

关闭系统的Swap方法如下:

swapoff -a

同时还需要修改/etc/fstab文件,注释掉 SWAP 的自动挂载,防止机子重启后swap启用。 
使用命令

vi /etc/fstab

输出如下:

#

# /etc/fstab

# Created by anaconda on Tue Jun 19 06:52:02 2018

#

# Accessible filesystems, by reference, are maintained under '/dev/disk'

# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

#

/dev/mapper/centos-root /                       xfs     defaults        0 0

UUID=2d32a0e0-9bda-4a68-9abf-6a827a517177 /boot                   xfs     defaults        0 0

/dev/mapper/centos-swap swap                    swap    defaults        0 0

注释swap这一行后保存退出

#/dev/mapper/centos-swap swap                    swap    defaults        0 0

确认swap已经关闭,使用命令

free -m

swap输出为0则说明已经关闭,如下:

 

 

k8s的swappiness参数调整,修改配置文件

vi /etc/sysctl.d/k8s.conf

添加下面一行:

vm.swappiness=0

执行

sysctl -p /etc/sysctl.d/k8s.conf

方式二去掉swap的限制

因为主机上还运行其他服务,关闭swap可能会对其他服务产生影响,则修改kubelet的启动参数去掉这个限制。 
修改/etc/systemd/system/kubelet.service.d/10-kubeadm.conf 
使用命令

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

加入内容:

Environment="KUBELET_EXTRA_ARGS=--fail-swap-on=false"

systemctl daemon-reload

启动kubelet服务

在各节点开机启动kubelet服务 
使用命令

systemctl enable kubelet.service

systemctl start kubelet.service

准备镜像

执行命令

kubeadm config images list

输出如下:

k8s.gcr.io/kube-apiserver:v1.14.1

k8s.gcr.io/kube-controller-manager:v1.14.1

k8s.gcr.io/kube-scheduler:v1.14.1

k8s.gcr.io/kube-proxy:v1.14.1

k8s.gcr.io/pause:3.1

k8s.gcr.io/etcd:3.3.10

k8s.gcr.io/coredns:1.3.1

根据https://hub.docker.com/中下载镜像,然后使用命令

docker pull  mirrorgooglecontainers/kube-proxy:v1.14.1

docker pull  mirrorgooglecontainers/kube-apiserver:v1.14.1

docker pull  mirrorgooglecontainers/kube-scheduler:v1.14.1  

docker pull  mirrorgooglecontainers/kube-controller-manager:v1.14.1

docker pull  quay.io/coreos/flannel:v0.11.0-amd64

docker pull  coredns/coredns:1.3.1      

docker pull  siriuszg/kubernetes-dashboard-amd64:latest      

docker pull  mirrorgooglecontainers/etcd:3.3.10       

docker pull  anjia0532/google-containers.kube-proxy-amd64:v1.11.2        

docker pull  anjia0532/google-containers.kube-controller-manager-amd64:v1.11.2       

docker pull  anjia0532/google-containers.kube-scheduler-amd64:v1.11.2          

docker pull  k8scn/kubernetes-dashboard-amd64:v1.8.3       

docker pull  anjia0532/etcd-amd64:3.2.18          

docker pull  anjia0532/pause:3.1

docker pull  radial/busyboxplus:curl

修改镜像名称

docker tag  mirrorgooglecontainers/kube-apiserver:v1.14.1    k8s.gcr.io/kube-apiserver:v1.14.1

docker tag  mirrorgooglecontainers/kube-controller-manager:v1.14.1   k8s.gcr.io/kube-controller-manager:v1.14.1

docker tag  mirrorgooglecontainers/kube-scheduler:v1.14.1   k8s.gcr.io/kube-scheduler:v1.14.1

docker tag  mirrorgooglecontainers/kube-proxy:v1.14.1    k8s.gcr.io/kube-proxy:v1.14.1

docker tag  anjia0532/pause:3.1   k8s.gcr.io/pause:3.1

docker tag  mirrorgooglecontainers/etcd:3.3.10   k8s.gcr.io/etcd:3.3.10

docker tag  coredns/coredns:1.3.1    k8s.gcr.io/coredns:1.3.1

注意 这里的前缀需要与kubeadm config images list时输出的前缀对应,否则init时仍然会识别不到去下载。 
我们这里是k8s.gcr.io所以 脚本中pull 时重命名使用的是

准备好的镜像如下,与kubeadm config images list时输出的镜像名称版本一致。

k8s.gcr.io/kube-apiserver:v1.14.1

k8s.gcr.io/kube-controller-manager:v1.14.1

k8s.gcr.io/kube-scheduler:v1.14.1

k8s.gcr.io/kube-proxy:v1.14.1

k8s.gcr.io/pause:3.1

k8s.gcr.io/etcd:3.3.10

k8s.gcr.io/coredns:1.3.1

使用kubeadm init初始化集群 (只在主节点执行)

初始化前确认 kubelet启动和 cgroup-driver等方式是否对应。

接下来使用kubeadm初始化集群,选择k8s作为Master Node 
确保没有设置http_proxy和https_proxy代理 
在k8s上执行下面的命令:

kubeadm init   --kubernetes-version=v1.14.1 --pod-network-cidr=10.244.0.0/16   --apiserver-advertise-address=192.168.0.145--token-ttl 0

–kubernetes-version根据上面安装成功时的提示:kubectl.x86_64 0:1.11.2-0对应版本。

因为我们选择flannel作为Pod网络插件,所以上面的命令指定–pod-network-cidr=10.244.0.0/16。

对于某些网络解决方案,Kubernetes master 也可以为每个节点分配网络范围(CIDR),这包括一些云提供商和 flannel。通过 –pod-network-cidr 参数指定的子网范围将被分解并发送给每个 node。这个范围应该使用最小的 /16,以让 controller-manager 能够给集群中的每个 node 分配 /24 的子网。如果我们是通过 这个 manifest 文件来使用 flannel,那么您应该使用 –pod-network-cidr=10.244.0.0/16。大部分基于 CNI 的网络解决方案都不需要这个参数。

–apiserver-advertise-address是apiserver的通信地址,一般使用master的ip地址。

 

通过kubeadm初始化后,都会提供节点加入k8s集群的token。默认token的有效期为24小时,当过期之后,该token就不可用了,需要重新生成token,会比较麻烦,这里–token-ttl设置为0表示永不过期。

token过期后重新创建token的方法看文末。

执行init成功后

 

 

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

 

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 192.168.0.145:6443 --token cma2cs.x4n8z4w5n4pxxelz \

--discovery-token-ca-cert-hash sha256:6ccdeb05dcdfe28e8b7b0e1e7a8b7b03d558ec60ef0acf8a97a7a60408b85fd3

上面记录了完成的初始化输出的内容。

其中有以下关键内容:

生成token记录下来,后边使用kubeadm join往集群中添加节点时会用到

下面的命令是配置常规用户如何使用kubectl(客户端)访问集群,因为master节点也需要使用kubectl访问集群,所以也需要运行以下命令:

  mkdir -p $HOME/.kube

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

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

kubeadm join 192.168.0.154:6443 --token cma2cs.x4n8z4w5n4pxxelz \

--discovery-token-ca-cert-hash

sha256:6ccdeb05dcdfe28e8b7b0e1e7a8b7b03d558ec60ef0acf8a97a7a60408b85fd3

查看一下集群状态如下:

kubectl get cs

NAME                 STATUS    MESSAGE              ERROR

scheduler            Healthy   ok

controller-manager   Healthy   ok

etcd-0               Healthy   {"health": "true"}

确认每个组件都处于healthy状态。

安装Pod Network (只在主节点执行)

接下来安装flannel network add-on:

mkdir -p ~/k8s/

cd ~/k8s

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

kubectl apply -f  kube-flannel.yml

输出如下:

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

这里可以cat查看kube-flannel.yml这个文件里的flannel的镜像的版本

cat kube-flannel.yml|grep quay.io/coreos/flannel

如果Node有多个网卡的话,目前需要在kube-flannel.yml中使用–iface参数指定集群主机内网网卡的名称,否则可能会出现dns无法解析。需要将kube-flannel.yml下载到本地,flanneld启动参数加上–iface=

containers:

      - name: kube-flannel

        image: quay.io/coreos/flannel:v0.10.0-amd64

        command:

        - /opt/bin/flanneld

        args:

        - --ip-masq

        - --kube-subnet-mgr

        - --iface=eth1

使用kubectl get pod  --all-namespaces -o wide确保所有的Pod都处于Running状态。

 

 

master node参与工作负载 (只在主节点执行)

使用kubeadm初始化的集群,出于安全考虑Pod不会被调度到Master Node上,也就是说Master Node不参与工作负载。

 

这里搭建的是测试环境可以使用下面的命令使Master Node参与工作负载:

k8s是master节点的hostname

允许master节点部署pod,使用命令如下:

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

输出如下:

Node k8s untainted

输出error: taint “node-role.kubernetes.io/master:” not found错误忽略。

禁止master部署pod

kubectl taint nodes k8s node-role.kubernetes.io/master=true:NoSchedule

测试DNS (只在主节点执行)

使用命令

kubectl run curl --image=radial/busyboxplus:curl -i --tty

输出如下:

If you don't see a command prompt, try pressing enter.

[ root@curl-87b54756-vsf2s:/ ]$

进入后执行:

nslookup kubernetes.default

确认解析正常,输出如下:

[ root@curl-87b54756-vsf2s:/ ]$ nslookup kubernetes.default

Server:    10.96.0.10

Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

 

Name:      kubernetes.default

Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local

输入

Exit;

可退出image

向Kubernetes集群添加Node (只在副节点执行)

kubeadm join 192.168.0.145:6443 --token hu2clf.898he8fnu64w3fur --discovery-token-ca-cert-hash sha256:2a196bbd77e4152a700d294a666e9d97336d0f7097f55e19a651c19e03d340a4

正确输入如下:

[root@k8s1 ~]# kubeadm join 192.168.11.90:6443 --token hu2clf.898he8fnu64w3fur --discovery-token-ca-cert-hash sha256:2a196bbd77e4152a700d294a666e9d97336d0f7097f55e19a651c19e03d340a4

[preflight] running pre-flight checks

    [WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}]

you can solve this problem with following methods:

 1. Run 'modprobe -- ' to load missing kernel modules;

2. Provide the missing builtin kernel ipvs support

 

I0815 16:53:55.675009    2758 kernel_validator.go:81] Validating kernel version

I0815 16:53:55.675090    2758 kernel_validator.go:96] Validating kernel config

[discovery] Trying to connect to API Server "192.168.11.90:6443"

[discovery] Created cluster-info discovery client, requesting info from "https://192.168.11.90:6443"

[discovery] Requesting info from "https://192.168.11.90:6443" again to validate TLS against the pinned public key

[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.11.90:6443"

[discovery] Successfully established connection with API Server "192.168.11.90:6443"

[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.11" ConfigMap in the kube-system namespace

[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"

[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"

[preflight] Activating the kubelet service

[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...

[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s1" as an annotation

 

This node has joined the cluster:

* Certificate signing request was sent to master 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.

下面在master节点上执行命令查看集群中的节点:

 

如果副节点是NotReady,可以使用命令检查是否有报错

Systemctl status kubelet.service

使用命令检查pod是否是running状态

 

 

如果卡在ContainerCreating状态和Init:0/1一般也是副节点的镜像获取不到的问题,请回到 准备镜像小节。 
准备好镜像之后一般很快就会变成running状态

此时查看nodes也已经变成了ready状态

 

 

如果副节点也需要使用kubectl命令则需要把conf文件复制过去,使用命令

mkdir -p $HOME/.kube

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

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

如何从集群中移除Node

如果需要从集群中移除k8s2这个Node执行下面的命令:

master节点上执行:

kubectl drain k8s2 --delete-local-data --force --ignore-daemonsets

kubectl delete node k8s2

在k8s2上执行:

kubeadm reset

ifconfig cni0 down

ip link delete cni0

ifconfig flannel.1 down

ip link delete flannel.1

rm -rf /var/lib/cni/

到这里我们就算成功安装好了k8s集群了。

我们还需要安装dashboard监控界面。

参考链接   https://blog.csdn.net/zzq900503/article/details/81710319

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐