Kubernetes介紹
Kubernetes是Google在2014年6月開源的一個容器集群管理系統(tǒng),使用Go語言開發(fā),Kubernetes也叫K8S。K8S是Google內部一個叫Borg的容器集群管理系統(tǒng)衍生出來的,Borg已經在Google大規(guī)模生產運行十年之久。K8S主要用于自動化部署、擴展和管理容器應用,提供了資源調度、部署管理、服務發(fā)現、擴容縮容、監(jiān)控等一整套功能。2015年7月,Kubernetes v1.0正式發(fā)布,截止到2018年4月25日最新穩(wěn)定版本是v1.10。Kubernetes目標是讓部署容器化應用簡單高效。
官方網站:www.kubernetes.io
Kubernetes 主要功能
- 數據卷
Pod中容器之間共享數據,可以使用數據卷。 - 應用程序健康檢查
容器內服務可能進程堵塞無法處理請求,可以設置監(jiān)控檢查策略保證應用健壯性。 - 復制應用程序實例
控制器維護著Pod副本數量,保證一個Pod或一組同類的Pod數量始終可用。 - 彈性伸縮
根據設定的指標(CPU利用率)自動縮放Pod副本數。 - 服務發(fā)現
使用環(huán)境變量或DNS服務插件保證容器中程序發(fā)現Pod入口訪問地址。 - 負載均衡
一組Pod副本分配一個私有的集群IP地址,負載均衡轉發(fā)請求到后端容器。在集群內部其他Pod可通過這個ClusterIP訪問應用。 - 滾動更新
更新服務不中斷,一次更新一個Pod,而不是同時刪除整個服務。 - 服務編排
通過文件描述部署服務,使得應用程序部署變得更高效。 - 資源監(jiān)控
Node節(jié)點組件集成cAdvisor資源收集工具,可通過Heapster匯總整個集群節(jié)點資源數據,然后存儲到InfluxDB時序數據庫,再由Grafana展示。 - 提供認證和授權
支持角色訪問控制(RBAC)認證授權等策略。
基本對象概念
- Pod
Pod是最小部署單元,一個Pod有一個或多個容器組成,Pod中容器共享存儲和網絡,在同一臺Docker主機上運行。 - Service
Service一個應用服務抽象,定義了Pod邏輯集合和訪問這個Pod集合的策略。
Service代理Pod集合對外表現是為一個訪問入口,分配一個集群IP地址,來自這個IP的請求將負載均衡轉發(fā)后端Pod中的容器。
Service通過Lable Selector選擇一組Pod提供服務。 - Volume
數據卷,共享Pod中容器使用的數據。 - Namespace
命名空間將對象邏輯上分配到不同Namespace,可以是不同的項目、用戶等區(qū)分管理,并設定控制策略,從而實現多租戶。命名空間也稱為虛擬集群。 - Lable
標簽用于區(qū)分對象(比如Pod、Service),鍵/值對存在;每個對象可以有多個標簽,通過標簽關聯對象。
基于基本對象更高層次抽象: - ReplicaSet:
下一代Replication Controller。確保任何給定時間指定的Pod副本數量,并提供聲明式更新等功能。RC與RS唯一區(qū)別就是lable selector支持不同,RS支持新的基于集合的標簽,RC僅支持基于等式的標簽。 - Deployment
Deployment是一個更高層次的API對象,它管理ReplicaSets和Pod,并提供聲明式更新等功能。官方建議使用Deployment管理ReplicaSets,而不是直接使用ReplicaSets,這就意味著可能永遠不需要直接操作ReplicaSet對象。 - StatefulSet
StatefulSet適合持久性的應用程序,有唯一的網絡標識符(IP),持久存儲,有序的部署、擴展、刪除和滾動更新。 - DaemonSet
DaemonSet確保所有(或一些)節(jié)點運行同一個Pod。當節(jié)點加入Kubernetes集群中,Pod會被調度到該節(jié)點上運行,當節(jié)點從集群中移除時,DaemonSet的Pod會被刪除。刪除DaemonSet會清理它所有創(chuàng)建的Pod。 - Job
一次性任務,運行完成后Pod銷毀,不再重新啟動新容器。還可以任務定時運行。
系統(tǒng)架構及組件功能

