k8s 1.28(cluster)

所有初始化的文件都会放到 /opt/k8s-init 文件夹下,请自行创建 -- mkdir /opt/k8s-init

1. 设备环境

节点名称 节点 IP OS 容器运行时 域名
master1 10.9.0.200 ubuntu20.04 containerd
master2 10.9.0.201 ubuntu20.04 containerd
master3 10.9.0.202 ubuntu20.04 containerd
vip 10.9.0.210 ubuntu20.04 containerd k8s.cloudnative.lucs.top

2. 基础配置(全部节点,除特殊指定)

1. 配置域名映射
root@master1:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 master1

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.9.0.210 k8s.cloudnative.lucs.top
10.9.0.200 master1
10.9.0.201 master2
10.9.0.202 master3
2. 关闭防火墙
sudo ufw status  --->  	inactive为已经关闭。

# 关闭防火墙
sudo ufw disable
3. 关闭 selinux
apt install policycoreutils -y
sed -i 's#SELINUX=permissive#SELINUX=disabled#g' /etc/selinux/config
sestatus -v
SELinux status:                 disabled
4. 设置同步

时间同步很重要! 很重要!! 很重要!!! 后面的证书之类的都会看时间的,一定要配置,反复检查!!!!

全部节点:

apt install -y chrony
systemctl enable --now chrony

master1:

root@master1:~# vim /etc/chrony/chrony.conf

# - 2 sources from 2.ubuntu.pool.ntp.org which is ipv6 enabled as well
# - 1 source from [01].ubuntu.pool.ntp.org each (ipv4 only atm)
# This means by default, up to 6 dual-stack and up to 2 additional IPv4-only
# sources will be used.
# At the same time it retains some protection against one of the entries being
# down (compare to just using one of the lines). See (LP: #1754358) for the
# discussion.
#
# About using servers from the NTP Pool Project in general see (LP: #104525).
# Approved by Ubuntu Technical Board on 2011-02-08.
# See http://www.pool.ntp.org/join.html for more information.
#pool ntp.ubuntu.com        iburst maxsources 4  ##屏蔽这些时间池,用阿里云的时间服务器
#pool 0.ubuntu.pool.ntp.org iburst maxsources 1
#pool 1.ubuntu.pool.ntp.org iburst maxsources 1
#pool 2.ubuntu.pool.ntp.org iburst maxsources 2

server ntp1.aliyun.com iburst   ## 添加阿里云的时钟服务器

allow 10.9.0.0/16      ## 允许 10.9.0.0/16网段的使用本节点的时钟

local stratum 10      ## 这意味着如果外部时间源不可用,系统将使用本地时间作为时间源

# This directive specify the location of the file containing ID/key pairs for
# NTP authentication.
keyfile /etc/chrony/chrony.keys

# This directive specify the file into which chronyd will store the rate
# information.
driftfile /var/lib/chrony/chrony.drift

# Uncomment the following line to turn logging on.
#log tracking measurements statistics

# Log files location.
logdir /var/log/chrony

# Stop bad estimates upsetting machine clock.
maxupdateskew 100.0

# This directive enables kernel synchronisation (every 11 minutes) of the
# real-time clock. Note that it can’t be used along with the 'rtcfile' directive.
rtcsync

# Step the system clock instead of slewing it if the adjustment is larger than
# one second, but only in the first three clock updates.
makestep 1 3

重启 chrony

root@master1:~# systemctl restart chrony

master2,master3

root@master2:~# vim /etc/chrony/chrony.conf

## 禁调时间池,添加master1为自己的时间服务器
server 10.9.0.200 iburst

root@master3:~# vim /etc/chrony/chrony.conf

## 禁调时间池,添加master1为自己的时间服务器
server 10.9.0.200 iburst

重启 chrony

root@master2:~# systemctl restart chrony
root@master3:~# systemctl restart chrony

chrony 的配置文件详解:

1. #pool ntp.ubuntu.com iburst maxsources 4
这几行配置原本是用于设置 Ubuntu 的默认 NTP 服务器池(通过 ntp.ubuntu.com 和 ubuntu.pool.ntp.org 提供)。每行指定了一个 NTP 服务器池,并且用 maxsources 限制了最多使用的时间源数量。
这些行被注释掉了,意味着它们不会被使用,因为你决定使用阿里云的时间服务器。

2. server ntp1.aliyun.com iburst
这一行指定了使用阿里云的 ntp1.aliyun.com 作为时间同步服务器。
iburst 选项用于在初次连接时快速同步时间。如果连接不上服务器,chrony 会快速发送一系列请求,以便更快地同步时间。

3. allow 10.9.0.0/16
这个配置允许 10.9.0.0/16 网段内的设备访问并使用此 chrony 服务器来同步时间。
这通常用于在局域网内提供时间同步服务。

4. local stratum 10
这个配置指定了本地时间源的 Stratum 值为 10。当无法访问外部时间服务器时,chrony 将使用本地系统时钟作为时间源,并标记为 Stratum 10。
Stratum 值越高,表示时间的准确性越低,这样设置的目的是确保即使外部时间源不可用,系统仍然有一个可用的时间参考。

5. keyfile /etc/chrony/chrony.keys
这个指令指定了 NTP 认证使用的密钥文件的位置。该文件包含了 ID 和密钥对,用于 NTP 服务器和客户端之间的身份验证。

6. driftfile /var/lib/chrony/chrony.drift
这个指令指定了漂移文件的位置。漂移文件用于记录本地时钟的频率偏移,这样 chrony 可以在下次启动时进行更准确的时间校准。

7. #log tracking measurements statistics
这个行被注释掉了。它的作用是开启日志记录,包括时间跟踪、测量和统计信息。你可以取消注释来启用这些日志记录。

8. logdir /var/log/chrony
这个配置指定了 chrony 日志文件的存放目录。

9. maxupdateskew 100.0
这个选项用于限制时间更新的最大偏移量,单位为秒。该设置用于防止较大的时间偏差影响系统时钟。

10. rtcsync
这个指令启用了每 11 分钟一次的内核时间同步功能,用于将系统时间与硬件实时时钟 (RTC) 同步。请注意,这个设置与 rtcfile 指令不兼容。

11. makestep 1 3
这个选项指定如果时间调整超过 1 秒,在首次的三次时间更新中,chrony 会直接跳步调整系统时间,而不是逐渐校正。这对于系统启动时确保快速同步时间非常有用。
5. 配置内核参数

安装网桥

apt -y install bridge-util

加载 br_netfilter​ 内核模块,用于桥接网络过滤功能的.

modprobe br_netfilter

