Kubeadm 部署 Kubernetes 单主节点集群(CentOS)

May 14, 2019 23:55 · 1316 words · 3 minute read Kubernetes Docker CentOS

2+ 台机器:

  • 64 位 CentOS Linux 系统
  • 机器网络互通
  • 可以访问外网(拉取镜像时要访问 gcr.io)
  • 2Core+ CPU、4GB+ RAM

以下所有操作在 root 账号上进行。

1. master 节点

1.1 设置主机名

$ hostnamectl set-hostname kube-master
$ hostname
kube-master

1.2 关防火墙

$ systemctl stop firewalld
$ systemctl disable firewalld

1.3 更新包

$ yum update -y

1.4 安装 Docker

$ yum install -y yum-utils \
    device-mapper-persistent-data \
    lvm2
$ yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
$ yum install -y docker-ce
$ systemctl start docker
$ docker info | grep Cgroup
Cgroup Driver: cgroupfs

这里要配置 Docker 使用 systemd 作为默认 Cgroup 驱动:

$ cat <<EOF > /etc/docker/daemon.json
{
    "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
$ systemctl restart docker
$ docker info | grep Cgroup
Cgroup Driver: systemd

使 Docker 开机自启动:

$ systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

1.5 安装 Kubernetes 全家桶

$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF
$ setenforce 0 # 关掉 SELinux
$ sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
$ yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
$ systemctl enable --now kubelet

1.6 关闭系统交换区

$ swapoff -a
$ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

1.7 初始化 master 节点

  • 使用 flannel 作为网络插件,kubeadm init 时带上 --pod-network-cidr=10.244.0.0/16 选项
  • 使用 calico 作为网络插件,kubeadm init 时带上 --pod-network-cidr=192.168.0.0/16 选项

初始化:

$ kubeadm init #--pod-network-cidr=10.244.0.0/16
[init] Using Kubernetes version: v1.14.1
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
......

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.211.55.80:6443 --token u0q8b5.yafzxgn70uirg59c \
    --discovery-token-ca-cert-hash sha256:e616f60bafbfba6b7147907d7bd5d5e7843599ff16c6c311d8c9aeea247d8d02

按照提示执行:

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

现在 kubectl 工具可以正常使用了!

Kubeadm 输出的 join 命令要记下来,用于添加工作节点:

kubeadm join 10.211.55.80:6443 --token u0q8b5.yafzxgn70uirg59c \
    --discovery-token-ca-cert-hash sha256:e616f60bafbfba6b7147907d7bd5d5e7843599ff16c6c311d8c9aeea247d8d02

检查一下 master 节点的状态

$ kubectl get nodes
NAME          STATUS     ROLES    AGE    VERSION
kube-master   NotReady   master   3m7s   v1.14.1

看到 master 节点状态为 NotReady,在调试 Kubernetes 集群时,经常要使用 kubectl describe 来查看节点对象的详细信息、状态和事件:

$ kubectl describe node kube-master
Name:               kube-master
Roles:              master
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=kube-master
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/master=
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Tue, 14 May 2019 22:46:30 +0800
Taints:             node.kubernetes.io/not-ready:NoExecute
                    node-role.kubernetes.io/master:NoSchedule
                    node.kubernetes.io/not-ready:NoSchedule
Unschedulable:      false
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  MemoryPressure   False   Tue, 14 May 2019 22:52:31 +0800   Tue, 14 May 2019 22:46:27 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Tue, 14 May 2019 22:52:31 +0800   Tue, 14 May 2019 22:46:27 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Tue, 14 May 2019 22:52:31 +0800   Tue, 14 May 2019 22:46:27 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            False   Tue, 14 May 2019 22:52:31 +0800   Tue, 14 May 2019 22:46:27 +0800   KubeletNotReady              runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

通过 kubectl describe 可以看到 network plugin is not ready: cni config uninitialized,这是因为还没有部署网络插件。

检查节点上各个系统 Pod 的状态

$ kubectl get pods -n kube-system
NAME                                  READY   STATUS    RESTARTS   AGE
coredns-fb8b8dccf-blnhr               0/1     Pending   0          8m56s
coredns-fb8b8dccf-z7498               0/1     Pending   0          8m56s
etcd-kube-master                      1/1     Running   0          7m45s
kube-apiserver-kube-master            1/1     Running   0          8m6s
kube-controller-manager-kube-master   1/1     Running   0          7m55s
kube-proxy-5h8p7                      1/1     Running   0          8m56s
kube-scheduler-kube-master            1/1     Running   0          8m5s

CoreDNS Pod 处于 Pending 状态。

接下来我们要部署网络插件:

1.8 部署网络插件

这里列出了一些可用的插件和对应的安装说明: https://kubernetes.io/docs/concepts/cluster-administration/addons/

  • Flannel

    $ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
    
  • Calico

    $ kubectl apply -f https://projectcalico.docs.tigera.io/manifests/calico.yaml
    

再检查 Pod 的状态

$ kubectl get po -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-547686d897-h2dbl   1/1     Running   0          6m5s
kube-system   calico-node-fhjsb                          1/1     Running   0          6m5s
kube-system   coredns-74ff55c5b-bfdkn                    1/1     Running   0          7m45s
kube-system   coredns-74ff55c5b-m8vd9                    1/1     Running   0          7m45s
kube-system   etcd-multuscni-test0                       1/1     Running   0          7m59s
kube-system   kube-apiserver-multuscni-test0             1/1     Running   0          7m59s
kube-system   kube-controller-manager-multuscni-test0    1/1     Running   0          7m59s
kube-system   kube-proxy-7hhf5                           1/1     Running   0          7m45s
kube-system   kube-scheduler-multuscni-test0             1/1     Running   0          7m59s

检查 master 节点的状态

$ kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
kube-master   Ready    master   16m   v1.14.1

master 节点现在已经是 Ready 状态了!接下来添加一个 worker 节点到集群中。

2. worker 节点

首先也要设置 hostname:

$ hostnamectl set-hostname kube-worker
$ hostname
kube-worker

初始化的操作和 master 节点完全一致:

  • 关闭防火墙
  • 更新包
  • 安装 Docker
  • 安装 Kubernetes
  • 关闭系统交换分区

然后要用到刚才记下的 join 指令:

$ kubeadm join 10.211.55.80:6443 --token u0q8b5.yafzxgn70uirg59c \
    --discovery-token-ca-cert-hash sha256:e616f60bafbfba6b7147907d7bd5d5e7843599ff16c6c311d8c9aeea247d8d02
[preflight] Running pre-flight checks
 [WARNING Service-Kubelet]: kubelet service is not enabled, please run 'systemctl enable kubelet.service'
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.14" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Activating the kubelet service
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

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 control-plane to see this node join the cluster.

这时我们再回 master 节点上查看节点状态:

$ kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
kube-master   Ready    master   34m   v1.14.1
kube-worker   Ready    <none>   71s   v1.14.1
$ kubectl

这个 worker 节点成功加入到了集群中,一个单主点 kubernetes 集群就搭建好了 👏

尝试使用 kubeadm-ansible playbook 4 CentOS 来加速集群初始化 😊