Master組件:
- kube-apiserver
Kubernetes API,集群的統(tǒng)一入口,各組件協調者,以HTTP API提供接口服務,所有對象資源的增刪改查和監(jiān)聽操作都交給APIServer處理后再提交給Etcd存儲。
- kube-controller-manager
處理集群中常規(guī)后臺任務,一個資源對應一個控制器,而ControllerManager就是負責管理這些控制器的。
- kube-scheduler
根據調度算法為新創(chuàng)建的Pod選擇一個Node節(jié)點。
Node組件:
-
kubelet
kubelet是Master在Node節(jié)點上的Agent,管理本機運行容器的生命周期,比如創(chuàng)建容器、Pod掛載數據卷、下載secret、獲取容器和節(jié)點狀態(tài)等工作。kubelet將每個Pod轉換成一組容器。
-
kube-proxy
在Node節(jié)點上實現Pod網絡代理,維護網絡規(guī)則和四層負載均衡工作。
-
docker或rocket/rkt
運行容器。
第三方服務:
-
etcd
分布式鍵值存儲系統(tǒng)。用于保持集群狀態(tài),比如Pod、Service等對象信息。
集群部署-環(huán)境規(guī)劃
| 軟件 | 版本 |
|---|---|
| Linux操作系統(tǒng) | Centos 7.3 |
| Kubernetes | 1.9 |
| Docker | 18.03.1-ce |
| Etcd | 3.0 |
| 角色 | IP | 組件 |
|---|---|---|
| Master | 172.16.0.42 | kube-apiserver kube-controller-manager kube-scheduler etcd |
| Node1 | 172.16.0.43 | kubelet kube-proxy docker flannel etcd |
| Node2 | 172.16.0.42 | kubelet kube-proxy docker flannel etcd |
| 鏡像倉庫 | 172.16.0.44 | docker |
集群部署-安裝Docker
將依賴包里面install-docker.sh docker-18.03.1-ce.tgz上傳至節(jié)點。
在兩個節(jié)點node01和node02以及鏡像倉庫上安裝docker并關閉防火墻。
# sudo sh install-docker.sh docker-18.03.1-ce.tgz
# sudo systemctl disable firewalld
# sudo systemctl stop firewalld
安裝完成后,在etc目錄下新建docker文件夾,在docker文件夾下新建daemon.json文件,并寫入國內公有鏡像倉庫地址以及私有鏡像倉庫地址。
#sudo vi /etc/docker/daemon.json
{
"registry-mirrors": [ "https://registry.docker-cn.com"],
"insecure-registries":["172.16.0.44:5000"]
}
啟動docker并設置docker開機啟動
# sudo systemctl start docker
# sudo systemctl enable docker
查看是否安裝成功
#sudo docker info

集群部署 – 自簽TLS證書
| 組件 | 使用的證書 |
|---|---|
| etcd | ca.pem,server.pem,server-key.pem |
| flannel | ca.pem,server.pem,server-key.pem |
| kube-apiserver | ca.pem,server.pem,server-key.pem |
| kubelet | ca.pem,ca-key.pem |
| kube-proxy | ca.pem,kube-proxy.pem,kube-proxy-key.pem |
| kubectl | ca.pem,admin.pem,admin-key.pem |
在master節(jié)點下/home目錄下新建ssl文件夾用來存放證書。
# cd home
# sudo mkdir ssl
將依賴包里面的cfssl_linux-amd64,cfssljson_linux-amd64, cfssl-certinfo_linux-amd64上傳至master節(jié)點。
添加可執(zhí)行權限
# sudo chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
移動文件
# sudo mv cfssl_linux-amd64 /usr/local/bin/cfssl
# sudo mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
# sudo mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
移動后可以輸入命令查看help
# sudo cfssl --help

將依賴包里面的certificate.sh上傳到master節(jié)點根目錄的ssl文件夾下。
修改權限
# sudo chmod +x certificate.sh
修改certificate.sh文件下host地址為你的三個節(jié)點的IP地址

運行腳本文件
# sudo ./certificate.sh
ssl目錄下會生成17個新文件。

刪除除了證書以外的其他文件
# sudo ls | grep -v pem | xargs -i rm {}

