目录
4.1 关闭firewalld防火墙,并安装设置Iptables规则为空
4.8 设置rsyslogd和systemd journald
4.11 安装 Kubeadm、Kubelet、Kubectl
5.1 建立虚拟网卡(master,node1,node2)
5.2 修改kubelet启动参数(master,node1,node2)
5.3.1 Master节点镜像导入脚本(pull_k8s_images_master.sh)-(master)
5.3.2 Node节点镜像导入脚本(pull_k8s_images_node.sh)-(node1,node2)
5.5 配置kube-apiserver参数(master)
一、背景介绍
不慌不忙,赶上了阿里云的飞天计划活动成功白嫖到了7个月的云服务器,反正我觉得是一次成功的薅羊毛,哈哈哈,不知道你们有没有这样认知,但是购买后我才发现,ECS服务器内网是不能互通的,正赶巧我刚好要自建一个基于ECS服务器的K8S集群,然后因为网络问题折腾了好久,估计最少3天,差点就想放弃了,然后我鼓起勇气在Google搜索资料发现,可以搞虚拟一张网卡,IP用当前节点的公网IP,然后使用此IP注册进集群。总算看到了希望,哈哈哈,下面我们开始填坑摸索吧!
二、环境准备
2.1 ECS云服务资源清单
云服务商 | 主机名 | 公网ip/私网ip | 推荐配置 |
阿里云 | zhuchangfei | 47.120.13.246/172.19.209.223 | 2C2G |
阿里云 | liuyongjie | 47.113.151.102/172.18.216.168 | 2C2G |
阿里云 | wangwei | 47.120.12.237/172.23.84.12 | 2C2G |
2.2 K8s软件列表
软件 | 版本 |
---|---|
CentOS | 7.9 |
Kubernetes | v1.18.6 |
Docker | 20.10.10 |
Etcd | 3.4.3-0 |
三、阿里云ECS服务器网络问题
3.1 问题阐述
一般情况下,“kubeadm"部署集群时指定”–apiserver-advertise-address=<public_ip>"参数,即可在其他机器上,通过公网ip join到本机器,然而,阿里云ecs里没配置公网ip,etcd会无法启动,导致初始化失败!
3.2 解决方案
当我部署k8s集群的时候发现,网卡上绑定的地址不是公网IP,而应用只能绑定网卡上的地址。但是私网IP之间又不通。当时内心是崩溃的!最后在官方文档得知,可以采用公网IP部署,具体参考:传送门-公网安装k8s
四、服务节点调整(master,node1,node2)
4.1 关闭firewalld防火墙,并安装设置Iptables规则为空
4.2 调整内核参数
cat > k8s.conf <<EOF
#开启网桥模式
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
#开启转发
net.ipv4.ip_forward = 1
##关闭ipv6
net.ipv6.conf.all.disable_ipv6=1
EOF
cp k8s.conf /etc/sysctl.d/k8s.conf
sysctl -p /etc/sysctl.d/k8s.conf
4.3 关闭 swap
swapoff -a ##这是临时关闭
4.4 关闭 selinux
4.5 设置hostname
#配置host映射
cat >> /etc/hosts << EOF
47.120.13.246 zhuchangfei
47.120.12.237 wangwei
139.196.220.152 liuyongjie01
47.113.151.102 liuyongjie02
EOF
4.6 调整服务器时区
# 设置系统时区为 中国/上海
timedatectl set-timezone Asia/Shanghai
# 将当前的UTC时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond
4.7 关闭邮件服务
#关闭邮件服务
systemctl stop postfix && systemctl disable postfix
4.8 设置rsyslogd和systemd journald
默认有两个日志服务,使用journald关闭rsyslogd
# 持久化保存日志的目录
mkdir /var/log/journal
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化
Storage=persistent
# 压缩历史日志
Compress=yes
SysnIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
#重启journald
systemctl restart systemd-journald
4.9 ipvs前置条件准备
ipvs转发效率比iptables更高,看上去也比iptables舒服
modprobe br_netfilter
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 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
4.10 安装 Docker
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
# yum list docker-ce --showduplicates | sort -r
yum -y install docker-ce-20.10.6-3.el7
systemctl enable docker && systemctl start docker
docker --version
# 换成阿里Docker仓库
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": [" https://wl5zc6br.mirror.aliyuncs.com"]
}
EOF
systemctl restart docker
docker info
# out info
# Registry Mirrors:
# https://wl5zc6br.mirror.aliyuncs.com/
4.11 安装 Kubeadm、Kubelet、Kubectl
# 添加源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[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
# 关闭selinux
setenforce 0
# 安装kubelet、kubeadm、kubectl
yum install -y kubelet-1.18.6 kubeadm-1.18.6 kubectl-1.18.6
# 设置为开机自启
systemctl enable kubelet
4.12 阿里云ECS安全组端口开放
- 10250/10260 TCP端口:给kube-schedule、kube-controll,kube-proxy、kubelet等使用
- 6443 TCP端口:给kube-apiserver使用
- 2379 2380 2381 TCP商品:ETCD使用
- 8472 UDP端口:vxlan使用端口
五、Kubeadm安装k8s
5.1 建立虚拟网卡(master,node1,node2)
# 写入虚拟网卡
cat > /etc/sysconfig/network-scripts/ifcfg-eth0:1 <<EOF
BOOTPROTO=static
DEVICE=eth0:1
IPADDR=你的公网IP
PREFIX=32
TYPE=Ethernet
USERCTL=no
ONBOOT=yes
EOF
# 重启网卡
systemctl restart network
# 查看ip
ip a
5.2 修改kubelet启动参数(master,node1,node2)
# 此文件安装kubeadm后就存在了
vim /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
# 注意,这步很重要,如果不做,节点仍然会使用内网IP注册进集群
# 在末尾添加参数 --node-ip=公网IP
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS --node-ip=公网IP
5.3 使用脚本导入镜像
5.3.1 Master节点镜像导入脚本(pull_k8s_images_master.sh)-(master)
set -o errexit
set -o nounset
set -o pipefail
##这里定义版本,按照上面得到的列表自己改一下版本号
KUBE_VERSION=v1.18.6
KUBE_PAUSE_VERSION=3.2
ETCD_VERSION=3.4.3-0
DNS_VERSION=1.6.7
##这是原始仓库名,最后需要改名成这个
GCR_URL=k8s.gcr.io
##这里就是写你要使用的仓库
DOCKERHUB_URL=gotok8s
##这里是镜像列表,新版本要把coredns改成coredns/coredns
images=(
kube-proxy:${KUBE_VERSION}
kube-scheduler:${KUBE_VERSION}
kube-controller-manager:${KUBE_VERSION}
kube-apiserver:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd:${ETCD_VERSION}
coredns:${DNS_VERSION}
)
##这里是拉取和改名的循环语句
for imageName in ${images[@]} ; do
docker pull $DOCKERHUB_URL/$imageName
docker tag $DOCKERHUB_URL/$imageName $GCR_URL/$imageName
docker rmi $DOCKERHUB_URL/$imageName
done
5.3.2 Node节点镜像导入脚本(pull_k8s_images_node.sh)-(node1,node2)
set -o errexit
set -o nounset
set -o pipefail
##这里定义版本,按照上面得到的列表自己改一下版本号
KUBE_VERSION=v1.18.6
KUBE_PAUSE_VERSION=3.2
ETCD_VERSION=3.4.3-0
DNS_VERSION=1.6.7
##这是原始仓库名,最后需要改名成这个
GCR_URL=k8s.gcr.io
##这里就是写你要使用的仓库
DOCKERHUB_URL=gotok8s
##这里是镜像列表,新版本要把coredns改成coredns/coredns
images=(
kube-proxy:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd:${ETCD_VERSION}
coredns:${DNS_VERSION}
)
##这里是拉取和改名的循环语句
for imageName in ${images[@]} ; do
docker pull $DOCKERHUB_URL/$imageName
docker tag $DOCKERHUB_URL/$imageName $GCR_URL/$imageName
docker rmi $DOCKERHUB_URL/$imageName
done
5.4 使用kubeadm初始化主节点(master)
# step1 添加配置文件,注意替换下面的IP
cat > kubeadm-config.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
apiServer:
certSANs: #填写所有kube-apiserver节点的hostname、IP、VIP
- zanzancloud-k8s-master #请替换为hostname
- 123.57.36.xx #请替换为公网
- 172.20.213.xx #请替换为私网
- 10.96.0.1 #不要替换,此IP是API的集群地址,部分服务会用到
controlPlaneEndpoint: 47.74.22.13:6443 #替换为公网IP
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
---
apiVersion: kubeproxy-config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
EOF
# 如果是1核心或者1G内存的请在末尾添加参数(--ignore-preflight-errors=all),否则会初始化失败!
# 同时注意,此步骤成功后,会打印,两个重要信息!
kubeadm init --config=kubeadm-config.yaml
kubeadm init --apiserver-advertise-address=47.120.13.246 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.6 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16
注意:
信息1 上面初始化成功后,将会生成kubeconfig文件,用于请求api服务器,请执行下面操作:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
信息2 此信息用于后面工作节点加入主节点使用
kubeadm join 47.120.13.246:6443 --token 1l1h9x.fyrricivjdodavsa \
--discovery-token-ca-cert-hash sha256:6bbd74ca2d75f3bf922c89c666341598af642432489a390d23653ebd219512d8
5.5 配置kube-apiserver参数(master)
# 修改两个信息,添加--bind-address和修改--advertise-address
vim /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 123.57.36.xx:6443
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=123.57.36.xx #修改为公网IP
- --bind-address=0.0.0.0 #添加此参数
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction
- --enable-bootstrap-token-auth=true
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
- --etcd-servers=https://127.0.0.1:2379
- --insecure-port=0
- --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
- --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
- --requestheader-allowed-names=front-proxy-client
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User
- --secure-port=6443
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --service-cluster-ip-range=10.96.0.0/12
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
image: k8s.gcr.io/kube-apiserver:v1.18.0
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 175.24.19.12
path: /healthz
port: 6443
scheme: HTTPS
initialDelaySeconds: 15
timeoutSeconds: 15
name: kube-apiserver
resources:
requests:
cpu: 250m
volumeMounts:
- mountPath: /etc/ssl/certs
name: ca-certs
readOnly: true
- mountPath: /etc/pki
name: etc-pki
readOnly: true
- mountPath: /etc/kubernetes/pki
name: k8s-certs
readOnly: true
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/ssl/certs
type: DirectoryOrCreate
name: ca-certs
- hostPath:
path: /etc/pki
type: DirectoryOrCreate
name: etc-pki
- hostPath:
path: /etc/kubernetes/pki
type: DirectoryOrCreate
name: k8s-certs
status: {}
5.6 检查是否加入集群(Master)
# 成功后,INTERNAL-IP均显示公网IP
kubectl get nodes -o wide
master:
node01:
我们发现node01和node01执行返回被拒绝连接
出现这个问题的原因是kubectl命令需要使用kubernetes-admin来运行
解决办法:
1.将主节点(master节点)中的【/etc/kubernetes/admin.conf】文件拷贝到从节 点相同目录下:
scp /etc/kubernetes/admin.conf 47.113.151.102:/etc/kubernetes/
2.配置环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
3.立即生效
source ~/.bash_profile
两个node执行后则再指令kubectl get ndoes命令则都可以返回
但是我们发现这里的STATUS都是NotReady,这是因为我们没有部署集群网络,集 群直接无法进行通信
5.7 安装Pod网络插件(CNI)
wget https://raw.githubusercontent.com/flannelio/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml