一、kubernetes+docker整合Kubernetes 文档 | Kubernetes
https://kubernetes.io/zh-cn/docs/home/
前置条件 :准备两台虚拟机:192.168.63.149 k8s master1节点
192.168.63.150 k8s node1节点
本次部署版本:centos:7.9+docker:19.03.9+kubeadm:1.20.4+Calico:v3.20(或Flanneld v0.15.1)+dashboard:v2.2.0
在master1、node1节点进行如下前置配置
# 编辑网卡配置文件,ens33是你的网卡名,根据实际修改
vi /etc/sysconfig/network-scripts/ifcfg-ens33
# 查看配置是否正确
cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static" # 使用静态IP
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="6f45d4ba-25db-4de7-b0e8-5f2731b3c2d9"
DEVICE="ens33"
ONBOOT="yes" # 开机自启网卡
IPADDR0=192.168.63.149 # 本机静态IP
PREFIX0=24 # 子网掩码24位
GATEWAY0=192.168.63.2 # 网关
DNS1=114.114.114.114 # 首选DNS
DNS2=8.8.8.8 # 备用DNS
# 重启网络服务使IP生效
systemctl restart network
# 测试网络连通性
ping www.baidu.com
# 下载阿里云CentOS 7基础源
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# 清空原有yum缓存
yum clean all
# 生成新的yum缓存
yum makecache
# 写入hosts解析,master和node都要配置一致
cat >/etc/hosts<<EOF
127.0.0.1 localhost localhost.localdomain
192.168.63.149 master1 # master节点
192.168.63.150 node1 # node节点
EOF
# 永久关闭SELinux(修改配置文件)
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
sed -i 's/^SELINUX/permissive/SELINUX=disabled/' /etc/selinux/config
# 临时关闭SELinux(无需重启立即生效)
setenforce 0
# 临时关闭防火墙
systemctl stop firewalld.service
# 永久禁用防火墙开机自启
systemctl disable firewalld.service
# 安装时间同步工具
yum install -y chrony
# 注释掉原有时间服务器
sed -i 's/^pool /#pool /g' /etc/chrony.conf
# 添加阿里云时间服务器
echo "server ntp.aliyun.com iburst" >> /etc/chrony.conf
# 设置开机自启并立即启动
systemctl enable --now chronyd
# 查看时间同步源状态
chronyc sources
# 自动根据IP匹配hosts中的主机名并设置
hostname `cat /etc/hosts|grep $(ifconfig|grep broadcast|awk '{print $2}')|awk '{print $2}'`;su
# 临时关闭swap(立即生效)
swapoff -a
# 永久关闭swap(注释fstab挂载配置)
sed -i '/swap/s/^/#/' /etc/fstab
# 设置内核参数,彻底禁用swap使用
echo "vm.swappiness=0" >> /etc/sysctl.conf
# 加载内核参数
sysctl -p
# 创建IPVS内核模块加载配置文件
cat > /etc/modules-load.d/ipvs.conf <<EOF
# 开机自动加载IPVS相关模块
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
modprobe nf_conntrack_ipv4
EOF
# 开机加载内核模块
systemctl enable --now systemd-modules-load.service
# 验证模块是否加载成功
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 安装ipvs管理工具
yum install -y ipset ipvsadm
# 写入K8s必需的内核参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.ipv4.tcp_syncookies = 1
vm.swappiness=0
EOF
# 强制加载所有内核参数
sysctl --system
# 安装Docker依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加阿里云Docker YUM源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装指定稳定版本Docker
yum install -y docker-ce-19.03.9 docker-ce-cli-19.03.9 containerd.io
# 创建Docker配置目录
mkdir /etc/docker
# 配置Docker:cgroup驱动、日志、国内镜像加速
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"registry-mirrors": [
"https://uyah70su.mirror.aliyuncs.com",
"https://docker.1ms.run",
"https://docker.m.daocloud.io",
"https://docker.xuanyuan.me",
"https://mirror.tuna.tsinghua.edu.cn"
]
}
EOF
# 创建Docker启动依赖配置(保证网络启动后再启Docker)
mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/wait-network.conf <<EOF
[Unit]
After=network-online.target
Wants=network-online.target
EOF
# 重新加载systemd配置
systemctl daemon-reload
# 设置Docker开机自启
systemctl enable docker.service
# 启动Docker服务
systemctl start docker.service
# 验证Docker进程是否正常
ps -ef|grep -aiE docker
# 写入k8s阿里云yum源
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=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
EOF
# 安装指定版本k8s工具
yum install -y kubeadm-1.20.4 kubelet-1.20.4 kubectl-1.20.4
# 配置kubelet依赖docker(保证启动顺序)
mkdir -p /etc/systemd/system/kubelet.service.d
cat > /etc/systemd/system/kubelet.service.d/20-docker.conf <<EOF
[Unit]
After=docker.service network-online.target
Wants=docker.service network-online.target
EOF
# 重新加载配置
systemctl daemon-reload
# 重启docker
systemctl restart docker
# 设置kubelet开机自启并启动
systemctl enable kubelet && systemctl restart kubelet