查看模块

lsmod | grep br_netfilter

修改内核参数配置

## 进入配置文件,将下面配置复制到文件末尾
vim /etc/sysctl.conf

net.ipv4.ip_forward=1  #启用ipv4转发
net.ipv6.conf.all.disable_ipv6=1  #禁用ipv6协议
vm.swappiness=0  #禁止使用swap空间,只有当系统OOM时才允许使用它
vm.overcommit_memory=1  #不检查物理内存是否够用
vm.panic_on_oom=0  #不启OOM
#网桥模式开启
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-arptables = 1

修改 rp_filter 内核参数

vim /etc/sysctl.d/10-network-security.conf
# Turn on Source Address Verification in all interfaces to
# prevent some spoofing attacks.
net.ipv4.conf.default.rp_filter=2
net.ipv4.conf.all.rp_filter=1

加载和应用内核参数

sysctl --system
6. 配置 ipvs

下载 ipvs

apt -y install ipvsadm ipset

配置参数

sudo cat > /opt/k8s-init/ipvs.modules <<'EOF'
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_lc
modprobe -- ip_vs_lblc
modprobe -- ip_vs_lblcr
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- ip_vs_dh
modprobe -- ip_vs_fo
modprobe -- ip_vs_nq
modprobe -- ip_vs_sed
modprobe -- ip_vs_ftp
modprobe -- ip_vs_sh
modprobe -- ip_tables
modprobe -- ip_set
modprobe -- ipt_set
modprobe -- ipt_rpfilter
modprobe -- ipt_REJECT
modprobe -- ipip
modprobe -- xt_set
modprobe -- br_netfilter
modprobe -- nf_conntrack
EOF

加载 ipvs 配置

sudo chmod 755 /opt/k8s-init/ipvs.modules && sudo bash /opt/k8s-init/ipvs.modules

## 确保重启后依然可以加载配置
sudo cp /opt/k8s-init/ipvs.modules /etc/profile.d/ipvs.modules.sh

查看是否生效

lsmod | grep -e ip_vs -e nf_conntrack
ip_vs_ftp              16384  0
ip_vs_sed              16384  0
ip_vs_nq               16384  0
ip_vs_fo               16384  0
ip_vs_dh               16384  0
ip_vs_sh               16384  0
ip_vs_wrr              16384  0
ip_vs_rr               16384  0
ip_vs_lblcr            16384  0
ip_vs_lblc             16384  0
ip_vs_lc               16384  0
ip_vs                 180224  22 ip_vs_rr,ip_vs_dh,ip_vs_lblcr,ip_vs_sh,ip_vs_fo,ip_vs_nq,ip_vs_lblc,ip_vs_wrr,ip_vs_lc,ip_vs_sed,ip_vs_ftp
nf_nat                 49152  4 xt_nat,nft_chain_nat,xt_MASQUERADE,ip_vs_ftp
nf_conntrack_netlink    53248  0
nf_conntrack          180224  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  5 nft_compat,nf_conntrack_netlink,nf_tables,ip_set
libcrc32c              16384  6 nf_conntrack,nf_nat,btrfs,nf_tables,raid456,ip_vs

3. 安装 containerd(全部节点)

  1. containerd 安装1

  2. 更改配置


vim /etc/containerd/config.toml

// 将镜像改为阿里云的
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"

4. 安装 kubeadm、kubectl、kubelet(全部节点)

  1. 导入 kuberntes 的清华源
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
  1. 创建源文件
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/kubernetes/core:/stable:/v1.28/deb/ /" > /etc/apt/sources.list.d/kubernetes.list
  1. 安装工具
// 直接安装
apt install -y kubelet kubeadm kubectl

//也可以安装特定版本
apt-cache madison kubectl | more
export KUBERNETES_VERSION=1.28.1-00
apt-get install -y kubelet=${KUBERNETES_VERSION} kubeadm=${KUBERNETES_VERSION} kubectl=${KUBERNETES_VERSION}

// 保证软件不会更新
apt-mark hold kubelet kubeadm kubectl 
  1. 启动 kubelet
systemctl enable --now kubelet

5. 部署 kube-vip

官网地址 | kube-vip

  1. 生成清单(master1)
root@master1:/opt/k8s-init# export VIP=10.9.0.210
root@master1:/opt/k8s-init# export INTERFACE=ens160
root@master1:/opt/k8s-init# export KVVERSION=v0.8.0

root@master1:/opt/k8s-init# alias kube-vip="ctr image pull ghcr.io/kube-vip/kube-vip:$KVVERSION; ctr run --rm --net-host ghcr.io/kube-vip/kube-vip:$KVVERSION vip /kube-vip"

// 生成清单
root@master1:/opt/k8s-init# kube-vip manifest pod \
>     --interface $INTERFACE \
>     --address $VIP \
>     --controlplane \
>     --services \
>     --arp \
>     --leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml
  1. 查看 arp 清单(master1)
root@master1:/opt/k8s-init# cat /etc/kubernetes/manifests/kube-vip.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  name: kube-vip
  namespace: kube-system
spec:
  containers:
  - args:
    - manager
    env:
    - name: vip_arp
      value: "true"
    - name: port
      value: "6443"
    - name: vip_nodename
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: vip_interface
      value: ens160
    - name: vip_cidr
      value: "32"
    - name: dns_mode
      value: first
    - name: cp_enable
      value: "true"
    - name: cp_namespace
      value: kube-system
    - name: svc_enable
      value: "true"
    - name: svc_leasename
      value: plndr-svcs-lock
    - name: vip_leaderelection
      value: "true"
    - name: vip_leasename
      value: plndr-cp-lock
    - name: vip_leaseduration
      value: "5"
    - name: vip_renewdeadline
      value: "3"
    - name: vip_retryperiod
      value: "1"
    - name: address
      value: 10.9.0.210
    - name: prometheus_server
      value: :2112
    image: ghcr.io/kube-vip/kube-vip:v0.8.0
    imagePullPolicy: IfNotPresent
    name: kube-vip
    resources: {}
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
        - NET_RAW
    volumeMounts:
    - mountPath: /etc/kubernetes/admin.conf
      name: kubeconfig
  hostAliases:
  - hostnames:
    - kubernetes
    ip: 127.0.0.1
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/kubernetes/admin.conf
    name: kubeconfig
status: {}
  1. 将清单发给 master2 和 master3(master1)
