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

Master組件:
- kube-apiserver
Kubernetes API,集群的統(tǒng)一入口,各組件協(xié)調(diào)者,以HTTP API提供接口服務(wù),所有對象資源的增刪改查和監(jiān)聽操作都交給APIServer處理后再提交給Etcd存儲(chǔ)。
- kube-controller-manager
處理集群中常規(guī)后臺任務(wù),一個(gè)資源對應(yīng)一個(gè)控制器,而ControllerManager就是負(fù)責(zé)管理這些控制器的。
- kube-scheduler
根據(jù)調(diào)度算法為新創(chuàng)建的Pod選擇一個(gè)Node節(jié)點(diǎn)。
Node組件:
-
kubelet
kubelet是Master在Node節(jié)點(diǎn)上的Agent,管理本機(jī)運(yùn)行容器的生命周期,比如創(chuàng)建容器、Pod掛載數(shù)據(jù)卷、下載secret、獲取容器和節(jié)點(diǎn)狀態(tài)等工作。kubelet將每個(gè)Pod轉(zhuǎn)換成一組容器。
-
kube-proxy
在Node節(jié)點(diǎn)上實(shí)現(xiàn)Pod網(wǎng)絡(luò)代理,維護(hù)網(wǎng)絡(luò)規(guī)則和四層負(fù)載均衡工作。
-
docker或rocket/rkt
運(yùn)行容器。
第三方服務(wù):
-
etcd
分布式鍵值存儲(chǔ)系統(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é)點(diǎn)。
在兩個(gè)節(jié)點(diǎn)node01和node02以及鏡像倉庫上安裝docker并關(guān)閉防火墻。
# sudo sh install-docker.sh docker-18.03.1-ce.tgz
# sudo systemctl disable firewalld
# sudo systemctl stop firewalld
安裝完成后,在etc目錄下新建docker文件夾,在docker文件夾下新建daemon.json文件,并寫入國內(nèi)公有鏡像倉庫地址以及私有鏡像倉庫地址。
#sudo vi /etc/docker/daemon.json
{
"registry-mirrors": [ "https://registry.docker-cn.com"],
"insecure-registries":["172.16.0.44:5000"]
}
啟動(dòng)docker并設(shè)置docker開機(jī)啟動(dòng)
# 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é)點(diǎn)下/home目錄下新建ssl文件夾用來存放證書。
# cd home
# sudo mkdir ssl
將依賴包里面的cfssl_linux-amd64,cfssljson_linux-amd64, cfssl-certinfo_linux-amd64上傳至master節(jié)點(diǎn)。
添加可執(zhí)行權(quán)限
# sudo chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
移動(dòng)文件
# 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
移動(dòng)后可以輸入命令查看help
# sudo cfssl --help

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

運(yùn)行腳本文件
# sudo ./certificate.sh
ssl目錄下會(huì)生成17個(gè)新文件。

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

集群部署 – 部署Etcd集群
將etcd-v3.2.12-linux-amd64.tar.gz 上傳至master節(jié)點(diǎn)
解壓
# sudo tar zxvf etcd-v3.2.12-linux-amd64.tar.gz
創(chuàng)建目錄
# sudo mkdir /opt/kubernetes
之后所有組件都放入這個(gè)文件夾,方便統(tǒng)一管理維護(hù)。
再創(chuàng)建三個(gè)目錄
# sudo mkdir /opt/kubernetes/{bin,cfg,ssl}
在剛才解壓的文件夾里面找到etcd和etcdctl并將兩個(gè)文件移動(dòng)到/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
寫入以下內(nèi)容
#[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
增加下面內(nèi)容
[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
==復(fù)制時(shí)候注意換行符?。。?!==
保存退出
將證書拷貝到kubernetes證書目錄
# sudo cp ssl/server*pem ssl/ca*.pem /opt/kubernetes/ssl/
啟動(dòng)etcd
# sudo systemctl start etcd
查看是否啟動(dòng)

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

然后將公鑰拷貝到節(jié)點(diǎn)上,即可免密碼交互。
# sudo ssh-copy-id root@172.16.0.42
# sudo ssh-copy-id root@172.16.0.43
之后在兩個(gè)節(jié)點(diǎn)下遞歸創(chuàng)建目錄
# sudo mkdir -p /opt/kubernetes/{bin,cfg,ssl}
創(chuàng)建完之后將master節(jié)點(diǎn)下的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/
以及數(shù)字證書
# 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é)點(diǎn)名字以及IP地址修改為節(jié)點(diǎn)IP


修改完之后分別在兩個(gè)節(jié)點(diǎn)下啟動(dòng)etcd
# sudo systemctl start etcd
設(shè)置為開機(jī)啟動(dòng)
# 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網(wǎng)絡(luò)
將flannel的二進(jìn)制包上傳至master,可以在依賴文件夾中找到
解壓flannel
# sudo tar zxvf flannel-v0.9.1-linux-amd64.tar.gz

傳送到node節(jié)點(diǎn)
# 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é)點(diǎn)寫入分配的子網(wǎng)段到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é)點(diǎn)上部署,暫時(shí)不部署在master節(jié)點(diǎn)上。
新建文件flanneld
# sudo vi /opt/kubernetes/cfg/flanneld
添加以下內(nèi)容
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
再添加一個(gè)systemd下的文件進(jìn)行管理
# sudo vi /usr/lib/systemd/system/flanneld.service
添加下面內(nèi)容
[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
啟動(dòng)flanneld
# sudo systemctl start flanneld
開機(jī)啟動(dòng)flanneld
# sudo systemctl enable flanneld
重啟docker
# sudo systemctl restart docker
使用ifconfig命令可以看到flannel啟動(dòng)成功(安裝ifconfig方法:yum -y install net-tools)

另一個(gè)節(jié)點(diǎn)跟以上配置一樣。

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

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

將三個(gè)二進(jìn)制包移動(dòng)到安裝目錄下
# sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /opt/kubernetes/bin
增加執(zhí)行權(quán)限
# sudo chmod +x /opt/kubernetes/bin/* && chmod +x *.sh
復(fù)制證書
# 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

啟動(dòng)kube-apiserver
#sudo systemctl start kube-apiserver
查看是否啟動(dòng)
#ps -ef | grep kube-apiserver

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

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

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

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