基于CentOS7.3下二进制安装Kubernetes1.9集群 开启TLS

  Kubernetes的相关原理性的东西之前有叙述过,网上也有很多,这里主要是写的自己在使用二进制的方式搭建Kubernetes1.9的一些方法,对学习的东西做一个自我的总结。

  Kubernetes有许多种安装方式,yum安装,kubeadm一键安装以及二进制安装,二进制安装方式是几乎所有企业生产环境都会选择的安装方式,kubeadm虽然是一键部署,安全性也不赖,但对于初学Kubernetes的人来说,没法去真正了解到Kubernetes的底层架构,所以二进制的安装方式还是需要去学习一下的,最好两者都有涉猎,研究过。

  kubeadm 能够用于生产环境吗? 到目前为止(2018 9月)这个问题的答案是:不能,因为kubeadm目前最缺乏而就是一键部署一个高可用的集群,etcd,mater组件都应该是高可用的,而不是现在这样的单节点,这也是现在kubeadm以后的发展方向。


  安装过程中所使用的所有安装包

  链接:链接:https://pan.baidu.com/s/1ytDCmcSZudiprW5dBkXihA
  提取码:reyu


  1.主机初始化

  CentOS7.3 node-1 192.168.175.128  master kube-apiserver,kube-scheduler,kube-controller-manager,kubectl,etcd

  CentOS7.3 node-2 192.168.175.130  node1 kube-proxy,etcd,kubelet,flanneld,docker

  CentOS7.3 node-3 192.168.175.131  node2 kube-proxy,etcd,kubelet,flanneld,docker


  关闭防火墙(三台主机)

  # systemctl stop firewalld

  # iptables -F

  # setenforce 0

  # sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux


  k8s的node节点上安装docker

  # yum install https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm  -y

  # yum install https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm  -y

  # systemctl start docker && systemctl enable docker

  # systemctl start docker && systemctl enable docker


  2.Kubernetes自签TLS证书

  图片.png

  上图为对应组件所需要的密钥对

  ca.pem:自签的CA证书。

  ca-key.pem:自签的CA私钥。

  server.pem:k8s集群通信使用的公钥。

  server-key.pem:k8s集群通信使用的私钥。

  kube-proxy.pem:kube-proxy组件应用的公钥,并用于生成kube-proxy kubeconfig文件用于进行授权认证。

  kube-proxy-key.pem:kube-proxy组件应用的私钥。

  admin.pem,admin-key.pem:k8s的node端想要远程使用kubectl所使用的密钥对。

 

  基于证书生成工具快速部署密钥

  安装证书生成工具cfssl:
  # wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
  # wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
  # wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
  # chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
  # mv cfssl_linux-amd64 /usr/local/bin/cfssl
  # mv cfssljson_linux-amd64 /usr/local/bin/cfssljson

  # mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

 

  在三台主机上,创建kubernetes的目录结构

  mkdir -pv /opt/kubernetes/{bin,cfg,ssl}

  在/opt/kubernetes/ssl路径下创建以下密钥

 ①创建CA密钥对

 # cat > ca-config.json <<EOF
 {
   "signing": {
     "default": {
       "expiry": "87600h"
     },
     "profiles": {
       "kubernetes": {
          "expiry": "87600h",
          "usages": [
             "signing",
             "key encipherment",
             "server auth",
             "client auth"
         ]
       }
     }
   }
  }
 EOF      

 # cat > ca-csr.json <<EOF
 {
     "CN": "kubernetes",
     "key": {
         "algo": "rsa",
         "size": 2048
     },
     "names": [
         {
             "C": "CN",
             "L": "Beijing",
             "ST": "Beijing",
             "O": "k8s",
             "OU": "System"
         }
     ]
 }
 EOF

 # cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

  ②创建集群通信密钥对

  # cat > server-csr.json <<EOF
  {
      "CN": "kubernetes",
      "hosts": [
        "127.0.0.1",
        "192.168.175.128",
        "192.168.175.130",
        "192.168.175.131",
        "10.10.10.1",
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local"
      ],
      "key": {
          "algo": "rsa",
          "size": 2048
      },
      "names": [
          {
              "C": "CN",
              "L": "BeiJing",
              "ST": "BeiJing",
              "O": "k8s",
              "OU": "System"
          }
      ]
  }
  EOF       

  #  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server


  ③创建admin密钥对

  # cat > admin-csr.json <<EOF
  {
    "CN": "admin",
    "hosts": [],
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
      {
        "C": "CN",
        "L": "BeiJing",
        "ST": "BeiJing",
        "O": "system:masters",
        "OU": "System"
      }
    ]
  }
  EOF

  # cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

 

  ④创建kube-proxy密钥对

  # cat > kube-proxy-csr.json <<EOF
  {
    "CN": "system:kube-proxy",
    "hosts": [],
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
      {
        "C": "CN",
        "L": "BeiJing",
        "ST": "BeiJing",
        "O": "k8s",
        "OU": "System"
      }
    ]
  }
  EOF

  # cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

  到这里,所需要的密钥已经全部创建完成,可以将其他不是以pem结尾的文件删除

  # ls | grep -v "pem$" | xargs -i rm {}

  图片.png

  bootstrap.kubeconfig以及kube-proxy.kubeconfig是后面node节点通过kubelet加入到kubernetes集群中所使用的认证


  注意:需要将在master上创建的密钥对发送到对应node节点上的/opt/kubernetes/ssl下,懒人可以全发,省事。

 

  3.etcd高可用集群部署

 ①导入etcd的二进制文件包,解压,将etcd,etcdctl放置在/opt/kubernetes/bin下

 # tar -xf etcd-v3.2.12-linux-amd64.tar.gz

  图片.png

  # mv etcd* /opt/kubernetes/bin

  # chmod +x /opt/kubernetes/bin/*

  ②创建etcd配置文件,指定当前节点etcd名称,当前节点etcd监听的地址,对etcd集群环境进行初始化

  图片.png

  ETCD_DATA_DIR:etcd数据存储位置,初次部署,当etcd配置运行错误时,最好将所有节点的该目录删除,重新初始化。

  ETCD_LISTEN_PEER_URLS:etcd集群节点之间通讯的监听地址,2380为通信接口。

  ETCD_LISTEN_CLIENT_URLS:etcd集群对外的数据访问接口,2379为数据访问接口,后面都会应用到。

  ETCD_INITIAL_CLUSTER:初始化etcd集群节点。

  node-2,node-3主机的etcd节点配置文件

  图片.png

  图片.png

  ③创建etcd的systemd服务启动(三个节点都通用的配置文件)
  [root@node-1 ~]# cat /usr/lib/systemd/system/etcd.service
  [Unit]
  Description=Etcd Server
  After=network.target
  After=network-online.target
  Wants=network-online.target

  [Service]
  Type=notify
  EnvironmentFile=-/opt/kubernetes/cfg/etcd
  ExecStart=/opt/kubernetes/bin/etcd \
  --name=${ETCD_NAME} \
  --data-dir=${ETCD_DATA_DIR} \
  --listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \
  --listen-client-urls=${ETCD_LISTEN_CLIENT_URLS},http://127.0.0.1:2379 \
  --advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \
  --initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
  --initial-cluster=${ETCD_INITIAL_CLUSTER} \
  --initial-cluster-token=${ETCD_INITIAL_CLUSTER} \
  --initial-cluster-state=new \
  --cert-file=/opt/kubernetes/ssl/server.pem \
  --key-file=/opt/kubernetes/ssl/server-key.pem \
  --peer-cert-file=/opt/kubernetes/ssl/server.pem \
  --peer-key-file=/opt/kubernetes/ssl/server-key.pem \
  --trusted-ca-file=/opt/kubernetes/ssl/ca.pem \
  --peer-trusted-ca-file=/opt/kubernetes/ssl/ca.pem
  Restart=on-failure
  LimitNOFILE=65536

  [Install]
  WantedBy=multi-user.target


  # systemctl start etcd.service && systemctl enable etcd.service

 启动没报错即可,ps查看进程是否起来

 # ps aux | grep etcd

 图片.png

 三个节点都启动etcd

 查看etcd集群节点的健康状态

 # /opt/kubernetes/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.175.128:2379,https://192.168.175.130:2379,https://192.168.175.131:2379" cluster-health

 图片.png

 etcd高可用集群部署成功

  4.flannel网络部署

   网络架构图如下

  图片.png

  ①下载flannel二进制包,并解压在k8s的两个node节点,将解压出来的flanneld可执行文件放在两个node节点的/opt/kubernetes/bin下并赋予执行权限

  # wget https://github.com/coreos/flannel/releases/download/v0.9.1/flannel-v0.9.1-linux-amd64.tar.gz

  ②创建flannel的配置文件

  /opt/kubernetes/cfg/flanneld

  flannel网络分配给每个node节点一个唯一的子网,这个字网范围需要在稍后指定,启动flannel之后生成这个子网,并记录对应的子网所在的宿主机的ip,方便不同

  node节点的容器进行访问。

  图片.png

  ③创建flanneld的systemd服务

  [root@node-2 ~]# cat /usr/lib/systemd/system/flanneld.service
  [Unit]
  Description=Flanneld overlay address etcd agent
  After=network-online.target network.target
  Before=docker.service

  [Service]
  Type=notify
  EnvironmentFile=/opt/kubernetes/cfg/flanneld
  ExecStart=/opt/kubernetes/bin/flanneld --ip-masq $FLANNEL_OPTIONS
  ExecStartPost=/opt/kubernetes/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/subnet.env
  Restart=on-failure

  [Install]
  WantedBy=multi-user.target

 ④分配flannel子网

 # /opt/kubernetes/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.175.128:2379,https://192.168.175.130:2379,https://192.168.175.131:2379"