root@master1:/opt/k8s-init# scp /etc/kubernetes/manifests/kube-vip.yaml master2:/etc/kubernetes/manifests/kube-vip.yaml
root@master1:/opt/k8s-init# scp /etc/kubernetes/manifests/kube-vip.yaml master3:/etc/kubernetes/manifests/kube-vip.yaml
  1. master2 和 master3 节点分别拉取清单中的镜像(master2 和 master3)
root@master2:/opt/k8s-init# nerdctl pull ghcr.io/kube-vip/kube-vip:v0.8.0
root@master3:/opt/k8s-init# nerdctl pull ghcr.io/kube-vip/kube-vip:v0.8.0

6. 初始化集群(master1)

1. 生成配置文件
root@master1:/opt/k8s-init# kubeadm config print init-defaults --component-configs KubeProxyConfiguration > kubeadm.yaml
2. 更改配置文件
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: 10.9.0.200   // 更改为本机ip
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  name: master1 // 更改为本机用户名
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
  certSANs:  // 为下面的域名和ip签证
  - k8s.cloudnative.lucs.top
  - master1
  - master2
  - master3
  - 10.9.0.210
  - 10.9.0.200
  - 10.9.0.201
  - 10.9.0.202
controlPlaneEndpoint: k8s.cloudnative.lucs.top:6443 //开启控制平面的加入
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 // 更改镜像仓库
kind: ClusterConfiguration
kubernetesVersion: 1.28.1 // 更改为自己的版本
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.244.0.0/16 //更改 pod 地址
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
bindAddressHardFail: false
clientConnection:
  acceptContentTypes: ""
  burst: 0
  contentType: ""
  kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
  qps: 0
clusterCIDR: ""
configSyncPeriod: 0s
conntrack:
  maxPerCore: null
  min: null
  tcpCloseWaitTimeout: null
  tcpEstablishedTimeout: null
detectLocal:
  bridgeInterface: ""
  interfaceNamePrefix: ""
detectLocalMode: ""
enableProfiling: false
healthzBindAddress: ""
hostnameOverride: ""
iptables:
  localhostNodePorts: null
  masqueradeAll: false
  masqueradeBit: null
  minSyncPeriod: 0s
  syncPeriod: 0s
ipvs:
  excludeCIDRs: null
  minSyncPeriod: 0s
  scheduler: ""
  strictARP: false
  syncPeriod: 0s
  tcpFinTimeout: 0s
  tcpTimeout: 0s
  udpTimeout: 0s
kind: KubeProxyConfiguration
logging:
  flushFrequency: 0
  options:
    json:
      infoBufferSize: "0"
  verbosity: 0
metricsBindAddress: ""
mode: "ipvs"  // 更改为ipvs
nodePortAddresses: null
oomScoreAdj: null
portRange: ""
showHiddenMetricsForVersion: ""
winkernel:
  enableDSR: false
  forwardHealthCheckVip: false
  networkName: ""
  rootHnsEndpointName: ""
  sourceVip: ""
3. 初始化节点
root@master1:/opt/k8s-init# kubeadm init --upload-certs --config kubeadm.yaml

信息如下

