kubernetes官方提供了中文文件,網上也有不少中文教程,可是實際的安裝過程中,還是遇到了不少的坑。主要有:
- kubernetes的版本迭代比較迅速。網上教程中版本多是
1.6
這樣的,最新的k8s版本是1.13.0
- kubernetes的需要安裝的rpm包及docker映象國內直接安裝會失敗。
- 官方的中文文件在翻譯不全,其中一些內容缺失。
發文時kubernetes1.14.0已經正式釋出,稍後會奉上更新手冊, 敬請期待。
我花了一些時間踩坑,主要參考kubernetes官網、github及stack overflow, 成功完成k8s的安裝,過程記錄如下。
機器準備
我們在內網的2臺伺服器上開始k8s的安裝,機器配置及規劃如下表:
機器名稱 | 機器IP | CPU | 記憶體 | Linux版本 | Docker版本 | 用途 |
---|---|---|---|---|---|---|
192-168-10-21 | 192.168.10.21 | 8 | 16G | CentOS 7.1.1503 | 17.03.2-ce/17.03.2-ce | master控制節點 |
192-168-10-18 | 192.168.10.18 | 8 | 28G | CentOS 7.6.1810 | 17.03.1-ce/17.03.1-ce | worker業務節點 |
Docker版本為:Client Version/Server Version的格式
本次安裝的k8s版本是 v1.13.0
,另外實測CentOS的小版本和Docker的小版本不用完全一致。
安裝環境準備及安裝
安裝k8s裝置環境要求主要有下面10點:
1. CentOS版本為7以上
2. 2核CPU和2G記憶體以上
3. 多臺機器內網互通
4. 每臺機器的主機名、mac地址和product_uuid唯一
5. 測試環境關閉防火牆,保證全部埠開放。
6. 禁用SELinux
7. 禁用交換分割槽
8. docker服務
9. root賬號許可權
10. 配置國內的repo源
複製程式碼
- 檢視機器CentOS版本
[root@192-168-10-21 ~]# cat /etc/centos-release
CentOS Linux release 7.1.1503 (Core)
複製程式碼
注意CentOS6升級到7比較麻煩,本著少折騰原則,從CentOS7的機器開始會省事一些。
- 檢視機器的cpu和記憶體資訊
比較簡單和常用的可以使用TOP
命令後再按1
檢視:
TOP 1
Tasks: 200 total, 1 running, 199 sleeping, 0 stopped, 0 zombie
%Cpu0 : 2.0 us, 1.0 sy, 0.0 ni, 97.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 1.0 us, 0.3 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.7 us, 0.7 sy, 0.0 ni, 98.3 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 0.7 us, 0.3 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 1.3 us, 0.7 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu6 : 0.7 us, 0.7 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu7 : 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16207100 total, 13269888 free, 974208 used, 1963004 buff/cache
複製程式碼
上面資訊可知,機器是8核,記憶體是16G。
更準確的檢視CPU資訊:
# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
8 Intel(R) Xeon(R) CPU E5-2640 0 @ 2.50GHz
複製程式碼
檢視記憶體資訊:
# cat /proc/meminfo | grep MemTotal
MemTotal: 16207100 kB 0 0 0
複製程式碼
-
多臺機器互通,這一般沒有問題,不用介紹。
-
檢查機器名稱、mac及product_uuid的唯一性
# 檢視uuid
# cat /sys/class/dmi/id/product_uuid
564D0DF3-FB05-2EC7-E989-FFE0F880069C
# 檢視hostname
# hostname
192-168-10-21
# 檢視IP
# ifconfig -a
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.21 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::20c:29ff:fe80:69c prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:80:06:9c txqueuelen 1000 (Ethernet)
RX packets 5333851 bytes 529922710 (505.3 MiB)
RX errors 0 dropped 152075 overruns 0 frame 0
TX packets 2560325 bytes 916120110 (873.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
複製程式碼
一般來說uuid和mac不可能重複,hostname可能會有重複(因為運維開機器是指令碼批處理,可能沒有修改hostname)。如果hostname重複,修改的方法如下:
1 vi /etc/hostname 修改名稱。2 vi /etc/hosts 增加機器名稱。 3 roboot重啟機器。
- 關閉防火牆
k8s對master和worker節點的埠開放有要求:
因為是內網測試服務,我簡單粗暴的關閉防火牆即可。
檢視firewall狀態:
# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
複製程式碼
檢視iptables狀態:
# systemctl status iptables
● iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled)
Active: inactive (dead)
複製程式碼
關閉防火牆
systemctl stop firewalld
停止防護牆開機啟動systemctl disable firewalld
。iptables的關閉同理。
- 禁用SELinux
禁用SELinux後,容器才能夠訪問宿主機檔案系統。檢視SELinux的狀態:
# sestatus
SELinux status: disabled
複製程式碼
禁用方法
setenforce 0 && sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
- 禁用交換分割槽
檢視交換分割槽狀態,如果swap數值全部為0,則表示已經禁用。
[root@192-168-10-21 ~]# free -h
total used free shared buff/cache available
Mem: 15G 940M 13G 17M 1.4G 14G
Swap: 0B 0B 0B
複製程式碼
禁用方法如下
1. run swapoff -a : this will immediately disable swap.
2. remove any swap entry from /etc/fstab.
3. reboot.
複製程式碼
- docker服務
檢視docker版本:
[root@192-168-10-18 ~]# docker version
Client:
Version: 17.03.1-ce
API version: 1.27
Go version: go1.7.5
Git commit: c6d412e
Built: Mon Mar 27 17:05:44 2017
OS/Arch: linux/amd64
Server:
Version: 17.03.1-ce
API version: 1.27 (minimum version 1.12)
Go version: go1.7.5
Git commit: c6d412e
Built: Mon Mar 27 17:05:44 2017
OS/Arch: linux/amd64
Experimental: false
複製程式碼
- root賬號
安裝 kubeadm
時候需要使用root賬號進行安裝。安裝完成後推薦非root賬號使用 kubectl
命令。
- 配置國內的repo源
kubeadm
使用yum
命令進行安裝,使用國內阿里雲的源,可以安裝成功
cat >> /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
複製程式碼
- 修改網路配置
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
複製程式碼
修改完成後執行sysctl --system
應用。
- 安裝kubernetes包
安裝條件全部具備以後, root
賬號進入 192-168-10-21
,執行下面命令:
[root@192-168-10-21 ~]# yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
複製程式碼
完成後啟動kubelet
服務
systemctl enable kubelet.service
systemctl start kubelet.service
複製程式碼
以上12項操作需要在所有節點執行。
初始化k8s叢集
1.1 初始化叢集
master上使用下面命令初始化k8s:
kubeadm init --kubernetes-version v1.13.0 --pod-network-cidr=10.244.0.0/16
複製程式碼
成功後會有下面的輸出:
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join 192.168.10.21:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:564e3ba4b76649e981300fcea9e4400b759f91a02f4a968e035ada454f3a1d2e
複製程式碼
這段提示主要介紹了3點:
1. 推薦非root賬號使用`kubectl`命令。本文使用hall賬號。
2. 需要在叢集中建立pod network。本文使用flannel, 初始化命令中的`--pod-network-cidr=10.244.0.0/16`是使用flannel的必備引數,詳情見官方英文文件。
3. 顯示了其它節點加入叢集的命令。
複製程式碼
檢視kubectl的版本資訊:
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", GitCommit:"ddf47ac13c1a9483ea035a79cd7c10005ff21a6d", GitTreeState:"clean", BuildDate:"2018-12-03T21:04:45Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", GitCommit:"ddf47ac13c1a9483ea035a79cd7c10005ff21a6d", GitTreeState:"clean", BuildDate:"2018-12-03T20:56:12Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"linux/amd64"}
複製程式碼
檢視節點:
[hall@192-168-10-21 ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
192-168-10-21 NotReady master 41m v1.13.0
複製程式碼
這裡master的狀態為NotReady是因為還沒有進行pod network安裝。
1.2 使用阿里雲的docker hub映象
如果網路ok,使用1.1的方法安裝不會存在問題。但是國內可能一些映象無法下載,可以使用阿里雲的docker hub映象進行安裝。
首先輸出kubeadm
預設配置:
kubeadm config print init-defaults > kubeadm-init.yaml
複製程式碼
配置內容大概如下:
apiVersion: kubeadm.k8s.io/v1beta1
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 1.2.3.4
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: 192-168-10-21
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: ""
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.13.0
networking:
dnsDomain: cluster.local
podSubnet: ""
serviceSubnet: 10.244.0.0/16
scheduler: {}
複製程式碼
注意:
- imageRepository修改成 registry.cn-hangzhou.aliyuncs.com/google_containers
- serviceSubnet部分設定成10.244.0.0/16,也就是--pod-network-cidr=10.244.0.0/16引數。
然後先進行映象下載:
kubeadm config images pull --config kubeadm-init.yaml
複製程式碼
最後再使用修改後的配置進行初始化:
kubeadm init --config kubeadm-init.yaml
複製程式碼
也可以通過在每個節點得docker daemon.json 中配置映象方式提速下載。
- work節點加入
在work節點上執行kubeadm init完成後得到的join命令:
[root@192-168-10-18 ~]#kubeadm join 192.168.10.21:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:564e3ba4b76649e981300fcea9e4400b759f91a02f4a968e035ada454f3a1d2e
複製程式碼
再次在master上檢視節點:
[hall@192-168-10-21 ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
192-168-10-18 NotReady <none> 98s v1.13.0
192-168-10-21 NotReady master 41m v1.13.0
複製程式碼
可以看到work節點192-168-10-18已經正常加入k8s叢集了。
- 後期work節點加入
如果join命令丟失或者過期,可以在master上執行下面命令,生成一個token:
[root@192-168-10-21 ~]# kubeadm token generate
ffppwv.04qrmsdwm6netaaq
複製程式碼
然後使用剛生成得token得到加入命令:
[root@192-168-10-21 ~]# kubeadm token create ffppwv.04qrmsdwm6netaaq --print-join-command --ttl=24h
kubeadm join 192.168.10.21:6443 --token pnstpk.kk3aevbn6i5mlsok --discovery-token-ca-cert-hash sha256:5ae89f1949e60f824b129c5520dc05f6da97cb8fa3edb806c3abb38eb439e007
複製程式碼
- --ttl=24h 代表這個Token 的有效期為 24 小時,初始化預設生成的 token 有效期也為 24 小時
- join的語法是:
kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>
然後work節點使用這個命令加入叢集。
- 安裝flannel網路
安裝flannel網路很簡單,分下面2步:
先下載yml檔案:
curl -O https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
複製程式碼
然後建立flannel:
kubectl create -f kube-flannel.yml
複製程式碼
完成後可以檢查:
[hall@192-168-10-21 ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
192-168-10-18 Ready <none> 102d v1.13.0
192-168-10-21 Ready master 102d v1.13.0
複製程式碼
這時候節點的狀態應該是Ready。同時也可以檢視flannel的pod:
[tyhall51@192-168-10-21 ~]$ kubectl get pods -n kube-system | grep flannel
kube-flannel-ds-amd64-j7lxz 1/1 Running 1 102d
kube-flannel-ds-amd64-lzjxg 1/1 Running 10 102d
複製程式碼
- 刪除節點
刪除節點可以使用:
kubeclt delete node 192-168-10-18
複製程式碼
Dashboard安裝
k8s完成後,可以使用 kubectl
進行所有控制。官方還提供了dashboard這種web介面,方便管理,一樣分2步。
先下載配置:
curl -o kubernetes-dashboard.yaml https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
curl -o heapster.yaml https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml
curl -o heapster-rbac.yaml https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml
curl -o influxdb.yaml https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml
複製程式碼
然後建立:
kubectl create -f kubernetes-dashboard.yaml
kubectl create -f heapster.yaml
kubectl create -f heapster-rbac.yaml
kubectl create -f influxdb.yaml
複製程式碼
也可以使用kubectl create -f .
一鍵將目錄下所有的yaml配置到k8s。
使用命令修改服務型別:
kubectl -n kube-system edit service kubernetes-dashboard
複製程式碼
修改 type: ClusterIP 成 type: NodePort 儲存。 (kubectl edit 和vi一樣操作)
測試服務使用NodePort暴露到叢集外,方便訪問
然後檢視dashboard暴露出來的本地埠:
[hall@192-168-10-21 dashboard]$ kubectl -n kube-system get service kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard NodePort 10.96.228.185 <none> 443:32145/TCP 6d21
複製程式碼
熟悉docker的就會知道,這裡顯示了dashboard容器的443埠對映到本地32145埠,然後我們使用https://192.168.10.21:32145
訪問.
訪問需要token登入,下面是獲取token的命令:
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk '{print $1}')
複製程式碼
效果如下:
增加Master節點
完成之前的內容,已經有一個初具規模的k8s叢集了。如果要比較正式的叢集,結合etcd的特性,控制節點多備,至少需要3臺master節點。接下來繼續介紹一下如何新增master節點。
使用命令 kubectl -n kube-system edit cm kubeadm-config
修改controlPlaneEndpoint值為192.168.10.21:6443,然後確認資訊修改完成:
[hall@192-168-10-21 ~]$ kubectl -n kube-system get cm kubeadm-config -oyaml
apiVersion: v1
data:
ClusterConfiguration: |
apiServer:
extraArgs:
authorization-mode: Node,RBAC
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: "192.168.10.21:6443"
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.13.0
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
scheduler: {}
ClusterStatus: |
apiEndpoints:
192-168-10-21:
advertiseAddress: 192.168.10.21
bindPort: 6443
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterStatus
kind: ConfigMap
metadata:
creationTimestamp: "2018-12-14T03:12:12Z"
name: kubeadm-config
namespace: kube-system
resourceVersion: "13566522"
selfLink: /api/v1/namespaces/kube-system/configmaps/kubeadm-config
uid: 0cf52c5b-ff4e-11e8-af11-000c2980069c
複製程式碼
這個ConfigMap就是之前kubeadm得config檔案。
複製第一個master節點上的相關證書到需要新增為master的192-168-10-14節點上,證書清單如下:
/etc/kubernetes/pki/sa.key
/etc/kubernetes/pki/sa.pub
/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key
/etc/kubernetes/pki/front-proxy-ca.crt
/etc/kubernetes/pki/front-proxy-ca.key
/etc/kubernetes/pki/etcd/ca.crt
/etc/kubernetes/pki/etcd/ca.key
/etc/kubernetes/admin.conf
複製程式碼
然後在192-168-10-14上執行join命令,等待命令執行完成。
kubeadm join 192.168.10.21:6443 --token ffppwv.04qrmsdwm6netaaq --discovery-token-ca-cert-hash sha256:0cd1dcabee49dd12aaf7913eab9b0fc0e5bda2be9c35f17ce0c0864c7a5bbdb1 --experimental-control-plane
複製程式碼
這個過程可能需要幾分鐘,期間kubectl會失效,耐心等待一下。
注意: 比新增work節點多了 --experimental-control-plane 引數
在第一個master節點執行 kubectl label nodes 192-168-10-14 node-role.kubernetes.io/master=""
,標記 192-168-10-14 為master
檢查一下節點情況:
[hall@192-168-10-21 ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
192-168-10-14 Ready master 17m v1.13.1
192-168-10-18 Ready <none> 102d v1.13.0
192-168-10-21 Ready master 102d v1.13.0
複製程式碼
最後給 192-168-10-14 增加一個汙點,標記為業務不可排程
kubectl taint nodes 192-168-10-14 node-role.kubernetes.io/master="":NoSchedule
複製程式碼
這樣就完成了master節點的新增,可以重複步驟新增第3個master節點。如果是正式服務,要完成高可用,還需用HA代理3個master節點的6443埠。其實現過程主要就是HA的配置,這裡就不在詳細介紹了。
自此,一個測試用的k8s叢集就搭建完成。簡單總結一下搭建過程:
- 按照官方要求進行環境監測和安裝kubelet、kubeadm、kubectl三個包。
- Master上初始化啟動k8s叢集,將節點加入叢集和配置叢集flannel網路。
- 安裝dashboard,視覺化管理叢集。
- 增加master節點,支援高可以。