set /coreos.com/network/config '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'

  设置网络172.17.0.0/16并在这个网络基础上分配子网

 ⑤启动flannel

  两个node节点进行相同的配置,并启动flanneld服务

  # systemctl start flanneld.service && systemctl enable flanneld.service

 ⑥查看flannel网络

  [root@node-2 ssl]# /opt/kubernetes/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.175.128:2379,https://192.168.175.130:2379,https://192.168.175.131:2379" ls /coreos.com/network

  图片.png

  /coreos.com/network/subnets:子网文件

  /coreos.com/network/config:配置文件

  图片.png

  两个node节点的子网范围

  图片.png

  进一步查看子网里的数据,可以查看到对应容器子网的物理机IP,从而实现最开始flannel网络的架构图

  图片.png

  flannel网络搭建完毕

  5.kubeconfig文件配置

   在开启TLS的集群中,kubeconfig(即证书)文件是用于后端node节点与master节点交互通信时所使用的身份认证,是目前使用的最简单也是最通用的认证方式  

   ①创建 TLS Bootstrapping Token(master节点的apiserver使用)
      export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
      cat > token.csv <<EOF
      ${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
      EOF

   ②创建kubelet bootstrapping kubeconfig

      export KUBE_APISERVER="https://192.168.0.211:6443"
      # 设置集群参数,创建集群证书。kubernetes在这只是一个名称,真正的集群指向是由--server指定的。

      # --certificate-authority:使用公钥进行证书认证。

      # --embed-certs=true:表示使用公钥进行认证,并将公钥证书写入到bootstrap.kubeconfig中去。

      # --server:表示集群kube-apiserver的地址。

      # --kubeconfig:基于bootstrap.kubeconfig文件创建。

      kubectl config set-cluster kubernetes \
      --certificate-authority=./ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=bootstrap.kubeconfig

     # 设置客户端认证参数

     # --token:客户端使用token认证来让集群master认可,也可以使用CA认证方式,master的apiserver配置文件中需要加入token文件的路径。

     # --kubeconfig:基于bootstrap.kubeconfig文件创建。

     kubectl config set-credentials kubelet-bootstrap \
     --token=${BOOTSTRAP_TOKEN} \
     --kubeconfig=bootstrap.kubeconfig

     # 设置上下文参数

     # --cluster:指定集群

     # --user:指定认证的用户,后端node节点使用这个用户进行通信,需要在主节点上对这个用户进行授权后,node节点才能加入到集群中来。

     kubectl config set-context default \
    --cluster=kubernetes \
    --user=kubelet-bootstrap \
    --kubeconfig=bootstrap.kubeconfig

    # 设置默认上下文,默认使用kubelet-bootstrap用户进行认证,来使用名为default的环境项来作为配置。如果配置了多个环境项,可以通过

   切换不同的环境项名字来访问到不同的集群环境。

    kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

  ③创建kube-proxy kubeconfig文件,用于客户端的kube-proxy进程通信master时进行的认证,配置同bootstrap.kubeconfig一般无二。
     kubectl config set-cluster kubernetes \
      --certificate-authority=./ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=kube-proxy.kubeconfig

    kubectl config set-credentials kube-proxy \
      --client-certificate=./kube-proxy.pem \
      --client-key=./kube-proxy-key.pem \
      --embed-certs=true \
      --kubeconfig=kube-proxy.kubeconfig

    kubectl config set-context default \
      --cluster=kubernetes \
      --user=kube-proxy \
      --kubeconfig=kube-proxy.kubeconfig

    kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

    最后,将生成的token.csv文件放置在master节点的/opt/kubernetes/cfg中用于后续kube-apiserver对后端node节点通讯时的认证。

    将bootstrap.kubeconfig,kube-proxy.kubeconfig文件放置在node节点的/opt/kubernetes/ssl中,用于kubelet,kube-proxy进程向master节点请求通信的认证。

    会在配置文件中指定。


  6.master节点部署

   在github官网上下载master的相关资源包,或者在我分享的百度网盘中

   ①安装kube-apiserver

   将kube-apiserver的可执行文件放在/opt/kubernetes/bin下

   在/opt/kubernetes/cfg下创建配置文件kube-apiserver

   指定etcd数据访问地址,apiserver的IP地址以及其他安全方面的配置,可以度娘看看

   --service-cluster-ip-range:表示service服务的clusterIP的子网范围。

   --enable-bootstrap-token-auth:开启bootstrap相关认证,需要在后端node节点通过bootstrap认证后才能加入到集群。

   --token-auth-file:token认证文件路径。

   --service-node-port-range:service服务随机端口的范围。

   图片.png

   配置kube-apiserver的systemd服务

   [root@node-1 ~]# cat /usr/lib/systemd/system/kube-apiserver.service
   [Unit]
   Description=Kubernetes API Server
   Documentation=
https://github.com/kubernetes/kubernetes 

   [Service]
   EnvironmentFile=-/opt/kubernetes/cfg/kube-apiserver
   ExecStart=/opt/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS
   Restart=on-failure

   [Install]
   WantedBy=multi-user.target


  ②配置kube-scheduler

  将kube-schduler的可执行文件放置在/opt/kubernetes/bin下

  在/opt/kubernetes/cfg下编辑配置文件kube-scheduler

  开启日志相关配置,设置apiserver的IP地址

  --leader-elect:如果多个master节点上的相关服务同时生效,则会有同步与一致性问题,所以多master节点中的kube-scheduler服务只能是主备的关系,kukubernetes采用租赁锁(lease-lock)实现leader的选举,具体到kube-scheduler,设置启动参数"--leader-elect=true"。

  图片.png

  配置kube-scheduler的systemd服务

  [root@node-1 ~]# cat /usr/lib/systemd/system/kube-scheduler.service
  [Unit]
  Description=Kubernetes Scheduler
  Documentation=https://github.com/kubernetes/kubernetes

  [Service]
  EnvironmentFile=-/opt/kubernetes/cfg/kube-scheduler
  ExecStart=/opt/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
  Restart=on-failure

  [Install]
  WantedBy=multi-user.target


  ③安装kube-controller-manager

  将kube-controller-manager的可执行文件放置在/opt/kubernetes/bin下

  在/opt/kubernetes/cfg下编辑配置文件kube-controller-manager

  图片.png

  配置kube-controller-manager的systemd服务

  [root@node-1 ~]# cat /usr/lib/systemd/system/kube-controller-manager.service
  [Unit]
  Description=Kubernetes Controller Manager
  Documentation=https://github.com/kubernetes/kubernetes

  [Service]
  EnvironmentFile=-/opt/kubernetes/cfg/kube-controller-manager
  ExecStart=/opt/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
  Restart=on-failure

  [Install]
  WantedBy=multi-user.target

 

  ④保险起见打开一下防火墙让node节点能够访问到master

  # iptables -I INPUT -s 192.168.175.0/24 -j ACCEPT

  ⑤启动master节点服务

  先启动kube-apiserver,其余两个随意

  # systemctl start kube-apiserver.service && systemctl enable kube-apiserver.service

  # systemctl start kube-controller-manager.service && systemctl enable kube-controller-manager.service

  # systemctl start kube-scheduler.service && systemctl enable kube-scheduler.service

 

  7.node节点部署

  ①安装kubelet

  解压node.zip文件,将kubelet可执行文件移动到/opt/kubernetes/bin下,并赋予可执行权限

  在/opt/kubernetes/cfg下配置kubelet配置文件

  指定当前节点IP地址,设定bootstrap-kubeconfig文件路径

  --kubeconfig:指定kubelet的kubeconfig路径。

  --cluster-dns:指定集群dns。

  --experimental-bootstrap-kubeconfig:指定bootstrap的kubeconfig路径。

  --pod-infra-container-image:指定node节点上部署容器时所需要的根pause。

  图片.png

  配置kubelet的systemd服务

  [root@node-2 ~]# cat /usr/lib/systemd/system/kubelet.service
  [Unit]
  Description=Kubernetes Kubelet
  After=docker.service
  Requires=docker.service

  [Service]
  EnvironmentFile=-/opt/kubernetes/cfg/kubelet
  ExecStart=/opt/kubernetes/bin/kubelet $KUBELET_OPTS
  Restart=on-failure
  KillMode=process

  [Install]
  WantedBy=multi-user.target

 

  需要对docker的配置文件进行一定的修改,使容器能够处在flannel网络配置的子网

  [root@node-2 ~]# cat /usr/lib/systemd/system/docker.service
  [Unit]
  Description=Docker Application Container Engine
  Documentation=https://docs.docker.com
  After=network-online.target firewalld.service
  Wants=network-online.target


  [Service]
  Type=notify
  EnvironmentFile=/run/flannel/subnet.env
  ExecStart=/usr/bin/dockerd  $DOCKER_NETWORK_OPTIONS
  ExecReload=/bin/kill -s HUP $MAINPID
  LimitNOFILE=infinity
  LimitNPROC=infinity
  LimitCORE=infinity
  TimeoutStartSec=0
  Delegate=yes
  KillMode=process
  Restart=on-failure
  StartLimitBurst=3
  StartLimitInterval=60s

  [Install]
  WantedBy=multi-user.target


  Bridge网络IP,即docker0网桥的IP为172.17.36.1,子网段为255.255.255.0

  [root@node-2 ~]# cat /run/flannel/subnet.env
  DOCKER_OPT_BIP="--bip=172.17.36.1/24"
  DOCKER_OPT_IPMASQ="--ip-masq=false"
  DOCKER_OPT_MTU="--mtu=1450"
  DOCKER_NETWORK_OPTIONS=" --bip=172.17.36.1/24 --ip-masq=false --mtu=1450"


  重启服务

  # systemctl restart docker.service && systemctl enable docker.service

  # systemctl start kubelet.service && systemctl enable kubelet.service

 

  ②安装kube-proxy

  将kube-proxy可执行文件移动到/opt/kubernetes/bin下,并赋予可执行权限

  在/opt/kubernetes/cfg下配置kube-proxy配置文件

  指定当前主机,以及对应kube-proxy的kubeconfig文件进行认证

  图片.png

  配置kube-proxy的systemd服务

  [root@node-2 ~]# cat /usr/lib/systemd/system/kube-proxy.service
  [Unit]
  Description=Kubernetes Proxy
  After=network.target

  [Service]
  EnvironmentFile=-/opt/kubernetes/cfg/kube-proxy
  ExecStart=/opt/kubernetes/bin/kube-proxy $KUBE_PROXY_OPTS
  Restart=on-failure

  [Install]
  WantedBy=multi-user.target

 

  启动kube-proxy

  # systemctl start kube-proxy.service  && systemctl enable kube-proxy.service

  在两台node主机上进行相同的配置操作,至此node主机的kubelet,kube-proxy已配置完成

 

  使用ps aux检查一下之前安装的服务是否正常,是否有挂掉的情况,这个时候可能就发现kubelet挂掉了,因为kubelet是使用bootstrap认证

需要在master主机上对起用户进行授权操作后node主机才能连接到master集群中来。


  8.bootstrap用户认证授权

  进行用户认证绑定

  [root@node-1 ~]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap


  9.node节点加入集群

   进行认证后,重启kubelet,查看是否正常运作,在master节点上查看是否有节点请求加入到集群中

   # kubectl get csr

   将请求的节点加入到集群中

   # kubectl certificate approve node-csr-ChigsskeLoJ0Phyzsu1K8KCe1HT3egU2B5ppHh1oT9A

   查看状态

   # kubectl get node


  Kubernetes部署完毕

 


  

 

 


猜你喜欢

转载自blog.51cto.com/12480612/2287449