学习笔记 · 2020年3月17日

使用 kubeadm 快速部署 Kubernetes 集群

浏览:152

基础环境配置

一些简单的步骤

由于这些步骤相对简单,就不作详细说明了:

  1. 新建 kube 用户并赋予管理员权限;
  2. 后续所有操作都在 kube 用户下执行;
  3. 打通 master 和 node 节点的免密登录;
  4. 统一 ntp 时间;
  5. 更新 hosts 文件,或者使用 dns 确保主机间解析正确;

添加 docker-ce 的 yum 源,并安装 docker-ce

所有主机执行:

wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo;
sudo sed -i 's+download.docker.com+mirrors.cloud.tencent.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo;
sudo yum makecache fast;
sudo yum install docker-ce;

安装完成后,修改 docker 配置,将 iptablesFORWARD 默认策略改为 ACCEPT

sudo vi /usr/lib/systemd/system/docker.service

ExecStart=/usr/bin/dockerd 一行之后新增如下内容:

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

修改后内容如下:

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

修改完成后,使其生效:

sudo systemctl daemon-reload;

启动 docker 并设置开机启动

所有主机执行:

sudo systemctl start docker.service;
sudo systemctl enable docker.service;

查看 iptables 配置是否更新成功:

sudo iptables -vnL
...
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0
...
# FORWARD policy 为 ACCEPT 即为成功。

将 kube 加入到 docker 组

所有主机执行:

sudo usermod -G docker kube;

确保 selinux 和 Firewalls 禁用状态;

所有主机执行:

sudo setenforce 0;
sudo systemctl stop firewalld.service;
sudo systemctl disable firewalld.service;

将桥接的 IPv4 流量传递到 iptables 的链

所有主机执行:

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

加载 ipvs 模块;

所有主机执行:

sudo vi /etc/sysconfig/modules/ipvs.modules 填入以下内容并保存:

#!/bin/bash
ipvs_mods_dir="/usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs"
for mod in $(ls ${ipvs_mods_dir}|grep -o "^[^.]*");do
    /sbin/modinfo -F filename ${mod} &> /dev/null
    if [ $? -eq 0 ]; then
        /sbin/modprobe -- ${mod}
    fi
done

修改文件权限,并手动为当前系统加载内核模块:

sudo chmod +x /etc/sysconfig/modules/ipvs.modules;
sudo bash /etc/sysconfig/modules/ipvs.modules;

添加 kubernetes 的 yum 源

所有主机执行:

sudo 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

安装基础组件:

sudo yum install -y --nogpgcheck kubelet kubeadm kubectl ipset;
sudo systemctl enable kubelet;

安装 Kubernetes 集群

忽略 swap 报错

所有主机执行:

由于我们没有禁用 Swap,所以要在 kubelet 配置文件里面添加忽略 Swap 的错误,否则每次重启都会报错。

编辑 /etc/sysconfig/kubelet 文件,更改如下内容:

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

生效:

sudo systemctl daemon-reload

使用 yaml 来部署 Kubernetes

在 master 主机执行:

编辑配置文件:

vi kubeadm.yaml

apiServer:
  extraArgs:
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers

kind: ClusterConfiguration
kubernetesVersion: v1.17.4
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.1.0.0/16
  podSubnet: 10.244.0.0/16
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs

注意,kubernetesVersion 版本要与 kubeadm 的版本一致,以及将 imageRepository 改为阿里云的镜像。

初始化 Kubernetes:

由于我们没有禁用 Swap,所以初始化时需要加忽略错误的参数 --ignore-preflight-errors=Swap

sudo kubeadm init --ignore-preflight-errors=Swap --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

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.147.118.61:6443 --token 8el3pj.ftk5mdcf9f6ok5l3 \
    --discovery-token-ca-cert-hash sha256:e812fa033aa638b5556974ac546de64c00bf0349989cc364043c63da67ca5f89 

然后根据提示执行以下命令:

(这步操作指定了 Kubernetes 管理员的帐号权限。)

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

执行完后,使用kubectl get pod -n kube-system验证:

注意:指定了 Kubernetes 管理员帐号后,使用该帐号执行 kubectl 不需要加 sudo

[kube@master-01 ~]$ kubectl get pod -n kube-system
NAME                                READY   STATUS    RESTARTS   AGE
coredns-9d85f5447-bdrz9             0/1     Pending   0          15m
coredns-9d85f5447-xhkhg             0/1     Pending   0          15m
etcd-master-01                      1/1     Running   0          15m
kube-apiserver-master-01            1/1     Running   0          15m
kube-controller-manager-master-01   1/1     Running   0          15m
kube-proxy-ctcc2                    1/1     Running   0          15m
kube-scheduler-master-01            1/1     Running   0          15m
[kube@master-01 ~]$ 