集群部署 – 部署Etcd集群
將etcd-v3.2.12-linux-amd64.tar.gz 上傳至master節(jié)點
解壓
# sudo tar zxvf etcd-v3.2.12-linux-amd64.tar.gz
創(chuàng)建目錄
# sudo mkdir /opt/kubernetes
之后所有組件都放入這個文件夾,方便統(tǒng)一管理維護。
再創(chuàng)建三個目錄
# sudo mkdir /opt/kubernetes/{bin,cfg,ssl}
在剛才解壓的文件夾里面找到etcd和etcdctl并將兩個文件移動到/opt/kubernetes/bin下
# sudo mv etcd-v3.2.12-linux-amd64/etcd /opt/kubernetes/bin/
# sudo mv etcd-v3.2.12-linux-amd64/etcdctl /opt/kubernetes/bin/
創(chuàng)建配置文件
# sudo vi /opt/kubernetes/cfg/etcd
寫入以下內容
#[Member]
ETCD_NAME="etcd01"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://172.16.0.41:2380"
ETCD_LISTEN_CLIENT_URLS="https://172.16.0.41:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.16.0.41:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://172.16.0.41:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://172.16.0.41:2380,etcd02=https://172.16.0.42:2380,etcd03=https://172.16.0.43:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
保存退出
創(chuàng)建配置文件,通過systemd管理配置文件
# sudo vi /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
==復制時候注意換行符?。。?!==
保存退出
將證書拷貝到kubernetes證書目錄
# sudo cp ssl/server*pem ssl/ca*.pem /opt/kubernetes/ssl/
啟動etcd
# sudo systemctl start etcd
查看是否啟動

# ps -ef | grep etcd
設置為開機啟動
# sudo systemctl enable etcd
為了集群以后的方便管理以及文件傳輸,我們做一個互信。
生成一個ssh證書
# sudo ssh-keygen
然后一路回車
生成之后在/root/.ssh/下可以看到一個公鑰、一個私鑰。

然后將公鑰拷貝到節(jié)點上,即可免密碼交互。
# sudo ssh-copy-id root@172.16.0.42
# sudo ssh-copy-id root@172.16.0.43
之后在兩個節(jié)點下遞歸創(chuàng)建目錄
# sudo mkdir -p /opt/kubernetes/{bin,cfg,ssl}
創(chuàng)建完之后將master節(jié)點下的etcd發(fā)送過去
# sudo scp -r /opt/kubernetes/bin/ root@172.16.0.42:/opt/kubernetes/
# sudo scp -r /opt/kubernetes/bin/ root@172.16.0.43:/opt/kubernetes/
再將配置文件傳送過去
# sudo scp -r /opt/kubernetes/cfg/ root@172.16.0.42:/opt/kubernetes/
# sudo scp -r /opt/kubernetes/cfg/ root@172.16.0.43:/opt/kubernetes/
以及數字證書
# sudo scp -r /opt/kubernetes/ssl/ root@172.16.0.42:/opt/kubernetes/
# sudo scp -r /opt/kubernetes/ssl/ root@172.16.0.43:/opt/kubernetes/
還有配置文件
# sudo scp /usr/lib/systemd/system/etcd.service root@172.16.0.42:/usr/lib/systemd/system
# sudo scp /usr/lib/systemd/system/etcd.service root@172.16.0.43:/usr/lib/systemd/system
在node1以及node2分別修改配置文件
# sudo vi /opt/kubernetes/cfg/etcd
將其中的ETCD_NAME修改為節(jié)點名字以及IP地址修改為節(jié)點IP


修改完之后分別在兩個節(jié)點下啟動etcd
# sudo systemctl start etcd
設置為開機啟動
# sudo systemctl enable etcd
查看集群狀態(tài):
/opt/kubernetes/bin/etcdctl \
--ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem \
--endpoints="https://172.16.0.41:2379,https://172.16.0.42:2379,https://172.16.0.43:2379" \
cluster-health

集群部署 – 部署Flannel網絡
將flannel的二進制包上傳至master,可以在依賴文件夾中找到
解壓flannel
# sudo tar zxvf flannel-v0.9.1-linux-amd64.tar.gz

傳送到node節(jié)點
# sudo scp flanneld mk-docker-opts.sh root@172.16.0.42:/opt/kubernetes/bin/
# sudo scp flanneld mk-docker-opts.sh root@172.16.0.43:/opt/kubernetes/bin/
在master節(jié)點寫入分配的子網段到etcd,供flanneld使用
/opt/kubernetes/bin/etcdctl \
--ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem \
--endpoints="https://172.16.0.41:2379,https://172.16.0.42:2379,https://172.16.0.43:2379" \
set /coreos.com/network/config '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'
Flannel只在node節(jié)點上部署,暫時不部署在master節(jié)點上。
新建文件flanneld
# sudo vi /opt/kubernetes/cfg/flanneld
添加以下內容
FLANNEL_OPTIONS="--etcd-endpoints=https://172.16.0.41:2379,https://172.16.0.42:2379,https://172.16.0.43:2379 --etcd-cafile=/opt/kubernetes/ssl/ca.pem --etcd-certfile=/opt/kubernetes/ssl/server.pem --etcd-keyfile=/opt/kubernetes/ssl/server-key.pem
再添加一個systemd下的文件進行管理
# sudo vi /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
保存退出
更新配置
# sudo systemctl daemon_reload
啟動flanneld
# sudo systemctl start flanneld
開機啟動flanneld
# sudo systemctl enable flanneld
重啟docker
# sudo systemctl restart docker
使用ifconfig命令可以看到flannel啟動成功(安裝ifconfig方法:yum -y install net-tools)

另一個節(jié)點跟以上配置一樣。

用node2去ping node1的docker網關,ping通即說明flannel網絡部署成功。
集群部署 – 創(chuàng)建Node節(jié)點kubeconfig文件
將kubeconfig.sh 上傳至master節(jié)點。
修改權限
# sudo chmod +x kubeconfig.sh
修改kubeconfig.sh文件中的IP地址為master地址。
將kubectl上傳至/opt/kubernetes/bin/目錄下并修改權限
# sudo chmod +x /opt/kubernetes/bin/kubectl
設置環(huán)境變量
# sudo export PATH="/opt/kubernetes/bin/:$PATH"
環(huán)境變量生效
# sudo source /etc/profile
切換到生成證書的ssl目錄,執(zhí)行kubeconfig.sh
執(zhí)行成功后目錄下會生成kube-proxy.kubeconfig,bootstrap.kubeconfig, token.csv

將兩個文件拷貝到兩個節(jié)點的cfg目錄下
# sudo scp *kubeconfig root@172.16.0.42:/opt/kubernetes/cfg/
# sudo scp *kubeconfig root@172.16.0.43:/opt/kubernetes/cfg/
集群部署 – 運行Master組件
將master.zip上傳至master,node.zip上傳至兩個node
在master節(jié)點下創(chuàng)建master_pkg目錄
# sudo mkdir master_pkg
將master.zip移動到master_pkg目錄
# sudo mv master.zip master_pkg/
解壓master.zip
# sudo unzip master.zip
可以看到以下文件

將三個二進制包移動到安裝目錄下
# sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /opt/kubernetes/bin
增加執(zhí)行權限
# sudo chmod +x /opt/kubernetes/bin/* && chmod +x *.sh
復制證書
# sudo cp ssl/ca*pem ssl/server*pem /opt/kubernetes/ssl/
token文件拷貝到cfg文件夾
# sudo cp ssl/token.csv /opt/kubernetes/cfg/
執(zhí)行apiserver.sh
# sudo ./apiserver.sh 172.16.0.41 https://172.16.0.41:2379,https:// 172.16.0.42:2379,https:// 172.16.0.43:2379
可以看到system下生成kube-apiserver.service

啟動kube-apiserver
#sudo systemctl start kube-apiserver
查看是否啟動
#ps -ef | grep kube-apiserver

執(zhí)行scheduler.sh
# sudo ./scheduler.sh 127.0.0.1
可以看到system下生成kube-scheduler
啟動kube-scheduler.
# sudo systemctl start kube-scheduler
執(zhí)行controller-manager.sh
# sudo ./controller-manager.sh 127.0.0.1
可以看到system下生成kube-controller-manager
啟動kube-controller-manager
# sudo systemctl start kube-controller-manager
看一下集群健康狀態(tài)
# sudo kubectl get cs

集群部署 – 運行Node組件
在master節(jié)點創(chuàng)建權限并綁定角色
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
解壓node.zip文件
將kubelet,kube-proxy復制到bin目錄下
# sudo mv kubelet kube-proxy /opt/kubernetes/bin
設置執(zhí)行權限
# sudo chmod +x /opt/kubernetes/bin/* && chmod +x *.sh
執(zhí)行kubelet.sh,ip地址為當前節(jié)點IP地址
# sudo ./kubelet.sh 172.16.0.42 10.10.10.2
查看是否啟動
# ps -ef | grep kubelet

啟動proxy,ip地址為當前節(jié)點IP地址
# sudo ./proxy.sh 172.16.0.42
查看是否啟動
# ps -ef | grep kube-proxy

另一個節(jié)點同樣執(zhí)行以上操作
部署完成后再master上執(zhí)行如下命令
# kubectl get node
此處會顯示No sources found
執(zhí)行命令
# kubectl get csr
將獲取到的節(jié)點加進去即可
# kubectl certificate approve csr-jwf0q
# kubectl get componentstatus
得到如下結果即證明部署成功。
