赞
踩
主机名 | IP 地址 | 角色 |
---|---|---|
redis2 | 10.10.10.22 | control-plane/data-plan/nfs |
redis3 | 10.10.10.23 | data-plan |
hadoop2 | 10.10.10.132 | data-plan |
hadoop3 | 10.10.10.133 | data-plan |
基于上述的节点规划,每个节点都需进行如下操作
Kubernets 的端口映射和转发都通过 iptables 服务实现。所以需要在安装 Kubernetes 之前,清空所有的 iptables 策略。以保证不会由于原有遗留策略,导致无法正常安装 Kubernetes
iptables -F
iptables -t nat -F
iptables -L -v
# 输出结果
# 所有类型策略都为空,则表示已完成清空操作
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
swapoff -a
sed -i '/^[^#]/ s/\(\s\+swap\s\)/#&/' /etc/fstab
free -g
# 输出结果
# swap 行的 total 为 0 时,表示已关闭所有的 swap
total used free shared buff/cache available
Mem: 15 8 0 0 6 6
Swap: 0 0 0
此操作主要目的是:将 kube-proyx 的代理模式从 iptables 切换至 ipvs。若无此需求,可跳过此操作
cat > /etc/modules-load.d/modules.conf << EOF
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF
for line in $(cat /etc/modules-load.d/modules.conf); \
do modprobe $line; \
done
cat > /etc/sysctl.d/k8s.conf << EOF
# Kubernetes
net.ipv4.ip_forward = 1
vm.swapiness = 0
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf
yum install chrony -y
cat > /etc/chrony.conf < EOF
# 根据实际情况,调整 Chrony Server 地址
server 10.10.10.21 iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony
EOF
systemctl enable chrony --now
chronyc sources -v # 输出结果 # 只有当某一行 Chrony Server 状态为 ^* 时,才表示能够基于此 Chrony Server 完成时间同步 210 Number of sources = 1 .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current synced, '+' = combined , '-' = not combined, | / '?' = unreachable, 'x' = time may be in error, '~' = time too variable. || .- xxxx [ yyyy ] +/- zzzz || Reachability register (octal) -. | xxxx = adjusted offset, || Log2(Polling interval) --. | | yyyy = measured offset, || \ | | zzzz = estimated error. || | | \ MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* redis1 4 6 377 18 +1539us[+1549us] +/- 63ms
mkdir -p /data/service/kubernetes
由于 Docker 已将 Containerd 作为独立服务贡献给社区,并且 Kubernetes 只需使用 Containerd 完成容器管理。所以若节点上已安装 Docker,可跳过此步骤;若未安装,则只需安装 Container 即可
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
yum clean all && yum makecache fast
yum install containerd.io -y
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
cp /etc/containerd/config.toml /etc/containerd/config.toml.orig
# 将镜像仓库地址调整为阿里云地址,以保证能够拉取到镜像
# 第 62 行,修改为如下配置
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
# 使用 systemd 作为容器的 cgroup driver,以保证节点资源紧张时更加稳定
# 第 126 行,修改为如下配置
SystemdCgroup = true
systemctl enable containerd --now
ctr version
# 输出结果
# 有输出,则表示服务已正常运行
Client:
Version: 1.6.25
Revision: d8f198a4ed8892c764191ef7b3b06d8a2eeb5c7f
Go version: go1.20.10
Server:
Version: 1.6.25
Revision: d8f198a4ed8892c764191ef7b3b06d8a2eeb5c7f
UUID: 0218e80c-c56f-4b65-98bb-48a44120978c
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum clean all && yum makecache fast
yum install kubelet kubeadm kubectl -y
基于上述的服务架构的规划,Master 需部署在 redis2 节点上
kubeadm config print init-defaults > /data/service/kubernetes/kubeadm.yaml
cp /data/service/kubernetes/kubeadm.yaml /data/service/kubernetes/kubeadm.yaml.orig
# 此 IP 为 Master 节点的 IP 地址 # 第 12 行,修改为如下配置 advertiseAddress: 10.10.10.22 # 设置 containerd 的连接套接字 # 第 15 行,修改为如下配置 criSocket: unix:///var/run/containerd/containerd.sock # 此名称为 Master 节点的主机名 # 第 17 行,修改为如下配置 name: redis2 # 将镜像仓库地址调整为阿里云地址,以保证能够拉取到镜像 # 第 30 行,修改为如下配置 imageRepository: registry.aliyuncs.com/google_containers # 指定 pod 的 IP 网段 # 在第 35 行后,添加如下配置 podSubnet: 10.244.0.0/16
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.10.10.22 bindPort: 6443 nodeRegistration: criSocket: unix:///var/run/containerd/containerd.sock imagePullPolicy: IfNotPresent name: redis2 taints: null --- apiServer: timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta3 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {} dns: {} etcd: local: dataDir: /var/lib/etcd imageRepository: registry.aliyuncs.com/google_containers kind: ClusterConfiguration kubernetesVersion: 1.28.0 networking: dnsDomain: cluster.local serviceSubnet: 10.96.0.0/12 podSubnet: 10.244.0.0/16 scheduler: {}
kubeadm config images pull --config /data/service/kubernetes/kubeadm.yaml
kubeadm init --config /data/service/kubernetes/kubeadm.yaml # 输出结果 Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 10.10.10.22:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:cad3fa778559b724dff47bb1ad427bd39d97dd76e934b9467507a2eb990a50c7
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
Kubernetes Master 部署完成后,查看集群状态会发现如下异常:
上述两个异常,主要由于未安装网络插件导致。而 Kubernetes 支持多种网络插件,此文档所选用的是最常见的网络插件:Calico
基于上述的节点规划,需在 redis2 节点上进行如下操作
# 获取 yaml 文件
curl https://breezey-public.oss-cn-zhangjiakou.aliyuncs.com/cka/calico.yaml -o /data/service/kubernetes/calico.yaml
# 部署网络插件 Calico
kubectl apply -f /data/service/kubernetes/calico.yaml
kubectl get pods -n kube-system -o wide # 输出结果 # 发现 coredns 状态更新为 Running NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES calico-kube-controllers-78496c69f6-bcqf9 1/1 Running 0 74d 10.244.214.65 redis2 <none> <none> calico-node-452ps 1/1 Running 0 74d 10.10.10.132 hadoop2 <none> <none> calico-node-4gqff 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> calico-node-lv4sg 1/1 Running 0 74d 10.10.10.23 redis3 <none> <none> calico-node-wc2hw 1/1 Running 0 74d 10.10.10.133 hadoop3 <none> <none> coredns-66f779496c-bb72k 1/1 Running 0 74d 10.244.214.66 redis2 <none> <none> coredns-66f779496c-pqfw7 1/1 Running 0 74d 10.244.214.67 redis2 <none> <none> etcd-redis2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> kube-apiserver-redis2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> kube-controller-manager-redis2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> kube-proxy-8882t 1/1 Running 0 74d 10.10.10.132 hadoop2 <none> <none> kube-proxy-8v5vq 1/1 Running 0 74d 10.10.10.23 redis3 <none> <none> kube-proxy-f4wf2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> kube-proxy-vst9n 1/1 Running 0 74d 10.10.10.133 hadoop3 <none> <none> kube-scheduler-redis2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none>
kubectl get nodes
# 输出结果
# 发现 Master 状态更新为 Ready
NAME STATUS ROLES AGE VERSION
redis2 Ready control-plane 11d v1.28.2
token 是 Master 与 Worker 之间认证的唯一凭证
每个 token 的有效时间为 24 小时。超时后,token 将无法再被使用,需要通过如下命令再次生成
基于上述的节点规划,需在 redis2 节点上进行如下操作
kubeadm token create --print-join-command
# 输出结果
kubeadm join 10.10.10.22:6443 --token w9g299.f9dymq7iza6h97s1 --discovery-token-ca-cert-hash sha256:5ec5a1e20cb9282f763c8aadb640e32f5a6e542df2ab7383125bd3334ab97521
基于上述的节点规划,需在 redis3、hadoop2 和 hadoop3 节点上运行
kubeadm join 10.10.10.22:6443 --token w9g299.f9dymq7iza6h97s1 --discovery-token-ca-cert-hash sha256:5ec5a1e20cb9282f763c8aadb640e32f5a6e542df2ab7383125bd3334ab97521
kubectl get nodes # 输出结果 # 所添加 Worker 状态已更新至 Ready NAME STATUS ROLES AGE VERSION hadoop2 Ready <none> 17d v1.28.2 hadoop3 Ready <none> 17d v1.28.2 hazelcast1 NotReady <none> 17d v1.28.2 redis2 Ready control-plane 17d v1.28.2 redis3 Ready <none> 17d v1.28.2 kubectl get pods -n kube-system -o wide # 输出结果 # 所添加 Worker 上已部署 calico-node 和 kube-proxy 容器 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES calico-kube-controllers-78496c69f6-bcqf9 1/1 Running 0 74d 10.244.214.65 redis2 <none> <none> calico-node-452ps 1/1 Running 0 74d 10.10.10.132 hadoop2 <none> <none> calico-node-4gqff 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> calico-node-lv4sg 1/1 Running 0 74d 10.10.10.23 redis3 <none> <none> calico-node-wc2hw 1/1 Running 0 74d 10.10.10.133 hadoop3 <none> <none> coredns-66f779496c-bb72k 1/1 Running 0 74d 10.244.214.66 redis2 <none> <none> coredns-66f779496c-pqfw7 1/1 Running 0 74d 10.244.214.67 redis2 <none> <none> etcd-redis2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> kube-apiserver-redis2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> kube-controller-manager-redis2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> kube-proxy-8882t 1/1 Running 0 74d 10.10.10.132 hadoop2 <none> <none> kube-proxy-8v5vq 1/1 Running 0 74d 10.10.10.23 redis3 <none> <none> kube-proxy-f4wf2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none> kube-proxy-vst9n 1/1 Running 0 74d 10.10.10.133 hadoop3 <none> <none> kube-scheduler-redis2 1/1 Running 0 74d 10.10.10.22 redis2 <none> <none>
默认情况下,只有 Kubernetes Master 能够管理 Kubernetes 集群。若在 Kubernetes Worker 节点上管理集群,将会出现如下报错:
E0123 09:42:49.858315 6523 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0123 09:42:49.859436 6523 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0123 09:42:49.860516 6523 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0123 09:42:49.861618 6523 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0123 09:42:49.862442 6523 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
The connection to the server localhost:8080 was refused - did you specify the right host or port?
基于上述报错信息,可以发现默认连接的 Kubernetes 集群为 localhost:8080,而非 Kubernetes Master 所在节点,所以导致无法正常连接 Kubernetes 集群。所以若希望 Kubernetes Worker 也具有管理 Kubernetes 集群的能力,则需要在 Kubernetes Worker 节点上存放 Kubernetes 集群的配置文件,以使其能够连接 Kubernetes Master。具体步骤如下:
# 此目录为 Kubernetes 内部指定路径,必须创建此路径用于存放配置文件
mkdir -p /root/.kube
scp /root/.kube/config root@redis3:/root/.kube/
kubectl get namespaces
# 输出结果
NAME STATUS AGE
default Active 46d
ingress-nginx Active 10d
kube-node-lease Active 46d
kube-public Active 46d
kube-system Active 46d
test Active 34d
基于上述内容,可以发现任何节点只需要状态 kubectl 工具,与 Kubernetes Master 节点网络互通,且存有 Kubernetes 集群配置文件(/root/.kube/config),就能够进行 Kubernetes 集群管理。所以在实际生产场景中,能够将某个特定节点作为集群管理节点,并且能够完成多集群管理。但在实际使用过程中,并不会直接将管理员权限提供给使用者,所以还需要与权限管理配合使用。具体内容请见权限管理相关文档
在实际生成场景中,一般使用 services(Kubernetes 自带功能) 实现集群内部代理,使用 ingresses 实现集群外部代理。若无需集群外部代理功能,则可跳过此步骤
基于上述的节点规划,需在 redis2 节点上进行如下操作
# 获取 yaml 文件
wget https://breezey-public.oss-cn-zhangjiakou.aliyuncs.com/cka/ingress-nginx-v1.9.3.yaml -O /data/service/kubernetes/ingress-nginx.yaml
# 调整配置文件
# 使用宿主机 IP 地址 Pod 的 IP 地址
# 在 139 行后,添加如下配置
hostNetwork: true
# 部署控制器 Ingress-Nginx
kubectl apply -f /data/service/kubernetes/ingress-nginx.yaml
kubectl get ns | grep ingress-nginx
# 输出结果
# 将会自动创建 Namespace:ingress-nginx
ingress-nginx Active 108s
kubectl get pods -n ingress-nginx -o wide | grep "ingress-nginx-controller"
# 输出结果
# 容器所使用的 IP 地址为宿主机 IP 地址
ingress-nginx-controller-769b6777ff-nnkf4 1/1 Running 0 4m40s 10.10.10.23 redis3 <none> <none>
Kubernetes 支持两种存储方式:存储卷(内置)和外置存储。此章节所说明的是持久化存储 NFS 的使用方式
基于上述的节点规划,需在 redis2 节点上进行如下操作
1.1. 创建并赋权 NFS 目录
mkdir -p /data/service/kubernetes/nfs
chmod 777 -R /data/service/kubernetes/nfs
1.2. 安装 NFS 服务
yum install nfs-utils -y
1.3. 配置 NFS 服务
此处所使用的配置只作为样例,生产中的实际配置参数需基于业务需求动态调整
*(rw): 允许所有客户端以读写方式(read-write)挂载共享目录
no_root_squash: 不将客户端的 root 用户映射为匿名用户。即当客户端以 root 用户访问共享目录时,其权限将不被映射为匿名用户(如:nobody),而是保持原样
cat > /etc/exports << EOF
/data/service/kubernetes/nfs *(rw,no_root_squash)
EOF
1.4. 重启 NFS 服务,并将其设置为开机自启服务
systemctl restart nfs && systemctl enable nfs
1.5. 验证 NFS 服务配置状态
showmount -e 10.10.10.22
# 输出结果
Export list for 10.10.10.22:
/data/service/kubernetes/nfs *
由于 Kubernetes 支持多种第三方存储,而每个存储的挂载配置各不相同。所以在生产环境中,不建议使用此种挂载方式,推荐使用后述的 PVC 方式
此处只提供 spec 部分书写方式
spec: volumes: - name: datadir # 使用 nfs,作为持久卷 nfs: # 指定 nfs server 地址 server: 10.10.10.22 # 指定 nfs server 共享路径 path: /data/service/kubernetes/nfs containers: - image: mysql:8.0 name: mysql volumeMounts: - name: datadir # 将卷 datadir 挂载至 Pods 内的 /var/lib/mysql 目录 mountPath: /var/lib/mysql
Kubernetes 提供了统一的持久卷接口 CSI (Container Storage Interface)。生产环境中,建议通过 PVC 的方式挂载持久卷,以保证无论使用任何存储类型,其挂载使用方式都能保持一致。更便于后续的自动化部署改造
3.1. 创建 testpv-pvc.yaml
# PV 部分 apiVersion: v1 kind: PersistentVolume metadata: name: testpv # 描述 spec: # 存储大小 # PV 自身无法限制底层存储空间。由于 NFS 不支持配额功能,所以此处的空间限制只能作为声明,而无法实现实际的存储空间配额 capacity: storage: 8Gi # 存储类型 volumeMode: Filesystem # 访问模式 accessModes: - ReadWriteMany # 回收策略 persistentVolumeReclaimPolicy: Recycle # 挂载参数 mountOptions: - hard - nfsvers=4.1 # 存储模式 nfs: path: /data/service/kubernetes/nfs server: 10.10.10.22 --- # PVC 部分 apiVersion: v1 kind: PersistentVolumeClaim metadata: name: testpvc namespace: test # 描述 spec: # 访问模式 accessModes: - ReadWriteMany # 类型 volumeMode: Filesystem # 大小 resources: requests: storage: 8Gi
3.2. 创建 PV 和 PVC
kubectl apply -f testpv-pvc.yaml
3.3. 查看 PV 状态
kubectl get pv
# 输出结果
# STATUS 为 Bound,CLAIM 所绑定 PVC 为上述指定 testpvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
testpv 8Gi RWX Recycle Bound test/testpvc 8m22s
3.4. 查看 PVC 状态
kubectl get pvc -n test
# 输出结果
# STATUS 为 Bound,VOLUME 为上述 testPV
# 需要注意的是,若集群中也存在其它满足 PVC 条件的 PV,则会由集群选择器自主选择最优 PV 进行绑定。可能会出现绑定的并非所期望 PV 的现象
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
testpvc Bound testpv 8Gi RWX 24s
3.5. 使用 PVC 完成挂载
此处只提供 spec 部分书写方式
spec: volumes: - name: datadir # 使用 pvc 挂载 persistentvolumeclaim: # 指定 pvc 名称 claimName: testpvc containers: - image: mysql:8.0 name: mysql volumeMounts: - name: datadir # 将卷 datadir 挂载至 Pods 内的 /var/lib/mysql 目录 mountPath: /var/lib/mysql
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。