1. 程式人生 > >Docker叢集管理工具-Kubernetes1.10.6(k8s)四節點叢集使用kubeadm部署流程(一)

Docker叢集管理工具-Kubernetes1.10.6(k8s)四節點叢集使用kubeadm部署流程(一)

一:Kubernetes介紹

1: Kubernetes是什麼

Kubernetes是Google開源的容器叢集管理系統,是基於Docker構建一個容器的排程服務,提供資源排程、均衡容災、服務註冊、動態擴縮容等功能套件。
Kubernetes提供應用部署、維護、 擴充套件機制等功能,利用Kubernetes能方便地管理跨機器執行容器化的應用,其主要功能如下:
1) 使用Docker對應用程式包裝(package)、例項化(instantiate)、執行(run)。
2) 將多臺Docker主機抽象為一個資源,以叢集的方式執行、管理跨機器的容器,包括任務排程、資源管理、彈性伸縮、滾動升級等功能。
3)使用編排系統(YAML File)快速構建容器叢集,提供負載均衡,解決容器直接關聯及通訊問題
4) 解決Docker跨機器容器之間的通訊問題。
5)自動管理和修復容器,簡單說,比如建立一個叢集,裡面有十個容器,如果某個容器異常關閉,那麼,會嘗試重啟或重新分配容器,始終保證會有 十個容器在執行,反而殺死多餘的。Kubernetes的自我修復機制使得容器叢集總是執行在使用者期望的狀態當前Kubernetes支援GCE、vShpere、CoreOS、OpenShift。

2:Kubernetes和Mesos的區別

1)Mesos是Apache下的開源分散式資源管理框架,它被稱為是分散式系統的核心;Kubernetes是Google開源的容器叢集管理系統,實現基於Docker構建容器,利用Kubernetes能很方面管理多臺Docker主機中的容器。

2)Mesos負責管理叢集管資源(動態執行時,某機器有額外的資源,通知master來分配);
Kubernetes抽象出新的容器組合模型並且對其編排管理(把容器自由組合提供服務這事兒搞定了,從而微服務,serverless等才真正的優雅地在開發和運維之間不吵架地被實現),而且kubernetes把以前運維的很多很難搞的東西都變得容易了。比如OpenStack,Kubernetes是把 OpenStack裡面的VM換成了容器,但是實現地更漂亮,更精簡,更抽象和本質化,用起來也更容易。

3)Mesos相比Kubernetes發展的時間更久,總體情況更成熟,在生產環境有更多的使用經驗,國外使用Mesos的公司有Twitter,Apple,Airbnb,Uber等,國內也有大批知名公司在使用Mesos,比如:小米、噹噹、豆瓣、去哪兒、攜程、唯品會、知乎、新浪微博、愛奇藝、七牛、唯品會、bilibili、中國聯通、中國移動、中國電信、華為、數人云等等。中大型公司會更傾向於使用Mesos,因為本身這些公司有一定的開發能力,Mesos提供了良好的API而且有非常多成熟的Framework跑在Mesos上,Mesos+Marathon+Zookeeper正常情況可以滿足絕大部分需求,只需要寫JSON或者DSL定義好service/application就好,只有一些特殊情況才確實需要寫自己的Framework。
而kubernetes(k8s)現在也正在慢慢成熟起來,它在生產環境顯然還需要更多時間來驗證。京東目前已經在kubernetes上跑15W+容器了。
Mesos現在越來越適應並且被新增上了很多Kubernete的概念同時支援了很多Kubernetes的API。因此如果你需要它們的話,它將是對你的Kubernetes應用去獲得更多能力的一個便捷方式(比如高可用的主幹、更加高階的排程命令、去管控很大數目結點的能力),同時能夠很好的
適用於產品級工作環境中(畢竟Kubernetes任然還是一個初始版本)。

4)如果你是一個叢集世界的新手,Kubernetes是一個很棒的起點。它是最快的、最簡單的、最輕量級的方法去擺脫束縛,同時開啟面向叢集開發的實踐。它提供了一個高水平的可移植方案,因為它是被一些不同的貢獻者所支援的( 例如微軟、IBM、Red Hat、CoreOs、MesoSphere、VMWare等等)。
如果你已經有已經存在的工作任務(Hadoop、Spark、Kafka等等),Mesos給你提供了一個可以讓你將不同工作任務相互交錯的框架,然後混合進一個包含Kubernetes 應用的新的東西。
如果你還沒有用Kubernetes 系列框架完成專案的能力,Mesos給了你一個減壓閥。

