[k8s 学习笔记]
本文只是自己的学习笔记,借鉴了很多别人的内容
摘自知乎:
一、 k8s简介
K8S 是Kubernetes的全称,官方称其是:
Kubernetes is an open source system for managing containerized applications across multiple hosts. It provides basic mechanisms for deployment, maintenance, and scaling of applications.
用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统
k8s是负责自当年规划运维管理多个docker程序的集群,比docker swarm门槛高,且功能强大
二、k8s组件
2.1 Master节点组件:
API Server: K8S 的请求入口服务, API Server 负责接收 K8S 所有请求(来自 UI 界面或者 CLI 命令行工具),然后,API Server 根据用户的具体请求,去通知其他组件干活
Scheduler:K8S 所有 Worker Node 的调度器,当用户要部署服务时,Scheduler 会选择最合适的 Worker Node(服务器)来部署
Controller Manager:K8S 所有 Worker Node 的监控器。Controller Manager 有很多具体的 Controller,在文章Components of Kubernetes Architecture中提到的有 Node Controller、Service Controller、Volume Controller 等。Controller 负责监控和调整在 Worker Node 上部署的服务的状态,比如用户要求 A 服务部署 2 个副本,那么当其中一个服务挂了的时候,Controller 会马上调整,让 Scheduler 再选择一个 Worker Node 重新部署服务。
etcd:K8S 的存储服务,etcd 存储了 K8S 的关键配置和用户配置,K8S 中仅 API Server 才具备读写权限,其他组件必须通过 API Server 的接口才能读写数据(见Kubernetes Works Like an Operating System)。
2.2 Work节点组件
Kubelet:Worker Node 的监视器,以及与 Master Node 的通讯器。Kubelet 是 Master Node 安插在 Worker Node 上的“眼线”,它会定期向 Worker Node 汇报自己 Node 上运行的服务的状态,并接受来自 Master Node 的指示采取调整措施。
Kube-Proxy:K8S 的网络代理。私以为称呼为 Network-Proxy 可能更适合?Kube-Proxy 负责 Node 在 K8S 的网络通讯、以及对外部网络流量的负载均衡。
Container Runtime:Worker Node 的运行环境。即安装了容器化所需的软件环境确保容器化程序能够跑起来,比如 Docker Engine。大白话就是帮忙装好了 Docker 运行环境。
Logging Layer:K8S 的监控状态收集器。私以为称呼为 Monitor 可能更合适?Logging Layer 负责采集 Node 上所有服务的 CPU、内存、磁盘、网络等监控项信息。
Add-Ons:K8S 管理运维 Worker Node 的插件组件。有些文章认为 Worker Node 只有三大组件,不包含 Add-On,但笔者认为 K8S 系统提供了 Add-On 机制,让用户可以扩展更多定制化功能,是很不错的亮点。
三、k8s重要概念
3.1 Pod
Pod是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元,可以被理解成一群可以共享网络、存储和计算资源的容器化服务的集合,同一个 Pod 之间的 Container 可以通过 localhost 互相访问,并且可以挂载 Pod 内所有的数据卷;但是不同的 Pod 之间的 Container 不能用 localhost 访问,也不能挂载其他 Pod 的数据卷。
下面是一个Pod的yaml示例:
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: mem-example
spec:
containers:
- name: memory-demo-ctr
image: polinux/stress
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
apiVersion
记录 K8S 的 API Server 版本,现在看到的都是v1
,用户不用管。
kind
记录该yaml 的对象,比如这是一份 Pod 的 yaml 配置文件,那么值内容就是Pod。
metadata
记录了 Pod 自身的元数据,比如这个 Pod 的名字、这个 Pod 属于哪个 namespace(命名空间的概念,后文会详述,暂时理解为“同一个命名空间内的对象互相可见”)。
spec
记录了 Pod 内部所有的资源的详细信息,看懂这个很重要:
containers
记录了 Pod 内的容器信息,containers
包括了:name
容器名,image
容器的镜像地址,resources
容器需要的 CPU、内存、GPU 等资源,command
容器的入口命令,args
容器的入口参数,volumeMounts
容器要挂载的 Pod 数据卷等。可以看到,上述这些信息都是启动容器的必要和必需的信息。
volumes
记录了 Pod 内的数据卷信息,后文会详细介绍 Pod 的数据卷
3.2 Volume数据卷
volume 是 K8S 的对象,对应一个实体的数据卷;而 volumeMounts 只是 container 的挂载点,对应 container 的其中一个参数。但是,volumeMounts 依赖于 volume,只有当 Pod 内有 volume 资源的时候,该 Pod 内部的 container 才可能有 volumeMounts。
3.3 Container容器
一个 Pod 内可以有多个容器 container,在 Pod 中,容器也有分类
标准容器 Application Container。
初始化容器 Init Container。
边车容器 Sidecar Container。
临时容器 Ephemeral Container。
一般部署的还是以标准容器为主
3.4 Deployment和ReplicaSet(简称 RS)
Deployment 的作用是管理和控制 Pod 和 ReplicaSet,管控它们运行在用户期望的状态中。哎,打个形象的比喻,Deployment 就是包工头,主要负责监督底下的工人 Pod 干活,确保每时每刻有用户要求数量的 Pod 在工作。如果一旦发现某个工人 Pod 不行了,就赶紧新拉一个 Pod 过来替换它。
ReplicaSet 的作用就是管理和控制 Pod,管控他们好好干活。但是,ReplicaSet 受控于 Deployment。形象来说,ReplicaSet 就是总包工头手下的小包工头。
总结: 从 K8S 使用者角度来看,用户会直接操作 Deployment 部署服务,而当 Deployment 被部署的时候,K8S 会自动生成要求的 ReplicaSet 和 Pod. 用户只需要关心 Deployment 而不操心 ReplicaSet:
ReplicationController 确保在任何时候都有特定数量的 Pod 副本处于运行状态。 换句话说,ReplicationController 确保一个 Pod 或一组同类的 Pod 总是可用的,ReplicationController 是 ReplicaSet 的前身
3.5 Service 和 Ingress
Service官方定义:
将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用 Kubernetes,您无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡
K8S 中的服务(Service)并不是我们常说的“服务”的含义,而更像是网关层,是若干个 Pod 的流量入口、流量均衡器
Service 主要负责 K8S 集群内部的网络拓扑。那么集群外部怎么访问集群内部呢?这个时候就需要 Ingress 了
Ingress官方定义:
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。
3.6 namespace 命名空间
namespace官方定义:
Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为名字空间。
namespace 是为了把一个 K8S 集群划分为若干个资源不可共享的虚拟集群而诞生的,可以通过在 K8S 集群内创建 namespace 来分隔资源和对象
3.7 其他
四、k8s部署
k8s有多种部署方式,对新手来说,kubeadm部署会容易上手些,除非熟悉很多组件并且理解k8s整体框架和流程之后,使用二进制部署才会得心应手,以下为kubeadm部署笔记
4.1. 环境准备
系统环境
硬件最低要求 | 系统版本 | docker版本 | role | ip地址 |
Memory >= 2GB CPU >= 双核 HardDisk >= 30GB | CentOS8.4.2105 (Linux version 4.18.0-348.xx Red Hat 8.5.0-4) | 20.10.12 | k8s-master | 192.168.100.129 |
k8s-node1 | 192.168.100.130 | |||
k8s-node2 | 192.168.100.131 |
推荐设置所有节点最好4GB内存以上,CPU4核,硬盘容量都至少设置100GB, 后续会不停更新
kubernetes组件
组件 | 版本 |
kubeadm | 1.21.1-0 |
kubectl | 1.21.1-0 |
kubelet | 1.21.1-0 |
docker镜像
REPOSITORY | TAG |
registry.aliyuncs.com/google_containers/kube-apiserver | v1.21.1 |
registry.aliyuncs.com/google_containers/kube-proxy | v1.21.1 |
registry.aliyuncs.com/google_containers/kube-controller-manager | v1.21.1 |
registry.aliyuncs.com/google_containers/kube-scheduler | v1.21.1 |
registry.aliyuncs.com/google_containers/etcd | 3.4.13-0 |
registry.aliyuncs.com/google_containers/coredns | v1.8.0 |
registry.aliyuncs.com/google_containers/pause | 3.4.1 |
4.2. 初始化虚拟机
在开始安装部署之前需要对所有的机器进行初始化环境,避免后续环境问题影响
4.2.1 关闭防火墙
在所有master节点和node节点都需要运行以下命令,只有2.5章节只需要在master上运行即可
systemctl stop firewalld
systemctl disable firewalld
4.2.2 关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config #永久
setenforce 0 # 临时
4.2.3 关闭swap
sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久
swapoff -a # 临时
4.2.4 修改主机名称
hostnamectl set-hostname <hostname> # 示例
hostnamectl set-hostname k8s-master # 在master机器上输入
hostnamectl set-hostname k8s-node1 # 在node1机器上输入
hostnamectl set-hostname k8s-node2 # 在node2机器上输入
4.2.5 只在master中添加hosts
cat > /etc/hosts << EOF
192.168.100.129 k8s-master
192.168.100.130 k8s-node1
192.168.100.131 k8s-node2
EOF
4.2.6 桥接IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
4.2.7 时间同步
rpm -ivh http://mirrors.wlnmp.com/centos/wlnmp-release-centos.noarch.rpm # 添加wlnmp源
yum install wntp
ntpdate time.windows.com
# 如果发现当前区域不一致,可以通过以下命令修改区域
timedatectl # 查看当前区域
timedatectl list-timezone # 查看支持的时区
timedatectl set-timezone Asia/Shanghai # 例如设置当前时区为亚洲/上海时区
4.3. 安装docker/kubeadmi/kubelet
Kubernetes默认CRI(容器运行时)为docker,因此先安装docker,所有节点都要安装并保持版本一致
4.3.1 安装docker
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo # 下载docker-ce源
yum install docker-ce -y # 安装docker-ce
systemctl enable docker && systemctl start docker # 开始docker并设置开机启动
docker --version # 检查docker版本
systemctl status docker # 检查docker当前的状态
4.3.2 添加阿里云软件源
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
4.3.3 安装kubeadm, kubelet和kubectl
yum install -y kubelet-1.21.1 kubeadm-1.21.1 kubectl-1.21.1
systemctl enable kubelet
PS: 由于官网未开放同步方式, 可能会有索引gpg检查失败的情况, 这时请用 yum install -y --nogpgcheck kubelet kubeadm kubectl 安装
4.4 部署Kubernetes Master
4.4.1在 192.168.100.129(master)上执行
kubeadm init \
--apiserver-advertise-address=192.168.100.129 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.21.1 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
# 由于默认拉取的镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库
# service-cidr和pod-network-cidr需要和其他机器IP不冲突皆可
拉取镜像的过程中可能会出现以下报错信息
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR ImagePull]: failed to pull image registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0: output: Error response from daemon: pull access denied for registry.aliyuncs.com/google_containers/coredns/coredns, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
, error: exit status 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
由于coredns/coredns:v1.8.0镜像下载失败,可以手动下载该镜像然后修改tag名称, 并删除之前的TAG镜像
docker pull coredns/coredns:1.8.0
docker tag coredns/coredns:1.8.0 registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
docker rmi coredns/coredns:1.8.0
reset(可查看4.4.3 )之后再重新进行Init操作,发现可以成功
默认的token有效期为24小时,如果过期,该token就无法使用了,需要重新创建token,操作如下:
kubeadm token create --print-join-command
4.4.2 使用kubectl工具
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes # 查看node节点
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane,master 83m v1.21.1
4.4.3 重置kubeadm
sudo kubeadm reset
有时会提示reset process does not clean XXXXX等等信息可以以下方法手动删除
删除net.d
rm -rf /etc/cni/net.d
重置iptables
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
sysctl net.bridge.bridge-nf-call-iptables=1
手动执行以下命令来清除对应的残余网卡信息:
sudo ip link del cni0
sudo ip link del flannel.1
删除 $HOME/.kube/config
rm -rf $HOME/.kube/config
4.5 加入Kubernetes Node
4.5.1在192.168.100.130/131(Node)执行
kubeadm join 192.168.100.129:6443 --token kvsx31.dx0ir4wicki90wut \
--discovery-token-ca-cert-hash sha256:2e731f87568256765fd0716f9d19c35a7777ea8c656f5559b177081328d7f16c
4.5.2 查看Master节点加入情况
kubectl get nodes # 查看node节点
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane,master 86m v1.21.1
k8s-node1 NotReady <none> 17s v1.21.1
k8s-node2 NotReady <none> 12s v1.21.1
当前网络插件CNI未配置,所以当前状态都是NotReady
五、部署CNI网络插件
部署CNI网络插件在Master上完成
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
The connection to the server raw.githubusercontent.com was refused - did you specify the right host or port?
发现这个源是无法访问的,是因为无法解析这个域名,然后参考了这份老哥的博客,这个问题解决了 https://blog.csdn.net/weixin_38074756/article/details/109231865,感谢!
通过这个网站: http://ip.tool.chinaz.com/raw.githubusercontent.com 然后输入raw.githubusercontent.com
然后打开/etc/hosts文件将这个IP地址加入到hosts文件中
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.129 k8s-master
192.168.100.130 k8s-node1
192.168.100.131 k8s-node2
185.199.111.133 raw.githubusercontent.com
PS: 这个地址可能会一直变更,在部署之前确认下即可
重新运行apply命令
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
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
查看POD状态,这个时候所有节点的状态变更为Ready
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-545d6fc579-62drv 0/1 ImagePullBackOff 0 123m
coredns-545d6fc579-bcrcg 0/1 ImagePullBackOff 0 123m
etcd-k8s-master 1/1 Running 0 123m
kube-apiserver-k8s-master 1/1 Running 0 123m
kube-controller-manager-k8s-master 1/1 Running 0 123m
kube-flannel-ds-6nlcw 1/1 Running 0 9m57s
kube-flannel-ds-cl2n4 1/1 Running 0 9m57s
kube-flannel-ds-tt2xc 1/1 Running 0 9m57s
kube-proxy-4zv7h 1/1 Running 0 123m
kube-proxy-75jvx 1/1 Running 0 36m
kube-proxy-f8nm5 1/1 Running 0 36m
kube-scheduler-k8s-master 1/1 Running 0 123m
此处发现coredns为ImagePullBackOff状态是因为其他节点上没有coredns的镜像,通过以下命令查看
kubectl get pods -A -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default nginx-6799fc88d8-mzgtx 1/1 Running 0 59m 10.244.2.2 k8s-node2 <none> <none>
kube-system coredns-545d6fc579-62drv 0/1 ImagePullBackOff 0 3h9m 10.244.1.2 k8s-node1 <none> <none>
kube-system coredns-545d6fc579-bcrcg 0/1 ImagePullBackOff 0 3h9m 10.244.1.3 k8s-node1 <none> <none>
可以看出这个ImagePullOff的状态是在k8s-node1节点上,故在node1节点上安装coredns镜像即可,此处node2节点也同样操作
docker pull coredns/coredns:1.8.0
docker tag coredns/coredns:1.8.0 registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
docker rmi coredns/coredns:1.8.0
安装完成后再次检查pod状态,此时都是Running状态
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-545d6fc579-62drv 1/1 Running 0 3h14m
coredns-545d6fc579-bcrcg 1/1 Running 0 3h14m
etcd-k8s-master 1/1 Running 0 3h14m
kube-apiserver-k8s-master 1/1 Running 0 3h14m
kube-controller-manager-k8s-master 1/1 Running 0 3h14m
kube-flannel-ds-6nlcw 1/1 Running 0 81m
kube-flannel-ds-cl2n4 1/1 Running 0 81m
kube-flannel-ds-tt2xc 1/1 Running 0 81m
kube-proxy-4zv7h 1/1 Running 0 3h14m
kube-proxy-75jvx 1/1 Running 0 107m
kube-proxy-f8nm5 1/1 Running 0 107m
kube-scheduler-k8s-master 1/1 Running 0 3h14m
查看Node状态
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 3h19m v1.21.1
k8s-node1 Ready <none> 113m v1.21.1
k8s-node2 Ready <none> 113m v1.21.1
六、测试Kubernetes集群
6.1 在k8s中创建一个pod,验证是否正常运行:
kubectl create deployment nginx --image=nginx
# 在创建的过程中等待镜像拉取完成并且是Running的状态
# 通过以下命令查看
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-mzgtx 0/1 ErrImagePull 0 6s
当出现ErrImagePull状态的时候可以等一段时间
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-mzgtx 1/1 Running 0 79m
目前发现本机拉取其他镜像失败,后续再看看如何
docker pull nginx
Using default tag: latest
Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
放置一夜之后,又可以拉取了,可能是网络原因吧。。。。
6.2 设置对外的端口
kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
# 对外暴露80端口,如果80端口被占用,使用其他端口
6.3 查看对外端口
kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/nginx-6799fc88d8-mzgtx 1/1 Running 0 16h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18h
service/nginx NodePort 10.96.33.37 <none> 80:32637/TCP 2m22s
# 服务此时对外端口为32637,可以用node节点通过这个端口来访问
6.4 Node访问此端口
http://192.168.100.131/132:32637
七、 卸载k8s相关组件
7.1 卸载kubelet\kubeadm\kubectl
yum remove -y kubelet kubeadm kubectl
7.2 停止k8s相关容器并移除docker相关镜像
docker stop $(docker container ls -a | grep google_containers | awk '{print $3}')
docker rm $(docker container ls -a | grep google_containers | awk '{print $3}')
docker rmi $(docker container ls -a | grep google_containers | awk '{print $3}')
7.3 删除本地残留文件
rm -rf ~/.kube/
rm -rf /etc/kubernetes/
rm -rf /etc/systemd/system/kubelet.service.d
rm -rf /etc/systemd/system/kubelet.service
rm -rf /usr/bin/kube*
rm -rf /etc/cni
rm -rf /opt/cni
rm -rf /var/lib/etcd
rm -rf /var/etcd
更多推荐
所有评论(0)