ubuntu 22.04安装k8s完整流程

775 阅读7分钟

参考:

Kubernetes 官网文档:Kubernetes 官网文档 (很重要,里面更完整 也有演示)

www.cnblogs.com/wangguishe/…

www.cnblogs.com/guangdelw/p…

1. 集群基础设置

1.1. 版本配置

OS: ubuntu 22.04

kubernetes: 1.28.3

Container Runtime:Docker 24.0.7

CRI: cri-docker v0.3.7

Kubernetes自v1.24移除了对docker-shim的支持,而Docker Engine默认又不支持CRI规范,因而二者将无法直接完成整合。

为此,Mirantis和Docker联合创建了cri-dockerd项目,用于为Docker Engine提供一个能够支持到CRI规范的垫片,从而能够让Kubernetes基于CRI控制Docker 。


1.2. 集群规划

服务器IP主机名配置
192.168.11.201k8s-master
192.168.11.202k8s-node

1.3. 网络规划

pod网络:10.200.0.0/16

service网络: 10.100.0.0/16

节点网络:192.168.11.0/24

1.4. 时间同步

apt -y install chrony
systemctl enable chrony && systemctl start chrony
chronyc sources -v

1.5. 设置主机名

# 设置主机名
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node-1

# 更新
bash

1.6. 设置 hosts

cat >> /etc/hosts << EOF
192.168.11.201 k8s-master
192.168.11.202 k8s-node-1
EOF

1.7. 禁用 swap

sudo swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab

or

systemctl disable --now swap.img.swap
systemctl mask swap.target

1.8. 禁用防火墙

ufw disable
ufw status

1.9. 内核参数调整

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

设置所需的 sysctl 参数,参数在重新启动后保持不变

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

应用 sysctl 参数而不重新启动

sudo sysctl --system

通过运行以下指令确认 br_netfilter 和 overlay 模块被加载

lsmod | grep br_netfilter
lsmod | grep overlay

通过运行以下指令确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables 和 net.ipv4.ip_forward 系统变量在你的 sysctl 配置中被设置为 1

sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

出现:

net.bridge.bridge-nf-call-iptables = 1

net.bridge.bridge-nf-call-ip6tables = 1

net.ipv4.ip_forward = 1

1.10. 开启 ipvs

安装 ipvs

apt install -y ipset ipvsadm

内核加载 ipvs

cat <<EOF | sudo tee /etc/modules-load.d/ipvs.conf
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF
sudo modprobe ip_vs
sudo modprobe ip_vs_rr
sudo modprobe ip_vs_wrr
sudo modprobe ip_vs_sh
sudo modprobe nf_conntrack

确认ipvs模块加载

lsmod |grep -e ip_vs -e nf_conntrack

出现:

ip_vs_sh 16384 0

ip_vs_wrr 16384 0

ip_vs_rr 16384 0

ip_vs 176128 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr

nf_conntrack_netlink 49152 0

nf_conntrack 172032 6 xt_conntrack,nf_nat,xt_nat,nf_conntrack_netlink,xt_MASQUERADE,ip_vs

nf_defrag_ipv6 24576 2 nf_conntrack,ip_vs

nf_defrag_ipv4 16384 1 nf_conntrack

nfnetlink 20480 4 nft_compat,nf_conntrack_netlink,nf_tables

libcrc32c 16384 6 nf_conntrack,nf_nat,btrfs,nf_tables,raid456,ip_vs

1.11. 开放端口

2. 2 安装 Kubernetes

2.1. 安装 K8s 三大件

安装 kubelet、kebeadm、kubectl;注意版本 (1.28.3)


# 安装依赖
apt-get update && apt-get install -y apt-transport-https

# 添加并信任APT证书
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/Release.key |
    gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
    
# 添加源地址
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/ /" |
    tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
# 查看 kubelet、kubeadm 和 kubectl版本
apt-cache madison kubeadm

apt-get install -y kubelet=1.28.3-1.1 kubeadm=1.28.3-1.1 kubectl=1.28.3-1.1

# 确认 kubectl 版本信息
kubectl version

# 锁定版本
sudo apt-mark hold kubelet kubeadm kubectl

# 运行服务
systemctl enable --now kubelet

# 查看 kubelet 状态:一会停止 一会运行。 这个状态是对的,kubelet 等待 kubeadm 发号指令。
systemctl status kubelet

# kubectl 命令补全
apt install -y bash-completion
kubectl completion bash > /etc/profile.d/kubectl_completion.sh
. /etc/profile.d/kubectl_completion.sh

kubernetes源配置方法

developer.aliyun.com/mirror/kube…

2.2. 准备镜像

查看镜像版本

 kubeadm config images list
 # 阿里云镜像
 kubeadm config images list --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers

出现:

registry.k8s.io/kube-apiserver:v1.28.12

registry.k8s.io/kube-controller-manager:v1.28.12

registry.k8s.io/kube-scheduler:v1.28.12

registry.k8s.io/kube-proxy:v1.28.12

registry.k8s.io/pause:3.9

