k8s 1.28(cluster)

本贴最后更新于 199 天前,其中的信息可能已经时异事殊

所有初始化的文件都会放到 /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 10Stratum 值越高,表示时间的准确性越低,这样设置的目的是确保即使外部时间源不可用,系统仍然有一个可用的时间参考。 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 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    116 引用 • 54 回帖 • 4 关注
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 更新了该帖

相关帖子

欢迎来到这里!

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

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