2022版使用云服务器搭建公网k8s容器集群

总体流程一览

主要流程如下:
1.准备云主机,升级CentOS系统到7.9
2.所有节点上安装Docker和Kubeadm,拉取相关镜像
3.在Master节点初始化集群,包括kubectl和部署CN容器网络插件
4.把Node节点加入k8s集群

可视化界面和私有镜像仓库请参考其他文章:
1.部署Dashboard Web 页面,可视化查看Kubernetes资源,看我下一篇文章:k8s dashboard安装
2.部署Harbor私有仓库,存放镜像资源(非必要,省略介绍)

下面,开始介绍各流程详细配置步骤。

环境准备

云主机

云服务器区域CentOS节点类型配置公网IP安装工具
腾讯云上海三区7.9master012C4G101.34.112.190docker、kubeadm、kubelet、kubectl、flannel
同上上海二区7.9node011C2G81.68.126.69同上
同上上海二区7.9node021C2G81.68.92.49同上

CentOS升级

如果低于CentOS 7.9,请先升级:

$ yum update -y
$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

PS:请务必不要跳过这步,低版本的CentOS安装Kubeadm时很可能会失败。作者就是失败之后升级CentOS才成功了!!

所有节点CentOS设置

基础设置

PS:该步骤基于:CentOS Linux release 7.9.2009 (Core) ,7.2 - 7.6 版本好像会失败,如果中途不成功,请考虑升级更换CentOS版本!

可以创建 k8s-pre-install-centos.sh 脚本,一键设置:

$ vim k8s-pre-install-centos.sh

#!/bin/sh

function set_base(){
  # 关闭防火墙,PS:如果使用云服务器,还需要在云服务器的控制台中把防火墙关闭了或者允许所有端口。
  systemctl stop firewalld
  systemctl disable firewalld

  # 关闭SELinux,这样做的目的是:为了让容器能读取主机文件系统。
  setenforce 0

  # 永久关闭swap分区交换,kubeadm规定,一定要关闭
  swapoff -a
  sed -ri 's/.*swap.*/#&/' /etc/fstab

  # iptables配置
  cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

  cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

  # iptables生效参数
  sysctl --system
}

set_base

执行上述脚本:

$ chmod 777 k8s-pre-install-centos.sh && ./k8s-pre-install-centos.sh

主机名设置

修改主机名

master执行:

hostnamectl set-hostname master01 

节点1执行:

hostnamectl set-hostname node01

节点2执行:

hostnamectl set-hostname node02
修改hosts文件

每台机器上都要执行:

$ vim /etc/hosts 
101.34.112.190 master01 
81.68.126.69 node01 
81.68.92.49 node02

PS:请更换为自己的公网IP(注意是公网IP,不是内网)!

所有节点安装Docker

k8s支持 3种容器运行时,这里我们优先使用熟悉的 Docker 作为容器运行时。请确保CentOS 7以上,最新要求以 官方 为主。

安装yum仓库

$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

安装docker

包括cli、engine、docker compose等

$ sudo yum install docker-ce-20.10.14-3.el7 docker-ce-cli-20.10.14-3.el7 containerd.io docker-compose-plugin
ps:本教程使用的是docker版本:20.10.14

配置Docker守护程序

尤其是使用 systemd 来管理容器的 cgroup,另外还要配置阿里云镜像源,加快拉取速度!

$ sudo mkdir /etc/docker
$ cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
  • registry-mirrors:镜像加速。
  • cgroupdriver:使用systemd。
  • log-driver:使用json日志,大小为100m。

启动docker,并设置为开机启动

$ sudo systemctl enable docker
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
$ systemctl status docker # 确保是running状态

确认Cgroup Driver为systemd

$ docker info | grep "Cgroup Driver"
 Cgroup Driver: systemd

PS:因为k8s是默认systemd作为cgroup driver,如果Docker使用另外的驱动,则可能出现不稳定的情况。

所有节点安装kubeadm

为保证不过期,请最终以 官方文档 为主:

配置yum源(使用aliyun,google你知道的)

$ 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 https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

$ yum makecache # 更新yum

安装kubeadm, kubelet, kubectl

$ sudo yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6 --disableexcludes=kubernetes

PS:k8s升级很快,为了保证教程正确,请使用相同版本。

启动klubelet,并设置为开机启动

$ sudo systemctl start kubelet
$ sudo systemctl enable kubelet

PS:kubeadm 将使用 kubelet 服务以容器方式部署和启动 Kubemetes 的主要服务。

所有节点拉取Docker镜像

ps:该1.23.6版本,需要docker为20,超过的不保证成功
拉取Docker镜像

查看初始化需要的镜像

$ kubeadm config images list

k8s.gcr.io/kube-apiserver:v1.23.6
k8s.gcr.io/kube-controller-manager:v1.23.6
k8s.gcr.io/kube-scheduler:v1.23.6
k8s.gcr.io/kube-proxy:v1.23.6
k8s.gcr.io/pause:3.6
k8s.gcr.io/etcd:3.5.1-0
k8s.gcr.io/coredns/coredns:v1.8.6