registry.k8s.io/etcd:3.5.9-0

registry.k8s.io/coredns/coredns:v1.10.1

2.3. 下载镜像

所有节点执行下载操作,也可导出导入操作。

docker image save `docker image ls --format "{{.Repository}}:{{.Tag}}"` -o k8s-images-v1.28.3.tar

或者:

# 下载阿里云镜像
#区别于1.23及之前的版本,一定要加--cri-socket unix:///run/cri-dockerd.sock, 指定容器运行时
kubeadm config images pull --kubernetes-version=v1.28.3 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers --cri-socket unix:///run/cri-dockerd.sock

出现:

[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.28.3

[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.28.3

[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.28.3

[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.28.3

[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9

[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.9-0

[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.10.1

2.4. 生成kubeadm init的配置文件

kubeadm-init-demo.yaml

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: wgs001.com3yjucgqr276rf # 可以自定义,正则([a-z0-9]{6}).([a-z0-9]{16})
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: ${K8S_API_ADDVERTISE_IP} # 修改成节点ip
  bindPort: 6443
nodeRegistration:
 criSocket: unix:///var/run/cri-dockerd.sock
  imagePullPolicy: IfNotPresent
  name: ${K8S_HOSTNAME} # 节点的hostname
  taints: 
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
  - effect: NoSchedule
    key: node-role.kubernetes.io/control-plane
---
apiServer:
  timeoutForControlPlane: 4m0s
  certSANs: # 主节点IP
  - ${K8S_API_ENDPOINT}
  - ${K8S_API_ADDVERTISE_IP}
apiVersion: kubeadm.k8s.io/v1beta3
controlPlaneEndpoint: "${K8S_API_ENDPOINT}:6443" # 设置高可用地址
certificatesDir: /etc/kubernetes/pki
clusterName: ${K8S_CLUSTER_NAME}
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers # 国内源
kind: ClusterConfiguration
kubernetesVersion: v${K8S_VERSION} # 指定版本
networking:
  dnsDomain: ${K8S_DNS_DOMAIN}
  podSubnet: ${K8S_POD_SUBNET} # 增加指定pod的网段
  serviceSubnet: ${K8S_SERVICE_SUBNET}
scheduler: {}
---
# 用于配置kube-proxy上为Service指定的代理模式: ipvs or iptables
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "${K8S_SERVICE_MODE}"
---
# 指定cgroup
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: "${K8S_CGROUP_DRIVER}"

generate-init-config.sh

#!/bin/bash
# export addresses and other vars
set -a
K8S_API_ENDPOINT=192.168.11.201        # 高可用地址
K8S_API_ADDVERTISE_IP=192.168.11.201   # 节点ip
K8S_VERSION=1.28.3
K8S_CLUSTER_NAME=kubernetes
K8S_SERVICE_MODE=ipvs
K8S_POD_SUBNET="10.200.0.0/16"
K8S_SERVICE_SUBNET="10.100.0.0/16"
K8S_DNS_DOMAIN="wgs.local"
K8S_CGROUP_DRIVER="systemd"
K8S_HOSTNAME="k8s-master"
set +a

envsubst < kubeadm-init-demo.yaml > kubeadm-init-config.yaml

生成配置文件

bash generate-init-config.sh

2.5. 初始化主节点

kubeadm init --config ./kubeadm-init-config.yaml  --upload-certs

遇到问题:

解决

# 安装
# 下载镜像时添加criSocket: unix:///var/run/cri-dockerd.sock

# 重新配置
kubeadm reset
kubeadm init --config ./kubeadm-init-config.yaml  --upload-certs

成功出现:


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/

You can now join any number of the control-plane node running the following command on each as root:

  kubeadm join 192.168.11.201:6443 --token wgs001.com3yjucgqr276rf \
        --discovery-token-ca-cert-hash sha256:e4e5f9cb5fcf3c86eb3c1343d0a563527e7bf2317f5f38af9edfe58487d68304 \
        --control-plane --certificate-key fba1e729d9fa7055d6b612d751985ac84bf3fef5deda3d31a4edf5cfd1621921

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

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

kubeadm join 192.168.11.201:6443 --token wgs001.com3yjucgqr276rf \
        --discovery-token-ca-cert-hash sha256:e4e5f9cb5fcf3c86eb3c1343d0a563527e7bf2317f5f38af9edfe58487d68304 

按照提示要求,创建配置文件目录以及复制配置文件

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

查看节点状态

kubectl  get node

2.6. 安装网络组件

下载 tigera-operator

wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.3/manifests/tigera-operator.yaml

下载 custom-resources

wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.3/manifests/custom-resources.yaml

修改 custom-resources.yaml

# This section includes base Calico installation configuration.
# For more information, see: https://projectcalico.docs.tigera.io/master/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  # Configures Calico networking.
  calicoNetwork:
    # Note: The ipPools section cannot be modified post-install.
    ipPools:
    - blockSize: 26
      cidr: 10.200.0.0/16    # 和 --pod-network-cidr  保持一致
      encapsulation: VXLANCrossSubnet  # VXLAN 跨子网模式
      natOutgoing: Enabled
      nodeSelector: all()
  #registry: myregistry.com     # 定义hub地址
---

# This section configures the Calico API server.
# For more information, see: https://projectcalico.docs.tigera.io/master/reference/installation/api#operator.tigera.io/v1.APIServer
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
  name: default
spec: {}

创建 tigera-operator 资源

kubectl create  -f tigera-operator.yaml 

创建 custom-resources

kubectl create -f custom-resources.yaml

查看 calico 资源

watch kubectl get pods -n calico-system

出現:

calico-kube-controllers-5b9898d88d-zm95k 1/1 Running 0 2m33s

calico-node-bx78n 1/1 Running 0 2m33s

calico-typha-5b474fb786-dj6q5 1/1 Running 0 2m33s

csi-node-driver-f9jqn 2/2 Running 0 2m33s

查看节点状态

kubectl get nodes

出现

NAME STATUS ROLES AGE VERSION

k8s-master Ready control-plane 89m v1.28.3

2.7. 工作节点加入到kubernetes集群

要使用初始化节点生成的命令

一定要加上--cri-socket unix:///run/cri-dockerd.sock,指定容器运行时

kubeadm join 192.168.11.201:6443 \
--token wgs001.com3yjucgqr276rf \
--discovery-token-ca-cert-hash \
sha256:e4e5f9cb5fcf3c86eb3c1343d0a563527e7bf2317f5f38af9edfe58487d68304 \
--cri-socket unix:///run/cri-dockerd.sock

2.8. 添加master节点

因为这里只是单master集群,所以不需要加入master节点,如果有需要可以按照如下的方法加入

在其他两个master节点上,接入主节点

用的是第一个master节点初始化时输出的另一个证书,也就是这部分

kubeadm join 192.168.11.201:6443 --token wgs001.com3yjucgqr276rf \
--discovery-token-ca-cert-hash sha256:e4e5f9cb5fcf3c86eb3c1343d0a563527e7bf2317f5f38af9edfe58487d68304 \
--control-plane --certificate-key fba1e729d9fa7055d6b612d751985ac84bf3fef5deda3d31a4edf5cfd1621921
2.8.1. 令牌过期

如果令牌过期了,重新 获取令牌。(在 master 服务器中 执行)

# 重新获取令牌
kubeadm token create --print-join-command
2.8.2. 节点启动不起来,如下

解决: 为节点服务器配置docker镜像

2.9. 集群自我修复测试

集群自我修复能力测试 (需要 docker 启动的前提下,systemctl start docker)

3台 服务器 分别重启

# 重启
reboot

集群 还是好好的。 nodes 的 STATUS 都是 Ready,查看 pods STATUS 过一会 都是 Running。

2.10. 删除集群节点

驱逐节点上的pod

kubectl drain k8s-node-03 --delete-emptydir-data --force --ignore-daemonsets 

重置节点

kubeadm reset -f --cri-socket unix:///run/cri-dockerd.sock

删除节点

kubectl delete node k8s-node

删除配置信息

rm -rf /etc/kubernetes/ /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni /etc/cni/net.d /var/lib/etcd /run/flannel/   $HOME/.kube/config

2.11. 部署 Dashboard

部署 dashboard(可视化页面),kubernetes 官方提供的可视化界面

2.11.1. 运行 pod(创建资源)(只在 master 服务器中执行)
# 根据 在线配置文件 创建资源
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
2.11.2. 设置访问端口
# 修改配置文件 找到 type,将 ClusterIP 改成 NodePort, k8s端口暴漏
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard

# 找到端口,在安全组放行
kubectl get svc -A |grep kubernetes-dashboard
2.11.3. 访问页面

https://192.168.11.201:32493(要注意是 https,port 是映射的端口,在配置文件查看)

2.11.4. 创建访问账号
# 创建 dash-usr.yaml,加入下面配置
vi dash-usr.yaml

# 创建访问账号,准备一个yaml文件,加入下面配置
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kube-system
#创建角色绑定关系
---
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: dashboard-admin
  namespace: kube-system
---
#创建secret(重点是这个创建secret指定类型为token)
apiVersion: v1
kind: Secret
metadata:
  name: dashboard-admin-secret
  namespace: kube-system
  annotations:
    kubernetes.io/service-account.name: "dashboard-admin" 
type: kubernetes.io/service-account-token

  
# 在 k8s 集群中创建资源
kubectl apply -f dash-usr.yaml

#关联token证书
kubectl patch sa dashboard-admin -p '{"secrets": [{"name": "dashboard-admin-secret"}]}' -n kube-system
#查看token
kubectl get secret -n kube-system $(kubectl get serviceaccount dashboard-admin -n kube-system -o jsonpath='{.secrets[0].name}') -o go-template='{{ .data.token | base64decode }}'
2.11.5. 复制生成的 token,粘贴到页面中,然后登录进去。

建议直接通过kubesphere来使用k8s,操作更加简单明了,强烈推荐!!!