K8s集群部署
K8s安装方式
## K8S的方式有一堆
二进制安装 都需要跟APIserver配证书,组件间还要配证书,很麻烦。现在也不是生产推荐了
kubeadmin #//kuberadmin,生产学习最佳实践
网友写的Ansible二进制安装 非常牛逼~~~
第三方安装工具,比如Rancher,我上家公司使用的方式
云服务的K8S安装,阿里云ACK
准备工作
机器准备
主机名 | IP | 角色 | 配置推荐 | 安装软件 |
---|---|---|---|---|
k8s01 | 10.0.0.101 | master | 1核4G40G | API Server、Controller、Scheduler、Kube-proxy、Kubelet、etcd |
k8s02 | 10.0.0.102 | node01 | 1核2G40G | Docker、Kubelet、Kube-proxy |
k8s03 | 10.0.0.103 | node02 | 1核2G40G | Docker、Kubelet、Kube-proxy |
IP规划
Service提供三种IP | IP |
---|---|
Pod IP | 10.2.0.0 |
Cluster IP | 10.1.0.0 |
Node IP | 10.0.0.0 |
环境优化:注意三台上面都需要操作
# 1.禁用swap
# 临时关闭
swapoff -a
# 永久关闭
vim /etc/fstab //注释掉swap那一行或者删除
云主机你上去free -m是没有swap的。因为你买的本来就虚拟机。虚拟磁盘性能本就不高。K8s也是个虚拟化环境
# 2.配置防火墙内核转发
使其网络互通
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
EOF
检查
sysctl --system
# 3.安装docker及镜像加速(略)
# 安装
yum install -y docker-ce-19.03.15 docker-ce-cli-19.03.15
# 4.启动docker
systemctl start docker
# 5.加载IPVS模块(回顾下LVS负载均衡)
lvs 负载均衡 只需装个命令。快,因为lvs直接把你物理机变物理负载均衡,直接路由转发
nginx啥的还要通过应用
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#! /bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod +x /etc/sysconfig/modules/ipvs.modules
source /etc/sysconfig/modules/ipvs.modules
lsmod|grep -e 'ip_vs' -e 'nf_conntrack_ipv' 看下是否加载成功
[root@k8s01 ~]# cat > /etc/sysconfig/modules/ipvs.modules <<EOF
> #! /bin/bash
> modprobe -- ip_vs
> modprobe -- ip_vs_rr
> modprobe -- ip_vs_wrr
> modprobe -- ip_vs_sh
> modprobe -- nf_conntrack_ipv4
> EOF
[root@k8s01 ~]# chmod +x /etc/sysconfig/modules/ipvs.modules
[root@k8s01 ~]# source /etc/sysconfig/modules/ipvs.modules
[root@k8s01 ~]# lsmod|grep -e 'ip_vs' -e 'nf_conntrack_ipv'
ip_vs_sh 12688 0
ip_vs_wrr 12697 0
ip_vs_rr 12600 4
ip_vs 145497 10 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack_ipv4 15053 9
nf_defrag_ipv4 12729 1 nf_conntrack_ipv4
nf_conntrack 133095 7 ip_vs,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntrack_ipv4
libcrc32c 12644 4 xfs,ip_vs,nf_nat,nf_conntrack
安装kubeadmin 与初始化集群
注:步骤1-4三台节点均需执行
# 1.更改阿里云k8s源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[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
# 2.安装kubeadm等一系列组件(node节点也要装,因为后面加入集群需要执行kubeadmin命令)
yum install kubeadm-1.19.3 kubelet-1.19.3 kubectl-1.19.3 ipvsadm -y
kubeadmin:类似于ansible,它帮你装组件、配证书。
kubelet:在客户端上创建pod的组件
kubectl:后面要执行的命令
ipvsadm:可以改网络相关设置,让pod之间网络通
你需要在每台机器上安装以下的软件包:
kubeadm:用来初始化集群的指令。
kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
kubectl:用来与集群通信的命令行工具。
kubeadm 不能帮你安装或者管理 kubelet 或 kubectl, 所以你需要确保它们与通过 kubeadm 安装的控制平面的版本相匹配。 如果不这样做,则存在发生版本偏差的风险,可能会导致一些预料之外的错误和问题。 然而,控制平面与 kubelet 之间可以存在一个次要版本的偏差,但 kubelet 的版本不可以超过 API 服务器的版本。 例如,1.7.0 版本的 kubelet 可以完全兼容 1.8.0 版本的 API 服务器,反之则不可以。
# 3.启动kubelet服务
systemctl start kubelet
systemctl enable kubelet
# 4.添加hosts解析
vim /etc/hosts
10.0.0.101 k8s01
10.0.0.102 k8s02
10.0.0.103 k8s03
# 5.停etcd(若装过etcd)
[root@k8s01 ~]# systemctl stop etcd
# 6.初始化k8s集群(master上执行)
kubeadm init \
--apiserver-advertise-address=10.0.0.101 \ # APIserver的地址
--image-repository registry.aliyuncs.com/google_containers \ # 阿里云镜像仓库
--kubernetes-version=v1.19.3 \ # k8s版本号
--service-cidr=10.1.0.0/16 \ # Cluster IP
--pod-network-cidr=10.2.0.0/16 \ # Pod IP
--service-dns-domain=cluster.local \
--ignore-preflight-errors=Swap \ # 忽略错误
--ignore-preflight-errors=NumCPU
kubeadm init \
--apiserver-advertise-address=10.0.0.101 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.19.3 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.2.0.0/16 \
--service-dns-domain=cluster.local \
--ignore-preflight-errors=Swap \
--ignore-preflight-errors=NumCPU
若遇上启动报错 [ERROR DirAvailable--var-lib-etcd]: /var/lib/etcd is not empty
[root@k8s01 ~]# rm -fr /var/lib/etcd/*
注意,不能重复初始化。若要重新初始化:
[root@k8s01 ~]# kubeadm reset
##### 初始化成功后会有以下信息 #####
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
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.0.0.101:6443 --token kamnt8.3ysfar4yg3nxgvwh \
--discovery-token-ca-cert-hash sha256:519d1ea4ac932771fe3bcf1af47b2f6d66b0ca604d36cefe5902db9fa9e0db6a
# 7.按照其说明创建证书目录并授权(master上执行)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s01 ~]# mkdir -p .kube
[root@k8s01 ~]# cp -i /etc/kubernetes/admin.conf .kube/config
[root@k8s01 ~]# ll .kube
total 8
-rw------- 1 root root 5566 Jan 27 21:58 config
# 8.查看集群所有节点
[root@k8s01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s01 NotReady master 11m v1.19.3
# 9.将其他node节点加入集群 (k8s02和k8s03)
[root@k8s02 ~]# join 10.0.0.101:6443 --token kamnt8.3ysfar4yg3nxgvwh \
--discovery-token-ca-cert-hash sha256:519d1ea4ac932771fe3bcf1af47b2f6d66b0ca604d36cefe5902db9fa9e0db6a
[root@k8s03 ~]# join 10.0.0.101:6443 --token kamnt8.3ysfar4yg3nxgvwh \
--discovery-token-ca-cert-hash sha256:519d1ea4ac932771fe3bcf1af47b2f6d66b0ca604d36cefe5902db9fa9e0db6a
# 10.执行后再看集群
[root@k8s01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s01 NotReady master 18m v1.19.3
k8s02 NotReady <none> 90s v1.19.3
k8s03 NotReady <none> 50s v1.19.3
#此时三个节点网络没有通,所以是NotReady
[root@k8s02 ~]# kubectl get nodes
The connection to the server localhost:8080 was refused - did you specify the right host or port?
[root@k8s03 ~]# kubectl get nodes
The connection to the server localhost:8080 was refused - did you specify the right host or port?
主节点上简单操作看看
[root@k8s01 ~]# kubectl get namespace //查看名称空间
NAME STATUS AGE
default Active 20m
kube-node-lease Active 20m
kube-public Active 20m
kube-system Active 20m
[root@k8s01 ~]# kubectl get pods //查看pod
No resources found in default namespace. 没有,是在kube-system
[root@k8s01 ~]# kubectl get pods -n kube-node-lease
No resources found in kube-node-lease namespace.
[root@k8s01 ~]# kubectl get pods -n kube-public
No resources found in kube-public namespace.
[root@k8s01 ~]# kubectl get pods -n kube-system //查看kube-system里的pod
NAME READY STATUS RESTARTS AGE
coredns-6d56c8448f-2rnf5 0/1 Pending 0 21m
coredns-6d56c8448f-x2hkm 0/1 Pending 0 21m
etcd-k8s01 1/1 Running 0 21m
kube-apiserver-k8s01 1/1 Running 0 21m
kube-controller-manager-k8s01 1/1 Running 0 21m
kube-proxy-bdw2r 1/1 Running 0 21m
kube-proxy-kpzxv 1/1 Running 0 4m36s
kube-proxy-v4nvz 1/1 Running 0 3m56s
kube-scheduler-k8s01 1/1 Running 0 21m
# 可见它把这些都起到pod里了
初始化:它是用容器把这些组件跑起来。没在物理机上
配置集群网络(打通网络)
# 利用ConfigMap配置网络,修改为ipvs模式
[root@k8s01 ~]# kubectl get cm -A //查看所有名称空间的ConfigMap信息
NAMESPACE NAME DATA AGE
kube-public cluster-info 2 162m
kube-system coredns 1 162m
kube-system extension-apiserver-authentication 6 162m
kube-system kube-proxy 2 162m
kube-system kubeadm-config 2 162m
kube-system kubelet-config-1.19 1 162m
[root@k8s01 ~]# kubectl edit cm kube-proxy -n kube-system //修改配置,相当于vim
找到 mode: "" 改为 mode: "ipvs"
k8s默认使用的是iptables防火墙,可以修改成性能更高的ipvs模式。该模式LVS也在用
# 重启pod(删除旧POD即可)
[root@k8s01 ~]# kubectl get pod -n kube-system|grep kube-proxy
kube-proxy-bdw2r 1/1 Running 0 3h21m
kube-proxy-kpzxv 1/1 Running 0 5h1m
kube-proxy-v4nvz 1/1 Running 0 5h16m
[root@k8s01 ~]# kubectl get pod -n kube-system|grep kube-proxy|awk '{print "kubectl -n kube-system delete pod "$1}'|bash
pod "kube-proxy-bdw2r" deleted
pod "kube-proxy-kpzxv" deleted
pod "kube-proxy-v4nvz" deleted
[root@k8s01 ~]# kubectl get pod -n kube-system|grep kube-proxy //查看,起了三个新的pod
NAME READY STATUS RESTARTS AGE
kube-proxy-j58j8 1/1 Running 0 63s
kube-proxy-sgtmk 1/1 Running 0 54s
kube-proxy-zv2hv 1/1 Running 0 60s
# 使用flannel打通网络
[root@k8s01 ~]# yum install -y git
[root@k8s01 ~]# git clone --depth 1 https://github.com/coreos/flannel.git //用git clone下载flannel。多试几次
[root@k8s01 ~]# ll
...
drwxr-xr-x 11 root root 332 Mar 6 20:30 flannel
# 修改flannel资源清单
[root@k8s01 ~]# cd flannel/Documentation
[root@k8s01 ~/flannel/Documentation]# vim kube-flannel.yml
...
...
net-conf.json: |
{
"Network": "10.2.0.0/16", #//改下Pod IP
"Backend": {
"Type": "vxlan"
}
}
command: #//找到启动命令,flannel启动时给它指定下网卡:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=eth0 #//加上这行,指定网卡
# 加载资源清单启动flannel
[root@k8s01 ~/flannel/Documentation]# kubectl apply -f kube-flannel.yml
namespace/kube-flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
# 查看flannel启动状态
[root@k8s01 ~/flannel/Documentation]# kubectl get namespace
NAME STATUS AGE
default Active 2h31m
kube-flannel Active 9s #//多了一个kube-flannel的名称空间
...
[root@k8s01 ~/flannel/Documentation]# kubectl get pods -n kube-flannel //查看该名称空间下Pod
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-dc9qh 1/1 Running 0 10m
kube-flannel-ds-dtp94 1/1 Running 0 10m
kube-flannel-ds-sdgxh 1/1 Running 0 10m
#//如果三个都是RUNNING,代表三个flannel都启动成功了。因为我们是3个节点,可以-o wide看一眼,它是分别起在三个节点上(如果前面ipvs没有配置则会显示CrashLoopBackOff,Pod一直处于重启状态)
[root@k8s01 ~/flannel/Documentation]# kubectl get pods -n kube-flannel -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-flannel-ds-8mrsq 1/1 Running 0 10m 10.0.0.101 k8s01 <none> <none>
kube-flannel-ds-xl86s 1/1 Running 0 10m 10.0.0.102 k8s02 <none> <none>
kube-flannel-ds-xxjnp 1/1 Running 0 10m 10.0.0.103 k8s03 <none> <none>
# 网络打通后,再看下三个node都变为Ready,成功
[root@k8s01 ~/flannel/Documentation]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s01 Ready master 10d v1.19.3
k8s02 Ready <none> 10d v1.19.3
k8s03 Ready <none> 10d v1.19.3
后续操作
给Node打标签
[root@k8s01 ~]# kubectl label nodes k8s02 node-role.kubernetes.io/node=
node/k8s02 labeled
[root@k8s01 ~]# kubectl label nodes k8s03 node-role.kubernetes.io/node=
node/k8s03 labeled
[root@k8s01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s01 Ready master 12h v1.19.3
k8s02 Ready node 12h v1.19.3
k8s03 Ready node 12h v1.19.3