k8s 部署
kubernetes(k8s)的部署有手動部署和 kubeadm 部署的方式. 還有一些簡單的部署方式, 但生產(chǎn)使用主要是使用 kubeadm方式.
以下就介紹 kubeadm 方式部署.
[toc]
處理基礎(chǔ)
修改 hostname
# 名稱可以根據(jù)情況看著設(shè)置
hostnamectl set-hostname k8s-master
# hostnamectl set-hostname k8s-node-01
# hostnamectl set-hostname k8s-node-02
固定 IP 地址
K8S 的服務(wù)器不能使用 dhcp 的類型.
vim /etc/sysconfig/network-scripts/ifcfg-{網(wǎng)卡號}
# 其他的參數(shù)基本不變
BOOTPROTO=static
ONBOOT="yes"
IPADDR="192.168.100.10"
PREFIX="24"
GATEWAY="192.168.100.1"
修改 resolv
如果有需要就修改
# 中國電信, 這個通用. 可以替換成自己本地的.
echo 'nameserver 114.114.114.114' > /etc/resolv.conf
安裝基礎(chǔ)工具包
# 安裝 wget web 請求工具
yum install -y wget
mkdir /etc/yum.repos.d/bak && mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak
# 更新 centos 源
wget -O /etc/yum.repos.d/centos7_base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo
wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
# 刷新緩存
yum clean all && yum makecache
# 安裝 vim telnet 及網(wǎng)絡(luò)工具包.
# 安裝 yum 擴(kuò)展管理工具
yum install -y vim curl telnet net-tools yum-utils device-mapper-persistent-data lvm2
修改 hosts
修改 hosts 原因系為了加速對 github 的訪問速度和訪問失敗問題
vim /etc/hosts
# 如果 IP 發(fā)生變化, 可以重新定位其真實(shí) IP, 不然下面有些 curl 或 get 或者 kubectl apply 可能會失敗
199.232.68.133 raw.githubusercontent.com
199.232.68.133 user-images.githubusercontent.com
199.232.68.133 avatars2.githubusercontent.com
199.232.68.133 avatars1.githubusercontent.com
140.82.114.4 github.com
199.232.69.194 github.global.ssl.fastly.net
140.82.113.9 codeload.github.com
關(guān)閉 Linux 功能
# 停止防火墻
systemctl stop firewalld
# 禁止防火墻自動啟動
systemctl disable firewalld
# 關(guān)閉SELinux(臨時)
setenforce 0
# 永久關(guān)閉SELinux
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
# 關(guān)閉 Linux swap Area(系統(tǒng)交換區(qū))
swapoff -a # -a 將/etc/fstab文件中所有設(shè)置為swap的設(shè)備關(guān)閉
# 永久關(guān)閉 swap area
sed -i 's/.*swap.*/#&/' /etc/fstab
配置網(wǎng)卡轉(zhuǎn)發(fā)
設(shè)置 ipv4 多網(wǎng)卡數(shù)據(jù)包轉(zhuǎn)發(fā)
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p
配置系統(tǒng)內(nèi)核
橋接 IPv4流量傳遞到 iptables 鏈
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness=0
EOF
sysctl --system
sysctl -p
設(shè)置 bridge-nf-call-iptables 為 1
cat /proc/sys/net/bridge/bridge-nf-call-iptables
# 如果是 0 則修改為 1
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
modprobe br_netfilter
echo "modprobe br_netfilter" >> /etc/rc.local
cat <<EOF> /etc/sysconfig/modules/br_netfilter.modules
modprobe br_netfilter
EOF
chmod 755 /etc/sysconfig/modules/br_netfilter.modules
安裝 docker
CRI 使用 docker. 其他的方式介紹請自行搜索, 但因為只要使用了 CRI 或 OCI 標(biāo)準(zhǔn)的容器, 都可以與 K8s 兼容, 即只改變當(dāng)前<安裝 docker>步驟, 其他不需要變動.
RUNTIME
這里的 RUNTIME 主要是概念性的東西, 指的是容器運(yùn)行時要執(zhí)行的東西, 其開源標(biāo)準(zhǔn)為 CRI, 即<容器運(yùn)行時接口>. 更多有關(guān)這方面的介紹可以見<TODO待補(bǔ)充>
支持該標(biāo)準(zhǔn)的主要虛擬化系統(tǒng)有:
- docker
- cri-o
- cri-contranerd
- rkt
- frakti
配置 docker daemon
創(chuàng)建 daemon docker 配置 使用
如果有私庫, 要加上自己的私庫地址.
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://26ujpd31.mirror.aliyuncs.com"],
"exec-opts":["native.cgroupdriver=systemd"],
"iptables":false
}
EOF
私庫添加配置[可選配置]
"insecure-registries":["repo.panda-inner.co"],
安裝 docker
更新 docker 安裝源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
查看可以安裝的版本
yum list docker-ce --showduplicates | sort -r
安裝 docker, 建議使用最新版本, 同時要考慮與 k8s 的兼容度.
# 為了與其他節(jié)點(diǎn)兼容, 當(dāng)前使用 18.06.3 版本
yum install -y docker-ce-19.03.13-3.el7
# 開啟 docker
systemctl enable docker && systemctl start docker && systemctl status docker
安裝 k8s
k8s 的編譯及處理是非常麻煩的事情, 平常使用建議直接使用二進(jìn)制安裝.
這種方式簡單快捷省時省力.
更新 K8s 源
注意, k8s 是 google 開源的服務(wù), 因為一些問題, 我們是不能直接使用原 google 的源的. 不解釋.
使用阿里源, 國內(nèi)訪問速度還是很快的.
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=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
EOF
安裝 k8s
安裝 k8s, 以下操作2選1
安裝最新版本(建議)
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet && systemctl status kubelet
安裝指定版本
這里以 1.12.1 舉例
yum -y install kubectl-1.12.1-0
yum -y install kubelet-1.12.1-0
yum -y install kubeadm-1.12.1-0
systemctl enable kubelet && systemctl start kubelet && systemctl status kubelet
部署 k8s
以下的安裝 master 和 node 將要分開安裝, 上面的命令都是完全相同的.
部署 k8s 直接使用 kubeadm 工具, 這個是官方的 Kubernetes 的自動化部署工作.
部署 k8s 分為 Master 和 Node, Master 的部署工具較為復(fù)雜和麻煩. 在本教程中 Node 只要加入 master 基本可以自動處理.
使用 kubeadm 創(chuàng)建集群
參數(shù)使用 option=args 方式 或 option args 方式
幾個參數(shù)說明:
--kubernetes-version={version} # 集群 k8s 版本
--apiserver-advertise-address={Master-IP} # apiserver 服務(wù)器的 IP 地址, 一般使用 master 做該作用.
--image-repository={倉庫URL} # 由于google無法訪問的原因, 這里使用阿里云的. 如果有自己的倉庫, 直接使用即可, 但一定要包含對應(yīng)版本的基礎(chǔ)組件鏡像, 不然無法完成集群安裝.
--service-cidr={CIDR} # 設(shè)置service的CIDRs,默認(rèn)為 10.96.0.0/12
--pod-network-cidr={CIDR} # 指定 pod 網(wǎng)絡(luò)的 IP 地址范圍. 如果設(shè)置時, k8s 控制中心將自動為每個節(jié)點(diǎn)分配 CIDR. 詳細(xì)介紹請見 pod-network-cidr
--dry-run # 該命令只會將 kubeadm 做的事情輸出到標(biāo)準(zhǔn)輸出中, 但不會實(shí)際執(zhí)行任何命令, 對于了解 kubeadm 都做了什么, 如何運(yùn)行是非常重要的.
kubeadm init --kubernetes-version=1.19.3 \
--apiserver-advertise-address=192.168.135.12 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16
本次執(zhí)行需要消耗比較多的時間, 需要從網(wǎng)絡(luò)中下載鏡像及安裝相關(guān)組件.
當(dāng)安裝完成后會給出反饋出一條命令, 這條命令在后續(xù)的使用中比較重要.
kubeadm join 192.168.100.10:6443 --token ukdlzf.7l82o3p4qelchdxx
--discovery-token-ca-cert-hash sha256:39def206e699bf9211619a1cfbb1d9c2fabf6c438d6481f6c2fac3983c384fe0
安裝 kubectl 工具
kubeadm 安裝完成后, kubectl 就已經(jīng)配置好了, 只需要拿來配置即可直接使用
mkdir -p /root/.kube
cp /etc/kubernetes/admin.conf /root/.kube/config
# 測試
kubectl get nodes
kubectl get cs
部署 Flannel 網(wǎng)絡(luò)
CNI 容器網(wǎng)絡(luò)接口
CNI意為容器網(wǎng)絡(luò)接口,它是一種標(biāo)準(zhǔn)的設(shè)計,為了讓用戶在容器創(chuàng)建或銷毀時都能夠更容易地配置容器網(wǎng)絡(luò)。
CNI 流行插件:
- Flannel
- Calico
- Weave
- Canal
部署 Flannel 網(wǎng)絡(luò)
由于 k8s 已經(jīng)安裝好了, 可以直接使用 K8s 安裝
# 安裝
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 驗證
kubectl get pods -n kube-system | grep flannel
節(jié)點(diǎn)加入集群
執(zhí)行 master init 時返回的命令即可
kubeadm join 192.168.100.10:6443 --token ukdlzf.7l82o3p4qelchdxx \
--discovery-token-ca-cert-hash sha256:39def206e699bf9211619a1cfbb1d9c2fabf6c438d6481f6c2fac3983c384fe0
驗證
待 flannel 安裝完之后, 基礎(chǔ)的 k8s 就已經(jīng)安裝完了. 然后可以來驗證一下.
# 查看節(jié)點(diǎn)狀態(tài)
kubectl get nodes
創(chuàng)建測試 pod
# 創(chuàng)建 NGINX
kubectl create deployment nginx --image=nginx:alpine
# 對外公開端口
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod -n default
kubectl get svc -n default
安裝 Dashboard
DashBoard 是 k8s 的可視化控制臺.
我在這里安裝時遇到了權(quán)限錯誤問題, 但這個并不影響集群的使用, 如果使用 bash 直接管理沒有任何問題.
獲取 yaml 編排文件
# 獲取 dashboard yaml 文件
wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
更新 yaml 內(nèi)容和端口
sed -i 's/k8s.gcr.io/loveone/g' kubernetes-dashboard.yaml
sed -i '/targetPort:/a\ \ \ \ \ \ nodePort: 30001\n\ \ type: NodePort' kubernetes-dashboard.yaml
部署 Dashboard
kubectl create -f kubernetes-dashboard.yaml
查看相關(guān)服務(wù)運(yùn)行狀態(tài)
kubectl get deployment kubernetes-dashboard -n kube-system
kubectl get pods -n kube-system -o wide
kubectl get services -n kube-system
此時訪問 https://192.168.100.10:30001 即可
查看 Dashboard 認(rèn)證令牌
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
更換安全證書
待補(bǔ)充
如果你不考慮安全, 跳過令牌
- 在部署前配置跳過:
vim kubernetes-dashboard.yaml
# 修改 Deployment 下的 spec.template.spec.containers.args
# 增加 - -- enable-skip-login
未修改前

修改后

- 已部署安裝方式
使用方式1修改編排文件
kubectl apply -f kubernetes-dashboard.yaml
- 沒有編排文件但已部署方式
kubectl edit deployment/kubernetes-dashboard -n kube-system
按方式1 增加--enable-skip-login 參數(shù)

之后多了一個 skip 按鈕
更多的
更多的還有 ingress 和其他組件安裝, 在后續(xù)文章中會寫出來
安裝中常見問題
kubeadm安裝k8s 組件controller-manager 和scheduler狀態(tài) Unhealthy
通過kubeadm安裝好kubernetes v1.19.3 查看集群狀態(tài),發(fā)現(xiàn)組件controller-manager 和scheduler狀態(tài) Unhealthy
查看組件狀態(tài)
kubectl get cs
NAME STATUS MESSAGE ERROR
controller-manager Unhealthy Get http://127.0.0.1:10252/healthz: dial tcp 127.0.0.1:10252: connect: connection refused
scheduler Unhealthy Get http://127.0.0.1:10251/healthz: dial tcp 127.0.0.1:10251: connect: connection refused
etcd-0 Healthy {"health":"true"}
通過 ss 命令檢查接口也未監(jiān)聽.
ss -ant | grep 10251
ss -ant | grep 10252
查看組件運(yùn)行正常
kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
... # 其他的 pod 省略
kube-apiserver-kube-master 1/1 Running 0 23m
kube-scheduler-kube-master 1/1 Running 0 23m
... # 其他的 pod 省略
kube-scheduler和kube-controller-manager組件配置是否禁用了非安全端口
vim /etc/kubernetes/manifests/kube-scheduler.yaml
vim /etc/kubernetes/manifests/kube-controller-manager.yaml
--port=0
如果有該配置, 將其去掉.
重啟 kubelet
systemctl restart kubelet
再檢查組件時, 已恢復(fù)正常.
kubectl get cs
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true"}
參考解決:https://www.gjie.cn/2618.html
kubeadm join token 失效
生成需要的 token
以下命令在 master 上執(zhí)行
adm_token=kubeadm token generate
kubeadm token create $adm_token --print-join-command --ttl=0
命令運(yùn)行完成后會再次輸出類似以下的東西
kubeadm join 192.168.100.10:6443 --token wd2yn5.9att0md62b2y5c04 \
--discovery-token-ca-cert-hash sha256:d32051303db2ccd07eb08b754e797cc58e057021a838e632cd172220cae645ec
將該命令拿到 node 上去執(zhí)行即可
錯誤 version 不匹配
在執(zhí)行時, kubeadm init 或 join 時, kubelet 的版本 與 kubeadm 執(zhí)行時的版本出現(xiàn)不兼容將會報此錯誤, 將 kubeadm init --kubernetes-version 的版本與 kubelet 版本完全相同, 盡量保持 node 版本與 master 版本相同.
Connecting raw.githubusercontent.com failed
Resolving raw.githubusercontent.com (raw.githubusercontent.com)...
151.101.228.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.228.133|:443... failed: Connection refused.
這個錯誤是因為墻的問題, 將域名與 IP 在 hosts 中綁定上就可以了.
# hosts 文件
199.232.68.133 raw.githubusercontent.com
199.232.68.133 user-images.githubusercontent.com
199.232.68.133 avatars2.githubusercontent.com
199.232.68.133 avatars1.githubusercontent.com
140.82.114.4 github.com
199.232.69.194 github.global.ssl.fastly.net
140.82.113.9 codeload.github.com
部署組件失敗, 無法下載組件
這個原因是因為 master 的 --image-url 使用的是無法使用的或 node 無法獲取到基礎(chǔ)組件.
自己摘取組件鏡像到 docker 本地 image.
將以下保存到一個 sh 中. 假設(shè)名稱叫:pull_k8s_img.sh
#!/bin/bash
# 注意自己的版本號
images=`kubeadm config images list --kubernetes-version=v1.19.3|awk -F '/' '{print $2}'`
for image in $images
do
docker pull keveon/$image
if [ $? -eq 0 ];then
docker tag keveon/$image k8s.gcr.io/$image
docker rmi keveon/$image
else
echo "ERROR: 下載鏡像報錯,$image"
fi
done
執(zhí)行
chmod +x pull_k8s_img.sh && bash ./pull_k8s_img.sh