部署 flannel

从以上信息可以看到,coredns 一直处于 pending 状态,所以现在需要部署一下容器的网络,还是用 flannel

# 仅限于 Kubernetes v1.17+ 可以这样操作
# 具体参见:https://github.com/coreos/flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

安装完成后等待一段时间,就可以看到 coredns 处于 running 状态了:

[kube@master-01 ~]$ kubectl get pod -n kube-system
NAME                                READY   STATUS    RESTARTS   AGE
coredns-9d85f5447-bdrz9             1/1     Running   0          31m
coredns-9d85f5447-xhkhg             1/1     Running   0          31m
etcd-master-01                      1/1     Running   0          31m
kube-apiserver-master-01            1/1     Running   0          31m
kube-controller-manager-master-01   1/1     Running   0          31m
kube-flannel-ds-amd64-tvw9b         1/1     Running   0          58s
kube-proxy-ctcc2                    1/1     Running   0          31m
kube-scheduler-master-01            1/1     Running   0          31m
[kube@master-01 ~]$

这时候,使用 kubectl get pod 命令可以看到整个集群处于 Ready 状态:

[kube@master-01 ~]$ kubectl get nodes
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   34m   v1.17.4
[kube@master-01 ~]$

添加 Kubernetes 集群的 node 节点

找到安装日志里的这一段话:

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.147.118.61:6443 --token 8el3pj.ftk5mdcf9f6ok5l3 \
    --discovery-token-ca-cert-hash sha256:e812fa033aa638b5556974ac546de64c00bf0349989cc364043c63da67ca5f89 

按里面提示,就可以很容易地添加 node 节点了。如果忘了记录,可以在 master 中使用以下命令获取 token 和 hash 值:

[kube@master-01 ~]$ sudo kubeadm token list|cut -d' ' -f1
TOKEN
8el3pj.ftk5mdcf9f6ok5l3
[kube@master-01 ~]$ sudo openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
e812fa033aa638b5556974ac546de64c00bf0349989cc364043c63da67ca5f89

添加 node 节点:

在 node 上执行:

由于我们没有禁用 Swap,所以还需要加忽略错误的参数 --ignore-preflight-errors=Swap

sudo kubeadm join 10.147.118.61:6443 --token 8el3pj.ftk5mdcf9f6ok5l3 --ignore-preflight-errors=Swap --discovery-token-ca-cert-hash sha256:e812fa033aa638b5556974ac546de64c00bf0349989cc364043c63da67ca5f89 

执行完成后,在 master 上执行 kubectl get nodes 就可以看到新加入的 node 了:

[kube@master-01 ~]$ kubectl get nodes
NAME        STATUS   ROLES    AGE     VERSION
master-01   Ready    master   71m     v1.17.4
node-01     Ready    <none>   12m     v1.17.4
node-02     Ready    <none>   6m12s   v1.17.4

执行后 node 也会进行一定的初始化工作,会启动 flannelkube-proxy 容器;一开始可能没那么快 Ready。在 master 等着就行了,一会 node 就会变为 Ready

至此,Kubernetes 集群就算初步部署完成了。

测试 Kubernetes 集群

部署 nginx 进行测试

在 master 上执行:

kubectl run nginx --replicas=3 --image=nginx:latest --port=80
kubectl expose deployment nginx --port=80 --type=NodePort --target-port=80 --name=nginx-service
kubectl get svc,pod -o wide
[kube@master-01 ~]$ kubectl get svc,pod -o wide
NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/kubernetes      ClusterIP   10.1.0.1       <none>        443/TCP        89m   <none>
service/nginx-service   NodePort    10.1.106.224   <none>        80:31862/TCP   40s   run=nginx

NAME                        READY   STATUS              RESTARTS   AGE   IP       NODE      NOMINATED NODE   READINESS GATES
pod/nginx-dd6b5d745-87zwf   0/1     ContainerCreating   0          53s   <none>   node-02   <none>           <none>
pod/nginx-dd6b5d745-jcwp9   0/1     ContainerCreating   0          53s   <none>   node-02   <none>           <none>
pod/nginx-dd6b5d745-rr8n9   0/1     ContainerCreating   0          53s   <none>   node-01   <none>           <none>
[kube@master-01 ~]$

可以看到,pod 被分别分配到了 node-1 和 node-2,并且 nginx-service 部署成功。

好了,一个简单的 Kubernetes 集群就部署完成了,后续再根据不断地学习过程来完善相关内容吧。

以下是在整个部署过程中参考的文章: 使用 kubeadm 快速部署 kubernetes 1.15.2 集群