zoukankan      html  css  js  c++  java
  • 使用kubeadm搭建一个完整的kubernetes集群

    环境准备

    本次部署一共三个节点,一个master,两个worker,都是 Ubuntu16.04 的虚拟机。

    • master : 172.31.0.57
    • worker01 : 172.31.0.32
    • worker02 : 172.31.0.53

    配置

    • 2核CPU
    • 8G内存
    • 40G系统盘+100G数据盘(数据盘用作ceph osd)
    • Ubuntu16.04
    • 内网互通

    部署流程

    1. 在所有节点安装 Docker 和 kubeadm
    2. 部署 Kubernetes Master
    3. 部署容器网络插件
    4. 部署 Kubernetes Worker
    5. 通过 Taint 调整 Master 执行 Pod 的策略
    6. 部署 Dashboard 可视化插件(可选)
    7. 部署容器存储插件

    安装 Docker 和 kubeadm

    备注:本次部署都是在root用户下进行操作

    这一步的所有操作在所有节点上都要执行

    root@master:~# apt-get update && apt-get install -y apt-transport-https
    root@master:~# curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
    root@master:~# vi /etc/apt/sources.list.d/kubernetes.list
    # 添加以下内容,然后保存退出,使用阿里的镜像源
    deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
    root@master:~# apt update
    root@master:~# apt -y install docker.io kubeadm
    

    在安装 kubeadm 的过程中,kubeadm 和 kubelet、kubectl、kubernetes-cni 这几个二进制文件都会被安装好。

    安装 docker 直接使用 docker.io 的安装源,因为发布的最新的 Docker CE(社区版)往往没有经过 Kubernetes 项目的验证,可能会有兼容性问题。

    另外,后续在执行 kubeadm 命令的时候,会进行一系列的检查工作(“preflight”),其中需要禁用虚拟内存(swap)。

    root@master:~# swapoff -a
    root@master:~# sed 's/.*swap.*/#&/' /etc/fstab
    

    部署 Kubernetes 的 Master 节点

    首先查看一下我们本次部署的 kubernetes 的版本信息

    root@master:~# kubeadm config print init-defaults
    .......
    .......
    apiServer:
      timeoutForControlPlane: 4m0s
    apiVersion: kubeadm.k8s.io/v1beta2
    certificatesDir: /etc/kubernetes/pki
    clusterName: kubernetes
    controllerManager: {}
    dns:
      type: CoreDNS
    etcd:
      local:
        dataDir: /var/lib/etcd
    imageRepository: k8s.gcr.io
    kind: ClusterConfiguration
    kubernetesVersion: v1.17.0
    networking:
      dnsDomain: cluster.local
      serviceSubnet: 10.96.0.0/12
    scheduler: {}
    
    

    备注:通过配置文件来开启一些实验性功能。

    有了这些信息后,接下来编写一个给 kubeadm 用的 YAML 文件(kubeadm.yaml):

    root@master:~# vi kubeadm.yaml
    
    apiVersion: kubeadm.k8s.io/v1beta2
    imageRepository: registry.aliyuncs.com/google_containers
    kind: ClusterConfiguration
    controllerManager:
        extraArgs:
            horizontal-pod-autoscaler-use-rest-clients: "true"
            horizontal-pod-autoscaler-sync-period: "10s"
            node-monitor-grace-period: "10s"
    apiServer:
        extraArgs:
            runtime-config: "api/all=true"
    kubernetesVersion: v1.17.0
    

    apiVersion、kind、kubernetesVersion 都可以从上面 print 的返回中得到。

    另外把 imageRepository 配置为 registry.aliyuncs.com/google_containers 阿里的源,因为默认的 k8s.gcr.io 因为一些原因访问不了。

    horizontal-pod-autoscaler-use-rest-clients: "true" 意味着,将来部署的 kube-controller-manager 能够使用自定义资源进行自动水平扩展。

    接下来,只需要一句指令,就可以完成 Kubernetes 的部署

    root@master:~# kubeadm init --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 172.31.0.57:6443 --token 1octc9.3uvkgo5vy1sgr7vy 
        --discovery-token-ca-cert-hash sha256:72fc3bf1a6cc0a159a27bf99518c116845b6a8ae05fb8e78cddc4c7156777c10
    

    部署完成后,kubeadm 会生成一行指令:

    kubeadm join 172.31.0.57:6443 --token 1octc9.3uvkgo5vy1sgr7vy 
        --discovery-token-ca-cert-hash sha256:72fc3bf1a6cc0a159a27bf99518c116845b6a8ae05fb8e78cddc4c7156777c10
    

    这个命令,就是用来给这个Master节点添加更多的工作节点使用的。

    另外,kubeadm 还会提示我们一些配置命令,也要执行一下:

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

    这样配置的原因是:Kubernetes 集群默认需要加密方式访问。所以将刚刚部署生成的 Kubernetes 集群的安全配置文件,保存到当前用户的.kube目录下,
    kubectl 默认会使用这个目录下的授权信息访问 Kubernetes 集群。

    现在,用 kubectl get 命令查看当前唯一一个节点的状态:

    root@master:~# kubectl get nodes
    NAME     STATUS     ROLES    AGE     VERSION
    master   NotReady   master   2m26s   v1.17.1
    

    输出结果中,master 的状态是 NotReady,排查问题,最重要的手段就是用 kubectl describe 来查看这个节点(Node)对象的详细信息、状态和事件(Event)。

    root@master:~# kubectl describe node master
    
    .....
    Conditions:
      Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
      ----             ------  -----------------                 ------------------                ------                       -------
      MemoryPressure   False   Sun, 19 Jan 2020 11:07:23 +0800   Sun, 19 Jan 2020 11:07:23 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
      DiskPressure     False   Sun, 19 Jan 2020 11:07:23 +0800   Sun, 19 Jan 2020 11:07:23 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
      PIDPressure      False   Sun, 19 Jan 2020 11:07:23 +0800   Sun, 19 Jan 2020 11:07:23 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
      Ready            False   Sun, 19 Jan 2020 11:07:23 +0800   Sun, 19 Jan 2020 11:07:23 +0800   KubeletNotReady              runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
    
    .....
    

    从输出中,可以看到原因在于为部署任何网络插件,network plugin is not ready: cni config uninitialized

    我们还可以通过 kubectl 查看这个节点上各个系统 Pod 的状态,其中 kube-system 是 Kubernetes 项目预留给系统 Pod 的工作空间。

    root@master:~# kubectl get pods -n kube-system 
    NAME                             READY   STATUS    RESTARTS   AGE
    coredns-9d85f5447-fksl4          0/1     Pending   0          6m45s
    coredns-9d85f5447-qqkwn          0/1     Pending   0          6m44s
    etcd-master                      1/1     Running   0          7m2s
    kube-apiserver-master            1/1     Running   0          7m2s
    kube-controller-manager-master   1/1     Running   0          7m1s
    kube-proxy-h2kdx                 1/1     Running   0          6m45s
    kube-scheduler-master            1/1     Running   0          7m1s
    

    从输出中可以看到,coredns 的 Pod 处于 Pending 状态,即调度失败,当然也符合预期,因为这个 Master 节点的网络尚未就绪。

    部署网络插件

    本次我们选择 Weave 为网络插件,只需执行一句kubectl apply指令

    root@master:~# kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '
    ')"
    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.apps/weave-net created
    

    部署完,等一两分钟,再次检查pod状态

    root@master:~# kubectl get pods -n kube-system
    NAME                             READY   STATUS    RESTARTS   AGE
    coredns-9d85f5447-fksl4          1/1     Running   0          12m
    coredns-9d85f5447-qqkwn          1/1     Running   0          12m
    etcd-master                      1/1     Running   0          12m
    kube-apiserver-master            1/1     Running   0          12m
    kube-controller-manager-master   1/1     Running   0          12m
    kube-proxy-h2kdx                 1/1     Running   0          12m
    kube-scheduler-master            1/1     Running   0          12m
    weave-net-xssqj                  2/2     Running   0          95s
    

    现在,所有的系统 Pod 都成功启动了,Weave 插件新建了一个名叫 weave-net-xssqj 的 Pod,这就是容器网络插件在每个节点上的控制组件。

    部署 Kubernetes 的 Worker 节点

    Kubernetes 的 Worker 节点和 Master 节点几乎是相同的,它们运行的都是一个 kubelet 组件。区别在于,Master 节点上多运行这 kube-apiserver、kube-scheduler、kube-controller-manager 这三个系统 Pod。

    部署 Worker 节点是最简单的,只需要两步即可。

    第一步,在所有的 Worker 节点上执行“安装 Docker 和 kubeadm”这一步的操作

    第二步,执行部署 Master 节点时生成的kubeadm join命令

    kubeadm join 172.31.0.57:6443 --token 1octc9.3uvkgo5vy1sgr7vy 
        --discovery-token-ca-cert-hash sha256:72fc3bf1a6cc0a159a27bf99518c116845b6a8ae05fb8e78cddc4c7156777c10
    

    这时,我们在 Master 节点上查看一下当前集群的节点(node)

    root@master:~# kubectl get node
    NAME       STATUS   ROLES    AGE   VERSION
    master     Ready    master   20m   v1.17.1
    worker01   Ready    <none>   1m   v1.17.1
    worker02   Ready    <none>   1m   v1.17.1
    
    

    可以看到,当前集群有三个节点,并且都是 Ready。

    通过 Taint 调整 Master 执行 Pod 的策略

    备注:默认情况下,Master 节点是不允许运行用户的 Pod 的。

    原理比较简单:一旦某个节点被打上了一个 Taint,即“有了污点”,那么所有的 Pod 就都不能在这个节点上运行。

    通过 kubectl descirbe 检查一下 Master 节点的 Taint 字段,

    root@master:~# kubectl describe node master
    Name:               master
    Roles:              master
    Labels:             ......
    Annotations:        ......
    CreationTimestamp:  ......
    Taints:             node-role.kubernetes.io/master:NoSchedule
    ......
    

    可以看到,Master节点默认加上了一个node-role.kubernetes.io/master:NoSchedule这样的Taint,键是node-role.kubernetes.io/master,值是NoSchedule

    所以,需要将这个Taint删掉才行

    root@master:~# kubectl taint nodes --all node-role.kubernetes.io/master-
    

    我们在node-role.kubernetes.io/master这个键后面加上了一个短横线-,这个格式就意味着移除所有以node-role.kubernetes.io/master为键的 Taint。

    至此,一个基本完整的 Kubernetes 集群就部署完毕了。

    接下来,会再安装一些其他的辅助插件,如 Dashboard 和存储插件。

    部署 Dashboard 可视化插件(可选)

    Dashboard 的部署也很简单,还是通过kubectl apply命令

    root@master:~# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc2/aio/deploy/recommended.yaml
    root@master:~# mv recommended.yaml kubernetes-dashboard.yaml
    root@master:~# kubectl apply -f kubernetes-dashboard.yaml
    namespace/kubernetes-dashboard created
    serviceaccount/kubernetes-dashboard created
    service/kubernetes-dashboard created
    secret/kubernetes-dashboard-certs created
    secret/kubernetes-dashboard-csrf created
    secret/kubernetes-dashboard-key-holder created
    configmap/kubernetes-dashboard-settings created
    role.rbac.authorization.k8s.io/kubernetes-dashboard created
    clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
    rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
    clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
    deployment.apps/kubernetes-dashboard created
    service/dashboard-metrics-scraper created
    deployment.apps/dashboard-metrics-scraper created
    

    部署完成后,在kubernetes-dashboard的命名空间下,会新建两个 Pod。

    root@master:~# kubectl get pod -n kubernetes-dashboard
    NAME                                         READY   STATUS    RESTARTS   AGE
    dashboard-metrics-scraper-7b64584c5c-w46jk   1/1     Running   0          3m
    kubernetes-dashboard-566f567dc7-554zh        1/1     Running   0          3m
    
    

    注意:Dashboard 部署完成后,默认只能通过 Proxy 的方式在本地访问。如果想从集群外访问这个 Dashboard 的话,需要用到 Ingress。

    部署容器存储插件

    本次部署选择 Rook 存储插件。

    root@master:~# kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/common.yaml
    root@master:~# kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/operator.yaml
    root@master:~# kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/cluster.yaml
    

    部署完成后,可以看到 Rook 在rook-ceph的命名空间下新建了一些 Pod。

    root@master:~# kubectl get pod -n rook-ceph           
    NAME                                                 READY   STATUS      RESTARTS   AGE
    csi-cephfsplugin-4t7qj                               3/3     Running     0          4m
    csi-cephfsplugin-9db7n                               3/3     Running     0          4m
    csi-cephfsplugin-pb8pv                               3/3     Running     0          4m
    csi-cephfsplugin-provisioner-8b9d48896-2qk22         4/4     Running     0          4m
    csi-cephfsplugin-provisioner-8b9d48896-dgbkm         4/4     Running     1          4m
    csi-rbdplugin-4ln69                                  3/3     Running     0          4m
    csi-rbdplugin-7qp7d                                  3/3     Running     0          4m
    csi-rbdplugin-provisioner-6d465d6c6f-4jsfj           5/5     Running     0          4m
    csi-rbdplugin-provisioner-6d465d6c6f-w4gzx           5/5     Running     1          4m
    csi-rbdplugin-sqmvz                                  3/3     Running     0          4m
    rook-ceph-crashcollector-master-6b8dd5d4fd-thq4w     1/1     Running     0          3m
    rook-ceph-crashcollector-worker01-68d69757d7-j9fzs   1/1     Running     0          4m
    rook-ceph-crashcollector-worker02-8474bd88d-xftgn    1/1     Running     0          3m
    rook-ceph-mgr-a-76c6c49cc9-7tlzb                     1/1     Running     0          3m
    rook-ceph-mon-a-59998d787-bdvlv                      1/1     Running     0          4m
    rook-ceph-mon-b-6d69bddc95-vvvkq                     1/1     Running     0          4m
    rook-ceph-mon-c-776d969f6c-89fhm                     1/1     Running     0          4m
    rook-ceph-operator-678887c8d-sm8bq                   1/1     Running     0          3m
    rook-ceph-osd-0-78fd8856df-lrfjx                     1/1     Running     0          3m
    rook-ceph-osd-1-5cd4b9564f-k55xt                     1/1     Running     0          3m
    rook-ceph-osd-2-7c4d99694f-j8phk                     1/1     Running     0          3m
    rook-ceph-osd-prepare-master-8f69h                   0/1     Completed   0          3m
    rook-ceph-osd-prepare-worker01-pm6cq                 0/1     Completed   0          3m
    rook-ceph-osd-prepare-worker02-dg7gb                 0/1     Completed   0          3m
    rook-discover-bpnc7                                  1/1     Running     0          4m
    rook-discover-bs9hj                                  1/1     Running     0          4m
    rook-discover-wwvr2                                  1/1     Running     0          4m
    
    

    rook-ceph-osd-prepare-master-8f69h、rook-ceph-osd-prepare-worker01-pm6cq 、rook-ceph-osd-prepare-worker02-dg7gb 它们的状态是 Completed,这个没有影响,其实它们是一种 job,完成部署 osd 的工作,执行完之后就变成 Completed 了。真正的 osd 的 Pod 是rook-ceph-osd-0-78fd8856df-lrfjx、rook-ceph-osd-1-5cd4b9564f-k55xt、rook-ceph-osd-2-7c4d99694f-j8phk。

    另外,默认启动的Ceph集群,是开启Ceph认证的,这样你登陆Ceph组件所在的Pod里,是没法去获取集群状态,以及执行CLI命令,需要部署Ceph toolbox,配置文件如toolbox.yaml所示(参考官网):

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: rook-ceph-tools
      namespace: rook-ceph
      labels:
        app: rook-ceph-tools
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: rook-ceph-tools
      template:
        metadata:
          labels:
            app: rook-ceph-tools
        spec:
          dnsPolicy: ClusterFirstWithHostNet
          containers:
          - name: rook-ceph-tools
            image: rook/ceph:v1.2.2
            command: ["/tini"]
            args: ["-g", "--", "/usr/local/bin/toolbox.sh"]
            imagePullPolicy: IfNotPresent
            env:
              - name: ROOK_ADMIN_SECRET
                valueFrom:
                  secretKeyRef:
                    name: rook-ceph-mon
                    key: admin-secret
            securityContext:
              privileged: true
            volumeMounts:
              - mountPath: /dev
                name: dev
              - mountPath: /sys/bus
                name: sysbus
              - mountPath: /lib/modules
                name: libmodules
              - name: mon-endpoint-volume
                mountPath: /etc/rook
          # if hostNetwork: false, the "rbd map" command hangs, see https://github.com/rook/rook/issues/2021
          hostNetwork: true
          volumes:
            - name: dev
              hostPath:
                path: /dev
            - name: sysbus
              hostPath:
                path: /sys/bus
            - name: libmodules
              hostPath:
                path: /lib/modules
            - name: mon-endpoint-volume
              configMap:
                name: rook-ceph-mon-endpoints
                items:
                - key: data
                  path: mon-endpoints
    

    执行 rook-ceph-tools的 pod

    root@master:~# kubectl apply -f toolbox.yaml
    

    部署完成后,可以看到在rook-ceph的命名空间下多了rook-ceph-tools-856c5bc6b4-mw7t8 Pod

    root@master:~# kubectl get pod -n rook-ceph| grep tools
    rook-ceph-tools-856c5bc6b4-mw7t8                     1/1     Running     0          3m
    

    现在,进入到pod当中,执行ceph -s,查看ceph 集群的状态

    root@master:~# kubectl exec -it rook-ceph-tools-856c5bc6b4-mw7t8  -n rook-ceph bash
    
    [root@worker02 /]# ceph -s
      cluster:
        id:     11436e29-c940-4a4f-9875-c65fac3531c1
        health: HEALTH_OK
     
      services:
        mon: 3 daemons, quorum a,b,c (age 5h)
        mgr: a(active, since 5m)
        osd: 3 osds: 3 up (since 5m), 3 in (since 5m)
     
      data:
        pools:   0 pools, 0 pgs
        objects: 0 objects, 0 B
        usage:   3.0 GiB used, 294 GiB / 297 GiB avail
        pgs:     
    
    

    可以看到,ceph集群是HEALTH_OK的。

  • 相关阅读:
    开源APM应用性能管理工具调研
    Inside ARC — to see the code inserted by the compiler
    报表应用系统中怎样正确使用图表功能
    创建cifs系统案例之“实现将Windows磁盘共享至Linux”
    Eclipse快捷键 10个最有用的快捷键
    如何生成KeyStore
    android中调用系统的发送短信、发送邮件、打电话功能
    android自带theme
    Android 报错:Conversion to Dalvik format failed: Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
    Android oncreate onupgrade什么时候被调用
  • 原文地址:https://www.cnblogs.com/zhaoyixin96/p/12582449.html
Copyright © 2011-2022 走看看