K8s集群搭建-版本-docker:1.20.9
1. 集群分布情况
这里使用三台机器搭建K8s集群,机器版本为:CentOS Linux release 7.9.2009 (Core)
架构为:x86-64
:
主机名 | IP | 角色 |
---|---|---|
docker-54 | 192.168.104.54 | master |
docker-55 | 192.168.104.55 | node1 |
docker-56 | 192.168.104.56 | node2 |
3台虚拟机,1个master,2个node节点。
首先这里修改 hostname
,便于后面区分当前操作所在机器:
使用 hostname 命令,可以查看当前 hostname
然后使用命令:hostnamectl set-hostname 主机名
可直接修改 hostname, 打开新的窗口,即可生效,重启仍然有效。
hostnamectl set-hostname docker-54
hostnamectl set-hostname docker-55
hostnamectl set-hostname docker-56
修改 hosts 文件:
echo "192.168.104.54 master" >> /etc/hosts
echo "192.168.104.55 node1" >> /etc/hosts
echo "192.168.104.56 node2" >> /etc/hosts
2. 安装操作步骤
2.1 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
2.2 禁用selinux
临时生效
setenforce 0
永久生效
vim /etc/selinux/config
SELINUX=disabled
2.3 关闭swap分区(必须,因为k8s官网要求)
swapoff -a
永久禁用swap,删除或注释掉 /etc/fstab
里的 swap 设备的挂载命令即可
# /dev/mapper/centos-swap swap swap defaults 0 0
2.4 时间同步
这里使用 ntpd 服务同步时间 添加定时任务
crontab -e
插入内容:
0-59/10 * * * * /usr/sbin/ntpdate us.pool.ntp.org | logger -t NTP
或者做定时任务如:*/5 * * * * /usr/sbin/ntpdate -u 192.168.104.54
先手动同步一次
ntpdate us.pool.ntp.org
2.5 打开路由转发和iptables桥接功能(三台)
创建k8s.conf文件,接着往k8s.conf文件添加内容
touch /etc/sysctl.d/k8s.conf
cat >> /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
net.ipv4.ip_forward=1
vm.swappiness=0
EOF
重新加载系统全部参数,或者使用sysctl -p亦可
sysctl --system
3. 使用kubeadm安装k8s
3.1 安装docker
这里安装的版本为: docker-ce-20.10.9
为了保险起见,可以先删除旧的docker版本
yum remove docker #先删除旧的docker版本
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
由于我这里是新机器,未安装 Docker,就直接安装对应版本了。
首先安装 yum-utils,主要提供yum-config-manager命令
[root@master ~]# yum install -y yum-utils
#下载并安装docker的repo仓库
[root@master ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
查看可获取的docker版本
[root@master ~]# yum list docker-ce --showduplicates | sort -r
#直接安装最新的docker版本
[root@master ~]# yum -y install docker-ce docker-ce-cli containerd.io
#或者安装指定版本
[root@master ~]# yum -y install docker-ce-20.10.9 docker-ce-cli-20.10.9 containerd.io
#设置开机自启
[root@master ~]# systemctl enable docker
#启动docker
[root@master ~]# systemctl start docker
#设置镜像加速器
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://o2wpcbk0.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
[root@master ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://o2wpcbk0.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
#重启docker
[root@master ~]# systemctl restart docker
#检查加速器配置是否成功
[root@master ~]# docker info |tail -5
127.0.0.0/8
Registry Mirrors:
https://b9pmyelo.mirror.aliyuncs.com/ #加速器配置成功,仓库已经是阿里云
Live Restore Enabled: false
如果上述步骤中,由于网络问题可能会报错 Could not resolve host: download.docker.com; 未知的错误"
等下再执行一遍即可。
3.2 配置kubernetes的阿里云yum源(所有节点服务器都需要执行)
[root@master ~]# cat >/etc/yum.repos.d/kubernetes.repo <<'EOF' #在3台虚拟机都配置k8s的yum源
[kubernetes]
name = Kubernetes
baseurl = https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled = 1
gpgcheck = 0
repo_gpgcheck = 0
gpgkey = https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
3.3 yum安装kubeadm、kubelet、kubectl(所有节点都执行)
这里安装1.22.6版本
[root@master ~]# yum list --showduplicates | grep kubeadm #查看yum可获取的kubeadm版本,不指定版本的话默认安装最新版本
[root@master ~]# yum -y install kubelet-1.22.6 kubeadm-1.22.6 kubectl-1.22.6 #安装kubeadm、kubelet、kubectl
[root@master ~]# systemctl enable kubelet #设置kubelet开机自启(先不用启动,也起不了,后面kubeadm init初始化master时会自动拉起kubelet)
3.4 初始化master节点的控制面板
在master节点执行初始化(node节点不用执行)
kubeadm init \
--apiserver-advertise-address=192.168.104.54 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.22.6 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
说明:
--apiserver-advertise-address=192.168.118.131 \ #指定apiserver的IP,即master节点的IP
--image-repository registry.aliyuncs.com/google_containers \ #设置镜像仓库为国内的阿里云镜像仓库
--kubernetes-version v1.22.6 \ #设置k8s的版本,跟步骤三的kubeadm版本一致
--service-cidr=10.96.0.0/12 \ #这是设置node节点的网络的,暂时这样设置
--pod-network-cidr=10.244.0.0/16 #这是设置node节点的网络的,暂时这样设置
这个过程取决于服务器的网速了,可能会很慢很慢。。。。。。
实际上上面操作 会自动去阿里云的服务器上拉取 k8s 的镜像,但是由于网络原因解析ip会很慢,导致步骤卡在拉镜像上了。
可以将阿里云仓库的域名配置到 hosts 文件里面,执行 ping registry.aliyuncs.com
看下 最新的解析地址:
接着将 上面 IP 添加到 hosts 文件:
echo "120.55.105.209 registry.aliyuncs.com" >> /etc/hosts
这时候就会很快拉下如下镜像:
[root@docker-54 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.aliyuncs.com/google_containers/kube-apiserver v1.22.6 d35b182b4200 15 months ago 128MB
registry.aliyuncs.com/google_containers/kube-scheduler v1.22.6 9fe44a6192d1 15 months ago 52.7MB
registry.aliyuncs.com/google_containers/kube-proxy v1.22.6 63f3f385dcfe 15 months ago 104MB
registry.aliyuncs.com/google_containers/kube-controller-manager v1.22.6 3618e4ab750f 15 months ago 122MB
registry.aliyuncs.com/google_containers/etcd 3.5.0-0 004811815584 23 months ago 295MB
registry.aliyuncs.com/google_containers/coredns v1.8.4 8d147537fb7d 23 months ago 47.6MB
registry.aliyuncs.com/google_containers/pause 3.5 ed210e3e4a5b 2 years ago 683kB
[root@docker-54 ~]#
然后上面 init 正常也会有结果了:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.104.54:6443 --token plk1ww.qufepfkpt1z2k2cq \
--discovery-token-ca-cert-hash sha256:2ae60c99f0ed0c2fbfd624c27f3e611d5159000ff2a4bb755d7ccf3d2e7cb363
根据输入的提示信息复制粘贴照着做即可:
3.5 将node节点加入k8s集群
上面提示的 kubeamd join 命令的 token 只有24h,24h就过期,需要执行kubeadm token create --print-join-command
重新生成。
[root@docker-55 ~]# kubeadm join 192.168.104.54:6443 --token plk1ww.qufepfkpt1z2k2cq \
> --discovery-token-ca-cert-hash sha256:2ae60c99f0ed0c2fbfd624c27f3e611d5159000ff2a4bb755d7ccf3d2e7cb363
[preflight] Running pre-flight checks
[WARNING Hostname]: hostname "docker-55" could not be reached
[WARNING Hostname]: hostname "docker-55": lookup docker-55 on 8.8.8.8:53: no such host
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
然后回到 master 节点上看下 节点信息:
[root@docker-54 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
docker-54 NotReady control-plane,master 8m34s v1.22.6
docker-55 NotReady <none> 64s v1.22.6
docker-56 NotReady <none> 36s v1.22.6
[root@docker-54 ~]#
这里显示 NotReady
,还需要配置网络插件才行。
3.6 配置 Pod 网络
你必须部署一个基于 Pod 网络插件的 容器网络接口 (CNI),以便你的 Pod 可以相互通信。 在安装网络之前,集群 DNS (CoreDNS) 将不会启动。
- 注意你的 Pod 网络不得与任何主机网络重叠: 如果有重叠,你很可能会遇到问题。 (如果你发现网络插件的首选 Pod 网络与某些主机网络之间存在冲突, 则应考虑使用一个合适的 CIDR 块来代替, 然后在执行 kubeadm init 时使用 --pod-network-cidr 参数并在你的网络插件的 YAML 中替换它)。
- 默认情况下,kubeadm 将集群设置为使用和强制使用 RBAC(基于角色的访问控制)。 确保你的 Pod 网络插件支持 RBAC,以及用于部署它的清单也是如此。
- 如果要为集群使用 IPv6(双协议栈或仅单协议栈 IPv6 网络), 请确保你的 Pod 网络插件支持 IPv6。 IPv6 支持已在 CNI v0.6.0 版本中添加。
集群网络系统是 Kubernetes 的核心部分,但是想要准确了解它的工作原理可是个不小的挑战。 下面列出的是网络系统的的四个主要问题:
- 高度耦合的容器间通信:这个已经被 Pod 和 localhost 通信解决了。
- Pod 间通信:这是本文档讲述的重点。
- Pod 与 Service 间通信:涵盖在 Service 中。
- 外部与 Service 间通信:也涵盖在 Service 中。
Kubernetes 的宗旨就是在应用之间共享机器。 通常来说,共享机器需要两个应用之间不能使用相同的端口,但是在多个应用开发者之间 去大规模地协调端口是件很困难的事情,尤其是还要让用户暴露在他们控制范围之外的集群级别的问题上。
动态分配端口也会给系统带来很多复杂度 - 每个应用都需要设置一个端口的参数, 而 API 服务器还需要知道如何将动态端口数值插入到配置模块中,服务也需要知道如何找到对方等等。 与其去解决这些问题,Kubernetes 选择了其他不同的方法。
可以使用以下命令在控制平面节点或具有 kubeconfig 凭据的节点上安装 Pod 网络附加组件:
kubectl apply -f <add-on.yaml>
每个集群只能安装一个 Pod 网络。
这里安装 flannel
网络;
执行下面这条命令在线配置pod网络,因为是国外网站,所以可能报错,测试去http://ip.tool.chinaz.com/网站查到
域名raw.githubusercontent.com对应的IP,把域名解析配置到/etc/hosts文件,然后执行在线配置pod网络,多尝试几次即可成功。
[root@master ~]# kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
执行之后,可以使用命令看下,
[root@docker-54 ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7f6cbbb7b8-nbp8h 0/1 Pending 0 10h
coredns-7f6cbbb7b8-zwtgx 0/1 Pending 0 10h
etcd-docker-54 1/1 Running 0 10h
kube-apiserver-docker-54 1/1 Running 0 10h
kube-controller-manager-docker-54 1/1 Running 0 10h
kube-proxy-9fjpc 1/1 Running 0 10h
kube-proxy-m6d4v 1/1 Running 0 10h
kube-proxy-qg5qd 1/1 Running 0 10h
kube-scheduler-docker-54 1/1 Running 0 10h
[root@docker-54 ~]#
其中有两个是 pending 状态,这是因为在下载对应的镜像,没有科学上网的话,这里会很慢,虽然上面我们配置了hosts 了,还是需要点时间。
成功安装 Pod 网络后,你可以通过在 kubectl get pods --all-namespaces
输出中检查 CoreDNS Pod 是否 Running 来确认其是否正常运行。 一旦 CoreDNS Pod 启用并运行,你就可以继续加入节点。
至此,集群环境搭建基本完成了,下面开始测试下集群;
4. 测试 K8s 集群
4.1 创建 httpd 服务
在k8s中创建一个pod,验证是否正常运行:
kubectl create deployment httpd --image=httpd
: 这个命令将会创建一个名为 httpd 的 Kubernetes 部署(Deployment),并使用 httpd 镜像作为该部署的容器镜像。一个 Kubernetes 部署是一组 Pod 的声明式更新,用于确保应用程序的期望状态与实际状态匹配。
kubectl expose deployment httpd --port=80 --type=NodePort
: 这个命令将会创建一个名为 httpd 的 Kubernetes 服务(Service),并将容器的 80 端口暴露到集群的节点上(NodePort)。Kubernetes 服务是一组 Pod 的抽象,用于提供网络连接和 DNS 命名。通过这个命令,我们可以将 httpd 应用程序公开到 Kubernetes 集群中,并通过节点的 IP 地址和 NodePort 端口号访问它。
[root@docker-54 ~]# kubectl create deployment httpd --image=httpd
deployment.apps/httpd created
[root@docker-54 ~]#
[root@docker-54 ~]# kubectl expose deployment httpd --port=80 --type=NodePort
service/httpd exposed
[root@docker-54 ~]#
[root@docker-54 ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/httpd-757fb56c8d-7wdls 0/1 ContainerCreating 0 28s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/httpd NodePort 10.108.245.230 <none> 80:30529/TCP 8s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
[root@docker-54 ~]#
可以看到上面显示 pod 的状态为 ContainerCreating
让容器飞一会,给他点时间,来反应下;
随后,当看到pod 为 Running
状态时,
[root@docker-54 ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/httpd-757fb56c8d-7wdls 1/1 Running 0 5m43s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/httpd NodePort 10.108.245.230 <none> 80:30529/TCP 5m23s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
测试访问服务器的 30529
端口:curl localhost:30527
看下是否正常访问httpd的网页;
[root@docker-54 ~]# curl localhost:30529
<html><body><h1>It works!</h1></body></html>
[root@docker-54 ~]#
[root@docker-54 ~]# curl 192.168.104.54:30529
<html><body><h1>It works!</h1></body></html>
[root@docker-54 ~]#
[root@docker-54 ~]# curl 192.168.104.55:30529
<html><body><h1>It works!</h1></body></html>
[root@docker-54 ~]#
[root@docker-54 ~]# curl 192.168.104.56:30529
<html><body><h1>It works!</h1></body></html>
[root@docker-54 ~]#
使用master节点的IP或者node节点的IP都可以访问,我这里端口是30529,这个端口是随机的,如果正常访问,这就说明我们k8s已经部署完成,网络ok。
在使用 kubectl expose
命令时,如果没有指定 NodePort 端口号,则 Kubernetes 会自动分配一个空闲的端口号。您可以通过以下命令查看 Service 的 NodePort 端口号:
kubectl get service httpd
输出结果中会有一个 80:NodePort
的端口映射,其中 NodePort 就是被自动分配的端口号。如果希望指定 NodePort 端口号,可以在命令中使用 --node-port 参数,例如:
kubectl expose deployment httpd --port=80 --type=NodePort --node-port=30080
这将会使用 30080 作为 httpd 服务的 NodePort 端口号。
4.2 删除 httpd 服务
可以使用 kubectl 命令删除已创建的 Service 和 Pod。具体命令如下:
- 删除 Service
kubectl delete service httpd
这个命令将删除名为 httpd 的 Kubernetes Service。
- 删除 Deployment 和 Pod
kubectl delete deployment httpd
这个命令将删除名为 httpd 的 Kubernetes Deployment,并删除该 Deployment 中所有的 Pod。
如果您希望同时删除 Service 和 Deployment,可以使用以下命令:
kubectl delete deployment httpd && kubectl delete service httpd
这个命令将同时删除名为 httpd 的 Kubernetes Deployment 和 Service。