二、安装Calico网络插件
注意:Calico网络插件与Flannel网络插件只能二选一
# 初始化K8s Master节点
# --control-plane-endpoint:控制平面地址(Master IP+端口)
# --image-repository:使用阿里云镜像仓库(解决国外镜像拉取不到问题)
# --kubernetes-version:指定K8s版本(必须和安装的一致)
# --service-cidr:service网络地址段
# --pod-network-cidr:Pod网络地址段(和Calico插件对应)
# --upload-certs:多Master高可用时上传证书(单Master也可加)
kubeadm init --control-plane-endpoint=192.168.63.149:6443 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.20.4 --service-cidr=10.10.0.0/16 --pod-network-cidr=10.244.0.0/16 --upload-certs
# 创建kubectl配置目录
mkdir -p $HOME/.kube
# 复制K8s管理员认证配置到当前用户目录
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# 给配置文件赋予当前用户权限(否则kubectl无法使用)
chown $(id -u):$(id -g) $HOME/.kube/config
#在 Node 节点(192.168.63.150)执行:加入 Kubernetes 集群
# 将Node节点加入集群
# 命令和token、hash值以你kubeadm init成功后输出的为准
# 以下是示例命令,直接复制你控制台输出的加入命令即可
kubeadm join 192.168.63.149:6443 --token qtsivh.9mqkdxvbtmcy2vyr \
--discovery-token-ca-cert-hash sha256:e2f3008f9235c9ddbb2aad556c75c5dd0fdf079301b95b2137756362d3b3a0c2
# 在192.168.64.149上安装Calico网络插件(v3.20版本适配K8s 1.20)
kubectl apply -f https://docs.projectcalico.org/archive/v3.20/manifests/calico.yaml
# 查看集群所有节点状态(等待所有节点变为 Ready 即成功)
kubectl get nodes
# 查看kube-system命名空间下的Calico组件运行状态
kubectl get pods -n kube-system | grep calico
# 查看集群中所有命名空间的所有Pod运行状态
kubectl get pods -A
# 查看节点详细信息(IP、操作系统、容器运行时等)
kubectl get nodes -o wide
# 查看K8s集群核心组件信息
kubectl cluster-info


三、安装Flanneld网络插件
# 如果之前安装的Calico网络插件执行下列命令删除(必须先删,否则网络冲突)
kubectl delete -f https://docs.projectcalico.org/archive/v3.20/manifests/calico.yaml
#替换Flanneld网络插件
# 下载v0.15.1版本flannel(最稳定、适配k8s 1.20.x)
wget https://raw.githubusercontent.com/flannel-io/flannel/v0.15.1/Documentation/kube-flannel.yml
# 把quay.io国外镜像替换为国内rancher镜像,下载速度极快(解决拉取失败)
sed -i \
-e 's#quay.io/coreos/flannel:v0.15.1#rancher/mirrored-coreos-flannel:v0.15.1#g' \
-e 's#quay.io/coreos/flannel:.*-amd64#rancher/mirrored-coreos-flannel:v0.15.1-amd64#g' \
kube-flannel.yml
# 检查配置文件中的镜像地址,确认已变成国内镜像(必须是v0.15.1)
grep "image:" kube-flannel.yml
# 自动读取配置文件里的镜像并执行docker pull
grep "image:" kube-flannel.yml | awk '{print $2}' | xargs -L1 docker pull
# 应用flannel网络配置,启动网络组件
kubectl apply -f kube-flannel.yml
# 查看kube-system命名空间下的flannel pod状态,等待全部为 Running
kubectl get pods -n kube-system -l app=flannel
# 查看节点状态,所有节点变为 Ready 代表 Flannel 部署成功
kubectl get nodes

四、部署Dashboard所有指令在master1节点上执行即可,部署Dashboard配置文件
# 1. 下载官方 v2.2.0 yaml
wget -O recommended.yaml https://ghproxy.net/https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
# 2. 只删权限(不改Service,绝对不报错)
sed -i '/securityContext:/,/runAsGroup/d' recommended.yaml
sed -i '/nodeSelector:/,/"kubernetes.io\/os"/d' recommended.yaml
# 3. 先部署应用!(必须先做这步),启动kubernetes-dashboard所有资源
kubectl apply -f recommended.yaml
# 4. 再改端口(这时候才有效)
kubectl patch svc kubernetes-dashboard -n kubernetes-dashboard -p '{"spec":{"type":"NodePort","ports":[{"port":443,"targetPort":8443,"nodePort":31001}]}}'
# 创建管理员服务账号和集群管理员权限绑定
# 必须创建,否则登录后无权限操作集群
cat > dashboard-admin.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user # 管理员账号名
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin # 绑定集群最高权限
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
# 应用管理员权限配置
kubectl apply -f dashboard-admin.yaml
## 查看dashboard服务状态,确认端口为31001
kubectl get svc -n kubernetes-dashboard
# 自动查询并解码管理员token,直接复制即可登录dashboard
kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"
# 查看dashboard所有pod状态,等待全部变为Running(正常1分钟内)
kubectl get pod -n kubernetes-dashboard
异常修复Pod 镜像拉取卡住时执行在 Node1 节点(192.168.63.150)手动拉取镜像
# 节点上缺少镜像时,直接本地拉取,加速启动
docker pull kubernetesui/dashboard:v2.2.0
docker pull kubernetesui/metrics-scraper:v1.0.6
# 在Master 节点,删除卡住的dashboard pod(把名称替换为你实际查询到的pod名)
kubectl delete pod kubernetes-dashboard-68f84c78fc-dlnfc -n kubernetes-dashboard
# 删除后再次查看状态,确认变为Running
kubectl get pods -n kubernetes-dashboard
# 重新查询并输出登录token
kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"
# 访问地址(必须用https,谷歌/Edge浏览器直接访问)
https://192.168.63.149:31001
# 重启服务器
reboot
# 重启后查看节点、pod状态,确认全部自启成功
kubectl get nodes
kubectl get pods -n kubernetes-dashboard