替换k8s镜像源

k8s模式镜像仓库是 k8s.gcr.io,由于众所周知的原因是无法访问的。

故这里需要创建配置 kubeadm-config-image.yaml 替换成阿里云的源:

$ vim kubeadm-config-image.yaml

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
# 默认为k8s.gcr.io,但是网络不通,所以要替换为阿里云镜像
imageRepository: registry.aliyuncs.com/google_containers 

确认镜像仓库改变

再查看,发现镜像的地址变了,才能执行下一步:

$ kubeadm config images list --config kubeadm-config-image.yaml

registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6
registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6
registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6
registry.aliyuncs.com/google_containers/pause:3.6
registry.aliyuncs.com/google_containers/etcd:3.5.1-0
registry.aliyuncs.com/google_containers/coredns:v1.8.6

拉取镜像

$ kubeadm config images pull --config kubeadm-config-image.yaml

所有机器 上执行,把这些镜像提前拉好。

Master节点初始化集群

生成默认配置 kubeadm-config.yaml

并更改下面几项:

$ kubeadm config print init-defaults > kubeadm-config.yaml
  • kubernetes-version:集群版本,上面安装的kubeadm版本必须小于等于这里的,可以查看这里:https://kubernetes.io/releases/
  • pod-network-cidr:pod资源的网段,需与pod网络插件的值设置一致。通常,Flannel网络插件的默认为10.244.0.0/16,Calico插件的默认值为192.168.0.0/16;
  • api-server:使用Master作为api-server,所以就是master机器的IP地址。
  • image-repository:拉取镜像的镜像仓库,默认是k8s.gcr.io。
  • nodeRegistration.name:改成master01
    最终如下:
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 101.34.112.190 # 指定master节点的IP地址(公网)
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  imagePullPolicy: IfNotPresent
  name: master01  # 改成master的主机名
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers  # 默认为k8s.gcr.io,但是网络不通,所以要替换为阿里云镜像
kind: ClusterConfiguration
kubernetesVersion: 1.23.6  # 指定kubernetes版本号,使用kubeadm config print init-defaults生成的即可
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.244.0.0/16  # 指定pod网段,10.244.0.0/16用于匹配flannel默认网段
scheduler: {}

上面的配置等价于:

$ kubeadm init \
--kubernetes-version=v1.23.6 \
--image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=101.34.112.190 --ignore-preflight-errors=Swap

或者1核CPU Master初始化(--ignore-preflight-errors=NumCPU这个如果是1核的ECS服务器一定要添加,不然会报错,因为K8S要求最低核数是2核)::

$ kubeadm init \
--kubernetes-version=v1.23.6 \
--apiserver-advertise-address=101.34.112.190 
--ignore-preflight-errors=NumCPU \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers \
--v=6

PS:建议通过配置文件的方式来操作,命令行不直观。

检查环境

$ kubeadm init phase preflight --config=kubeadm-config.yaml 

这个命令会检查配置文件是否正确,以及系统环境是否支持kubeadm的安装。

初始化kubeadm集群

只需要在master上执行如下命令:

$ kubeadm init --config=kubeadm-config.yaml

PS:这里是最难的,作者卡在这里卡了一整天,查阅各种资料才解决,所以如果你也失败了,比较正常,这里是相比于内网部署k8s,公网最麻烦也是最难的点,这一步成功了,后面也没啥了。最终参考:https://blog.51cto.com/u_15152259/2690063解决

到这里,会有2种结果:

  • 如果是内网,上面的docker版本,kubeadm版本没错的话,会成功,直接跳到4步骤。
  • 如果在云服务器(腾讯云,阿里云)上,一定会失败(原因和办法在这里)
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests”
// ...
[kubelet-check] Initial timeout of 40s passed.

提示:请一定先执行上面的初始化(目的是为了生成k8s的配置文件,否则下面的步骤中你会找不到etcd.yaml),失败后再执行下面的步骤!!

云服务器初始化失败解决版本

1)编辑etcd配置文件
配置文件位置:/etc/kubernetes/manifests/etcd.yaml

    - --listen-client-urls=https://127.0.0.1:2379,https://101.34.112.190:2379
    - --listen-peer-urls=https://101.34.112.190:2380

改成

    - --listen-client-urls=https://127.0.0.1:2379
    - --listen-peer-urls=https://127.0.0.1:2380

引用 在腾讯云安装K8S集群
此处"118.195.137.68"为腾讯云公网ip,要关注的是"–listen-client-urls"和"–listen-peer-urls"。需要把–listen-client-urls后面的公网IP删除,把–listen-peer-urls改成127.0.0.1:2380
原因是因为腾讯云只要选择VPC网络均是采用NAT方式将公网IP映射到私人网卡的,有兴趣的同学可以了解下NAT。这也就是为什么很多同事无法在腾讯云或阿里云上安装k8s集群的原因

2)手工停止已启动的进程

# 先停止kubelet
$ systemctl stop kubelet 
# 把所有kube的进程杀掉
$ netstat -anp |grep kube