3:Kubernetes結構圖

這裡寫圖片描述

4:kubernetes角色組成

1)Pod
在Kubernetes系統中,排程的最小顆粒不是單純的容器,而是抽象成一個Pod,Pod是一個可以被建立、銷燬、排程、管理的最小的部署單元。比如一個或一組容器。Pod是kubernetes的最小操作單元,一個Pod可以由一個或多個容器組成;同一個Pod只能執行在同一個主機上,共享相
同的volumes、network、namespace;

2)ReplicationController(RC)
RC用來管理Pod,一個RC可以由一個或多個Pod組成,在RC被建立後,系統會根據定義好的副本數來建立Pod數量。在執行過程中,如果Pod數量小於定義的,就會重啟停止的或重新分配Pod,反之則殺死多餘的。當然,也可以動態伸縮執行的Pods規模或熟悉。RC通過label關聯對應的Pods,在滾動升級中,RC採用一個一個替換要更新的整個Pods中的Pod。
Replication Controller是Kubernetes系統中最有用的功能,實現複製多個Pod副本,往往一個應用需要多個Pod來支撐,並且可以保證其複製的副本數,即使副本所排程分配的宿主機出現異常,通過Replication Controller可以保證在其它主宿機啟用同等數量的Pod。Replication Controller可以通過repcon模板來建立多個Pod副本,同樣也可以直接複製已存在Pod,需要通過Label selector來關聯。

3)Service
Service定義了一個Pod邏輯集合的抽象資源,Pod集合中的容器提供相同的功能。集合根據定義的Label和selector完成,當建立一個Service後,會分配一個Cluster IP,這個IP與定義的埠提供這個集合一個統一的訪問介面,並且實現負載均衡。
Services是Kubernetes最外圍的單元,通過虛擬一個訪問IP及服務埠,可以訪問我們定義好的Pod資源,目前的版本是通過iptables的nat轉發來實現,轉發的目標埠為Kube_proxy生成的隨機埠,目前只提供GOOGLE雲上的訪問排程,如GCE。

4)Label
Label是用於區分Pod、Service、RC的key/value鍵值對;僅使用在Pod、Service、Replication Controller之間的關係識別,但對這些單元本身進行操作時得使用name標籤。Pod、Service、RC可以有多個label,但是每個label的key只能對應一個;主要是將Service的請求通過lable轉發給後端提供服務的Pod集合;

說說個人一點看法,目前Kubernetes保持一週一小版本、一個月一大版本的節奏,迭代速度極快,同時也帶來了不同版本操作方法的差異,另外官網文件更新速度相對滯後及欠缺,給初學者帶來一定挑戰。在上游接入層官方側重點還放在GCE(Google Compute Engine)的對接優化,針對個人私有云還未推出一套可行的接入解決方案。在v0.5版本中才引用service代理轉發的機制,且是通過iptables來實現,在高併發下效能令人擔憂。但作者依然看好Kubernetes未來的發展,至少目前還未看到另外一個成體系、具備良好生態圈的平臺,相信在V1.0時就會具備生產環境的服務支撐能力。

5:kubernetes元件組成

1)kubectl
客戶端命令列工具,將接受的命令格式化後傳送給kube-apiserver,作為整個系統的操作入口。

2)kube-apiserver
作為整個系統的控制入口,以REST API服務提供介面。

3)kube-controller-manager
用來執行整個系統中的後臺任務,包括節點狀態狀況、Pod個數、Pods和Service的關聯等。

4)kube-scheduler
負責節點資源管理,接受來自kube-apiserver建立Pods任務,並分配到某個節點。

5)etcd
負責節點間的服務發現和配置共享。

6)kube-proxy
執行在每個計算節點上,負責Pod網路代理。定時從etcd獲取到service資訊來做相應的策略。

7)kubelet
執行在每個計算節點上,作為agent,接受分配該節點的Pods任務及管理容器,週期性獲取容器狀態,反饋給kube-apiserver。

8)DNS
一個可選的DNS服務,用於為每個Service物件建立DNS記錄,這樣所有的Pod就可以通過DNS訪問服務了。

6:Kubelet

