kubernetes1.9.2基于kubeadm的高可用安装HA

使用kubeadm安装安全高可用kubernetes集群
[安装包地址]

非高可用安装三步即可

  • 在master上 cd shell && init.sh && master.sh
  • 在node上 init.sh
  • 在node上执行master输出的join命令
  •  [单master视频教程]

    1. 建议二进制方法提前部署好docker-compose,步骤参考后文

    2. 建议永久关闭selinux和swap以免后续问题

    3. 建议停止并关闭firewalld/iptables等防火墙

     安装包介绍

     

    解压完之后看到如下目录:

    ├── bin 所需要的k8s相关的bin文件
    │ ├── kubeadm
    │ ├── kubectl
    │ └── kubelet
    ├── image 依赖的所有镜像包
    │ └── images.tar
    ├── out 所有的配置文件
    │ ├── dashboard dashboard相关配置
    │ │ ├── dashboard-admin.yaml
    │ │ └── kubernetes-dashboard.yaml
    │ ├── etcd etcd相关配置
    │ │ ├── etcd-docker-compose-0.yml
    │ │ ├── etcd-docker-compose-1.yml
    │ │ └── etcd-docker-compose-2.yml
    │ ├── haproxy haproxy相关配置
    │ │ └── haproxy.cfg
    │ ├── heapster heapster相关yaml配置
    │ │ ├── influxdb
    │ │ │ ├── grafana.yaml
    │ │ │ ├── heapster.yaml
    │ │ │ └── influxdb.yaml
    │ │ └── rbac
    │ │ └── heapster-rbac.yaml
    │ ├── kube k8s自身配置
    │ │ ├── 10-kubeadm.conf
    │ │ ├── config kubeadm配置
    │ │ └── kubelet.service
    │ ├── kubeinit.json 忽略
    │ └── net 网络相关配置
    │ ├── calico.yaml
    │ └── calicoctl.yaml
    └── shell 初始化脚本
    ├── init.sh 初始化节点,安装bin文件,systemd配置等
    └── master.sh 执行kubeadm init和其它组件

    初始化节点

    集群中所有节点都需要执行`cd shell ; sh init.sh`

    有以下需要注意的事项:
    kubelet的启动文件里面的cgroups配置和(修改位置/etc/systemd/system/kubelet.service.d) 与 docker info|grep Cg一致

     起动etcd集群

    etcd集群安装使用docker-compose方式部署

    A.使用docker-compose启动,如果没装:

    $ pip install docker-compose

    B.使用二进制包启动docker-compose(离线可选)

    $ wget https://github.com/docker/compose/releases/download/1.18.0/docker-compose-Linux-x86_64
     $ mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose && chmod a+x /usr/local/bin/docker-compose

    在out/etcd目录下有相关模板etcd-docker-compose-x.yaml,启动多个节点时修改成自己的ip地址 其它两个节点照抄,修改ip即可, image那行 应改为 gcr.io/google_containers/etcd-

    amd64:3.1.11
     version: '2.1'
     services:
     etcd0:
     container_name: etcd_infra0
     image: gcr.io/google_containers/etcd-amd64:3.0.17 #这里最后改为3.1.11
     command: |
     etcd --name infra0
     --initial-advertisie-peer-urls http://10.230.204.160:2380
     --listen-peer-urls http://10.230.204.160:2380
     --listen-client-urls http://10.230.204.160:2379,http://127.0.0.1:2379
     --advertise-client-urls http://10.230.204.160:2379
     --data-dir /etcd-data.etcd
     --initial-cluster-token etcd-cluster-1
     --initial-cluster infra0=http://10.230.204.160:2380,infra1=http://10.230.204.165:2380,infra2=http://10.230.204.151:2380
     --initial-cluster-state new
     restart: always
     volumes:
     - /data/etcd-data.etcd:/etcd-data.etcd
     network_mode: "host"

    三个节点分别启动:

    $ docker-compose -f out/etcd/etcd-docker-compose-x.yml up -d

    检查是不是安装成功:

    $ docker exec etcd_infra0 etcdctl member list
     5ded6dd284b89d31: name=infra1 peerURLs=http://10.230.204.153:2380 clientURLs=http://10.230.204.153:2379 isLeader=true
     6d4b5eee32c1497a: name=infra0 peerURLs=http://10.230.204.150:2380 clientURLs=http://10.230.204.150:2379 isLeader=false
     729d9cd56debb1a1: name=infra2 peerURLs=http://10.230.204.154:2380 clientURLs=http://10.230.204.154:2379 isLeader=false

     kubeadm配置

    修改配置 out/kube/config 文件

    apiVersion: kubeadm.k8s.io/v1alpha1
     kind: MasterConfiguration
     apiServerCertSANs: #此处填所有的masterip和lbip和其它你可能需要通过它访问apiserver的地址和域名或者主机名等,如阿里fip,证书中会允许这些ip
     - 172.31.244.231
     - 172.31.244.232
     - 172.31.244.233
     - 172.31.244.234
     - master1
     - master2
     - master3
     - node1
     - 47.75.1.72
    
    etcd:
     endpoints: #这里填之前安装的etcd集群地址列表,修改IP地址
     - http://172.31.244.232:2379
     - http://172.31.244.233:2379
     - http://172.31.244.234:2379
    
    apiServerExtraArgs:
     endpoint-reconciler-type: lease
    
    networking:
     podSubnet: 192.168.0.0/16 #不用改
     kubernetesVersion: v1.9.2 #不用改
     featureGates: #不用改
     CoreDNS: true
    
    然后执行:
     $ kubeadm init --config out/kube/config

    把成功后的kubeadm join命令存在文件里,那东西不能丢了

     启动calico等

    mkdir ~/.kube && cp /etc/kubernetes/admin.conf ~/.kube/config

    修改calico配置,把etcd地址换成你安装好的集群地址:

    out/net/calico.yaml:
    
    kind: ConfigMap
     apiVersion: v1
     metadata:
     name: calico-config
     namespace: kube-system
     data:
     # The location of your etcd cluster. This uses the Service clusterIP
     # defined below.
     etcd_endpoints: "http://10.96.232.136:6666" # 这里改成etcd集群地址如 "http://172.31.244.232:2379,http://172.31.244.233:2379,http://172.31.244.234:2379"
    
    $ kubectl apply -f out/net/calico.yaml -f out/heapster/influxdb -f out/heapster/rbac -f out/dashboard

    1. 然后访问https://master1IP:32000端口即可,在chrome下无法进入提示证书有误,更换firefox可以,提示说证书日期不对(待修复)

    启动多个master

    第一个master我们称之为master0 (假设其他master已经init.sh过),现在把第一个master的/etc/kubernetes/pki目录拷贝到别的master节点上

    $ mkdir -p /etc/kubernetes
     $ scp -r /etc/kubernetes/pki root@10.1.245.93:/etc/kubernetes/pki

    删除pki目录下的apiserver.crt 和 apiserver.key文件rm -rf apiserver.crt apiserver.key,注意如果不删除会只能看到一个master,是不正常的

    同样使用master0上的out/kube/config文件,复制内容,拷贝到master1上,scp out/kube/config root@10.230.204.151:/root/执行kubeadm init –config ~/config

    master2节点同master1

     启动loadbalance

    我比较推荐使用四层代理 HAproxy配置out/haproxy目录:

    `vi out/haproxy/haproxy.cfg`
    
    global
     daemon
     log 127.0.0.1 local0
     log 127.0.0.1 local1 notice
     maxconn 4096
    
    defaults
     log global
     retries 3
     maxconn 2000
     timeout connect 5s
     timeout client 50s
     timeout server 50s
    
    frontend k8s
     bind *:6444
     mode tcp
     default_backend k8s-backend
    
    backend k8s-backend
     balance roundrobin
     mode tcp
     #下面三个ip替换成三个你自己master的地址
     server k8s-1 10.1.245.93:6443 check
     server k8s-1 10.1.245.94:6443 check
     server k8s-2 10.1.245.95:6443 check
     ```
    
    先` mkdir /etc/haproxy` 然后把这个文件拷贝在`cp out/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg`
     $ docker run --net=host -v /etc/haproxy:/usr/local/etc/haproxy --name ha -d haproxy:1.7

    修改kubeproxy配置

    $ kubectl -n kube-system edit configmap kube-proxy

    找到master地址,修改成LB地址,6444端口 (这里关键在于怎么知道LB的地址到底是哪一个呀?上面配置之后三个masterIP 轮询并不知道哪个是LB地址)

    #找到文件的这一块,第七行server 有个ip地址

    apiVersion: v1
     kind: Config
     clusters:
     - cluster:
     certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
     server: https://10.230.204.151:6443 #修改为 LoadBalanceIP:6444
     name: default
     contexts:
     - context:
     cluster: default
     namespace: default
     user: default
     name: default
     current-context: default
     users:
     - name: default
     user:
     tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token

    join node节点
    还是在node节点执行第一个master输出的命令

    $ kubeadm join --token 10.1.245.94:6443 --discovery-token-ca-cert-hash sha256:

     修改node节点kubelet配置

    `vi /etc/kubernetes/kubelet.conf ` 同样把地址修改成LB地址,如:`10.1.245.94:6444` ,修改如下第五行(展示的例子已经修改过)

    apiVersion: v1
     clusters:
     - cluster:
     certificate-authority-data: xxxxxx #此处省略几百字符
     server: https://10.230.204.160:6444 #修改这里为LB:6444,原本是另外的ip:6443
     name: default-cluster
     contexts:
     - context:
     cluster: default-cluster
     namespace: default
     user: default-auth
     name: default-context
     current-context: default-context

     kubectl配置

    修改`~/.kube/config`文件,server的ip改成LB的ip `10.1.245.94:6444`

    或者通过命令修改:

    $ kubectl config set-cluster kubernetes --server=https://47.52.227.242:6444 --kubeconfig=$HOME/.kube/config

     启动多DNS副本

    $ kubectl edit deploy coredns -n kube-system
    
    replicas: 3
    
    [root@master1 ~]$ kubectl get pod -n kube-system -o wide|grep core
     coredns-65dcdb4cf-4j5s8 1/1 Running 0 39m 192.168.137.65 master1
     coredns-65dcdb4cf-ngx4h 1/1 Running 0 38s 192.168.180.1 master2
     coredns-65dcdb4cf-qbsr6 1/1 Running 0 38s 192.168.166.132 node1

    这样,启动了三个dns

     验证与测试

    $ kubectl run test --image busybox sleep 10000
     $ kubectl exec your-busybox-pod-name nslookup kubernetes

    杀非LB的master,多次测试看创建pod与dns是否正常,还可以telnet 10.96.0.1 443 去验证clusterip是否正常