暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

centos上用kubeadm安装k8s1.18,步骤最详细一篇

蛮懒 2020-05-21
662

背景介绍

Kubernetes将集群中的机器划分为单个Master和多个Node。

Master上运行集群管理相关的进程,实现整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理的自动完成功能,如kube-apiserver、kube-controller-manager、kubescheduler、etcd

Node是工作节点,运行真正的应用,其最小运行单元是Pod,POD相当于一个容器,有独立的ip、hostname,通过namespace进行资源隔离,独立沙箱环境;一个Pod包含调用链上的一组容器,一个pod内部的多个容器,共享一个pause容器;同时一个pod中的不同容器间通过localhost访问。Node上运行kubelet、kube-proxy
服务进程来负责Pod的创建、启动、监控、重启、销毁,及实现软件模式的负载均衡器。POD有生命周,有宕机、版本更新的情况,会创建新的pod,ip及hostname会发生变化。

针对服务的容器化部署,主要涉及2类:

  • StatefulSet:解决有状态服务使用容器化部署

  • deployment:解决无状态服务的容器化部署

Service资源对象

  • POD IP :pod的ip地址,其上层是pod网关,同网段的pod之间通过该IP进行路由分发

  • Cluster IP:虚拟IP(VIP),由k8s抽象出的service对象

  • Node IP :物理机IP地址

Service  VIP:

1、service与pod都是进程(非物理硬件),service也不能对外网提供服务;

2、service与pod之间可以直接进行通信,它们的通信属局域网通信

3、把请求交给service后,service使用iptables/ipvs进行数据包的分发

将pod绑定物理端口:物理机IP+端口--->Service VIP---> 通过iptables/ipvs进行数据包转发

service对象 通过“标签选择器”关联一组pod,如果POD出现宕机、版本更新,每个节点上的kube-proxy会监听pod的存活状态,然后更新VIP到endpoints的映射关系,该映射关系存储在etcd中


实际操作

机器配置要求

  • 每台机器 2 GB 或更多的 RAM 

  • 2 核CPU 或更多

安装的步骤流程图

前期准备工作

kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,在安装前,先满足如下条件:

(1)集群中的所有机器的网络互通

(2)集群中的所有机器主机名、MAC 地址或 uuid唯一

  • 针对product_uuid 校验:cat /sys/class/dmi/id/product_uuid
     

(3)禁用交换分区:swapoff -a

(4)关闭防火墙以及selinux

systemctl stop firewalld && systemctl disable firewalld
yum -y install iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

(5)修改主机名及时区,确保集群中各节点不同主机名、相同时区:

hostnamectl set-hostname master
echo "127.0.0.1 $(hostname)" >> /etc/hosts
timedatectl set-timezone Asia/Shanghai

(6)持久化journal日志,非必要。可以参考:https://blog.steamedfish.org/post/systemd-journald/

mkdir /etc/systemd/journald.conf.d && mkdir /var/log/journal
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
Storage=persistent
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
SystemMaxUse=2G
SystemMaxFileSize=200M
MaxRetentionSec=2week
ForwardToSyslog=no
EOF
systemctl restart systemd-journald

(7)安装docker

针对iptables被绕过而导致流量无法正确路由的问题,可以设置sysctl
配置中的 net.bridge.bridge-nf-call-iptables
被设置为1。

modprobe br_netfilter
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
vm.swappiness=0
EOF
sysctl --system

可以使用 lsmod |grep br_netfilter
查看模块是否有正常加载。再运行安装docker,设置aliyun源:

yum install yum-utils device-mapper-persistent-data lvm2 -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install containerd.io-1.2.10 docker-ce-19.03.4 docker-ce-cli-19.03.4 -y
systemctl start docker
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
systemctl enable docker && systemctl daemon-reload && systemctl restart docker

使用systemd作为docker的cgroup driver可确保服务器节点在资源紧张的情况更稳定,因此这里修改各个节点上docker的cgroup driver为systemd。即:native.cgroupdriver=systemd

安装k8s工具

      需要在集群中的每个节点上安装以下的软件包:

  • kubeadm
    :用来初始化集群的指令。

  • kubelet
    :在集群中的每个节点上用来启动 pod 和容器等,是一个持续运行的后台服务。

  • kubectl
    :用来与集群通信的命令行工具。

(8.1)先配置K8S的yum源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
(8.2)使用 yum list kubelet --showduplicates
来查看可用的版本,默认可以直接进行安装:
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet


# yum install -y ipvsadm bash-completion 无法直接安装的情况下使用如下4行
wget http://mirror.centos.org/altarch/7/os/armhfp/Packages/bash-completion-2.1-8.el7.noarch.rpm
rpm -ivh bash-completion-2.1-8.el7.noarch.rpm
wget http://mirror.centos.org/centos/7/os/x86_64/Packages/ipvsadm-1.27-8.el7.x86_64.rpm
rpm -ivh ipvsadm-1.27-8.el7.x86_64.rpm


mkdir ~/.kube/
kubectl completion bash > ~/.kube/completion.bash.inc


printf "
# Kubectl shell completion
source '$HOME/.kube/completion.bash.inc'
" >> $HOME/.bash_profile


source $HOME/.bash_profile
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >>~/.bashrc
source ~/.bashrc

(8.3)加载ipvs模块:使用ipvs模块替代iptables,性能更好,但不是必须。

cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- br_netfilter
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && \
bash /etc/sysconfig/modules/ipvs.modules && \
lsmod | grep -E "ip_vs|nf_conntrack_ipv4"

手工下载k8s镜像

总体思路是使用 kubeadm config images list
先输出镜像名,然后替换为阿里源:

k8s.gcr.io/kube-apiserver:v1.18.3
k8s.gcr.io/kube-controller-manager:v1.18.3
k8s.gcr.io/kube-scheduler:v1.18.3
k8s.gcr.io/kube-proxy:v1.18.3
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.7

具体镜像下载脚本如下:

#!/bin/bash
kube_version=:v1.18.3
kube_images=(kube-proxy kube-scheduler kube-controller-manager kube-apiserver)
addon_images=(etcd-amd64:3.4.3 coredns:1.6.7 pause-amd64:3.2)
for imageName in ${kube_images[@]} ;do
  docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version
  docker image tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version k8s.gcr.io/$imageName$kube_version
  docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version
done


for imageName in ${addon_images[@]} ;do
  docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
  docker image tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
  docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done
docker tag k8s.gcr.io/etcd-amd64:3.4.3 k8s.gcr.io/etcd:3.4.3-0
docker image rm k8s.gcr.io/etcd-amd64:3.4.3
docker tag k8s.gcr.io/pause-amd64:3.2 k8s.gcr.io/pause:3.2
docker image rm k8s.gcr.io/pause-amd64:3.2

kubeadm init初始化

使用kubeadm init
进行初始化,具体命令如下:

kubeadm init --kubernetes-version=1.18.3 \
--apiserver-advertise-address=0.0.0.0 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.96.0.0/12 \
--apiserver-cert-extra-sans=XXXX授信IP或域名列表(通过逗号分隔) \
--pod-network-cidr=10.244.0.0/16 \
ignore-preflight-errors

kubeadm说明参考:https://k8smeetup.github.io/docs/admin/kubeadm/# 

执行成功后,根据提示,根据拷贝 admin.conf 文件到当前用户相应目录下。

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

查看集群中node、创建的POD等信息,通过exec -it进入Pod里面

kubectl get pod -n kube-system -o wide
kubectl get nodes -o wide
kubectl describe pods -n kube-system $PODName
kubectl exec -it $PODName /bin/bash

kubeadm init初始化流程详细描述如下:

  • [init]:指定版本进行初始化操作

  • [preflight] :初始化前的检查和下载所需要的Docker镜像文件

  • [kubelet-start] :生成kubelet配置文件/var/lib/kubelet/config.yaml

  • [certs]:生成Kubernetes使用的证书在/etc/kubernetes/pki
    目录。

  • [kubeconfig] :生成 KubeConfig 文件,存放在/etc/kubernetes目录中,组件之间通信需要使用对应文件。

  • [control-plane]:使用/etc/kubernetes/manifest
    目录下的YAML文件,安装 Master 组件。

  • [etcd]:使用/etc/kubernetes/manifest/etcd.yaml
    安装Etcd服务。

  • [wait-control-plane]:等待control-plan部署的Master组件启动。

  • [apiclient]:检查Master组件服务状态。

  • [upload-config]:更新配置

  • [kubelet]:使用configMap配置kubelet。

  • [mark-control-plane]:为当前节点打标签,打了角色Master,和不可调度标签,这样默认就不会使用Master节点来运行Pod。

  • [bootstrap-token]:生成token记录下来,后边使用kubeadm join往集群中添加节点时会用到

  • [addons]:安装附加组件CoreDNS和kube-proxy

安装pod-network
在安装网络插件之前,运行
kubectl get nodes
展示node的状态是NotReady。下载kube-flannel.yml文件,并安装网络插件:

wget https://github.com/coreos/flannel/edit/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml

备注:如果只有Master 主机,集群也可以正常使用的,但默认情况下,出于安全考虑,集群不会在 control-plane 运行节点上部署 pods,如果需要正常使用单节点集群,需要使用如下命令解除该限制:

> kubectl describe nodes master |grep Taints
Taints: node-role.kubernetes.io/master:NoSchedule
> kubectl taint node master node-role.kubernetes.io/master-
node/master untainted
> kubectl describe nodes master |grep Taints
Taints: <none>

节点部署

使用master上的k8s配置文件yaml部署node节点上的POD

使用kubeadm config print init-defaults 2>/dev/null >kubeadm-config.yaml
获取集群初始化默认的使用的配置,基于实际配置对文件进行微调(标+:改后;表-:改前)

apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
- advertiseAddress: 1.2.3.4
+ advertiseAddress: 192.168.1.60 #master节点的IP
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
+ name: master #这里可以填写IP地址以及域名,使用域名时,必须保证解析
taints:
- - effect: NoSchedule
+ - effect: PreferNoSchedule #taints污点,
key: node-role.kubernetes.io/master
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
-imageRepository: k8s.gcr.io
+imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers #修改为国内源
kind: ClusterConfiguration
kubernetesVersion: v1.18.3
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
+ podSubnet: 10.100.0.1/16
scheduler: {}

在其他节点上运行 kubeadm init --config kubeadm-config.yaml
进行初始化。

成功之后,再安装pod-network网络插件。使用 kubeadm config view
查看集群信息。

加入到集群的命令为:kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>

(12.1)token未过期

默认情况下,kubeadm init成功之后,会默认生成一个token,默认是24小时有效的。如果未过期,可以使用kubeadm token create --print-join-command
来查看。如果使用kubectl get nodes
查看集群,可能会看到node是NotReady的状态(下载images需要较慢导致)

(12.2)token过期

如果超过了24小时,可通过如下命令创建一个新的token。然后在要加的节点上面运行 kubeadm join 192.168.1.60:6443 --token $OUT1 --discovery-token-ca-cert-hash $OUT2 其中OUT1、OUT2分别对应两条命令的输出

kubeadm token create  #OUT1
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' # OUT2

安装Dashboard 

Dashboard 是基于网页的 Kubernetes 用户界面。集成应用部署、容器应用排错、管理集群资源、获取应用的概览信息、创建或修改 Kubernetes 资源。

具体链接:https://github.com/kubernetes/dashboard/tree/master/docs

(13.1)下载yml并通过kubectl apply创建pod

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc5/aio/deploy/recommended.yaml
kubectl apply -f recommended.yaml


注意,目前Dashboard的namespace为 kubernetes-dashboard
。可以运行 kubectl get pods -n kubernetes-dashboard
来查看pod的状态。

(13.2)要需要创建RBAC。就是创建权限访问控制。

apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
  namespace: kubernetes-dashboard
执行 kubectl create -f kubernetes-dashboard-admin.rbac.yaml
也可用以下方法快速创建:
kubectl create serviceaccount admin-user -n kubernetes-dashboard
kubectl create clusterrolebinding admin-user --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:admin-user
(13.3)API方式访问。可以使用浏览器访问地址:

https://{master-ip}:6443/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login 
这时会要求输入一个token,可以使用使用来获取:kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

chrome浏览器不能访问,因SSL证书是自签的,chrome不认,但可以这样做:

grep 'client-certificate-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d >> kubecfg.crt
grep 'client-key-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d >> kubecfg.key
openssl pkcs12 -export -clcerts -inkey kubecfg.key -in kubecfg.crt -out kubecfg.p12 -name "kubernetes-client"

按要求输入密码直接回车即可,密码不要胡乱输,后面给浏览器导入的时候要用。
运行完后在当前目录会有个kubecfg.p12证书文件。该证书文件一次运行,多次使用

也可以使用rancher通过helm进行部署,部署成功后重复步骤13.2、13.3


问题现象

events is forbidden: User "system:serviceaccount:kube-system:kube-system-kubernetes-dashboard" cannot list resource "events" in API group "" in the namespace "default"

问题解决

kubectl create clusterrolebinding kube-system-kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kube-system-kubernetes-dashboard



文章转载自蛮懒,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论