這裡寫圖片描述
根據上圖可知Kubelet是Kubernetes叢集中每個Minion和Master API Server的連線點,Kubelet執行在每個Minion上,是Master API Server和Minion之間的橋樑,接收Master API Server分配給它的commands和work,與永續性鍵值儲存etcd、file、server和http進行互動,讀取配置資訊。Kubelet的主要工作是管理Pod和容器的生命週期,其包括Docker Client、Root Directory、Pod Workers、Etcd Client、Cadvisor Client以及Health Checker元件,具體工作如下:
1) 通過Worker給Pod非同步執行特定的Action。
2) 設定容器的環境變數。
3) 給容器繫結Volume。
4) 給容器繫結Port。
5) 根據指定的Pod執行一個單一容器。
6) 殺死容器。
7) 給指定的Pod建立network 容器。
8) 刪除Pod的所有容器。
9) 同步Pod的狀態。
10) 從Cadvisor獲取container info、 pod info、root info、machine info。
11) 檢測Pod的容器健康狀態資訊。
12) 在容器中執行命令。

kubernetes基本部署步驟
1)minion節點安裝docker
2)minion節點配置跨主機容器通訊
3)master節點部署etcd、kube-apiserver、kube-controller-manager和kube-scheduler元件
4)minion節點部署kubelet、kube-proxy元件

溫馨提示:
如果minion主機沒有安裝docker,啟動kubelet時會報如下錯誤:
Could not load kubeconfig file /var/lib/kubelet/kubeconfig: stat /var/lib/kubelet/kubeconfig: no such file or directory. Trying auth path instead.
Could not load kubernetes auth path /var/lib/kubelet/kubernetes_auth: stat /var/lib/kubelet/kubernetes_auth: no such file or directory. Continuing with defaults.
No cloud provider specified.

二:前言

kubeadm是Kubernetes官方推出的快速部署Kubernetes叢集工具,其思路是將Kubernetes相關服務容器化(Kubernetes靜態Pod)以簡化部署。kubeadm當前處於beta階段,不建議生產環境使用(比如etcd單點)。使用kubeadm部署Kubernetes叢集非常簡單方便,本文記錄了centos 7.4上用kubeadm部署一個安全的Kubernetes叢集的全過程。

三:準備工作

2.1. centos 7.4( 8GB RAM);
2.2. 叢集機器之間網路互通;
2.3. 所有節點系統在centos7.4以上;
2.4. 所有節點上hosts檔案指定ip和主機名的對應關係;

四:目標

3.1. 部署一個安全的Kubernetes v1.10.6叢集;
3.2. 部署pod網路以便pod之間可以互通;

五:使用kubeadm在Red Hat 7.4/CentOS 7.4快速部署四節點Kubernetes 1.10.6叢集

5.1 叢集架構如下

IP 功能 版本 docker版本 主機名
192.168.10.110 master1、etcd、registry、keepalived centos7.4 18.06.0-ce k8s-m1.trjcn.com
192.168.10.111 master2、etcd、keepalived centos7.4 18.06.0-ce k8s-m2.trjcn.com
192.168.10.112 master3、etcd、keepalived centos7.4 18.06.0-ce k8s-m3.trjcn.com
192.168.10.113 node centos7.4 18.06.0-ce k8s-s1.trjcn.com
192.168.10.115 keepalived生成的虛擬IP

5.2 將所有節點的kernel版本升級到最新

安裝ELRepo
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
載入elrepo-kernel元資料
yum –disablerepo=* –enablerepo=elrepo-kernel repolist
檢視可用的rpm包
yum –disablerepo=* –enablerepo=elrepo-kernel list kernel*
安裝最新版本的kernel
yum –disablerepo=* –enablerepo=elrepo-kernel install -y kernel-lt.x86_64

設定grub的預設核心版本
echo “GRUB_DEFAULT=0” >> /etc/default/grub
重新建立核心配置
grub2-mkconfig -o /boot/grub2/grub.cfg

最後一步,需要將核心工具包一併升級
刪除舊版本工具包
yum -y remove kernel-tools-libs.x86_64 kernel-tools.x86_64
安裝新版本工具包
yum –disablerepo=* –enablerepo=elrepo-kernel install -y kernel-lt-tools.x86_64

然後重啟即可。
重啟後會發現系統已經是以最新的4.4.153-1.el7.elrepo.x86_64核心版本啟動的。

