跳至主要內容

K8S + Flannel 公网IP搭建笔记

Yaien Blog原创大约 7 分钟kuberneteskubernetes

K8S + Flannel 公网IP搭建笔记

159.75.154.193 master 1.12.242.126 node1 139.159.219.202 node2 101.34.229.23 node3

版本简介

软件版本信息

名称版本
docker10.10.21
kubernetes1.21.0-0
Flannel0.20.2

集群角色规划

服务商内核公网IP节点
腾讯云centOS7.6159.75.154.193master
腾讯云centOS7.61.12.242.126node1
华为云centOS7.6139.159.219.202node2
腾讯云centOS7.6101.34.229.23node3

准备工作

修改服务器名称

修改所有的服务器名称,使用命令

# instanceName 处填写每个服务器的名称
sudo hostnamectl set-hostname <instanceName>

修改服务器hosts文件

修改所有服务器的hosts文件内容,往hosts文件中添加我们的服务器公网ip和对应的服务器名称

sudo tee -a /etc/hosts <<EOF
159.75.154.193 master
1.12.242.126 node1
139.159.219.202 node2
101.34.229.23 node3
EOF

创建虚拟网卡

为所有服务器添加虚拟网卡,在{IP}处填写公网IP


# 创建临时虚拟网卡
ifconfig eth0:1 {IP}
 
# 创建永久的虚拟网卡
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

# 验证,如果多了一个 eth0:1 说明创还能成功
ifconfig

云服务器安全组设置

master节点

协议端口使用者
TCP2379~2380kube-apiserver, etcd
TCP6443所有组件
UDP8472Flannel 网络插件
TCP10250kubelet, Control Plane 组件
TCP10251kube-scheduler
TCP10252kube-controller-manager
防火墙设置
# 开启防火墙
systemctl start firewalld
# 添加端口
firewall-cmd --zone=public --add-port=22/tcp --permanent
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --zone=public --add-port=6443/tcp --permanent
firewall-cmd --zone=public --add-port=8472/udp --permanent
firewall-cmd --zone=public --add-port=10250/tcp --permanent
firewall-cmd --zone=public --add-port=10251/tcp --permanent
firewall-cmd --zone=public --add-port=10252/tcp --permanent
firewall-cmd --zone=public --add-port=2379-2380/tcp --permanent
# 刷新防火墙
systemctl restart firewalld
# 查看所有开放的端口
firewall-cmd --zone=public --list-ports

worker节点

协议端口使用者
UDP8472Flannel 网络插件
TCP10250kubelet, Control Plane 组件
TCP30000~32767所有组件
服务器防火墙设置
systemctl start firewalld
firewall-cmd --zone=public --add-port=22/tcp --permanent
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --zone=public --add-port=8472/udp --permanent
firewall-cmd --zone=public --add-port=10250/tcp --permanent
firewall-cmd --zone=public --add-port=30000-32767/tcp --permanent
systemctl restart firewalld
firewall-cmd --zone=public --list-ports

基础配置

所有的服务器都要执行

更新安装依赖

sudo yum -y update 
sudo yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp
sudo yum install -y yum-utils

关闭SELinux

# 临时关闭
sudo setenforce 0
# 永久关闭
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

关闭swap

# 临时关闭
swapoff -a  
# 永久关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab

配置iptables的ACCEPT规则

iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT

设置系统参数

cat <<EOF> /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

重启服务器

sudo systemctl reboot

安装Docker

所有服务器都要安装

配置阿里云镜像

# 配置镜像地址
sudo yum-config-manager \
    --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 查看 Docker-CE
yum list | grep docker-ce
# 更新 yum 缓存
sudo yum makecache fast

安装(指定20.10.21版本)

sudo yum install -y docker-ce-20.10.21 docker-ce-cli-20.10.21 containerd.io

启动

sudo systemctl start docker

开启自启动

sudo systemctl enable docker

查看版本

docker --version

安装k8s及组件

所有服务器都需要安装

配置yum源

