官方中文帮助文档:https://kubernetes.io/zh-cn/docs/home/
Docker和K8s安装
集群安装之前,主机环境需要初始化的步骤:
各主机需要预设的系统环境如下:
(1)借助于chronyd服务(程序包名称chrony)设定各节点时间精确同步;
apt install chrony
systemctl start chrony.service
(2)通过DNS完成各节点的主机名称解析;
(3)各节点禁用所有的Swap设备;
swapoff -a
systemctl --type swap
systemctl mask SWAP_DEV
(4)各节点禁用默认配置的iptables防火墙服务;
ufw disable
ufw status
1.docker安装
ubuntu22.04
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get -y update
列出可用的 Docker 版本
# Debian/Ubuntu
apt-cache madison docker-ce
# CentOS/RHEL
yum list docker-ce --showduplicates | sort -r
sudo apt-get -y install docker-ce=5:23.0.5-1~ubuntu.22.04~jammy
2.安装cri-dockerd
下载地址:https://github.com/Mirantis/cri-dockerd
curl -LO https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.1/cri-dockerd_0.3.1.3-0.ubuntu-jammy_amd64.deb
dpkg -i ./cri-dockerd_0.3.1.3-0.ubuntu-jammy_amd64.deb
systemctl status cri-docker.service
3.安装kubelet、kubeadm、kubectl
apt-get update && apt-get install -y apt-transport-https
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.27/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.27/deb/ /" |
tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt install -y kubelet kubeadm kubectl
安装指定版本
apt-get install -y kubelet-1.26.4-00 kubeadm=1.26.4-00 kubectl=1.26.4-00
systemctl enable kubelet
4.整合kubelet和cri-dockerd
1.配置cri-dockerd
vim /lib/systemd/system/cri-docker.service
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --cni-bin-dir=/opt/cni/bin --cni-cache-dir=/var/lib/cni/cache --cni-conf-dir=/etc/cni/net.d
systemctl daemon-reload && systemctl restart cri-docker.service
2.配置kubelet
编辑文件/etc/sysconfig/kubelet
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=/run/cri-dockerd.sock"
集群节点部署
kubeadm config images list
1.配置国内镜像站
配置国内的阿里云Mirror站点下载Image
kubeadm config images list --image-repository=registry.aliyuncs.com/google_containers
docker image pull registry.aliyuncs.com/google_containers/pause:3.6
docker image tag registry.aliyuncs.com/google_containers/pause:3.6 registry.k8s.io/pause:3.6
kubeadm config images pull --cri-socket unix:///run/cri-dockerd.sock --image-repository=registry.aliyuncs.com/google_containers
registry.aliyuncs.com/google_containers/kube-apiserver:v1.27.16
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.27.16
registry.aliyuncs.com/google_containers/kube-scheduler:v1.27.16
registry.aliyuncs.com/google_containers/kube-proxy:v1.27.16
registry.aliyuncs.com/google_containers/pause:3.9
registry.aliyuncs.com/google_containers/etcd:3.5.12-0
registry.aliyuncs.com/google_containers/coredns:v1.10.1
2.方式一:命令初始化
1.kubeadm init
kubeadm init \
--control-plane-endpoint "kubeapi.lei.com" \
--kubernetes-version=v1.27.16 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--token-ttl=0 \
--cri-socket unix:///run/cri-dockerd.sock \
--upload-certs \
--image-repository=registry.aliyuncs.com/google_containers
OK 搞定! initialized successfully!
2.保存初始化token
Your Kubernetes control-plane 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
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
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 the control-plane node running the following command on each as root:
kubeadm join kubeapi.lei.com:6443 --token djh1ki.bmtathyph8hn0h4o \
--discovery-token-ca-cert-hash sha256:59996c44f538ef715a94cb7d2f46e55f2db6653f41cba56368389cf726734772 \
--control-plane --certificate-key 2d8b0af288b5433cb02b1c8f4ded5439434c81494ab3ac86c0b716871dca6fdd
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join kubeapi.lei.com:6443 --token djh1ki.bmtathyph8hn0h4o \
--discovery-token-ca-cert-hash sha256:59996c44f538ef715a94cb7d2f46e55f2db6653f41cba56368389cf726734772
3.拷贝/etc/kubernetes/admin.conf
准备配置文件/etc/kubernetes/admin.conf
root@master01:~# mkdir .kube
root@master01:~# cp /etc/kubernetes/admin.conf .kube/config
出现以下配置信息说明配置文件加载成功!
kubectl config view --raw
#查看最原始的信息,私钥证书等
4.部署网络插件
https://github.com/flannel-io/flannel
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
查看网络插件是否部署成功
kubectl get pods -n kube-flannel
这里要多等一会儿,我第一次等了31m,第二次等了28m.
5.kubectl get nodes
查看集群节点,我的master01已经ready了
kubectl get nodes
kubectl get pods -n kube-system
status都是running状态时,就表示已经就绪了。
6.添加集群高可用master节点
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join kubeapi.lei.com:6443 --token ggvxkc.proki24n1vumyjno \
--discovery-token-ca-cert-hash sha256:2c1b8a80dc56b42091798eac991376316290c9baf15507aaade00fab7707d952 \
--control-plane --certificate-key ecab8bceeb40704066860e9b60219e4d9d98ce0d8f2d34ffc7746ddd54669453
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
7.添加worker节点
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join kubeapi.lei.com:6443 --token ggvxkc.proki24n1vumyjno \
--discovery-token-ca-cert-hash sha256:2c1b8a80dc56b42091798eac991376316290c9baf15507aaade00fab7707d952
在node1节点上执行以下命令
kubeadm join kubeapi.lei.com:6443 --token ggvxkc.proki24n1vumyjno \
--discovery-token-ca-cert-hash sha256:2c1b8a80dc56b42091798eac991376316290c9baf15507aaade00fab7707d952 --cri-socket unix:///run/cri-dockerd.sock
新增第一个node01节点到集群中
查看集群节点
解决woker节点一直NotReady
添加node01和node02后它们的status一直是NotReady,苦思良久,不得其解。
1.主机名不能解析
这是最白痴的错误,无意中看到了这条消息“unable to resolve host node01: Name or service not known”不能解析主机名,哦哦。原来是hosts文件配置有误。
node01的主机名没有有映射到相应的主机上ip上
vim /etc/hosts
10.0.0.206 k8s-master01.lei.com k8s-master01 kubeapi.lei.com
10.0.0.207 k8s-node01.lei.com k8s-node01
10.0.0.208 k8s-node02.lei.com k8s-node02
10.0.0.209 k8s-node03.lei.com k8s-node03
2.woker节点网络插件异常
node02节点添加
node02不知道为啥很快就ready,node01和node03就是死活都不ready啊,我郁闷啊·····。
后来还是寻见了端倪,还是网络插件flannel的问题。
于是将node02的两个flannel相关镜像,拷贝到node01和node03上吧。
3.拷贝Docker镜像的步骤
方法1:使用 docker save 和 docker load
第一步:docker save -o my_image.tar my_image:latest
第二步:scp image.tar user@target_host:/path/to/destination
第三步:docker load -i /path/to/destination/image.tar
第一步:保存镜像为 tar 文件
保存镜像为 tar 文件在源主机上,将 Docker镜像保存为一个 .tar 文件:
docker save -o image.tar flannel/flannel:v0.25.6
第二步:传输镜像文件
传输镜像文件,你可以使用 scp、rsync 或其他工具将镜像文件传输到目标主机。
scp ./image.tar root@10.0.0.207:/root
第三步:在目标主机上加载镜像
在目标主机上加载镜像,通过 docker load 将镜像重新加载到 Docker:
docker load -i ./image.tar
node03节点添加
8.查看所有节点是否Ready
乖乖啊,终于都Ready了。折磨了我一天一夜。
9.kubeadm reset
如果初始化不成功,可能需要重置配置,可使用以下命令
重置节点:
kubeadm reset 命令
kubeadm reset --cri-socket unix:///run/cri-dockerd.sock
rm -rf /etc/kubernetes/ /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni /etc/cni/net.d /var/lib/etcd /run/flannel/
从集群中删除节点:
kubectl delete node <node-name>
部署Add-ons
部署OpenELB
OpenELB 是一个开源的云原生负载均衡器实现,可以在基于裸金属服务器、边缘以及虚拟化的 Kubernetes 环境中使用 LoadBalancer 类型的 Service 对外暴露服务。
kubectl apply -f https://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml
报错“raw.githubusercontent.com was refused …” 这个错误通常表示无法连接到 raw.githubusercontent.com,这就会导致“ImagePullBackOff”
我的解决办法是设置了Google的DNS服务器8.8.8.8
解决 ImagePullBackOff
修改/etc/resolv.conf的nameserver为8.8.8.8后,status都为Running了
认openelb-manager Pod已经处于Running状态,且容器已经Ready。
此时openelb已经部署完了。
配置示例:layer2模式
vim eip-pool.yaml
apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
name: eip-pool
annotations:
eip.openelb.kubesphere.io/is-default-eip: "true"
spec:
address: 10.0.0.51-10.0.0.80
protocol: layer2
interface: ens33
disable: false
kubectl apply -f eip-pool.yaml
看到一下信息说明部署完成
创建Deployment和LoadBalancer Service,测试地址池是否已经能正常向Service分配LoadBalancer IP。
kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=2
部署Ingress Nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/cloud/deploy.yaml
运行如下命令,确认部署的结果状态。后面的命令结果中,ingress-nginx-controller相关的Pod转为Runing状态,即为部署成功。
kubectl get pods -n ingress-nginx
运行下面的命令,查看相关Service的状态信息。如果部署了OpenELB,其External-IP应该可以获得EIP可用分配范围内的一个地址,类似如下命令及其结果所示。
kubectl get services -n ingress-nginx
我这里External-IP是pending。后续跟进,先前进。
部署Metrics Server
kubectl apply -f https://raw.githubusercontent.com/iKubernetes/learning-k8s/master/metrics-server/components.yaml
运行如下命令,确认部署的结果状态。后面的命令结果中,metrics-server相关的Pod转为Runing状态,即为部署成功。
kubectl get pods -n kube-system -l k8s-app=metrics-server
运行下面的命令,查看相关Service的状态信息。
kubectl get services -n kube-system -l k8s-app=metrics-server
部署Kuboard
kubectl apply -f https://raw.githubusercontent.com/iKubernetes/learning-k8s/master/Kuboard/deploy.yaml
部署Nginx
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
一条命令整个集群的四台机器同时部署nginx成功了
再次解决 ImagePullBackOff
服了这个ImagePullBackOff状态,上面已经配置了Google的DNS,主机上使用curl和ping都能正常响应,但这些个镜像就是拉不下来。反反复复配置/etc/resolv.conf,就是不生效。浪费老子的生命~~
这次解决过程,我轮番上阵了三个方案
1.注册dockerhub,使用用户名登录到www.docker.com/products/docker-hub
2.配置DNS到/etc/netplan/00-installer-config.yaml
3.配置阿里云镜像加速器
最后上述方案都用上了,也不知道具体是哪一项生效了,反正配置完就能正常pull镜像了。奇怪!
遇到的 ImagePullBackOff 通常是由于 Kubernetes 无法拉取指定的镜像。你可以尝试以下几步解决:
1.检查镜像名称:确认镜像名称和标签是否正确。
2.认证问题:确保你有权限访问该镜像。如果使用私有镜像仓库,需要配置正确的凭证。
3.网络问题:确保你的集群可以访问镜像仓库,检查网络连接。
4.查看事件:使用 kubectl describe pod <pod-name> 命令查看详细错误信息。
1.查看详细错误
kubectl describe pod nginx-77b4fdf86c-bbmf2
事件信息显示“Error response from daemon: Get “https://registry-1.docker.io/v2/”:”
当使用curl访问这个地址时,提示没有权限访问,(实际上我登录了dockerhub后,镜像倒是拉取成功了,但这个地址还是报错unauthorized,反正错误奇奇怪怪,解决的也糊糊涂涂).
2.登录dockerhub
https://www.docker.com/products/docker-hub/
于是我注册了dockerhub的用户,在节点上登录了
再次查看事件信息时,就能成功了pull镜像了。
反正登录了dockerhub后nginx就Running了
3.配置DNS
在/etc/resolv.conf里配置nameservers,会被系统重置掉(后面补充原因)。
还是在/etc/netplan/00-installer-config.yaml 配置nameservers吧
root@k8s-master01:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
ethernets:
ens33:
dhcp4: no
addresses: [10.0.0.206/24]
gateway4: 10.0.0.2
nameservers:
addresses:
- 180.76.76.76
- 8.8.8.8
version: 2
renderer: NetworkManager
3.5 配置 systemd-resolved
在 Ubuntu 中,/etc/resolv.conf 文件通常由网络管理工具(如 NetworkManager 或 systemd-resolved)自动生成,因此手动更改会在系统重启或网络服务重启时被重置。要持久化 DNS 配置,可以通过配置 systemd-resolved方法实现:
Ubuntu 默认使用 systemd-resolved 服务管理 DNS,可以在其配置文件中指定 DNS 服务器:
第一步
编辑 /etc/systemd/resolved.conf 文件,取消注释 DNS= 和 FallbackDNS=,并添加所需的 DNS 地址:
[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1 1.0.0.1
第二步
重启 systemd-resolved 服务以应用更改:
sudo systemctl restart systemd-resolved
第三步
确保 /etc/resolv.conf 文件是指向 systemd-resolved 生成的文件。执行以下命令以创建正确的符号链接:
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
配置完以上步骤,你再怎么重启系统,/etc/resolv.conf都不会被重置了。
4.跟踪服务日志
以上配置完成后,需要restart 重启docker和kubelet的service服务。如果起不来,可以使用以下命令跟踪日志。
使用以下命令跟踪服务日志,可以找到服务启动失败的原因
sudo journalctl -u docker.service -f
5.阿里云镜像加速器
通过过修改daemon配置文件/etc/docker/daemon.json来使用加速器。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
6.如果防火墙启用,允许 Docker 的网络端口:
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp
任意节点执行kubectl
目前worker节点上是执行不了kubectl命令的
1.拷贝/etc/kubernetes/admin.conf
将master节点中/etc/kubernetes/admin.conf拷贝到需要运行的服务器的/etc/kubernetes目录中
scp /etc/kubernetes/admin.conf root@k8s-node01:/etc/kubernetes
2.配置环境变量
2.在对应的服务器上配置环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
之后就可以在node01节点上执行kubectl命令了。其他节点以此类推