5.3 所有節點上安裝docker並配置direct-lvm模式

5.3.1:安裝docker

由於k8s v1.11目前最高只支援docker 17.03.2版本,所有這裡使用該docker版本:

yum  -y  install wget
mkdir   -p   /opt/docker/rpm  &&  cd  /opt/docker/rpm
wget   https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm
wget   https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm
yum   -y  localinstall  /opt/docker/rpm/*

完成效果如下:
docker -v
Docker version 17.03.2-ce, build f5ec1e2

啟動docker
systemctl enable docker.service && systemctl start docker

5.3.2:配置direct-lvm模式

5.3.2.1. 停止Docker

sudo systemctl stop docker

5.3.2.2. 安裝依賴包

yum -y install device-mapper-persistent-data lvm2

5.3.2.3. 建立物理卷/dev/xvdf來替換塊裝置

sudo pvcreate /dev/sdb

5.3.3.4. 用vgcreate命令在同一個裝置上建立docker卷組

sudo vgcreate docker /dev/sdb

5.3.3.5. 用lvcreate命令建立thinpool(資料)和thinpoolmeta(元資料)兩個邏輯卷

最後一個引數指定空閒空間的數量,以允許在空間執行低時自動擴充套件資料或元資料,作為臨時的權宜之計。這些是推薦的值。

sudo lvcreate     --wipesignatures  y   -n thinpool   docker   -l   95%VG
sudo lvcreate     --wipesignatures  y   -n thinpoolmeta docker    -l   1%VG

5.3.3.6. 用lvconvert命令把thinpool資料卷和thinpoolmeta元資料卷換為一個精簡池,且此精簡池使用原資料卷的名字

sudo lvconvert -y –zero n -c 512K –thinpool docker/thinpool –poolmetadata docker/thinpoolmeta

5.3.3.7. 通過lvm profile配置精簡池的自動擴容

sudo vi /etc/lvm/profile/docker-thinpool.profile
編輯該檔案成如下內容:
activation {
thin_pool_autoextend_threshold=80
thin_pool_autoextend_percent=10
}
當磁碟使用達到80%時,再擴充套件當前容量的10%。
thin_pool_autoextend_threshold:當達到使用空間的指定閾值(百分數)後,lvm就會試圖嘗試自動擴充套件可用的空間(100=禁用)
thin_pool_autoextend_percent:當磁碟每次達到上面定義的閾值後,自動再擴充套件的百分比數(0=禁用)。

5.3.3.8. 用lvchange命令啟用LVM profile

sudo lvchange –metadataprofile docker-thinpool docker/thinpool

5.3.3.9. 對主機上的邏輯卷啟用監視

如果沒有這個步驟,即使在LVM配置檔案出現時也不會發生自動擴充套件。
sudo lvs -o+seg_monitor

5.3.3.10. 備份Docker原有資料

如果曾經在這個主機上執行過Docker,或者如果/var/ lib/docker存在,那麼將它移出後,Docker就可以使用新的LVM池來儲存映象和容器的內容了。

mkdir /var/lib/docker.bk
mv /var/lib/docker/*    /var/lib/docker.bk

5.3.3.11. 編輯/etc/docker/daemon.json

配置devicemapper儲存驅動程式所需的選項。如果該檔案以前是空的,那麼現在應該包含以下內容:
{
“storage-driver”:”devicemapper”,
“storage-opts”: [
“dm.thinpooldev=/dev/mapper/docker-thinpool”,
“dm.use_deferred_removal=true”,
“dm.use_deferred_deletion=true”
]
}

注意:
延遲刪除選項,dm.use_deferred_deletion=true,在使用預設核心版本3.18時還不支援RHEL、CentOS或Ubuntu 14.04。

5.3.3.12. 啟動Docker

systemd:
sudosystemctlstartdockerservice: sudo service docker start

5.3.3.13. 檢視Docker啟動資訊

$ docker info
If Docker is configured correctly, the Data file and Metadata file is blank, and the pool name is docker-thinpool

5.3.3.14. 驗證配置正確後,就可以刪除/var/lib/docker.bk目錄了

rm -rf /var/lib/docker.bk

5.4 安裝kubelet,kubeadm and kubectl

5.4.1:新增yum源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF

5.4.2:設定IP和主機名對應關係

/etc/hosts中加入所有節點的IP和hosts的對應關係,重要
新增以下行:
192.168.10.110 k8s-m1.trjcn.com
192.168.10.111 k8s-m2.trjcn.com
192.168.10.112 k8s-m3.trjcn.com
192.168.10.113 k8s-s1.trjcn.com

並且要修改每個節點的hostname與之對應。

5.4.3:關閉selinux和防火牆

systemctl stop firewalld
systemctl disable firewalld

setenforce 0
sed -i “s/^SELINUX=enforcing/SELINUX=disabled/g” /etc/sysconfig/selinux
sed -i “s/^SELINUX=enforcing/SELINUX=disabled/g” /etc/selinux/config
sed -i “s/^SELINUX=permissive/SELINUX=disabled/g” /etc/sysconfig/selinux
sed -i “s/^SELINUX=permissive/SELINUX=disabled/g” /etc/selinux/config

5.4.4:關閉swap

sudo swapoff -a
要永久禁掉swap分割槽,開啟如下檔案註釋掉swap那一行
sudo sed -i ‘s/.swap./#&/’ /etc/fstab

5.4.5:設定sysctl

$echo   "net.ipv4.ip_forward = 1"   >>  /etc/sysctl.conf 
$sysctl  -p

5.4.6:配置檔案最大開啟數和ntp

yum  -y  install   yum-utils device-mapper-persistent-data lvm2 net-tools conntrack-tools wget vim  ntpdate libseccomp libtool-ltdl 
systemctl enable ntpdate.service  &&  systemctl start   ntpdate.service 
echo '*/30 * * * * /usr/sbin/ntpdate time7.aliyun.com >/dev/null 2>&1' > /tmp/crontab2.tmp
crontab /tmp/crontab2.tmp
echo "* soft nofile 65536" >> /etc/security/limits.conf
echo "* hard nofile 65536" >> /etc/security/limits.conf
echo "* soft nproc 65536"  >> /etc/security/limits.conf
echo "* hard nproc 65536"  >> /etc/security/limits.conf
echo "* soft  memlock  unlimited"  >> /etc/security/limits.conf
echo "* hard memlock  unlimited"  >> /etc/security/limits.conf

5.4.7:初始化

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl    --system

5.5 主節點192.168.10.110 192.168.10.111 192.168.10.112上配置haproxy代理

5.5.1:首先拉取haproxy映象

docker pull haproxy:1.7.8-alpine
mkdir /etc/haproxy

5.5.2:harpoxy配置檔案配置

cat > /etc/haproxy/haproxy.cfg <<EOF
global
  log 127.0.0.1 local0 err
  maxconn 50000
  uid 99
  gid 99
  #daemon
  nbproc 1
  pidfile haproxy.pid

defaults
  mode http
  log 127.0.0.1 local0 err
  maxconn 50000
  retries 3
  timeout connect 5s
  timeout client 30s
  timeout server 30s
  timeout check 2s

listen admin_stats
  mode http
  bind 0.0.0.0:1080
  log 127.0.0.1 local0 err
  stats refresh 30s
  stats uri     /haproxy-status
  stats realm   Haproxy\ Statistics
  stats auth    will:will
  stats hide-version
  stats admin if TRUE

frontend k8s-https
  bind 0.0.0.0:8443
  mode tcp
  #maxconn 50000
  default_backend k8s-https

backend k8s-https
  mode tcp
  balance roundrobin
  server lab1 192.168.10.110:6443 weight 1 maxconn 1000 check inter 2000 rise 2 fall 3
  server lab2 192.168.10.111:6443 weight 1 maxconn 1000 check inter 2000 rise 2 fall 3
  server lab3 192.168.10.112:6443 weight 1 maxconn 1000 check inter 2000 rise 2 fall 3
EOF

5.5.3:啟動haproxy

$docker run -d --name my-haproxy   -v /etc/haproxy:/usr/local/etc/haproxy   -p 8443:8443  -p 1080:1080  --restart always   haproxy:1.7.8-alpine

5.5.4:檢視日誌

$docker logs my-haproxy

5.5.5:瀏覽器檢視狀態

5.6 主節點192.168.10.110 192.168.10.111 192.168.10.112上配置keepalived

5.6.1:安裝keepalived

yum install -y keepalived && systemctl enable keepalived

5.6.2:主節點192.168.10.110上的keepalived配置

cat <<EOF > /etc/keepalived/keepalived.conf
global_defs {
   router_id LVS_k8s
}

vrrp_script CheckK8sMaster {
    script "curl -k https://192.168.10.115:6443"
    interval 3
    timeout 9
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens160
    virtual_router_id 61
    priority 100
    nopreempt
    advert_int 1
    mcast_src_ip 192.168.10.110
    authentication {
        auth_type PASS
        auth_pass sqP05dQgMSlzrxHj
    }
    unicast_peer {
        192.168.10.111
        192.168.10.112
    }
    virtual_ipaddress {
        192.168.10.115/24
    }
    track_script {
        CheckK8sMaster
    }

}
EOF

5.6.3:主節點192.168.10.111上的keepalived配置

cat <<EOF > /etc/keepalived/keepalived.conf
global_defs {
   router_id LVS_k8s
}

vrrp_script CheckK8sMaster {
    script "curl -k https://192.168.10.115:6443"
    interval 3
    timeout 9
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens160
    virtual_router_id 61
    priority 90
    nopreempt
    advert_int 1
    mcast_src_ip 192.168.10.111
    authentication {
        auth_type PASS
        auth_pass sqP05dQgMSlzrxHj
    }
    unicast_peer {
        192.168.10.110
        192.168.10.112
    }
    virtual_ipaddress {
        192.168.10.115/24
    }
    track_script {
        CheckK8sMaster
    }

}
EOF

5.6.4:主節點192.168.10.112上的keepalived配置

cat <<EOF > /etc/keepalived/keepalived.conf
global_defs {
    router_id LVS_k8s
}

vrrp_script CheckK8sMaster {
    script "curl -k https://192.168.10.115:6443"
    interval 3
    timeout 9
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens160
    virtual_router_id 61
    priority 80
    nopreempt
    advert_int 1
    mcast_src_ip 192.168.10.112
    authentication {
        auth_type PASS
        auth_pass sqP05dQgMSlzrxHj
    }
    unicast_peer {
        192.168.10.110
        192.168.10.111
    }
    virtual_ipaddress {
        192.168.10.115/24
    }
    track_script {
        CheckK8sMaster
    }

}
EOF

5.6.5:啟動keepalived

$ systemctl restart keepalived

可以看到VIP已經繫結到主節點192.168.10.110上面了。

5.7 建立etcd證書(192.168.10.110主節點上執行即可)

5.7.1:設定cfssl環境

mkdir  -p  /opt/k8s/software  &&  cd  /opt/k8s/software
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
mv cfssl_linux-amd64 /usr/local/bin/cfssl
chmod +x cfssljson_linux-amd64
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
chmod +x cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
export PATH=/usr/local/bin:$PATH

5.7.2:建立CA 配置檔案(下面配置的IP為etc節點的IP)

mkdir  -p  /opt/k8s/ssl  &&  cd  /opt/k8s/ssl
cat >  ca-config.json <<EOF
{
"signing": {
"default": {
  "expiry": "8760h"
},
"profiles": {
  "kubernetes-Soulmate": {
    "usages": [
        "signing",
        "key encipherment",
        "server auth",
        "client auth"
    ],
    "expiry": "8760h"
  }
}
}
}
EOF

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

利用證書請求檔案生成簽名的CA證書和對應的金鑰證書
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
完成後會在當前目錄下看到生成的簽名的CA證書ca.pem和對應的金鑰證書ca-key.pem。

配置etcd的證書請求檔案