cat <<EOF> /etc/yum.repos.d/kubernetes.repo 
[kubernetes] 
name=Kubernetes 
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 
enabled=1 
gpgcheck=0 
repo_gpgcheck=0 
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg 
    http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg 
EOF

安装(指定1.21.0-0版本)

# 确认 yum 中是否有指定版本
yum list kubeadm --showduplicates | sort -r
 
# 安装
yum install -y kubeadm-1.21.0-0 kubelet-1.21.0-0 kubectl-1.21.0-0

修改daemon.json文件

打开文件

vim /etc/docker/daemon.json

删除所有内容,然后复制保存

{
  "registry-mirrors": [
    "https://nmxk8hna.mirror.aliyuncs.com"
  ],
  "exec-opts": [
    "native.cgroupdriver=systemd"
  ]
}

重启docker

systemctl restart docker

检查 kubelet,如果在输出信息中发现 No such file or directory,说明没问题

sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

修改 kubelet启动参数

打开文件

vim /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

在 KUBELET_KUBECONFIG_ARGS 后面追加 --node-ip={IP}

重新加载

systemctl daemon-reload

启动kubelet

systemctl enable kubelet && systemctl start kubelet

重启kubectl

systemctl restart kubectl

拉取镜像

查看kubeadm所需镜像

kubeadm config images list

输出

k8s.gcr.io/kube-apiserver:v1.21.14
k8s.gcr.io/kube-controller-manager:v1.21.14
k8s.gcr.io/kube-scheduler:v1.21.14
k8s.gcr.io/kube-proxy:v1.21.14
k8s.gcr.io/pause:3.4.1
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns/coredns:v1.8.0

下载这些镜像需要魔法上网,尝试使用国内源进行下载

国内源拉取镜像

# 测试国内源是否可以拉取
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.14

发现可是拉取,添加脚本kubeadm_image.sh脚本将拉取的镜像切换到一个目录,现在假设文件在/var/local/k8s下创建

mkdir -p /var/local/k8s
cat <<EOF> /var/local/k8s/kubeadm_image.sh
#!/usr/bin/env bash
 
# 镜像处理过程中,如果遇到错误,立即退出
set -e
 
# 版本定义
readonly KUBE_VERSION=v1.21.0
readonly PAUSE_VERSION=3.4.1
readonly ETCD_VERSION=3.4.13-0
readonly CORE_DNS_VERSION=v1.8.0
readonly OFFICIAL_URL=k8s.gcr.io
readonly ALIYUN_URL=registry.cn-hangzhou.aliyuncs.com/google_containers
 
# 镜像列表
imageList=(kube-apiserver:${KUBE_VERSION} 
kube-controller-manager:${KUBE_VERSION} 
kube-scheduler:${KUBE_VERSION} 
kube-proxy:${KUBE_VERSION} 
pause:${PAUSE_VERSION} 
etcd:${ETCD_VERSION} 
coredns:${CORE_DNS_VERSION})
 
# 镜像转换操作
for imageItem in ${imageList[@]} ; do 
  # 从国内镜像源拉取镜像
  docker pull $ALIYUN_URL/$imageItem
  # 给镜像重新打一个标签,命名为 kubeadm 所需的镜像
  docker tag $ALIYUN_URL/$imageItem $OFFICIAL_URL/$imageItem
  # 删除原有镜像
  docker rmi $ALIYUN_URL/$imageItem
done
 
# coredns 的镜像比较特殊,单独处理
docker tag ${OFFICIAL_URL}/coredns:${CORE_DNS_VERSION} ${OFFICIAL_URL}/coredns/coredns:${CORE_DNS_VERSION}
docker rmi ${OFFICIAL_URL}/coredns:${CORE_DNS_VERSION}
EOF

运行脚本

sh /var/local/k8s/kubeadm_image.sh

搭建集群(仅master节点执行)

初始化master节点

替换公网IP

kubeadm init --kubernetes-version=1.21.0 \
  --apiserver-advertise-address={IP} \
  --pod-network-cidr=10.244.0.0/16 \
  -v=5

