概述:
Kubernetes(简称K8S)是开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能
。它既是一款容器编排工具,也是全新的基于容器技术的分布式架构领先方案。在Docker技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等功能,提高了大规模容器集群管理的便捷性。
Kubernetes集群包含所有节点代理kubelet和Master组件(APIs、scheduler、etc)
,一切都基于分布式的存储系统.
Master为管理节点主要负责K8S集群管理,集群中各节点间的信息交互、任务调度,还负责容器、Pod、NameSpaces、PV等生命周期的管理。
Node 节点是真正运行应用容器的工作节点,在每个 Node 节点上都会运行一个 Kubelet 代理,控制该节点上的容器、镜像和存储卷等。
Kubernetes主要由以下几个核心组件组成:
etcd:
保存了整个集群的状态;
apiserver:
提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
controller manager:
负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
scheduler:
负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
kubelet:
负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
Container runtime:
负责镜像管理以及Pod和容器的真正运行(CRI);
kube-proxy:
负责为Service提供cluster内部的服务发现和负载均衡,负责将访问到某个服务的请求具体分配给工作节点上的 Pod。
pod
一个pod就是一个或一组共享网络/存储的容器。
在一个 Pod 中同时运行多个容器。一个 Pod 中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个 Pod 中的容器可以互相协作成为一个 service 单位 —— 一个容器共享文件,另一个 “sidecar” 容器来更新这些文件。Pod 将这些容器的存储资源作为一个实体来管理。
pod的状态
pending(等待中):
Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。
running(运行中):
Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
succeeded (正常终止):
Pod 中的所有容器都已成功终止,并且不会再重启。
failed (异常停止):
Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
unknown(为止状态)
:因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。
pod详细状态描述
状态 | 描述 |
---|---|
CrashLoopBackOff |
容器退出,kubelet正在将它重启 |
InvalidImageName | 无法解析镜像名称 |
ImageInspectError | 无法校验镜像 |
ErrImageNeverPull | 策略禁止拉取镜像 |
ImagePullBackOff |
正在重试拉取 |
RegistryUnavailable | 连接不到镜像中心 |
ErrImagePull | 通用的拉取镜像出错 |
CreateContainerConfigError | 不能创建kubelet使用的容器配置 |
CreateContainerError | 创建容器失败 |
m.internalLifecycle.PreStartContainer | 执行hook报错 |
RunContainerError | 启动容器失败 |
PostStartHookError | 执行hook报错 |
ContainersNotInitialized | 容器没有初始化完毕 |
ContainersNotRead | 容器没有准备完毕 |
ContainerCreating | 容器创建中 |
PodInitializing | pod 初始化中 |
DockerDaemonNotReady | docker还没有完全启动 |
NetworkPluginNotReady | 网络插件还没有完全启动 |
kubeadm部署k8s集群v1.14.1
一、前提条件
部署kubernetes集群机器需要满足的条件
:
> 一台或多台机器,操作系统 CentOS7.x-86_x64(`centos7以上的系统`)。
> 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多。
> 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点。
> 必须禁止swap分区。
二、准备环境
ip | 主机名 |
---|---|
192.168.200.66 | master(主节点/管理节点) |
192.168.200.67 | node1 (工作节点) |
192.168.200.68 | node2(工作节点) |
(一)所有节点关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
(二)更改主机名
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2
(三)所有节点关闭swap交换空间
关闭的交换空间的原因:是为了性能考虑,如果一个 pod 开了交换空间,可能被认为有很多剩余资源,从而被分配较多的实例。
swapoff -a #临时关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab #永久关闭
(三)所有节点添加hosts
cat >> /etc/hosts << EOF
192.168.200.66 master
192.168.200.67 node1
192.168.200.68 node2
EOF
(四)所有节点配置内核参数
cat << EOF | tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
modprobe br_netfilter #加载 br_netfilter 模块到内核
sysctl -p /etc/sysctl.d/k8s.conf #生效配置文件
(四)所有节点配置IPVS
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 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
lsmod | grep -e ip_vs -e nf_conntrack_ipv4 #查看是否已经正确加载所需的内核模块
所有节点安装ipset软件包
yum install ipset ipvsadm -y
三、所有节点安装docker
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum install docker-ce-18.09.6 docker-ce-cli-18.09.6 containerd.io -y
systemctl enable docker && systemctl start docker
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
#配置cgroup driver,对于使用systemd作为init system的Linux的发行版,使用systemd作为docker的cgroup driver可以确保服务器节点在资源紧张的情况更加稳定.
}
EOF
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
uname -a
:查看系统名、节点名称、操作系统的发行版号、操作系统版本
overlay2
是运行 Linux 内核版本 4.0 或更高版本,或使用版本 3.10.0-514
及更高版本的 RHEL 或CentOS 的系统的首选存储驱动程序。
四、部署集群
(一)所有节点配置yum源
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=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
(二)所有节点安装kubeadm,kubelet和kubectl
Kubelet
负责与其他节点集群通信,并进行本节点Pod和容器生命周期的管理。
Kubeadm
是Kubernetes的自动化部署工具,降低了部署难度,提高效率。
Kubect
l是Kubernetes集群管理工具
yum install -y kubelet-1.14.1 kubeadm-1.14.1 kubectl-1.14.1
systemctl start kubelet && systemctl enable kubelet
(三)master 节点初始化Kubernetes集群
kubeadm init --apiserver-advertise-address 192.168.200.66 --kubernetes-version="v1.14.1" --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --image-repository=registry.aliyuncs.com/google_containers
参数解释:
--image-repository:
指定要使用的镜像仓库;
--apiserver-advertise-address:
apiserver 引用给其他组件的IP地址,一般应该是主节点的用于0内部通信的IP地址,0.0.0.0表示节点上可用地址;
--kubernetes-version:
kubernetes程序组件的版本号,应该与kubelet的版本号相同
–-pod-network-cidr:
Pod网络的地址范围,其值为CIDR格式的网络地址,flannel网络插件的默认为10.244.0.0/16,callco插件的默认值为192.168.0.0/16;根据kube-flannel.yml文件写入。
--service-cidr:
Service的网咯地址范围,其值为CIDR格式的网络地址,默认为10.96.0.0/12;
[root@master ~]# kubeadm init --apiserver-advertise-address 192.168.200.66 --kubernetes-version="v1.14.1" --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --image-repository=registry.aliyuncs.com/google_containers
W0611 02:16:26.422410 95252 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[init] Using Kubernetes version: v1.14.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'
[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
[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 [master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.200.66]
[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 [master localhost] and IPs [192.168.200.66 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [master localhost] and IPs [192.168.200.66 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
[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"
W0611 02:16:30.265215 95252 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-scheduler"
W0611 02:16:30.266754 95252 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[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 17.004509 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.18" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node master as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: ta9t9x.pvoj1vs3f9asae1c
[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
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.200.66:6443 --token ta9t9x.pvoj1vs3f9asae1c \
--discovery-token-ca-cert-hash sha256:21697a2daaae041da45cb2b587a3a078fc81752b20a40e3dfc9f233187dd5fd7
[init]:指定版本进行初始化操作。
[preflight]:初始化前的检查和下载所需要的Docker镜像文。
[kubelet-start]:生成Kubelet的配置文件/var/lib/kubelet/config.yaml,没有这个文件Kubelet无法启动,所以初始化之前的Kubelet实际上启动失败。
[certificates]:生成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组件服务状态。
[uploadconfig]:更新配置。
[kubelet]:使用configMap配置Kubelet。
[patchnode]:更新CNI信息到Node上,通过注释的方式记录。
[mark-control-plane]:为当前节点打标签,打了角色Master,和不可调度标签,这样默认就不会使用Master节点来运行Pod。
[bootstrap-token]:生成的Token需要记录下来,后面使用kubeadm join命令往集群中添加节点时会用到。
[addons]:安装附加组件CoreDNS和kube-proxy。
(1)master节点配置kubectl工具
[root@master ~]# mkdir -p $HOME/.kube
[root@master ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
(2)node节点(工作节点)加入到集群
默认token有效期为24小时,使用下面命令重新生成token。
[root@master ~]#kubeadm token create --print-join-command
五、查看集群状态
(一)kubectl get cs #查看K8s集群状态
[root@master ~]# kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}
(二)kubectl get node #查看节点状态
[root@master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
master NotReady master 39m v1.14.1
node1 NotReady <none> 37m v1.14.1
状态是 NotReady 是因为网络还没配置
六、k8s集群安装flannel网络插件
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
[root@master ~]# kubectl apply -f kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged 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
[root@master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready master 39m v1.14.1
node1 Ready <none> 37m v1.14.1
查看pods状态
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7ff77c879f-sdrgc 1/1 Running 0 21m
coredns-7ff77c879f-zg8v2 1/1 Running 0 21m
etcd-master 1/1 Running 0 22m
kube-apiserver-master 1/1 Running 0 22m
kube-controller-manager-master 1/1 Running 0 22m
kube-flannel-ds-rqndx 1/1 Running 0 85s
kube-flannel-ds-x7ktt 1/1 Running 0 85s
kube-proxy-5q2ps 1/1 Running 0 21m
kube-proxy-dxwx5 1/1 Running 0 9m54s
kube-scheduler-master 1/1 Running 0 22m
查看指定命名空间的pods的信息
[root@master ~]# kubectl get pods -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-7ff77c879f-sdrgc 1/1 Running 0 23m 10.244.1.2 node1 <none> <none>
coredns-7ff77c879f-zg8v2 1/1 Running 0 23m 10.244.1.3 node1 <none> <none>
etcd-master 1/1 Running 0 23m 192.168.200.66 master <none> <none>
kube-apiserver-master 1/1 Running 0 23m 192.168.200.66 master <none> <none>
kube-controller-manager-master 1/1 Running 0 23m 192.168.200.66 master <none> <none>
kube-flannel-ds-rqndx 1/1 Running 0 2m53s 192.168.200.67 node1 <none> <none>
kube-flannel-ds-x7ktt 1/1 Running 0 2m53s 192.168.200.66 master <none> <none>
kube-proxy-5q2ps 1/1 Running 0 23m 192.168.200.66 master <none> <none>
kube-proxy-dxwx5 1/1 Running 0 11m 192.168.200.67 node1 <none> <none>
kube-scheduler-master 1/1 Running 0 23m 192.168.200.66 master <none> <none>
出现的问题和解决的方法
`检查错误常用的命令
journalctl -xefu kubelet #查看kubelet服务日志
systemctl status kubelet #查看kubelet服务状态
kubectl get cs #查看组件状态
kubectl get nodes #获取集群状态
kubectl get pods -n kube-system #查看kube-system namespace下的pod状态
kubeadm token create --print-join-command #token超时后,重新创建token
问题一、
[ERROR FileContent–proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 1
解决
echo "1" > /proc/sys/net/ipv4/ip_forward
问题二、
kubeadm reset -f #重置节点
kubeadm join ip --token #重新加入集群
问题三、
解决:
在/etc/sysconfig/kubelet中添加--feature-gates SupportPodPidsLimit=false --feature-gates SupportNodePidsLimit=false
[root@master ~]# vi /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=--feature-gates SupportPodPidsLimit=false --feature-gates SupportNodePidsLimit=false
systemctl daemon-reload
systemctl restart kubelet