$ cat > etcd-csr.json <<EOF
{
  "CN": "etcd",
  "hosts": [
    "127.0.0.1",
    "192.168.10.110",
    "192.168.10.111",
    "192.168.10.112"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "shanghai",
      "L": "shanghai",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

利用CA證書以及對應的金鑰證書和etcd-csr證書請求檔案來生成etcd相關證書
$ cfssl gencert -ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes-Soulmate etcd-csr.json | cfssljson -bare etcd

5.7.3:主節點192.168.10.110將etcd證書分發到其他所有節點

cd /opt/k8s/ssl
mkdir -p /etc/etcd/ssl
cp etcd.pem etcd-key.pem ca.pem /etc/etcd/ssl/
ssh [email protected]192.168.10.111 “mkdir -p /etc/etcd/ssl && exit”
ssh [email protected] “mkdir -p /etc/etcd/ssl && exit”
scp /etc/etcd/ssl/*.pem [email protected]:/etc/etcd/ssl
scp /etc/etcd/ssl/*.pem [email protected]:/etc/etcd/ssl

5.8 安裝配置etcd (192.168.10.110 192.168.10.111 192.168.10.112三主節點上安裝)

5.8.1:安裝etcd

yum install etcd -y
mkdir -p /var/lib/etcd

5.8.1.1:主節點192.168.10.110上的的etcd.service

cat <<EOF >/etc/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/bin/etcd \
  --name k8s-m1.trjcn.com \
  --cert-file=/etc/etcd/ssl/etcd.pem \
  --key-file=/etc/etcd/ssl/etcd-key.pem \
  --peer-cert-file=/etc/etcd/ssl/etcd.pem \
  --peer-key-file=/etc/etcd/ssl/etcd-key.pem \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --initial-advertise-peer-urls https://192.168.10.110:2380 \
  --listen-peer-urls https://192.168.10.110:2380 \
  --listen-client-urls https://192.168.10.110:2379,http://127.0.0.1:2379 \
  --advertise-client-urls https://192.168.10.110:2379 \
  --initial-cluster-token etcd-cluster-0 \
  --initial-cluster k8s-m1.trjcn.com=https://192.168.10.110:2380,k8s-m2.trjcn.com=https://192.168.10.111:2380,k8s-m3.trjcn.com=https://192.168.10.112:2380 \
  --initial-cluster-state new \
  --data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

5.8.1.2:主節點192.168.10.111上的的etcd.service

cat <<EOF >/etc/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/bin/etcd \
  --name k8s-m2.trjcn.com \
  --cert-file=/etc/etcd/ssl/etcd.pem \
  --key-file=/etc/etcd/ssl/etcd-key.pem \
  --peer-cert-file=/etc/etcd/ssl/etcd.pem \
  --peer-key-file=/etc/etcd/ssl/etcd-key.pem \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --initial-advertise-peer-urls https://192.168.10.111:2380 \
  --listen-peer-urls https://192.168.10.111:2380 \
  --listen-client-urls https://192.168.10.111:2379,http://127.0.0.1:2379 \
  --advertise-client-urls https://192.168.10.111:2379 \
  --initial-cluster-token etcd-cluster-0 \
  --initial-cluster k8s-m1.trjcn.com=https://192.168.10.110:2380,k8s-m2.trjcn.com=https://192.168.10.111:2380,k8s-m3.trjcn.com=https://192.168.10.112:2380  \
  --initial-cluster-state new \
  --data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

5.8.1.3:主節點192.168.10.112上的的etcd.service

cat <<EOF >/etc/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/bin/etcd \
  --name k8s-m3.trjcn.com \
  --cert-file=/etc/etcd/ssl/etcd.pem \
  --key-file=/etc/etcd/ssl/etcd-key.pem \
  --peer-cert-file=/etc/etcd/ssl/etcd.pem \
  --peer-key-file=/etc/etcd/ssl/etcd-key.pem \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --initial-advertise-peer-urls https://192.168.10.112:2380 \
  --listen-peer-urls https://192.168.10.112:2380 \
  --listen-client-urls https://192.168.10.112:2379,http://127.0.0.1:2379 \
  --advertise-client-urls https://192.168.10.112:2379 \
  --initial-cluster-token etcd-cluster-0 \
--initial-cluster k8s-m1.trjcn.com=https://192.168.10.110:2380,k8s-m2.trjcn.com=https://192.168.10.111:2380,k8s-m3.trjcn.com=https://192.168.10.112:2380  \
  --initial-cluster-state new \
  --data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

5.8.2:新增自啟動(etc叢集最少2個節點才能啟動,啟動報錯看mesages日誌)

mv /etc/systemd/system/etcd.service /usr/lib/systemd/system
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
systemctl status etcd

5.8.3:在三個etcd節點執行一下命令檢查

etcdctl --endpoints=https://192.168.10.110:2379,https://192.168.10.111:2379,https://192.168.10.112:2379 \
  --ca-file=/etc/etcd/ssl/ca.pem \
  --cert-file=/etc/etcd/ssl/etcd.pem \
  --key-file=/etc/etcd/ssl/etcd-key.pem  cluster-health

5.9 所有節點安裝配置kubelet kubeadm kubectl

5.9.1:所有節點安裝kubelet kubeadm kubectl(這裡使用1.10.6版本)

檢視有那些版本可以安裝
yum list kubeadm –showduplicates
安裝指定版本
yum -y install kubeadm-1.10.6-0 kubectl-1.10.6-0 kubelet-1.10.6-0

5.9.2: 所有節點修改kubelet配置檔案

/etc/systemd/system/kubelet.service.d/10-kubeadm.conf中:

修改這一行

Environment=”KUBELET_CGROUP_ARGS=–cgroup-driver=systemd”
修改為
Environment=”KUBELET_CGROUP_ARGS=–cgroup-driver=cgroupfs”

在[Service]下在新增這一行
Environment=”KUBELET_EXTRA_ARGS=–v=2 –fail-swap-on=false –pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/k8sth/pause-amd64:3.0”

5.9.3:所有節點修改完配置檔案一定要重新載入配置

systemctl daemon-reload
systemctl enable kubelet
systemctl restart kubelet

這時系統啟動時,會報錯,先不用管他。因為還沒有初始化。初始化後就沒事了。

5.9.4: 命令補全

yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo “source <(kubectl completion bash)” >> ~/.bashrc

5.10 初始化叢集

5.10.1:三個主節點192.168.10.110 192.168.10.111 192.168.10.112新增叢集初始配置檔案(叢集配置檔案一樣)

$ mkdir -p /opt/k8s/config/ && cd /opt/k8s/config

注:config.yml中的kubernetesVersion版本資訊必須和kube-proxy、kube-scheduler、kube-controller-manager、kube-apiserver等映象的版本一致。

cat <<EOF > config.yaml 
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
etcd:
  endpoints:
  - https://192.168.10.110:2379
  - https://192.168.10.111:2379
  - https://192.168.10.112:2379
  caFile: /etc/etcd/ssl/ca.pem
  certFile: /etc/etcd/ssl/etcd.pem
  keyFile: /etc/etcd/ssl/etcd-key.pem
  dataDir: /var/lib/etcd
networking:
  podSubnet: 10.244.0.0/16
kubernetesVersion: 1.10.6
api:
  advertiseAddress: "192.168.10.115"
token: "b99a00.a144ef80536d4344"
tokenTTL: "0s"
apiServerCertSANs:
- k8s-m1.trjcn.com
- k8s-m2.trjcn.com
- k8s-m3.trjcn.com
- 192.168.10.110
- 192.168.10.111
- 192.168.10.112
- 192.168.10.113
- 192.168.10.115
featureGates:
  CoreDNS: true
imageRepository: "registry.cn-hangzhou.aliyuncs.com/k8sth"
imagePullPolicy: IfNotPresent
EOF

5.10.2:首先主節點192.168.10.110初始化叢集

配置檔案定義podnetwork是10.244.0.0/16

kubeadmin init –hlep可以看出,service預設網段是10.96.0.0/12
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf預設dns地址cluster-dns=10.96.0.10

kubeadm init –config /opt/k8s/config/config.yaml

初始化失敗後處理辦法
kubeadm reset

初始化正常的結果如下:

[init] using Kubernetes version: v1.10.0
[preflight] running pre-flight checks
I0831 03:06:18.253104   32698 kernel_validator.go:81] Validating kernel version
I0831 03:06:18.253173   32698 kernel_validator.go:96] Validating kernel config
        [WARNING KubeletVersion]: the kubelet version is higher than the control plane version. This is not a supported version skew and may lead to a malfunctional cluster. Kubelet version: "1.11.2" Control plane version: "1.10.0"
[preflight/images] Pulling images required for setting up a Kubernetes cluster
[preflight/images] This might take a minute or two, depending on the speed of your internet connection
[preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[preflight] Activating the kubelet service
[certificates] Generated ca certificate and key.
[certificates] Generated apiserver certificate and key.
[certificates] apiserver serving cert is signed for DNS names [k8s-m1.trjcn.com kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local k8s-m1.trjcn.com k8s-m2.trjcn.com k8s-m3.trjcn.com] and IPs [10.96.0.1 192.168.10.115 192.168.10.110 192.168.10.111 192.168.10.112 192.168.10.113 192.168