Kubernetes权威指南:从Docker到Kubernetes实践全接触(第4版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.2 使用kubeadm工具快速安装Kubernetes集群

最简单的方法是使用yum install kubernetes命令安装Kubernetes集群,但仍需修改各组件的启动参数,才能完成对Kubernetes集群的配置,整个过程比较复杂,也容易出错。Kubernetes从1.4版本开始引入了命令行工具kubeadm,致力于简化集群的安装过程,并解决Kubernetes集群的高可用问题。在Kubernetes 1.13版本中,kubeadm工具进入GA阶段,宣称已经为生产环境应用准备就绪。本节先讲解基于kubeadm的安装过程(以CentOS 7为例)。

2.2.1 安装kubeadm和相关工具

首先配置yum源,官方yum源的地址为https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64。如果无法访问官方yum源的地址,则也可以使用国内的一个yum源,地址为http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/,yum源的配置文件/etc/yum.repos.d/kubernetes.repo的内容如下:

        [kuebrnetes]
        name=Kubernetes Repository
        baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
        enabled=1
        gpgcheck=0

然后运行yum install命令安装kubeadm和相关工具:

        # yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

运行下面的命令,启动Docker服务(如果已安装Docker,则无须再次启动)和kubelet服务,并设置为开机自动启动:

        # systemctl enable docker && systemctl start docker
        # systemctl enable kubelet && systemctl start kubelet

2.2.2 kubeadm config

kubeadm已经进入GA阶段,其控制面初始化和加入节点步骤都支持大量的可定制内容,因此kubeadm还提供了配置文件功能用于复杂定制。同时,kubeadm将配置文件以ConfigMap的形式保存到集群之中,便于后续的查询和升级工作。kubeadm config子命令提供了对这一组功能的支持:

◎ kubeadm config upload from-file:由配置文件上传到集群中生成ConfigMap。

◎ kubeadm config upload from-flags:由配置参数生成ConfigMap。

◎ kubeadm config view:查看当前集群中的配置值。

◎ kubeadm config print init-defaults:输出kubeadm init默认参数文件的内容。

◎ kubeadm config print join-defaults:输出kubeadm join默认参数文件的内容。

◎ kubeadm config migrate:在新旧版本之间进行配置转换。

◎ kubeadm config images list:列出所需的镜像列表。

◎ kubeadm config images pull:拉取镜像到本地。

例如,执行kubeadm config print init-defaults,可以取得默认的初始化参数文件:

        # kubeadm config print init-defaults > init.default.yaml

对生成的文件进行编辑,可以按需生成合适的配置。例如,若需要定制镜像仓库的地址,以及Pod的地址范围,则可以使用如下配置:

        apiVersion: kubeadm.k8s.io/v1beta1
        kind: ClusterConfiguration
        imageRepository: docker.io/dustise
        kubernetesVersion: v1.14.0
        networking:
          podSubnet: "192.168.0.0/16"

将上面的内容保存为init-config.yaml备用。

2.2.3 下载Kubernetes的相关镜像

为了从国内的镜像托管站点获得镜像加速支持,建议修改Docker的配置文件,增加Registry Mirror参数,将镜像配置写入配置参数中,例如echo '{"registry-mirrors":["https://registry.docker-cn.com"]}' > /etc/docker/daemon.json,然后重启Docker服务。

使用config images pull子命令下载所需镜像,例如:

        # kubeadm config images pull --config=init-config.yaml
        [config/images] Pulled docker.io/dustise/kube-apiserver:v1.14.0
        [config/images] Pulled docker.io/dustise/kube-controller-manager:v1.14.0
        [config/images] Pulled docker.io/dustise/kube-scheduler:v1.14.0
        [config/images] Pulled docker.io/dustise/kube-proxy:v1.14.0
        [config/images] Pulled docker.io/dustise/pause:3.1
        [config/images] Pulled docker.io/dustise/etcd:3.3.10
       [config/images] Pulled docker.io/dustise/coredns:1.3.1

在镜像下载完成之后,就可以进行安装了。

2.2.4 运行kubeadm init命令安装Master

至此,准备工作已就绪,执行kubeadm init命令即可一键安装Kubernetes的Master。

在开始之前需要注意:kubeadm的安装过程不涉及网络插件(CNI)的初始化,因此kubeadm初步安装完成的集群不具备网络功能,任何Pod包括自带的CoreDNS都无法正常工作。而网络插件的安装往往对kubeadm init命令的参数有一定的要求。例如,安装Calico插件时需要指定--pod-network-cidr=192.168.0.0/16,详情可参考https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network

接下来使用kubeadm init命令,使用前面创建的配置文件进行集群控制面的初始化:

        # kubeadm init --config=init-config.yaml

运行后,控制台将输出如下内容:

        [init] Using Kubernetes version: v1.14.0
        ......
        [preflight] Pulling images required for setting up a Kubernetes cluster
        ......
        [kubelet-start] Activating the kubelet service
        ......
        [certs] Using certificateDir folder "/etc/kubernetes/pki"
        [certs] Generating "ca" certificate and key
        [certs] Generating "apiserver" certificate and key
        ......
        [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
        [kubeconfig] Writing "admin.conf" kubeconfig file
        [kubeconfig] Writing "kubelet.conf" kubeconfig file
        ......
        [kubeconfig] Writing "scheduler.conf" kubeconfig file
        [control-plane] Using manifest folder "/etc/kubernetes/manifests"
        [control-plane] Creating static Pod manifest for "kube-apiserver"

等待一段时间后,Kubernetes的Master安装成功,显示如下信息:

        [addons] Applied essential addon: CoreDNS
        [addons] Applied essential addon: kube-proxy

        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.30:6443--token ah9koe.nvuvz2v60iam0e0d \
            --discovery-token-ca-cert-hash
    sha256:9ded80601bc7f5568a9a7ece7ee13fd73be193777641054420a080f778b330fc

按照提示执行下面的命令,复制配置文件到普通用户的home目录下:

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

这样就在Master上安装了Kubernetes,但在集群内还是没有可用的工作Node,并缺乏对容器网络的配置。

这里需要注意kubeadm init命令执行完成后的最后几行提示信息,其中包含加入节点的指令(kubeadm join)和所需的Token。

此时可以用kubectl命令验证在2.2.2节中提到的ConfigMap:

        # kubectl get -n kube-system configmap
        kubectl get -n kube-system configmap
        NAME                                 DATA   AGE
        coredns                              1      48m
        extension-apiserver-authentication   6      48m
        kube-proxy                           2      48m
        kubeadm-config                       2      48m
        kubelet-config-1.14                  1      48m

可以看到其中生成了名为kubeadm-config的ConfigMap对象。

2.2.5 安装Node,加入集群

对于新节点的添加,系统准备和Kubernetes yum源的配置过程是一致的,在Node主机上执行下面的安装过程。

(1)安装kubeadm和相关工具:

        # yum install kubelet kubeadm --disableexcludes=kubernetes

运行下面的命令启动Docker服务与kubelet服务,并将其设置为开机自启动:

        # systemctl enable docker && systemctl start docker
        # systemctl enable kubelet && systemctl start kubelet

(2)为kubeadm命令生成配置文件。创建文件join-config.yaml,内容如下:

        apiVersion: kubeadm.k8s.io/v1beta1
        kind: JoinConfiguration
        discovery:
          bootstrapToken:
            apiServerEndpoint: 10.211.55.30:6443
            token: ah9koe.nvuvz2v60iam0e0d
            unsafeSkipCAVerification: true
          tlsBootstrapToken: ah9koe.nvuvz2v60iam0e0d

其中,apiServerEndpoint的值来自Master服务器的地址,token和tlsBootstrapToken的值就来自于使用kubeadm init安装Master的最后一行提示信息。

(3)执行kubeadm join命令,将本Node加入集群:

          # kubeadm join --config=join-config.yaml
          [preflight] Running pre-flight checks
          ......
          [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.

kubeadm在Master上也安装了kubelet,在默认情况下并不参与工作负载。如果希望安装一个单机All-In-One的Kubernetes环境,则可以执行下面的命令(删除Node的Label“node-role.kubernetes.io/master”),让Master成为一个Node:

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

2.2.6 安装网络插件

执行kubectl get nodes命令,会发现Kubernetes提示Master为NotReady状态,这是因为还没有安装CNI网络插件:

          # kubectl get nodes
          NAME             STATUS     ROLES    AGE    VERSION
          node-kubeadm-1   NotReady   master   67m    v1.14.0
          node-kubeadm-2   NotReady   <none>   2m9s   v1.14.0

下面根据kubeadm的提示安装CNI网络插件。对于CNI网络插件,可以有许多选择,请参考https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network的说明。

例如,选择weave插件,执行下面的命令即可一键完成安装:

        # kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl
    version | base64 | tr -d '\n')"
        serviceaccount/weave-net created
        clusterrole.rbac.authorization.k8s.io/weave-net created
        clusterrolebinding.rbac.authorization.k8s.io/weave-net created
        role.rbac.authorization.k8s.io/weave-net created
        rolebinding.rbac.authorization.k8s.io/weave-net created
        daemonset.extensions/weave-net created

2.2.7 验证Kubernetes集群是否安装完成

执行下面的命令,验证Kubernetes集群的相关Pod是否都正常创建并运行:

        # kubectl get pods --all-namespaces
        NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
        kube-system   coredns-7d8f5b649d-2lckr        1/1     Running   0          71m
        kube-system   coredns-7d8f5b649d-stssz        1/1     Running   0          71m
        kube-system   etcd-node1                         1/1     Running   0          70m
        kube-system   kube-apiserver-node1             1/1     Running   0          70m
        kube-system   kube-controller-manager-node1  1/1     Running   0          70m
        kube-system   kube-proxy-tnm4c                  1/1     Running   0          71m
        kube-system   kube-proxy-xjwgw                  1/1     Running   0          10m
        kube-system   kube-scheduler-node1             1/1     Running   0          70m
        kube-system   weave-net-nsfmn                   2/2     Running   0          61s
        kube-system   weave-net-qfk5x                   2/2     Running   0          61s

如果发现有状态错误的Pod,则可以执行kubectl --namespace=kube-system describe pod<pod_name>来查看错误原因,常见的错误原因是镜像没有下载完成。

至此,通过kubeadm工具就实现了Kubernetes集群的快速搭建。如果安装失败,则可以执行kubeadm reset命令将主机恢复原状,重新执行kubeadm init命令,再次进行安装。