[init] Using Kubernetes version: v1.28.1
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s.cloudnative.lucs.top kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master1 master2 master3] and IPs [10.96.0.1 10.9.0.200 10.9.0.210 10.9.0.201 10.9.0.202]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost master1] and IPs [10.9.0.200 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost master1] and IPs [10.9.0.200 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[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
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[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"
[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
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 12.505639 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
c68c96e5b844f13f0e4aee4508c583195a821c958504a177e4a2deb6485e1ac0
[mark-control-plane] Marking the node master1 as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node master1 as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
[bootstrap-token] Using token: abcdef.0123456789abcdef
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

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 k8s.cloudnative.lucs.top:6443 --token abcdef.0123456789abcdef \
	--discovery-token-ca-cert-hash sha256:79600be0419be6be354927b90146a4e0eb1153daf551da1571c548491cfff965 \
	--control-plane --certificate-key c68c96e5b844f13f0e4aee4508c583195a821c958504a177e4a2deb6485e1ac0

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 k8s.cloudnative.lucs.top:6443 --token abcdef.0123456789abcdef \
	--discovery-token-ca-cert-hash sha256:79600be0419be6be354927b90146a4e0eb1153daf551da1571c548491cfff965

执行

root@master1:/opt/k8s-init# mkdir -p $HOME/.kube
root@master1:/opt/k8s-init# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
root@master1:/opt/k8s-init# sudo chown $(id -u):$(id -g) $HOME/.kube/config

控制平面 可以通过下面加入集群

  kubeadm join k8s.cloudnative.lucs.top:6443 --token abcdef.0123456789abcdef \
	--discovery-token-ca-cert-hash sha256:79600be0419be6be354927b90146a4e0eb1153daf551da1571c548491cfff965 \
	--control-plane --certificate-key c68c96e5b844f13f0e4aee4508c583195a821c958504a177e4a2deb6485e1ac0

数据平面 可以通过下面加入集群

kubeadm join k8s.cloudnative.lucs.top:6443 --token abcdef.0123456789abcdef \
	--discovery-token-ca-cert-hash sha256:79600be0419be6be354927b90146a4e0eb1153daf551da1571c548491cfff965

7. 加入控制平面

master2

root@master2:~# kubeadm join k8s.cloudnative.lucs.top:6443 --token abcdef.0123456789abcdef \
> --discovery-token-ca-cert-hash sha256:79600be0419be6be354927b90146a4e0eb1153daf551da1571c548491cfff965 \
> --control-plane --certificate-key c68c96e5b844f13f0e4aee4508c583195a821c958504a177e4a2deb6485e1ac0

信息如下:

[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'
[preflight] Running pre-flight checks before initializing the new control plane instance
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[download-certs] Downloading the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[download-certs] Saving the certificates to the folder: "/etc/kubernetes/pki"
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s.cloudnative.lucs.top kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master1 master2 master3] and IPs [10.96.0.1 10.9.0.201 10.9.0.210 10.9.0.200 10.9.0.202]
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost master2] and IPs [10.9.0.201 127.0.0.1 ::1]
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost master2] and IPs [10.9.0.201 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[certs] Using the existing "sa" key
[kubeconfig] Generating kubeconfig files
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[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"
[check-etcd] Checking that the etcd cluster is healthy
[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...
[etcd] Announced new etcd member joining to the existing etcd cluster
[etcd] Creating static Pod manifest for "etcd"
[etcd] Waiting for the new etcd member to join the cluster. This can take up to 40s
The 'update-status' phase is deprecated and will be removed in a future release. Currently it performs no operation
[mark-control-plane] Marking the node master2 as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node master2 as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]

This node has joined the cluster and a new control plane instance was created:

* Certificate signing request was sent to apiserver and approval was received.
* The Kubelet was informed of the new secure connection details.
* Control plane label and taint were applied to the new node.
* The Kubernetes control plane instances scaled up.
* A new etcd member was added to the local/stacked etcd cluster.

To start administering your cluster from this node, 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

Run 'kubectl get nodes' to see this node join the cluster.

执行:

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

master3:

root@master3:~# kubeadm join k8s.cloudnative.lucs.top:6443 --token abcdef.0123456789abcdef \
> --discovery-token-ca-cert-hash sha256:79600be0419be6be354927b90146a4e0eb1153daf551da1571c548491cfff965 \
> --control-plane --certificate-key c68c96e5b844f13f0e4aee4508c583195a821c958504a177e4a2deb6485e1ac0

信息如下:

[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'
[preflight] Running pre-flight checks before initializing the new control plane instance
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[download-certs] Downloading the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[download-certs] Saving the certificates to the folder: "/etc/kubernetes/pki"
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s.cloudnative.lucs.top kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master1 master2 master3] and IPs [10.96.0.1 10.9.0.202 10.9.0.210 10.9.0.200 10.9.0.201]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost master3] and IPs [10.9.0.202 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost master3] and IPs [10.9.0.202 127.0.0.1 ::1]
[certs] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[certs] Using the existing "sa" key
[kubeconfig] Generating kubeconfig files
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[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"
[check-etcd] Checking that the etcd cluster is healthy
[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...
{"level":"warn","ts":"2024-09-05T02:45:15.10704+0800","logger":"etcd-client","caller":"v3@v3.5.9/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00060b880/10.9.0.201:2379","attempt":0,"error":"rpc error: code = Unavailable desc = etcdserver: unhealthy cluster"}
{"level":"warn","ts":"2024-09-05T02:45:15.216045+0800","logger":"etcd-client","caller":"v3@v3.5.9/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00060b880/10.9.0.201:2379","attempt":0,"error":"rpc error: code = Unavailable desc = etcdserver: unhealthy cluster"}
{"level":"warn","ts":"2024-09-05T02:45:15.380315+0800","logger":"etcd-client","caller":"v3@v3.5.9/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00060b880/10.9.0.201:2379","attempt":0,"error":"rpc error: code = Unavailable desc = etcdserver: unhealthy cluster"}
{"level":"warn","ts":"2024-09-05T02:45:15.616802+0800","logger":"etcd-client","caller":"v3@v3.5.9/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00060b880/10.9.0.201:2379","attempt":0,"error":"rpc error: code = Unavailable desc = etcdserver: unhealthy cluster"}
{"level":"warn","ts":"2024-09-05T02:45:15.958678+0800","logger":"etcd-client","caller":"v3@v3.5.9/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00060b880/10.9.0.201:2379","attempt":0,"error":"rpc error: code = Unavailable desc = etcdserver: unhealthy cluster"}
{"level":"warn","ts":"2024-09-05T02:45:16.504533+0800","logger":"etcd-client","caller":"v3@v3.5.9/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00060b880/10.9.0.201:2379","attempt":0,"error":"rpc error: code = Unavailable desc = etcdserver: unhealthy cluster"}
{"level":"warn","ts":"2024-09-05T02:45:17.303892+0800","logger":"etcd-client","caller":"v3@v3.5.9/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00060b880/10.9.0.201:2379","attempt":0,"error":"rpc error: code = Unavailable desc = etcdserver: unhealthy cluster"}
{"level":"warn","ts":"2024-09-05T02:45:18.530751+0800","logger":"etcd-client","caller":"v3@v3.5.9/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00060b880/10.9.0.201:2379","attempt":0,"error":"rpc error: code = Unavailable desc = etcdserver: unhealthy cluster"}
[etcd] Announced new etcd member joining to the existing etcd cluster
[etcd] Creating static Pod manifest for "etcd"
[etcd] Waiting for the new etcd member to join the cluster. This can take up to 40s
The 'update-status' phase is deprecated and will be removed in a future release. Currently it performs no operation
[mark-control-plane] Marking the node master3 as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node master3 as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]

This node has joined the cluster and a new control plane instance was created:

* Certificate signing request was sent to apiserver and approval was received.
* The Kubelet was informed of the new secure connection details.
* Control plane label and taint were applied to the new node.
* The Kubernetes control plane instances scaled up.
* A new etcd member was added to the local/stacked etcd cluster.

To start administering your cluster from this node, 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

Run 'kubectl get nodes' to see this node join the cluster.

执行

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

8. 去除污点

去除控制平面不能调度的污点,在任意一台执行

root@master1:/opt/k8s-init# kubectl taint nodes --all node-role.kubernetes.io/control-plane-
node/master1 untainted
node/master2 untainted
node/master3 untainted

9. 安装 cni(calico)(master1)

官方 | calico

containerd 的插件必需安装到/opt/cni/bin 中,如下

CNI plug-in enabled

Calico must be installed as a CNI plugin in the container runtime.

This installation must use the Kubernetes default CNI configuration directory (/etc/cni/net.d​) and binary directory (/opt/cni/bin​).

1. 下载 calico 的 manifest 文件
// 这个文件时calico的crd文件
root@master1:/opt/k8s-init# curl -LO https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/tigera-operator.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1724k  100 1724k    0     0  48087      0  0:00:36  0:00:36 --:--:-- 23252

// 这个是利用crd创建的cr
root@master1:/opt/k8s-init# curl -OL https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/custom-resources.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   777  100   777    0     0    219      0  0:00:03  0:00:03 --:--:--   219
2. 部署 crd 文件(一定要用 kubectl create )
root@master1:/opt/k8s-init# kubectl create -f tigera-operator.yaml
namespace/tigera-operator created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgpfilters.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/apiservers.operator.tigera.io created
customresourcedefinition.apiextensions.k8s.io/imagesets.operator.tigera.io created
customresourcedefinition.apiextensions.k8s.io/installations.operator.tigera.io created
customresourcedefinition.apiextensions.k8s.io/tigerastatuses.operator.tigera.io created
serviceaccount/tigera-operator created
clusterrole.rbac.authorization.k8s.io/tigera-operator created
clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created
deployment.apps/tigera-operator created

会创建很多的 crd,并且创建了一个 sa 和 rbac 用于提供权限,还创建了一个 deployment 作为控制器.

3. 部署 cr

修改 cr 文件

# This section includes base Calico installation configuration.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  # 配置 Calico 网络
  calicoNetwork:
    ipPools:
    - name: default-ipv4-ippool
      blockSize: 26
      cidr: 10.244.0.0/16
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()

    # 配置 IP 地址自动检测方法
    nodeAddressAutodetectionV4:
      interface: ens160  # 通过网卡名称指定

---

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

创建

root@master1:/opt/k8s-init# kubectl create -f custom-resources.yaml
installation.operator.tigera.io/default created
apiserver.operator.tigera.io/default created

10. 全部服务(完美收尾 😍)

root@master1:/opt/k8s-init# kubectl get pods -A -owide
NAMESPACE          NAME                                       READY   STATUS    RESTARTS            AGE         IP              NODE      NOMINATED NODE   READINESS GATES
calico-apiserver   calico-apiserver-647c596749-9l22f          1/1     Running   0                   4m42s       10.244.137.66   master1   <none>           <none>
calico-apiserver   calico-apiserver-647c596749-fnclw          1/1     Running   0                   4m42s       10.244.136.2    master3   <none>           <none>
calico-system      calico-kube-controllers-6bcd4db96d-g2k9p   1/1     Running   0                   5m57s       10.244.180.1    master2   <none>           <none>
calico-system      calico-node-l5lzs                          1/1     Running   0                   5m58s       10.9.0.201      master2   <none>           <none>
calico-system      calico-node-qxbrk                          1/1     Running   0                   5m58s       10.9.0.200      master1   <none>           <none>
calico-system      calico-node-wnc2c                          1/1     Running   0                   5m58s       10.9.0.202      master3   <none>           <none>
calico-system      calico-typha-cbb7d497f-bkwpp               1/1     Running   0                   5m58s       10.9.0.202      master3   <none>           <none>
calico-system      calico-typha-cbb7d497f-hbv9m               1/1     Running   0                   5m54s       10.9.0.200      master1   <none>           <none>
calico-system      csi-node-driver-57fb5                      2/2     Running   0                   5m57s       10.244.137.65   master1   <none>           <none>
calico-system      csi-node-driver-5f9jf                      2/2     Running   0                   5m57s       10.244.180.2    master2   <none>           <none>
calico-system      csi-node-driver-fzfdj                      2/2     Running   0                   5m57s       10.244.136.1    master3   <none>           <none>
kube-system        coredns-66f779496c-d8b2f                   1/1     Running   0                   4h48m       10.4.0.5        master1   <none>           <none>
kube-system        coredns-66f779496c-xrt24                   1/1     Running   0                   4h48m       10.4.0.4        master1   <none>           <none>
kube-system        etcd-master1                               1/1     Running   2                   4h48m       10.9.0.200      master1   <none>           <none>
kube-system        etcd-master2                               1/1     Running   0                   4h43m       10.9.0.201      master2   <none>           <none>
kube-system        etcd-master3                               1/1     Running   0                   <invalid>   10.9.0.202      master3   <none>           <none>
kube-system        kube-apiserver-master1                     1/1     Running   0                   4h48m       10.9.0.200      master1   <none>           <none>
kube-system        kube-apiserver-master2                     1/1     Running   0                   4h43m       10.9.0.201      master2   <none>           <none>
kube-system        kube-apiserver-master3                     1/1     Running   0                   4h43m       10.9.0.202      master3   <none>           <none>
kube-system        kube-controller-manager-master1            1/1     Running   0                   4h48m       10.9.0.200      master1   <none>           <none>
kube-system        kube-controller-manager-master2            1/1     Running   0                   4h43m       10.9.0.201      master2   <none>           <none>
kube-system        kube-controller-manager-master3            1/1     Running   0                   4h43m       10.9.0.202      master3   <none>           <none>
kube-system        kube-proxy-rz59w                           1/1     Running   0                   4h43m       10.9.0.201      master2   <none>           <none>
kube-system        kube-proxy-t8f2z                           1/1     Running   0                   4h43m       10.9.0.202      master3   <none>           <none>
kube-system        kube-proxy-wbpmc                           1/1     Running   0                   4h48m       10.9.0.200      master1   <none>           <none>
kube-system        kube-scheduler-master1                     1/1     Running   0                   4h48m       10.9.0.200      master1   <none>           <none>
kube-system        kube-scheduler-master2                     1/1     Running   0                   4h43m       10.9.0.201      master2   <none>           <none>
kube-system        kube-scheduler-master3                     1/1     Running   0                   4h43m       10.9.0.202      master3   <none>           <none>
kube-system        kube-vip-master1                           1/1     Running   0                   4h37m       10.9.0.200      master1   <none>           <none>
kube-system        kube-vip-master2                           1/1     Running   1 (<invalid> ago)   4h43m       10.9.0.201      master2   <none>           <none>
kube-system        kube-vip-master3                           1/1     Running   0                   4h43m       10.9.0.202      master3   <none>           <none>
tigera-operator    tigera-operator-5d56685c77-5lgj4           1/1     Running   0                   6m51s       10.9.0.201      master2   <none>           <none>

测试一下:

部署一个 nginx 服务

kubernetes apply -f nginx.yaml

nginx.yaml 服务信息如下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginxapp
spec:
  selector:
    matchLabels:
      app: nginxapp
  template:
    metadata:
      labels:
        app: nginxapp
    spec:
      containers:
      - name: nginxapp
        image: registry.cn-hangzhou.aliyuncs.com/lucs/nginx
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginxapp
spec:
  selector:
    app: nginxapp
  type: NodePort
  ports:
  - port: 80
    targetPort: 80

这里使用我们的 vip,访问成功

image

测试一下 kube-vip 的 lb 功能,具体看这里配置 | lb

修改 nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginxapp
spec:
  selector:
    matchLabels:
      app: nginxapp
  template:
    metadata:
      labels:
        app: nginxapp
    spec:
      containers:
      - name: nginxapp
        image: registry.cn-hangzhou.aliyuncs.com/lucs/nginx
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginxapp
spec:
  selector:
    app: nginxapp
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  loadBalancerIP: 10.9.0.233

创建

kubernetes apply -f nginx.yaml

kubectl get po,svc
NAME                            READY   STATUS    RESTARTS   AGE
pod/nginxapp-67d9758fbf-ggv9h   1/1     Running   0          10s

NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP        14h
service/nginxapp     LoadBalancer   10.104.121.11   10.9.0.233    80:30166/TCP   10s

访问 10.9.0.233

image


  1. containerd 安装部署

    containerd 官方安装文档 | containerd

    nerdctl 官方安装包 | nerdctl

    一、安装二进制包

    两种安装方式:

    1. 单独安装(推荐):

    containerd 的官方二进制版本适用于 amd64​(也称为 x86_64​)和 arm64​(也称为 aarch64​)架构。

    通常,您还必须 从其官方网站安装 runcCNI 插件。

    步骤 1:安装 containerd

    containerd-<VERSION>-<OS>-<ARCH>.tar.gz​从 https://github.com/containerd/containerd/releases 下载档案,验证其 sha256sum,并将其解压到 /usr/local​:

    $ tar Cxzvf /usr/local containerd-1.6.2-linux-amd64.tar.gz
    bin/
    bin/containerd-shim-runc-v2
    bin/containerd-shim
    bin/ctr
    bin/containerd-shim-runc-v1
    bin/containerd
    bin/containerd-stress
    

    containerd​二进制文件是针对基于 glibc 的 Linux 发行版(例如 Ubuntu 和 Rocky Linux)动态构建的。此二进制文件可能无法在基于 musl 的发行版(例如 Alpine Linux)上运行。此类发行版的用户可能必须从源代码或第三方软件包安装 containerd。

    常见问题解答:对于 Kubernetes,我也需要下载吗 cri-containerd-(cni-)<VERSION>-<OS-<ARCH>.tar.gz​?

    答案:不是。

    由于 Kubernetes CRI 功能已经包含在内 containerd-<VERSION>-<OS>-<ARCH>.tar.gz​,因此您无需下载 cri-containerd-....​档案即可使用 CRI。

    这些 cri-containerd-...​档案已被弃用,不适用于旧的 Linux 发行版,并将在 containerd 2.0 中删除。

    systemd

    如果你打算通过 systemd 启动 containerd,你还应该 containerd.service​从 https://raw.githubusercontent.com/containerd/containerd/main/containerd.service 下载单元文件到 /etc/systemd/system/containerd.service​,并运行以下命令:

    systemctl daemon-reload
    systemctl enable --now containerd
    

    第 2 步:安装 runc

    runc.<ARCH>​从 https://github.com/opencontainers/runc/releases 下载二进制文件,验证其 sha256sum,并将其安装为 /usr/local/sbin/runc​。

    $ install -m 755 runc.amd64 /usr/local/sbin/runc
    

    二进制文件是静态构建的,应该可以在任何 Linux 发行版上运行。

    步骤 3:安装 CNI 插件(不要更改/opt/cni/bin 的位置)

    cni-plugins-<OS>-<ARCH>-<VERSION>.tgz​从 https://github.com/containernetworking/plugins/releases 下载档案,验证其 sha256sum,然后将其解压到 /opt/cni/bin​:

    $ mkdir -p /opt/cni/bin
    $ tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.1.1.tgz
    ./
    ./macvlan
    ./static
    ./vlan
    ./portmap
    ./host-local
    ./vrf
    ./bridge
    ./tuning
    ./firewall
    ./host-device
    ./sbr
    ./loopback
    ./dhcp
    ./ptp
    ./ipvlan
    ./bandwidth
    

    二进制文件是静态构建的,应该可以在任何 Linux 发行版上运行。

    步骤 4: 安装 nerdctl

    https://github.com/containerd/nerdctl/releases 从这个页面进行下载,然后将其解压到 /usr/local/bin

    tar Cxzvvf /usr/local/bin nerdctl-1.7.6-linux-amd64.tar.gz
    -rwxr-xr-x root/root  25116672 2024-04-30 06:21 nerdctl
    -rwxr-xr-x root/root     21916 2024-04-30 06:20 containerd-rootless-setuptool.sh
    -rwxr-xr-x root/root      7187 2024-04-30 06:20 containerd-rootless.sh
    

    步骤 5: 更改 containerd 配置

    生成配置文件

    containerd config default > /etc/containerd/config.toml
    

    更改镜像配置目录

    vim /etc/containerd/config.toml
        [plugins."io.containerd.grpc.v1.cri".registry]
          config_path = "/etc/containerd/certs.d"
    
          [plugins."io.containerd.grpc.v1.cri".registry.auths]
    
          [plugins."io.containerd.grpc.v1.cri".registry.configs]
    
          [plugins."io.containerd.grpc.v1.cri".registry.headers]
    
          [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    
        [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
          tls_cert_file = ""
          tls_key_file = ""
    

    2. 全部安装

    步骤 1: 下载安装包

    打开链接 https://github.com/containerd/nerdctl/releases ,下载带有 full 的包.

    image-20240903105109-x3rsywj

    下载

    curl -LO https://github.com/containerd/nerdctl/releases/download/v1.7.6/nerdctl-full-1.7.6-linux-amd64.tar.gz
    

    步骤 2: 解压压缩包

    tar Cxzvvf /usr/local nerdctl-full-1.7.6-linux-amd64.tar.gz
    
    drwxr-xr-x 0/0               0 2024-04-30 06:28 bin/
    -rwxr-xr-x 0/0        27644700 2015-10-21 00:00 bin/buildctl
    -rwxr-xr-x 0/0        23724032 2022-09-05 09:52 bin/buildg
    -rwxr-xr-x 0/0        53374823 2015-10-21 00:00 bin/buildkitd
    -rwxr-xr-x 0/0         7277848 2024-04-30 06:26 bin/bypass4netns
    -rwxr-xr-x 0/0         5308416 2024-04-30 06:26 bin/bypass4netnsd
    -rwxr-xr-x 0/0        38946168 2024-04-30 06:27 bin/containerd
    -rwxr-xr-x 0/0         9474048 2023-11-02 17:34 bin/containerd-fuse-overlayfs-grpc
    -rwxr-xr-x 0/0           21916 2024-04-30 06:26 bin/containerd-rootless-setuptool.sh
    -rwxr-xr-x 0/0            7187 2024-04-30 06:26 bin/containerd-rootless.sh
    -rwxr-xr-x 0/0        12161024 2024-04-30 06:28 bin/containerd-shim-runc-v2
    -rwxr-xr-x 0/0        45903872 2023-10-31 08:57 bin/containerd-stargz-grpc
    -rwxr-xr-x 0/0        20630617 2024-04-30 06:28 bin/ctd-decoder
    -rwxr-xr-x 0/0        18870272 2024-04-30 06:27 bin/ctr
    -rwxr-xr-x 0/0        29671743 2024-04-30 06:28 bin/ctr-enc
    -rwxr-xr-x 0/0        19931136 2023-10-31 08:58 bin/ctr-remote
    -rwxr-xr-x 0/0         1785448 2024-04-30 06:28 bin/fuse-overlayfs
    -rwxr-xr-x 0/0        65589641 2024-04-30 06:27 bin/ipfs
    -rwxr-xr-x 0/0        25088000 2024-04-30 06:26 bin/nerdctl
    -rwxr-xr-x 0/0        10666181 2024-03-05 22:20 bin/rootlessctl
    -rwxr-xr-x 0/0        12358373 2024-03-05 22:20 bin/rootlesskit
    -rwxr-xr-x 0/0        15074072 2024-04-30 06:26 bin/runc
    -rwxr-xr-x 0/0         2346328 2024-04-30 06:28 bin/slirp4netns
    -rwxr-xr-x 0/0          870496 2024-04-30 06:28 bin/tini
    drwxr-xr-x 0/0               0 2024-04-30 06:28 lib/
    drwxr-xr-x 0/0               0 2024-04-30 06:28 lib/systemd/
    drwxr-xr-x 0/0               0 2024-04-30 06:28 lib/systemd/system/
    -rw-r--r-- 0/0            1475 2024-04-30 06:28 lib/systemd/system/buildkit.service
    -rw-r--r-- 0/0            1414 2024-04-30 06:25 lib/systemd/system/containerd.service
    -rw-r--r-- 0/0             312 2024-04-30 06:28 lib/systemd/system/stargz-snapshotter.service
    drwxr-xr-x 0/0               0 2024-04-30 06:28 libexec/
    drwxr-xr-x 0/0               0 2024-04-30 06:28 libexec/cni/
    -rw-r--r-- 0/0           11357 2024-03-12 10:56 libexec/cni/LICENSE
    -rw-r--r-- 0/0            2343 2024-03-12 10:56 libexec/cni/README.md
    -rwxr-xr-x 0/0         4119661 2024-03-12 10:56 libexec/cni/bandwidth
    -rwxr-xr-x 0/0         4662227 2024-03-12 10:56 libexec/cni/bridge
    -rwxr-xr-x 0/0        11065251 2024-03-12 10:56 libexec/cni/dhcp
    -rwxr-xr-x 0/0         4306546 2024-03-12 10:56 libexec/cni/dummy
    -rwxr-xr-x 0/0         4751593 2024-03-12 10:56 libexec/cni/firewall
    -rwxr-xr-x 0/0         4198427 2024-03-12 10:56 libexec/cni/host-device
    -rwxr-xr-x 0/0         3560496 2024-03-12 10:56 libexec/cni/host-local
    -rwxr-xr-x 0/0         4324636 2024-03-12 10:56 libexec/cni/ipvlan
    -rwxr-xr-x 0/0         3651038 2024-03-12 10:56 libexec/cni/loopback
    -rwxr-xr-x 0/0         4355073 2024-03-12 10:56 libexec/cni/macvlan
    -rwxr-xr-x 0/0         4095898 2024-03-12 10:56 libexec/cni/portmap
    -rwxr-xr-x 0/0         4476535 2024-03-12 10:56 libexec/cni/ptp
    -rwxr-xr-x 0/0         3861176 2024-03-12 10:56 libexec/cni/sbr
    -rwxr-xr-x 0/0         3120090 2024-03-12 10:56 libexec/cni/static
    -rwxr-xr-x 0/0         4381887 2024-03-12 10:56 libexec/cni/tap
    -rwxr-xr-x 0/0         3743844 2024-03-12 10:56 libexec/cni/tuning
    -rwxr-xr-x 0/0         4319235 2024-03-12 10:56 libexec/cni/vlan
    -rwxr-xr-x 0/0         4008392 2024-03-12 10:56 libexec/cni/vrf
    drwxr-xr-x 0/0               0 2024-04-30 06:26 share/
    drwxr-xr-x 0/0               0 2024-04-30 06:26 share/doc/
    drwxr-xr-x 0/0               0 2024-04-30 06:26 share/doc/nerdctl/
    -rw-r--r-- 0/0           12480 2024-04-30 06:20 share/doc/nerdctl/README.md
    drwxr-xr-x 0/0               0 2024-04-30 06:20 share/doc/nerdctl/docs/
    -rw-r--r-- 0/0            3953 2024-04-30 06:20 share/doc/nerdctl/docs/build.md
    -rw-r--r-- 0/0            2570 2024-04-30 06:20 share/doc/nerdctl/docs/builder-debug.md
    -rw-r--r-- 0/0            3996 2024-04-30 06:20 share/doc/nerdctl/docs/cni.md
    -rw-r--r-- 0/0           74383 2024-04-30 06:20 share/doc/nerdctl/docs/command-reference.md
    -rw-r--r-- 0/0            1814 2024-04-30 06:20 share/doc/nerdctl/docs/compose.md
    -rw-r--r-- 0/0            5329 2024-04-30 06:20 share/doc/nerdctl/docs/config.md
    -rw-r--r-- 0/0            9128 2024-04-30 06:20 share/doc/nerdctl/docs/cosign.md
    -rw-r--r-- 0/0            5660 2024-04-30 06:20 share/doc/nerdctl/docs/cvmfs.md
    -rw-r--r-- 0/0            2435 2024-04-30 06:20 share/doc/nerdctl/docs/dir.md
    -rw-r--r-- 0/0             906 2024-04-30 06:20 share/doc/nerdctl/docs/experimental.md
    -rw-r--r-- 0/0           14217 2024-04-30 06:20 share/doc/nerdctl/docs/faq.md
    -rw-r--r-- 0/0             884 2024-04-30 06:20 share/doc/nerdctl/docs/freebsd.md
    -rw-r--r-- 0/0            3228 2024-04-30 06:20 share/doc/nerdctl/docs/gpu.md
    -rw-r--r-- 0/0           14463 2024-04-30 06:20 share/doc/nerdctl/docs/ipfs.md
    -rw-r--r-- 0/0            1748 2024-04-30 06:20 share/doc/nerdctl/docs/multi-platform.md
    -rw-r--r-- 0/0            2960 2024-04-30 06:20 share/doc/nerdctl/docs/notation.md
    -rw-r--r-- 0/0            2596 2024-04-30 06:20 share/doc/nerdctl/docs/nydus.md
    -rw-r--r-- 0/0            3277 2024-04-30 06:20 share/doc/nerdctl/docs/ocicrypt.md
    -rw-r--r-- 0/0            1876 2024-04-30 06:20 share/doc/nerdctl/docs/overlaybd.md
    -rw-r--r-- 0/0           15657 2024-04-30 06:20 share/doc/nerdctl/docs/registry.md
    -rw-r--r-- 0/0            5088 2024-04-30 06:20 share/doc/nerdctl/docs/rootless.md
    -rw-r--r-- 0/0            2015 2024-04-30 06:20 share/doc/nerdctl/docs/soci.md
    -rw-r--r-- 0/0           10312 2024-04-30 06:20 share/doc/nerdctl/docs/stargz.md
    drwxr-xr-x 0/0               0 2024-04-30 06:28 share/doc/nerdctl-full/
    -rw-r--r-- 0/0            1154 2024-04-30 06:28 share/doc/nerdctl-full/README.md
    -rw-r--r-- 0/0            6578 2024-04-30 06:28 share/doc/nerdctl-full/SHA256SUMS
    

    包含的所有包如下:

    # nerdctl (full distribution)
    - nerdctl: v1.7.6
    - containerd: v1.7.16
    - runc: v1.1.12
    - CNI plugins: v1.4.1
    - BuildKit: v0.12.5
    - Stargz Snapshotter: v0.15.1
    - imgcrypt: v1.1.10
    - RootlessKit: v2.0.2
    - slirp4netns: v1.2.3
    - bypass4netns: v0.4.0
    - fuse-overlayfs: v1.13
    - containerd-fuse-overlayfs: v1.0.8
    - Kubo (IPFS): v0.27.0
    - Tini: v0.19.0
    - buildg: v0.4.1
    
    ## License
    - bin/slirp4netns:    [GNU GENERAL PUBLIC LICENSE, Version 2](https://github.com/rootless-containers/slirp4netns/blob/v1.2.3/COPYING)
    - bin/fuse-overlayfs: [GNU GENERAL PUBLIC LICENSE, Version 2](https://github.com/containers/fuse-overlayfs/blob/v1.13/COPYING)
    - bin/ipfs: [Combination of MIT-only license and dual MIT/Apache-2.0 license](https://github.com/ipfs/kubo/blob/v0.27.0/LICENSE)
    - bin/{runc,bypass4netns,bypass4netnsd}: Apache License 2.0, statically linked with libseccomp ([LGPL 2.1](https://github.com/seccomp/libseccomp/blob/main/LICENSE), source code available at https://github.com/seccomp/libseccomp/)
    - bin/tini: [MIT License](https://github.com/krallin/tini/blob/v0.19.0/LICENSE)
    - Other files: [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
    

    步骤 3: 配置 systemd

    如果你打算通过 systemd 启动 containerd,你还应该 containerd.service​从 https://raw.githubusercontent.com/containerd/containerd/main/containerd.service 下载单元文件到 /etc/systemd/system/containerd.service​,并运行以下命令:

    systemctl daemon-reload
    systemctl enable --now containerd
    

    步骤 4: 更改 containerd 配置

    生成配置文件

    containerd config default > /etc/containerd/config.toml
    

    更改 cni 目录位置

    vim /etc/containerd/config.toml
        [plugins."io.containerd.grpc.v1.cri".cni]
          bin_dir = "/usr/local/libexec/cni"
          conf_dir = "/etc/cni/net.d"
          conf_template = ""
          ip_pref = ""
          max_conf_num = 1
          setup_serially = false
    

    更改镜像配置目录

    vim /etc/containerd/config.toml
        [plugins."io.containerd.grpc.v1.cri".registry]
          config_path = "/etc/containerd/certs.d"
    
          [plugins."io.containerd.grpc.v1.cri".registry.auths]
    
          [plugins."io.containerd.grpc.v1.cri".registry.configs]
    
          [plugins."io.containerd.grpc.v1.cri".registry.headers]
    
          [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    
        [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
          tls_cert_file = ""
          tls_key_file = ""
    

    二、配置加速镜像

    镜像加速地址 | registry

    1. config_path 了解

    上面我们将文件路径改为 config_path = "/etc/containerd/certs.d"​,所以镜像的配置应该配置到该目录下.该目录的结构应该如下:

    $ tree /etc/containerd/certs.d
    /etc/containerd/certs.d
    └── docker.io
        └── hosts.toml
    
    $ cat /etc/containerd/certs.d/docker.io/hosts.toml
    server = "https://docker.io"
    
    [host."https://registry-1.docker.io"]
      capabilities = ["pull", "resolve"]
    

    目录名为镜像仓库地址,hosts.toml 中可以指定对应的加速地址.

    2.使用镜像加速

    编写一个 shell 脚本

    root@master1:/opt/k8s-init# cat registrys.sh 
    #!/bin/bash
    
    dirs=(docker.io gcr.io ghcr.io k8s.gcr.io registry.k8s.io quay.io)
    registrys=(docker.m.daocloud.io gcr.m.daocloud.io ghcr.m.daocloud.io k8s-gcr.m.daocloud.io k8s.m.daocloud.io quay.m.daocloud.io)
    
    if [ ! -d "/etc/containerd/certs.d" ]; then
        mkdir -p /etc/containerd/certs.d
    fi
    
    for ((i=0; i<${#dirs[@]}; i++)); do
        if [ ! -d "/etc/containerd/certs.d/${dirs[i]}" ]; then
            mkdir -p /etc/containerd/certs.d/${dirs[i]}
        fi
        host="[host.\"https://${registrys[i]}\"]\n    capabilities = [\"pull\", \"resolve\"]"
        echo -e $host > /etc/containerd/certs.d/${dirs[i]}/hosts.toml
    done
    

    执行脚本

    bash registrys.sh
    

    查看 /etc/containerd/certs.d​ 的目录结构.

    tree /etc/containerd/certs.d/
    /etc/containerd/certs.d/
    ├── docker.io
    │   └── hosts.toml
    ├── gcr.io
    │   └── hosts.toml
    ├── ghcr.io
    │   └── hosts.toml
    ├── k8s.gcr.io
    │   └── hosts.toml
    ├── quay.io
    │   └── hosts.toml
    └── registry.k8s.io
        └── hosts.toml
    

    三、进行测试

    运行 nginx 容器

    nerdctl --debug=true run -d --name nginx -p 80:80 nginx:alpine
    

    查看容器

    nerdctl ps -a
    CONTAINER ID    IMAGE                             COMMAND                   CREATED           STATUS    PORTS                 NAMES
    fce1a2183dd7    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    37 minutes ago    Up        0.0.0.0:80->80/tcp    nginx
    

    访问页面

    image-20240903111733-o66jnjq

    停止容器

    nerdctl rm -f nginx
    

  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    110 引用 • 54 回帖 • 1 关注
4 操作
Apang 在 2024-09-05 10:35:04 更新了该帖
Apang 在 2024-09-05 09:00:03 更新了该帖
Apang 在 2024-09-05 01:05:32 更新了该帖
Apang 在 2024-09-04 23:17:55 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...