请注意,不要执行 kubeadm reset,先 systemctl stop kubelet ,然后手动通过 netstat -anp |grep kube 来找pid,再通过 kill -9 pid 强杀。否则又会生成错误的etcd配置文件,这里非常关键!!!

3)重新初始化,但是跳过etcd文件已经存在的检查:

# 重新启动kubelet
$ systemctl start kubelet
# 重新初始化,跳过配置文件生成环节,不要etcd的修改要被覆盖掉
$ kubeadm init --config=kubeadm-config.yaml --skip-phases=preflight,certs,kubeconfig,kubelet-start,control-plane,etcd

成功初始化

如果所有配置都正常,很快会输出下面的信息(秒级别)代表了成功,否则大概率是失败(由于网络超时等):

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.1.200:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:af2a6e096cb404da729ef3802e77482f0a8a579fa602d7c071ef5c5415aac748

保存上面输出的token和sha256值。

也就是下面这一段,这段命令主要是让node节点加入k8s集群:

kubeadm join 101.34.112.190:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:af2a6e096cb404da729ef3802e77482f0a8a579fa602d7c071ef5c5415aac748

常见错误

Initial timeout of 40s passed
  • 可能1:检查镜像版本,可能是不匹配或者本地替换tag出错造成的了,或者是因为公网IP ETCD无法启动造成的。执行:journalctl -xeu kubelet 查看具体错误,或者时候 journalctl -f -u kubelet 查看初始化的实时输出,下次初始化之前执行 kubeadm reset 重置。
  • 可能2:CentOS版本太低,推荐7.8以上。我在7.2和7.5都失败了,执行 yum update -y升级到7.9才成功。
证书忘记
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2> /dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
token忘记
kubeadm token list

配置kubectl(master)

准备配置文件

kubectl需经由API server认证及授权后方能执行相应的管理操作,kubeadm 部署的集群为其生成了一个具有管理员权限的认证配置文件 /etc/kubernetes/admin.conf,它可由 kubectl 通过默认的 “$HOME/.kube/config” 的路径进行加载。

拷贝配置文件到kubectl默认加载路径:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
使用kubectl查看集群信息

在Master节点上执行,输出集群信息:

$ kubectl get nodes
NAME       STATUS     ROLES                  AGE   VERSION
master01   NotReady   control-plane,master   15m   v1.23.6

$ kubectl get cs
etcd-0               Healthy   {"health":"true","reason":""}
controller-manager   Healthy   ok
scheduler            Healthy   ok

这里STATUS是NotReady是因为还没有配置网络的原因,接下来会介绍。

安装CN网络(master)

$ curl https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml>>kube-flannel.yml
$ chmod 777 kube-flannel.yml 
$ kubectl apply -f kube-flannel.yml

等待几分钟,再查看Master节点状态,由NotRead变成了Ready状态:

$ kubectl get nodes
NAME       STATUS   ROLES                  AGE   VERSION
master01   Ready    control-plane,master   15m   v1.23.6

允许master节点部署pod

此时k8s master节点安装完毕(为了不浪费云服务器资源,需要让master节点能部署pod,需要运行以下命令)。

  1. 查看调度策略
$ kubectl describe node|grep -E "Name:|Taints:"

Name:               master01
Taints:             node-role.kubernetes.io/master:NoSchedule
  • NoSchedule: 一定不能被调度
  • PreferNoSchedule: 尽量不要调度
  • NoExecute: 不仅不会调度, 还会驱逐Node上已有的Pod
  1. 更改master节点可被部署pod
$ kubectl taint nodes --all node-role.kubernetes.io/master-
  1. 查看是否生效
$ kubectl describe node|grep -E "Name:|Taints:"
Name:               master01
Taints:             <none>

把Node节点加入集群

在node上执行上面kubeadm输出的命令(注意token和sha256值不同):

$ kubeadm join 192.168.1.200:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:af2a6e096cb404da729ef3802e77482f0a8a579fa602d7c071ef5c5415aac748

[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

此时,在master执行以下命令,可以看到node节点已经加入成功了:

$ kubectl get nodes
NAME       STATUS     ROLES                  AGE   VERSION
master01   Ready   control-plane,master   60m   v1.23.6
node01     NotReady   <none>                 54s   v1.23.6

等待5分钟左右,node01的状态变成Ready。

另外一台Node节点机器,重复改步骤加入集群即可!

测试集群

创建个nginx Pod

在master节点运行以下命令:

$ kubectl run --image=nginx nginx-app --port=80
$ kubectl run --image=nginx nginx-app1 --port=81

然后再运行:

$ kubectl get pods
NAME        READY   STATUS              RESTARTS   AGE
nginx-app   0/1     ContainerCreating   0          18s

$ kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
nginx-app   1/1     Running   0          26s

$ kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
nginx-app   1/1     Running   0          57s   10.244.1.2   node01   <none>           <none>

可以看到2个pod已经是运行状态,证明k8s集群成功安装

Dashboard可视化界面安装

请移步下一篇文章:k8s dashboard安装

参考

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值