通过浏览器访问Dashboard WEB,https://192.168.63.149:31001/,如图所示,输入Token登录即可
在这个报错页面,直接在键盘上输入 thisisunsafe (注意:输入时屏幕不会有任何显示,输完回车即可)浏览器会直接放行,跳转到 Dashboard 登录页
后续访问会记住这个例外,不用重复输入

工作负载正常显示

创建新镜像

在去192.168.63.150上拉取centos 7 镜像
#拉取镜像
docker pull centos:7
#查看拉取的镜像
docker images | grep centos
#在 node1 临时配置 kubectl权限
mkdir -p $HOME/.kube
scp root@192.168.63.149:/etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config


k8s平台中配置

部署正常

192.168.63.150上部署Docker registry镜像仓库
#下载官方 registry 镜像
docker pull registry:latest
#创建本地数据目录
mkdir -p /data/registry
#启动私有仓库容器
docker run -itd --name registry --restart=always -p 5000:5000 -v /data/registry:/var/lib/registry registry:latest
#检测本地私有仓库
curl -XGET http://192.168.63.150:5000/v2/_catalog
#拉取nginx镜像
docker pull nginx
#检测本地私有仓库nginx
curl -XGET http://192.168.63.150:5000/v2/nginx/tags/list
#在Docker客户端192.168.63.149与192.168.63.150主机上追加本地仓库地址(insecure-registries": ["192.168.63.150:5000"])
vi /etc/docker/daemon.json
..................................................
"insecure-registries": ["192.168.63.150:5000"]
......................................................
#重启 Docker 生效
systemctl daemon-reload
systemctl restart docker
#客户端上传镜像至本地私有仓库,如下以nginx镜像为例,将nginx上传至私有仓库服务器
docker images|grep nginx
#查看本地镜像
docker images
#给镜像打搬迁并上传至私有仓库
docker tag nginx 192.168.63.150:5000/nginx
docker push 192.168.63.150:5000/nginx
#验证是否成功
curl 192.168.63.150:5000/v2/_catalog
# 查看 nginx 版本
curl 192.168.63.150:5000/v2/nginx/tags/list
#查看私有仓库中的镜像
docker images | grep 192.168.63.150:5000
#测试在192.168.63.149上查看 192.168.63.150 私有仓库镜像
curl http://192.168.63.150:5000/v2/_catalog
# 试探拉取私有仓库nginx
docker pull 192.168.63.150:5000/nginx


192.168.63.149上验证拉取

浏览器中验证

在k8s管理平台验证仓库(192.168.63.150:5000/nginx)

验证成功

五、部署故障排查
以下故障如图

# 停止服务
systemctl stop kubelet
systemctl stop docker
# 官方重置
kubeadm reset -f
# 删除所有残留文件
rm -rf /etc/kubernetes/
rm -rf /var/lib/kubelet/
rm -rf /var/lib/etcd/
rm -rf $HOME/.kube/
# 清空网络规则
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
ipvsadm --clear 2>/dev/null
# 重启服务
systemctl start docker
systemctl start kubelet
处理残留 Calico插件配置,导致Flannel创建容器卡死问题,情况如下图

#在 master1 + node1 两台机器 都执行下面命令!
1. 清理所有残留 Calico 配置(两台节点都执行)
rm -rf /etc/cni/net.d/calico*
rm -rf /var/lib/calico
rm -f /etc/cni/net.d/10-calico.conflist
rm -f /opt/cni/bin/calico
#2. 只保留 Flannel 配置(两台节点都执行)
ls /etc/cni/net.d/
#3. 重启 kubelet 和 容器服务(两台节点都执行)
systemctl stop kubelet
systemctl stop docker
iptables -F && iptables -t nat -F
systemctl start docker
systemctl start kubelet
#4. 回到 master 节点,重建 Dashboard Pod
kubectl delete pod -n kubernetes-dashboard --all
#5. 等待 30 秒,查看结果
kubectl get pod -n kubernetes-dashboard
