前言
项目组出于某种需要,拟在内网构建一套云原生环境,尝试脱离阿里提供的PAAS服务进行微服务应用的部署。
可能大家通常都是直接使用相关部门构建完成的环境,自己从没有动手构建过云原生的环境。这里给大家提供本人的实践,抛砖引玉,仅供参考。
首先,公司提供的服务器非常干净,内网属于要什么没什么的状态,一切所需的工件都需要从外网下载并通过堡垒机转移至内网,所以通过各种一键式命令部署,经由互联网拉取依赖或镜像的方案都不成立。而二进制方式又太过复杂,因此我选择 Kubeadm 来帮助我构建环境。
这里需要说明的是,Kubeadm 经过迭代,已经更加适应在生产环境的应用,当然,应视具体情况而定。
安装包和 docker 镜像准备
我在外网工作机安装了 VMware 来下载所需的资源。
所需的工件包括:
- createrepo 用于创建内网 yum 源
- docker (及其依赖)
- kubeadm (及其依赖 kubectl, kubelet, kubernetes-cni, cri-tools)
- docker images
- coredns
- dashboard
- etcd
- kube-apiserver
- kube-controller-manager
- kube-proxy
- kube-scheduler
- mirrored-flannelcni-flannel
- mirrored-flannelcni-flannel-cni-plugin
- pause
关于 RPM 包,增加对应的镜像源后,
yum list [name] --showduplicates 查看版本 yum install --downloadonly --downloaddir /path [name]-[version] 下载对应版本不安装(不会下载已拥有的依赖)
如果你的服务器允许有一台接入外网作为跳板,并且服务器已有的依赖都相同,那么仅需要上面的命令,然后使用 scp 复制到其他服务器。
但是对于完全无法访问外网的情况,在下载了 docker-ce 和 kubeadm 后,使用 repotrack 命令 进一步下载全量依赖包(需要安装 yum-utils)。
repotrack [name] 在当前文件夹下载对应的全量依赖
关于镜像,这里最好先去官网查看文档,确认版本没有冲突后,再去 docker 镜像仓库 里面下载对应版本的依赖。
在 VMware 安装 docker,下载镜像,使用 docker save 命令将其保存为 tar 包。
这里可以把 rpm 包放在一起,这样安装时只需要让 yum 自动判断依赖关系。
如果嫌麻烦,这里提供我搜集好的内网构建所需的资源。
链接:https://pan.baidu.com/s/1Rr89zi5d_W3sZeewCz8zGg 提取码:tmlc
执行构建
createrepo 创建本地 yum 源
首先安装 createrepo。
在 /etc/yum.repos.d/ 下的 repo 文件中,增加存放本地 rpm 安装包的文件夹 localrepo
[localrepo] name=RedFlag-Localrepo baseurl=file:///home/localrepo/ gpgcheck=0 enabled=1
执行 createrepo /home/localrepo 创建 yum repo
服务器准备工作
systemctl stop firewalld 临时关闭防火墙,或者手动打开所需的端口 systemctl disable firewalld 长期关闭 setenforce 0 临时关闭 SELinux,这个争议较大,大部分人选择关闭,也可以手动设置规则 /etc/selinux/config disabled 长期关闭 swapoff -a 临时关闭分区交换 hostnamectl set-hostname [name] 设置主机名 /etc/hosts 添加 ip 映射 /etc/sysctl.conf 新增 ip 规则 echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-ip6table=1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.conf sysctl --system 更新配置 chrony 时间同步(内网服务器一般都做了)
安装 docker
由于配置了本地源,使用 yum 命令安装即可
systemctl start docker 启动 docker systemctl enable docker.service 自动启动 docker docker load -i [name].tar 导入镜像包 docker load -i coredns.tar; docker load -i etcd.tar; docker load -i dashboard.tar; docker load -i kube-controller-manager.tar; docker load -i kube-apiserver.tar; docker load -i kube-proxy.tar; docker load -i kube-scheduler.tar; docker load -i pause.tar; docker load -i metrics-scraper.tar; docker load -i mirrored-flannelcni-flannel.tar; docker load -i mirrored-flannelcni-flannel-cni-plugin.tar; 下面是给对应容器添加 tag,以便于 kubeadm 获取,image id 对同一个镜像是固定的 docker tag 3fc1d62d6587 k8s.gcr.io/kube-apiserver:v1.23.5; docker tag b0c9e5e4dbb1 k8s.gcr.io/kube-controller-manager:v1.23.5; docker tag 3c53fa8541f9 k8s.gcr.io/kube-proxy:v1.23.5; docker tag 884d49d6d8c9 k8s.gcr.io/kube-scheduler:v1.23.5; docker tag 68d542c34203 k8s.gcr.io/etcd:3.5.1-0; docker tag a4ca41631cc7 k8s.gcr.io/coredns/coredns:v1.8.6; docker tag 6270bb605e12 k8s.gcr.io/pause:3.6; docker tag 8b675dda11bb docker.io/rancher/mirrored-flannelcni-flannel:v0.19.2; docker tag fcecffc7ad4a docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0; docker tag 783e2b6d87ed kubernetesui/dashboard:v2.6.1; docker tag 115053965e86 kubernetesui/metrics-scraper:v1.0.8;
创建并修改 /etc/docker/daemon.json
{ "exec-opts":["native.cgroupdriver=systemd"] }
重启 docker
安装 kubernetes
这里我把 kubernetes 需要的 rpm 包放在一个文件夹里,只需要 yum install *.rpm
使用 kubeadm 启动
kubeadm config print init-defaults > kubeadm-config.yaml 保存默认 config 配置,并进行修改 这里略微修改了几处 localAPIEndpoint: advertiseAddress: 本机 IP nodeRegistration: name:{本主机名} imagePullPolicy: IfNotPresent # 内网可以不修改,切换仓库为阿里云镜像 imageRepository: registry.aliyuncs.com/google_containers kubernetesVersion: 1.23.5 networking: podSubnet: 10.244.0.0/16 kubeadm init kubeadm init --config [config file]
启动的时候还是遇到过许多问题的,通过如下命令尝试排查错误:
docker ps -a 查看容器状态 journalctl -u kubelet 查看错误日志 docker logs [container_id] 查看容器日志 /var/log/containers or pods 进入如下地址查看日志
我遇到的问题是,关闭 SELinux 后依然报 permission denied。查看日志后发现 kubeadm 创建的 PKI 文件夹下的文件无法被读取。
那么我们在后台执行 kubeadm init 命令,并手动进入 /etc/kubernetes/ 使用 chmod 755 -R 给 pki 文件夹赋予权限,即解决问题。
启动 flannel 和 dashboard
dashboard 的配置文件修改(增加 NodePort)
recommended.yaml 文件直接去官网复制:
https://github.com/kubernetes/dashboard/blob/v2.6.1/aio/deploy/recommended.yaml
--- kind: Service ... spec: type: NodePort ports: - port: 443 targetPort: 8443 nodePort: 30118 selector: k8s-app: kubernetes-dashboard
scp /etc/kubernetes/admin.conf root@ip:/etc/kubernetes/ 使用 scp 命令复制 admin.conf 文件到其他服务器 export KUBECONFIG=/etc/kubernetes/admin.conf 系统环境中增加文件路径 # 这里更建议在 /etc/profile 里新增这一行,并 source master: kubeadm token create --print-join-command 创建 token node 节点执行 join command master: kubectl apply -f kube-flannel.yml 启动 flannel master: kubectl apply -f recommended.yml 启动 dashboard(配置文件中 imagePullPolicy 应为 IfNotPresent) master: kubectl apply -f dashboard-admin.yml 配置 dashboard 用户 kubectl -n kube-system describe $(kubectl -n kube-system get secret -n kube-system -o name | grep namespace) | grep token 获取 dashboard 访问令牌
开启 IPVS
ipvsadm -Ln
yum install ipset ipvsadm -y
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod +x /etc/sysconfig/modules/ipvs.modules
/bin/bash /etc/sysconfig/modules/ipvs.modules
# 查看
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
kubectl edit cm kube-proxy -n kube-system
# 修改 mode 为 "ipvs"
# 修改 masqueradeAll 为 true
# 删除 pod 自动拉起新的
# 检查 ipvs
ipvsadm -Ln
安装 Metrics-server 监控节点资源
# 下载配置文件
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
vim components.yaml
# ./找到 containers
# 在 args 下新增参数
-- -kubelet-insecure-tls
# 替换镜像地址
sed -i 's/k8s.gcr.io\/metrics-server/registry.cn-hangzhou.aliyuncs.com\/google_containers/g' components.yaml
安装 ingress-nginx 暴露服务
# 获取配置文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml
# 镜像仓库替换
controller
image: bitnami/nginx-ingress-controller:1.1.2
create/patch
image: liangjw/kube-webhook-certgen:v1.1.1
其他命令
提供一些排错和其他命令
kubectl get pods --all-namespaces 查看全部 pods kubectl get svc,pods -n [namespace] 查看 svc,pods 信息 kubectl logs -f [pod-name] -n [namespace] 查看 pod 日志 kubectl delete pod/[pod-name] -n [namespace] 删除 pod 后自动重启 pod docker rm $(docker ps -all -q -f status=exited) 删除不使用的容器(慎重) docker rmi $(docker images -f "dangling=true" -q) 删除空悬镜像
遇到 cni0 网卡错误,可以删除 cni0,系统会自动创建新的:
sudo ifconfig cni0 down
sudo ip link delete cni0
容器和外部交互操作:
// 打包镜像
docker commit [container_id] [image_name]
// 创建检测用的 busy-box
centos 进入 sh -c 'while true; do sleep 3600; done'
// 复制出 Pod
kubectl cp [namespace]/[podname]:[filePath] [filePath]
// 复制进 Pod(多个容器)
kubectl cp [src_path] [namespace]/[podname]:[filePath] -c [container_name]
// 一个容器
kubectl exec -it [podname] -n [namespace] -- /bin/sh
// 多个容器
kubectl exec -it [podname] -c [container_name] -n [namespace] -- /bin/sh