如果出现

Your Kubernetes control-plane has initialized successfully! 

说明初始化成功,需要执行中间的命令:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

保存好最后的

kubeadm join 159.75.154.193:6443 --token 1b751g.6cbt5hjo7z6nopxx 
    --discovery-token-ca-cert-hash sha256:e6e99c36b3f99c782788e375fc6b86947531e73d78965863d86ad7f479f1e67e

集群健康检查

# 检查集群状态
kubectl cluster-info
 
# 健康检查
curl -k https://localhost:6443/healthz

修改kube-apiserver.yaml配置

vim /etc/kubernetes/manifests/kube-apiserver.yaml
  • 确定 --advertise-address=159.75.154.193 是公网的IP
  • 添加 --bind-address=0.0.0.0

最终修改后配置如下

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 159.75.154.193:6443
  creationTimestamp: null
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-apiserver
    # 确定是不是公网的IP
    - --advertise-address=159.75.154.193
    # 添加下面一行
    - --bind-address=0.0.0.0
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
 # ...

检查集群状态

kubectl get pods -n kube-system
kubectl get nodes

会发现两个coredns还是Pending,并且master节点并没有Ready,这是因为缺少网络插件

安装flannel插件 (仅在master执行)

安装flannel

cd /var/local/k8s

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

修改vim kube-flannel.yml文件

vim kube-flannel.yml

第一处

containers:
- name: kube-flannel
  #image: flannelcni/flannel:v0.20.2 #for ppc64le and mips64le (dockerhub limitations may apply)
  image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.2
  command:
  - /opt/bin/flanneld
  args:
  # 添加
  - --public-ip=$(PUBLIC_IP)
  # 添加
  - --iface=eth0
  - --ip-masq
  - --kube-subnet-mgr

第二处

env:
# 添加
- name: PUBLIC_IP
  valueFrom:
    fieldRef:
      fieldPath: status.podIP

最综配置展示

      containers:
      - name: kube-flannel
        image: docker.io/flannel/flannel:v0.22.0
       #image: docker.io/rancher/mirrored-flannelcni-flannel:v0.22.0
        command:
        - /opt/bin/flanneld
        args:
        # 添加
        - --public-ip=$(PUBLIC_IP)
        # 添加
        - --iface=eth0
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
        env:
        # 添加
        - name: PUBLIC_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
        - name: xtables-lock
          mountPath: /run/xtables.lock

安装

kubectl apply -f kube-flannel.yml

从节点加入集群

所有从节点执行上面保存的kubeadm join

kubeadm join 159.75.154.193:6443 --token 1b751g.6cbt5hjo7z6nopxx 
    --discovery-token-ca-cert-hash sha256:e6e99c36b3f99c782788e375fc6b86947531e73d78965863d86ad7f479f1e67e

如果出现 This node has joined the cluster 表示已经加入

从新获取

## 重新生成令牌
kubeadm token create --print-join-command

自定义Pod测试

添加文件

cat <<EOF> /var/local/k8s/pod-nginx.yml 
apiVersion: apps/v1 
kind: ReplicaSet 
metadata: 
  name: my-nginx 
  labels: 
    tier: frontend 
spec: 
  replicas: 4 
  selector: 
    matchLabels: 
      tier: frontend 
  template: 
    metadata: 
      name: my-nginx 
      labels: 
        tier: frontend 
    spec:
      containers: 
      - name: my-nginx 
        image: nginx 
        ports: 
        - containerPort: 80 
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx-service
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    nodePort: 30992
  selector:
    tier: frontend 
EOF

执行

cd /var/local/k8s/
kubectl apply -f pod-nginx.yml

查看对外暴露的端口

kubectl get services

查看pod提供的服务

kubectl get pods -o wide

访问

使用提供pod服务的公网ip+暴露的端口访问,假设是node1,则为

1.12.242.126:30992

参考文档

kubeadm+Flannel基于公网IP搭建k8s集群open in new window

上次编辑于:
贡献者: yanggl