Kubernetes 1.13 的完整部署方案
前言:
由於Kubernetes版本和作業系統的版本關係非常敏感,部署前請查閱版本關係對應表
地址:https://github.com/kubernetes/kubernetes/releases
1.實踐環境準備
伺服器虛擬機器準備
IP 地址 | 192.168.1.11 | 192.168.1.12 |
---|---|---|
節點角色 | master and etcd | worker |
CPU | >=2c | >=2c |
記憶體 | >=2G | >=2G |
主機名 | master | node |
節點數量 | 1臺 | 1臺 |
本實驗我這裡用的VM是vmware workstation建立的,每個給了4C 4G 100GB配置,需要保證兩臺節點都可以正常訪問網際網路,大家根據自己的資源情況,按照上面給的建議最低值建立即可。
注意:hostname不能有大寫字母,比如Master這樣。
2. 軟體版本
如下是軟體版本的對照情況:
作業系統版本: CentOS7.1804
Kubernetes版本: v1.13
docker版本: 18.06.1-ce
kubeadm版本: v1.13
kubectl版本: v1.13
kubelet版本: v1.13
注意:這裡採用的軟體版本,請大家儘量嚴格與我保持一致! 開源軟體,版本非常敏感和重要!
3. 基礎環境配置
3.1 配置節點的hostname
$ hostnamectl set-hostname master
$ hostnamectl set-hostname node
注意:每臺機器上設定對應好hostname,注意,不能有大寫字母!
3.2 配置節點的 /etc/hosts 檔案
注意:hosts檔案非常重要,請在每個節點上執行:
vi /etc/hosts
192.168.1.11 master
192.168.1.12 node
3.3 關閉防火牆、selinux、swap
關停防火牆
$ systemctl stop firewalld
$ systemctl disable firewalld
關閉Selinux
$ 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
關閉Swap
$ swapoff -a
$ sed -i 's/.*swap.*/#&/' /etc/fstab
載入br_netfilter
$ modprobe br_netfilter
3.4 配置核心引數
配置sysctl核心引數
$ cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
生效檔案
$ sysctl -p /etc/sysctl.d/k8s.conf
修改Linux 資源配置檔案,調高ulimit最大開啟數和systemctl管理的服務檔案最大開啟數
$ echo "* soft nofile 655360" >> /etc/security/limits.conf
$ echo "* hard nofile 655360" >> /etc/security/limits.conf
$ echo "* soft nproc 655360" >> /etc/security/limits.conf
$ echo "* hard nproc 655360" >> /etc/security/limits.conf
$ echo "* soft memlock unlimited" >> /etc/security/limits.conf
$ echo "* hard memlock unlimited" >> /etc/security/limits.conf
$ echo "DefaultLimitNOFILE=1024000" >> /etc/systemd/system.conf
$ echo "DefaultLimitNPROC=1024000" >> /etc/systemd/system.conf
4. 配置CentOS YUM源
配置國內tencent yum源地址、epel源地址、Kubernetes源地址
$ rm -rf /etc/yum.repos.d/*
$ curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
$ yum install -y wget
$ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo
$ wget -O /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
$ yum clean all && yum makecache
配置國內Kubernetes源地址
$ vi /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
5. 安裝依賴軟體包
有些依賴包我們要把它安裝上,方便到時候使用
$ yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp bash-completion yum-utils device-mapper-persistent-data lvm2 net-tools conntrack-tools vim libtool-ltdl
6. 時間同步配置
Kubernetes是分散式的,各個節點系統時間需要同步對應上。
$ yum install chrony –y
$ systemctl enable chronyd.service && systemctl start chronyd.service && systemctl status chronyd.service
$ chronyc sources
執行date命令看下系統時間,過一會兒時間就會同步。
7. 配置節點間ssh互信
配置ssh互信,那麼節點之間就能無密訪問,方便日後執行自動化部署
$ ssh-keygen # 每臺機器執行這個命令, 一路回車即可
$ ssh-copy-id node # 到master上拷貝公鑰到其他節點,這裡需要輸入 yes和密碼
8. 初始化環境配置檢查
- 重啟,做完以上所有操作,最好reboot重啟一遍
- ping 每個節點hostname 看是否能ping通
- ssh 對方hostname看互信是否無密碼訪問成功
- 執行date命令檢視每個節點時間是否正確
- 執行 ulimit -Hn 看下最大檔案開啟數是否是655360
- cat /etc/sysconfig/selinux |grep disabled 檢視下每個節點selinux是否都是disabled狀態
二、docker安裝
Kubernetes 是容器排程編排PaaS平臺,那麼docker是必不可少要安裝的。最新Kubernetes 1.13 支援最新的docker版本是18.06.1,那麼我們就安裝最新的 docker-ce 18.06.1
具體Kubernetes changelog 文件地址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.12.md#v1123
1. remove舊版本docker
$ yum remove -y docker docker-ce docker-common docker-selinux docker-engine
2. 設定docker yum源
$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
3. 列出docker版本
$ yum list docker-ce --showduplicates | sort -r
4. 安裝docker 指定18.06.1
$ yum install -y docker-ce-18.06.1.ce-3.el7
5. 配置映象加速器和docker資料存放路徑
$systemctl restart docker
$vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://q2hy3fzi.mirror.aliyuncs.com"]
}
6. 啟動docker
$ systemctl daemon-reload && systemctl restart docker && systemctl enable docker && systemctl status docker
檢視docker 版本
$ docker --version
三、安裝kubeadm、kubelet、kubectl
這一步是所有節點都得安裝(包括node節點)
1. 工具說明
• kubeadm: 部署叢集用的命令
• kubelet: 在叢集中每臺機器上都要執行的元件,負責管理pod、容器的生命週期
• kubectl: 叢集管理工具
2. yum 安裝
安裝工具
$ yum install -y kubelet-1.13.2 kubeadm-1.13.2 kubectl-1.13.2 kubernetes-cni-0.6.0
啟動kubelet
$ systemctl enable kubelet && systemctl start kubelet
注意:kubelet 服務會暫時啟動不了,先不用管它。
四、映象下載準備
1. 初始化獲取要下載的映象列表
使用kubeadm來搭建Kubernetes,那麼就需要下載得到Kubernetes執行的對應基礎映象,比如:kube-proxy、kube-apiserver、kube-controller-manager等等 。那麼有什麼方法可以得知要下載哪些映象呢?從kubeadm v1.11+版本開始,增加了一個kubeadm config print-default 命令,可以讓我們方便的將kubeadm的預設配置輸出到檔案中,這個檔案裡就包含了搭建K8S對應版本需要的基礎配置環境。另外,我們也可以執行 kubeadm config images list
命令檢視依賴需要安裝的映象列表。
注意:這個列表顯示的tag名字和映象版本號,從Kubernetes v1.12+開始,映象名後面不帶amd64, arm, arm64, ppc64le 這樣的標識了。
1.1 生成預設kubeadm.conf檔案
執行這個命令就生成了一個kubeadm.conf檔案
$ kubeadm config print init-defaults > kubeadm.conf
1.2 繞過牆下載映象方法(注意認真看,後期版本安裝也可以套用這方法)
注意這個配置檔案預設會從google的映象倉庫地址k8s.gcr.io下載映象。因此,我們通過下面的方法把地址改成國內的,比如用阿里的:
$ sed -i "s/imageRepository: .*/imageRepository: registry.aliyuncs.com/google_containers/g" kubeadm.conf
1.4 下載需要用到的映象
kubeadm.conf修改好後,我們執行下面命令就可以自動從國內下載需要用到的映象了:
$ kubeadm config images pull --config kubeadm.conf
自動下載v1.13需要用到的映象,執行 docker images 可以看到下載好的映象列表:
注:除了上面的方法,還有一種方式是搭建自己的映象倉庫。不過前提你得下載好對應的版本映象,然後上傳到你映象倉庫裡,然後pull下載。不過上面我提到的方法更加方便省事。
1.5 docker tag 映象
映象下載好後,我們還需要tag下載好的映象,讓下載好的映象都是帶有 k8s.gcr.io 標識的,目前我們從阿里下載的映象 標識都是,如果不打tag變成k8s.gcr.io,那麼後面用kubeadm安裝會出現問題,因為kubeadm裡面只認 google自身的模式。我們執行下面命令即可完成tag標識更換:
$ docker tag registry.aliyuncs.com/google_containers/kube-apiserver:v1.13.0 k8s.gcr.io/kube-apiserver:v1.13.0
$ docker tag registry.aliyuncs.com/google_containers/kube-controller-manager:v1.13.0 k8s.gcr.io/kube-controller-manager:v1.13.0
$ docker tag registry.aliyuncs.com/google_containers/kube-scheduler:v1.13.0 k8s.gcr.io/kube-scheduler:v1.13.0
$ docker tag registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0 k8s.gcr.io/kube-proxy:v1.13.0
$ docker tag registry.aliyuncs.com/google_containers/pause:3.1 k8s.gcr.io/pause:3.1
$ docker tag registry.aliyuncs.com/google_containers/etcd:3.2.24 k8s.gcr.io/etcd:3.2.24
$ docker tag registry.aliyuncs.com/google_containers/coredns:1.2.6 k8s.gcr.io/coredns:1.2.6
1.6 docker rmi 清理下載的映象
執行完上面tag映象的命令,我們還需要把帶有 registry.aliyuncs.com 標識的映象刪除,執行:
$ docker rmi registry.aliyuncs.com/google_containers/kube-apiserver:v1.13.0
$ docker rmi registry.aliyuncs.com/google_containers/kube-controller-manager:v1.13.0
$ docker rmi registry.aliyuncs.com/google_containers/kube-scheduler:v1.13.0
$ docker rmi registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0
$ docker rmi registry.aliyuncs.com/google_containers/pause:3.1
$ docker rmi registry.aliyuncs.com/google_containers/etcd:3.2.24
$ docker rmi registry.aliyuncs.com/google_containers/coredns:1.2.6
1.7 檢視下載的映象列表
執行docker images命令,即可檢視到,這裡結果如下,您下載處理後,結果需要跟這裡的一致:
注:以上操作其實可以寫到一個腳本里,然後自動處理。另外兩個master節點,重複上面的操作下載即可。
[root@master ~]# cat docker.sh
#!/bin/bash
docker tag registry.aliyuncs.com/google_containers/kube-apiserver:v1.13.0 k8s.gcr.io/kube-apiserver:v1.13.0
docker tag registry.aliyuncs.com/google_containers/kube-controller-manager:v1.13.0 k8s.gcr.io/kube-controller-manager:v1.13.0
docker tag registry.aliyuncs.com/google_containers/kube-scheduler:v1.13.0 k8s.gcr.io/kube-scheduler:v1.13.0
docker tag registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0 k8s.gcr.io/kube-proxy:v1.13.0
docker tag registry.aliyuncs.com/google_containers/pause:3.1 k8s.gcr.io/pause:3.1
docker tag registry.aliyuncs.com/google_containers/etcd:3.2.24 k8s.gcr.io/etcd:3.2.24
docker tag registry.aliyuncs.com/google_containers/coredns:1.2.6 k8s.gcr.io/coredns:1.2.6
docker rmi registry.aliyuncs.com/google_containers/kube-apiserver:v1.13.0
docker rmi registry.aliyuncs.com/google_containers/kube-controller-manager:v1.13.0
docker rmi registry.aliyuncs.com/google_containers/kube-scheduler:v1.13.0
docker rmi registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0
docker rmi registry.aliyuncs.com/google_containers/pause:3.1
docker rmi registry.aliyuncs.com/google_containers/etcd:3.2.24
docker rmi registry.aliyuncs.com/google_containers/coredns:1.2.6
五、部署master節點
1. kubeadm init 初始化master節點
$ kubeadm init --kubernetes-version=v1.13.0 --pod-network-cidr=172.22.0.0/16 --apiserver-advertise-address=192.168.1.11
這裡我們定義POD的網段為: 172.22.0.0/16 ,然後api server地址就是master本機IP地址。
2. 初始化成功後,/etc/kubernetes/ 會生成下面檔案
3. 同時最後會生成一句話
kubeadm join 192.168.1.11:6443 --token zs4s82.r9svwuj78jc3px43 --discovery-token-ca-cert-hash sha256:45063078d23b3e8d33ff1d81e903fac16fe6c8096189600c709e3bf0ce051ae8
這個我們記錄下,到時候新增node的時候要用到。
4. 驗證測試
配置kubectl命令
$ mkdir -p /root/.kube
$ cp /etc/kubernetes/admin.conf /root/.kube/config
執行獲取pods列表命令,檢視相關狀態
$ kubectl get pods --all-namespaces
其中coredns pod處於Pending狀態,這個先不管。
我們也可以執行 kubectl get cs 檢視叢集的健康狀態:
六、部署flannel網路 (在所有節點執行上執行)
[root@master ~]$ docker pull docker.io/dockerofwj/flannel
[root@master ~]$ docker tag docker.io/dockerofwj/flannel quay.io/coreos/flannel:v0.10.0-amd64
[root@master ~]$ docker image rm docker.io/dockerofwj/flannel
在master節點執行上執行
[root@master ~]$ echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile
[root@master ~]$ source /etc/profile
[root@master ~]$ echo $KUBECONFIG
[root@master ~]$ sysctl net.bridge.bridge-nf-call-iptables=1
[root@master ~]$ vi kube-flannel.yaml
[檔案內容地址: https://files-cdn.cnblogs.com/files/wenyang321/kube-flannel.yaml.sh]
注意:該yaml檔案內容太長了,我無法很好的貼上進來,所以放到了部落格園的檔案裡,檔案內容使用連結下的內容。 檔名為 “kube-flannel.yaml” 並不是“kube-flannel.yaml.sh”
[root@master ~]$ kubectl apply -f kube-flannel.yaml
[root@master ~]$ kubectl get pods --all-namespaces
把node加入叢集裡
加node計算節點非常簡單,在node上執行:
$ kubeadm join 192.168.1.11:6443 --token zs4s82.r9svwuj78jc3px43 --discovery-token-ca-cert-hash sha256:45063078d23b3e8d33ff1d81e903fac16fe6c8096189600c709e3bf0ce051ae8
兩個節點執行的引數命令一樣,執行完後,我們在master節點上執行 kubectl get nodes 命令檢視node是否正常
[root@master ~]$ kubectl get nodes
七、部署dashboard
部署dashboard之前,我們需要生成證書,不然後面會https訪問登入不了。
1. 生成私鑰和證書籤名請求
$ mkdir -p /var/share/certs
$ cd /var/share/certs
$ openssl genrsa -des3 -passout pass:x -out dashboard.pass.key 2048
$ openssl rsa -passin pass:x -in dashboard.pass.key -out dashboard.key
刪除剛才生成的dashboard.pass.key
$ rm -rf dashboard.pass.key
$ openssl req -new -key dashboard.key -out dashboard.csr
生成了dashboard.csr
生成SSL證書
$ openssl x509 -req -sha256 -days 365 -in dashboard.csr -signkey dashboard.key -out dashboard.crt
dashboard.crt檔案是適用於儀表板和dashboard.key私鑰的證書。
建立secret
$ kubectl create secret generic kubernetes-dashboard-certs --from-file=/var/share/certs -n kube-system
注意/etc/kubernetes/certs 是之前建立crt、csr、key 證書檔案存放的路徑
2. 下載dashboard映象、tag映象(在全部節點上)
$ docker pull registry.cn-hangzhou.aliyuncs.com/kubernete/kubernetes-dashboard-amd64:v1.10.0
$ docker tag registry.cn-hangzhou.aliyuncs.com/kubernete/kubernetes-dashboard-amd64:v1.10.0 k8s.gcr.io/kubernetes-dashboard:v1.10.0
$ docker rmi registry.cn-hangzhou.aliyuncs.com/kubernete/kubernetes-dashboard-amd64:v1.10.0
3. 建立dashboard的pod
[root@master ~]$ vi kubernetes-dashboard.yaml
//# ------------------- Dashboard Service Account ------------------- #
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
---
//# ------------------- Dashboard Role & Role Binding ------------------- #
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
//# Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
//# Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
//# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
verbs: ["get", "update", "delete"]
//# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
//# Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
---
//# ------------------- Dashboard Deployment ------------------- #
kind: Deployment
apiVersion: apps/v1beta2
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
nodeName: master
containers:
- name: kubernetes-dashboard
image: docker.io/mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.1
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
- --token-ttl=5400
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
volumes:
- name: kubernetes-dashboard-certs
hostPath:
path: /var/share/certs
type: Directory
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
// # Comment the following tolerations if Dashboard must not be deployed on master
//# tolerations:
//# - key: node-role.kubernetes.io/master
//# effect: NoSchedule
---
//# ------------------- Dashboard Service ------------------- #
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
ports:
- port: 443
targetPort: 8443
nodePort: 31234
selector:
k8s-app: kubernetes-dashboard
type: NodePort
$ kubectl create -f kubernetes-dashboard.yaml
4. 檢視服務執行情況
$ kubectl get deployment kubernetes-dashboard -n kube-system
$ kubectl --namespace kube-system get pods -o wide
$ kubectl get services kubernetes-dashboard -n kube-system
$ netstat -ntlp|grep 31234
5.配置dashboard-user-role.yaml
在master節點執行
vi dashboard-user-role.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: admin
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
$kubectl create -f dashboard-user-role.yaml
$kubectl describe secret/$(kubectl get secret -nkube-system |grep admin|awk '{print $1}') -nkube-system
複製tocken
6. 開啟dashboard介面並登入
Web訪問 https://192.168.1.11:31234 使用Token登陸