K8s+Docker部署实战

一、kubernetes+docker整合Kubernetes 文档 | Kuberneteshttps://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登录即可![](https://i-blog.csdnimg.cn/direct/0983b0f33e70465ebbf13e552564fb00.png)

在这个报错页面,直接在键盘上输入 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
相关推荐
何妨呀~2 小时前
CentOS7.9搭建K8s1.28.2集群实战
云原生·容器·kubernetes
@土豆2 小时前
k3s一键部署教程(快速安装轻量k8s)
云原生·容器·kubernetes
手握风云-2 小时前
基于倒排索引的 Java 文档搜索引擎(一)
java·搜索引擎
拾光Ծ2 小时前
【Linux系统编程】深入理解命名管道(Named Pipe):从原理到实战的完整指南
linux·c语言·linux系统编程·进程间通信·ipc·命名管道
淼淼爱喝水2 小时前
Ansible Playbook 入门实战:自动化创建 Linux 用户
linux·运维·服务器·网络·ansible
雨奔2 小时前
Kubernetes PodSecurityPolicy 完全指南:Pod 安全准入控制核心
安全·容器·kubernetes
雨奔2 小时前
Kubernetes 实操:创建 CPU 约束的 LimitRange 与 Pod
云原生·容器·kubernetes
无籽西瓜a2 小时前
【西瓜带你学设计模式 | 第十九期 - 状态模式】状态模式 —— 状态流转与行为切换实现、优缺点与适用场景
java·后端·设计模式·状态模式·软件工程