前言
最近為某客戶搭建內網的信創環境下的x8s集群,走了一些彎路,客戶提供的環境完全與互聯網分離,通過yum、apt這些直接拉依賴就別想了,用的操作系統和cpu都是國產版本,好在仍然是x86的,不是其他架構,這里把完整搭建過程記錄一下
準備工作
- 準備搭建k8s集群主機
- 一臺可連接互聯網的麒麟v10系統虛機,單核cpu 1g內存的配置就行,這個如果客戶方能給開出來最好,沒有的話,去https://eco.kylinos.cn/注冊下載麒麟操作系統的鏡像,安裝virtualbox搭建一個麒麟v10虛擬機,記著網絡這塊選雙網卡nat+hostonly,否則沒法同時連外網+ssh
- k8s版本這里選擇了1.23.6
安裝包下載
docker安裝包
?從Index of linux/static/stable/x86_64/https://download.docker.com/linux/static/stable/x86_64/Index of linux/static/stable/x86_64/?下載,建議選擇23、24版本,不建議18ce,有兼容問題
harbor安裝包
?(如果客戶方提供了內網的鏡像倉庫,這一步跳過),harbor需要兩個文件,分別是:docker-compose(https://github.com/docker/compose/releases),harbor離線包(https://github.com/goharbor/harbor/releases),2.5.1版本就行
k8s的rpm安裝包
登錄那臺能連互聯網的麒麟v10系統的虛擬機
增加如下yum repo:
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[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安裝包:
yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6 kubernetes-cni-0.8.7 --downloadonly --downloaddir /opt/rpm
這里安裝包版本選擇1.23.6,不使用默認高版本的k8s,因為1.24之后k8s的引擎不再使用docker,而是containerd
下載后的安裝包除了幾個kub*之外,應該還會有其他依賴包
flanneld安裝包
flannel是k8s的網絡通信組件,必須安裝
在https://github.com/flannel-io/flannel/releases/下載,這里選擇的是v0.21.0,注意要下載的文件有3個:
flanneld-amd64
flanneld-v0.21.0-amd64.docker
kube-flannel.yml
安裝環境分配
模擬環境分配:
主機名 | ip | 角色 |
qlk8s-master | 192.168.15.21 | k8s主節點 |
qlk8s-worker1 | 192.168.15.22 | k8s work節點 |
qlk8s-worker2 | 192.168.15.23 | k8s work節點 |
qlk8s-worker3 | 192.168.15.24 | k8s work節點,harbor鏡像服務器 |
注意:很多情況下,每臺機器除了自身內網ip外還會有一個浮動ip,也就是供外部訪問的ip,下面所有操作不做特別說明的情況下默認都是自身內網ip
配置主機名
所有主機修改主機名和hosts文件
hostnamectl set-hostname qlk8s-master
修改/etc/hosts文件,增加每臺主機的配置如:
192.168.15.21 qlk8s-master
192.168.15.22 qlk8s-worker1
192.168.15.23 qlk8s-worker2
192.168.15.24 qlk8s-worker3
所有主機基礎配置
掛載云硬盤
(如果有)請先掛載附帶的云硬盤到/data目錄
關閉防火墻
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
關閉swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
內核ip調整
modprobe br_netfilter
touch /etc/sysctl.d/k8s.conf
vi /etc/sysctl.d/k8s.conf
# 增加內容:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1#執行
sysctl -p /etc/sysctl.d/k8s.conf
組件安裝
安裝docker
1.上傳docker安裝包文件到每臺主機
2.解壓docker文件
tar -xf docker-24.0.1.tgz
3.復制到bin
sudo cp docker/* /usr/bin/
#查詢bin功能正常
docker -v
4.創建目錄
docker需要更多的硬盤空間保證運行,最好不要放在系統盤,如果額外掛載的云硬盤,比如在/data目錄,提前做好關聯
mkdir /data/docker
ln -s /data/docekr /var/lib/docker
5.創建服務
vi /etc/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always[Install]
WantedBy=multi-user.target
6.增加配置文件
mkdir /etc/docker/vi /etc/docker/daemon.json#寫入
{"insecure-registries": [],"registry-mirrors": [],"debug": false,"experimental": false,"exec-opts": ["native.cgroupdriver=systemd"]
}
7.啟動服務
systemctl daemon-reload
systemctl enable --now docker
systemctl start docker
安裝harbor
(如果客戶方提供了內網的鏡像倉庫,這一步跳過)
1.登錄規劃好的harbor服務器主機,并上傳2個安裝包
2.安裝docker-compose
docker-compose的文件只有一個二進制文件,直接重命名文件為docker-compose,復制到/usr/local/bin,并使用chmod a+x?/usr/local/bin/docker-compose 賦予權限
3.解壓harbor
tar -xvf harbor-online-installer-v2.5.1.tgz
4.修改harbor.yml文件
cp harbor.yml.tmpl harbor.yml
修改hostname內容為harbor.qlk8s.com
注釋掉https有關的配置項
修改data_volume,指定為/data/harbor,(或本機的存儲硬盤目錄),否則harbor會把鏡像數據放在系統盤下
5.啟動harbor
./install.sh
完成后使用命令驗證:
docker-compose ps
6.驗證
外部先配置hosts,如:192.168.15.24?harbor.qlk8s.com
瀏覽器訪問http://harbor.qlk8s.com,默認用戶名密碼admin Harbor12345,注意必須使用域名訪問,否則會出現跨域錯誤
在harbor的web端創建目錄images,注意類型為公開
7.docker修改
- 登錄所有主機,修改/etc/hosts,增加192.168.15.24?
- 修改docker配置并重啟
vi /etc/docker/daemon.json#寫入 {"insecure-registries": [harbor.qlk8s.com],"registry-mirrors": [harbor.qlk8s.com],"debug": false,"experimental": false,"exec-opts": ["native.cgroupdriver=systemd"] }#重啟 systemctl restart docker
8.docker客戶端驗證
docker login harbor.qlk8s.com
#輸入用戶名密碼
?安裝k8s基礎服務
1.登錄待安裝k8s的所有主機,將從麒麟外網虛擬機上yum下載的文件統一上傳,并放在一個/opt/k8srpm目錄下
2.安裝rpm
cd /opt/k8srpm
rpm -ivh *.rpm
安裝過程中如果錯誤,找不到依賴,可以單獨執行rpm -ivh試試,把同時依賴的文件放在一起執行,如:rpm -ivh?kubelet-1.23.6-0.x86_64.rpm?kubernetes-cni-0.8.7-0.x86_64
3.配置服務
systemctl enable kubelet
echo "source <(kubectl completion bash)" >> ~/.bash_profile
source ~/.bash_profile
systemctl start kubelet
安裝flannel
安裝網絡flannel插件,flannel是k8s的通信組件必須安裝。
把flanneld-amd64和kube-flannel.yml上傳到每臺機器上,做如下操作
sudo mkdir /opt/bin
sudo cp flanneld-amd64 /opt/bin/flanneld
sudo chmod +x /opt/bin/flanneld
鏡像下載
k8s本身的服務都是以鏡像方式提供,都在外網的docker.io倉庫,可以指定阿里云等倉庫,但是如果不能連接互聯網,就必須提前下載
1.獲取鏡像列表
執行如下,命令,獲取依賴的全部鏡像列表
kubeadm config images list
2.獲取鏡像列表
找一臺連接互聯網并安裝了docker的主機,找到上面所有鏡像的可下載地址,進行下載,并打包為一個k8simage.tar
docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6
docker pull registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6
docker pull registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6
docker pull registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6
docker pull registry.aliyuncs.com/google_containers/pause:3.6
docker pull registry.aliyuncs.com/google_containers/etcd:3.5.1-0docker save -o k8simages.tar registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6 registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6 registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6 registry.aliyuncs.com/google_containers/pause:3.6 registry.aliyuncs.com/google_containers/etcd:3.5.1-0
獲取flannel相關鏡像,flannel也需要相關鏡像,必須一塊獲取
flannel包含兩個插件,一個是flanneld自身,另一個是plugin,flanneld自身的鏡像已經包含在下載鏈接了,flanneld-v0.21.0-amd64.docker就是,另一個plugin必須下載
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.1.2docker save -o flannel-cni-plugin.v1.1.2.tar swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.1.2
3.鏡像導入
這一步要把剛才下載的鏡像導入到待部署環境的鏡像倉庫和docker
先把剛才導出的k8simages.tar、flannel-cni-plugin.v1.1.2.tar、flanneld-v0.21.0-amd64.docker,3個文件上傳到部署環境的任意一臺主機
導入文件
docker load -i k8simages.tar
docker load -i flannel-cni-plugin.v1.1.2.tar
docker load -i flanneld-v0.21.0-amd64.docker
修改鏡像名稱
docker tag registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6 harbor.qlk8s.com/images/kube-apiserver:v1.23.6
docker tag registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6 harbor.qlk8s.com/images/kube-controller-manager:v1.23.6
docker tag registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6 harbor.qlk8s.com/images/kube-scheduler:v1.23.6
docker tag registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6 harbor.qlk8s.com/images/kube-proxy:v1.23.6
docker tag registry.aliyuncs.com/google_containers/etcd:3.5.1-0 harbor.qlk8s.com/images/etcd3.5.1-0
docker tag registry.aliyuncs.com/google_containers/etcd:3.5.1-0 harbor.qlk8s.com/images/etcd:3.5.1-0
docker tag registry.aliyuncs.com/google_containers/coredns:v1.8.6 harbor.qlk8s.com/images/coredns:v1.8.6
docker tag registry.aliyuncs.com/google_containers/pause:3.6 harbor.qlk8s.com/images/pause:3.6
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.1.2 harbor.qlk8s.com/images/flannel-cni-plugin:v1.1.2
docker tag quay.io/coreos/flannel:v0.21.0-amd64 harbor.qlk8s.com/images/flannel/flannel:v0.21.0
上傳鏡像到鏡像倉庫
docker push harbor.qlk8s.com/images/coredns:v1.9.3
docker push harbor.qlk8s.com/images/kube-apiserver:v1.23.6
docker push harbor.qlk8s.com/images/kube-controller-manager:v1.23.6
docker push harbor.qlk8s.com/images/kube-scheduler:v1.23.6
docker push harbor.qlk8s.com/images/kube-proxy:v1.23.6
docker push harbor.qlk8s.com/images/etcd:3.5.1-0
docker push harbor.qlk8s.com/images/pause:3.6
docker push harbor.qlk8s.com/images/flannel-cni-plugin:v1.1.2
docker push harbor.qlk8s.com/images/flannel/flannel:v0.21.0
flannel的鏡像要單獨處理一下,避免運行的時候找不到
登錄每臺待部署的主機
docker pull harbor.qlk8s.com/images/flannel-cni-plugin:v1.1.2
docker tag harbor.qlk8s.com/images/flannel-cni-plugin:v1.1.2 docker.io/flannel/flannel-cni-plugin:v1.1.2
docker pull harbor.qlk8s.com/images/flannel/flannel:v0.21.0
docker tag harbor.qlk8s.com/images/flannel/flannel:v0.21.0 docker.io/flannel/flannel:v0.21.0
master節點搭建
下面開始針對k8s每個節點的搭建
導出并修改配置文件
登錄規劃為節點的master主機,執行如下命令,導出配置文件
kubeadm config print init-defaults > kubeadm-init.yaml
修改kubeadm-init.yaml的幾個參數:
advertiseAddress改為master節點本機ip地址
kubernetesVersion改為1.23.6
imageRespository改為harbor.qlk8s.com/images
執行初始化
kubeadm init --config kubeadm-init.yaml --v=5
注意觀察這一步輸出的日志,如果成功,最下方會有一個類似如下命令的輸出:
kubeadm join x.x.x.x:6443 --token kbkagt.5ylgk5ylzfemzpq7 \--discovery-token-ca-cert-hash sha256:293cb244a8df56a6eb2db9c4c92bcb3af6558e5a522fd79790c80361d8910572 \
記著把這一段kubeadm init輸出的命令保存,后面需要用到
如果這一步失敗,后面需要重做的話,先執行
kubeadm reset -f
權限配置
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/configmkdir /run/flannel
cd /run/flannel
touch subnet.env
vi subnet.env#寫入
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true#重啟服務
systemctl restart kubelet.service
配置flannel組件和網絡
執行如下命令
kubectl apply -f kube-flannel.yml
修改文件/etc/kubernetes/manifests/kube-controller-manager.yaml
其中的spec.containers.command下加入
- --allocate-node-cidrs=true
- --cluster-cidr=10.244.0.0/16
執行生效
kubectl taint nodes --all node-role.kubernetes.io/master-
systemctl restart kubelet.service
完成master配置
使用命令kubectl get pod -A
查看結果,待所有pod為running狀態則為執行成功
如果有pod為pending狀態,注意用kubectl get nodes命令看一下,可能當前master為NotReady狀態了,這時候用journalctl -xefu kubelet看看日志,看看是不是有flannel的鏡像沒有拉下來,如果有的話看看前面的鏡像下載導入部分的操作是否完成
worker節點搭建
登錄每一臺worker節點主機
執行剛才在master完成kubeadm init后取得的join命令
使用命令kubectl get nodes
當節點為ready后代表正常
可以使用label命令修改節點role
kubectl label node qlk8s-master kubernetes.io/role=master --overwrite
到此為止,加入每一臺主機后操作后,k8s集群的基本搭建完成
ingress-nginx安裝
ingress-nginx是k8s的對外服務提供,這里一塊安裝上
選擇版本
版本使用v1.4.0版本,因為ingress與k8s的版本有對應關系,v1.4.0與1.23是可以兼容的
下載配置文件
https://github.com/kubernetes/ingress-nginx/blob/controller-v1.4.0/deploy/static/provider/cloud/deploy.yaml
鏡像下載并導出
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.4.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10fdocker save -o ingress-nginx.tar registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.4.0 registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f
導入鏡像
登錄master主機,先上傳鏡像
docker load -i ingress-nginx.tar
修改并上傳到鏡像倉庫
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.4.0 harbor.qlk8s.com/images/ingress-nginx/controller:v1.4.0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f harbor.qlk8s.com/images/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c34docker push harbor.qlk8s.com/images/ingress-nginx/controller:v1.4.0
docker push harbor.qlk8s.com/images/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c34
修改配置文件
上傳deply.yml文件到master節點
文件中搜索image,修改所有鏡像地址,改成前面配置的harbor.qlk8s.com/images前綴倉庫
把文件中spec:下的4給內容注釋掉
type: LoadBalancerexternalTrafficPolicy:LocalipFamilyPolicy:SingleStackipFamilies:-IPv4
Deployment的ports下面,http和https,下面各增加一個hostPort:端口號,端口號自己定,作為暴露在外的訪問地址
執行安裝
運行如下命令即可
kubectl apply -f deploy.yaml
通過kubectl get all -n ingress-nginx,查看所有狀態正常即為安裝成功
dashboard安裝
作為安裝成功后的一個例子,裝一個dashboard監控看看效果,這里使用2.5.1版
下載文件
下載配置文件https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml
下載鏡像
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/kubernetesui/dashboard:v2.5.1
docker pull registry.aliyuncs.com/google_containers/metrics-scraper:v1.0.7docker save -o dashboard.tar swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/kubernetesui/dashboard:v2.5.1 registry.aliyuncs.com/google_containers/metrics-scraper:v1.0.7
上傳鏡像到部署環境
docker load -i dashboard.tar
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/kubernetesui/dashboard:v2.5.1 harbor.qlk8s.com/images/dashboard:v2.5.1
docker tag registry.aliyuncs.com/google_containers/metrics-scraper:v1.0.7 harbor.qlk8s.com/images/metrics-scraper:v1.0.7docker push harbor.qlk8s.com/images/dashboard:v2.5.1
docker push harbor.qlk8s.com/images/metrics-scraper:v1.0.7
修改配置文件
修改recommended.yml里面有關image的內容,改成鏡像倉庫的實際地址
部署dashboard
執行命令
kubectl apply -f recommended.yaml
用kubectl get pod -A 查看pod都running即為成功
授權創建用戶
kubectl create serviceaccount dashboard-admin -nkube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
配置ingress規則
生產證書
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout kube-dashboard.key -out kube-dashboard.crt -subj "/CN=dashboard.qlk8s.com/O=k8s.dashboard.local"kubectl create secret tls dashboard-tls --key kube-dashboard.key --cert kube-dashboard.crt -n kubernetes-dashboard
vi ingress-dashboard.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: dashboard-ingressnamespace: kubernetes-dashboardannotations:nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:ingressClassName: "nginx"tls:- hosts:- dashboard.qlk8s.comsecretName: dashboard-tlsrules:- host: dashboard.qlk8s.comhttp:paths:- path: /pathType: Prefixbackend: service:name: kubernetes-dashboardport:number: 443
執行策略
kubectl apply -f ingress-dashboard.yaml
訪問
使用kubectl get pod -ningress-nginx,找到ingress controller的pod
使用 kubectl describe pod <pod名稱> -ningress-nginx,找出ingress所在的節點
配置訪問端的hosts,ingress所在主機ip(如果在外網使用浮動ip訪問,應當配置浮動ip)?dashboard.qlk8s.com
訪問測試https://dashboard.qlk8s.com:<端口號>,端口號為之前指定過的hostPort
登錄的是需要使用token,通過如下方式獲取
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
在界面輸入token,訪問測試成功即完成全部安裝過程