Kubernetes

一、Kubernetes介绍

1.Kubernetes简介

Kubernetes是一种开源的容器编排工具,用于管理和编排云原生应用程序。它可以协调和管理运行在多个计算机集群上的Docker容器,自动进行容器部署、更新、扩容和负载均衡等操作,以确保应用程序的可用性和高可靠性。


2.Kubernetes概念

Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控

Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行

Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器

Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等

Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod

Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签

NameSpace:命名空间,用来隔离pod的运行环境

3.Kubernetes功能

kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:

  • 自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器
  • 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
  • 服务发现:服务可以通过自动发现的形式找到它所依赖的服务
  • 负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
  • 版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
  • 存储编排:可以根据容器自身的需求自动创建存储卷
4.Kubernetes工作原理

Kubernetes的工作原理可以简单地概括为:通过API服务器、etcd和调度器等组件,将容器化的应用程序部署到集群中的工作节点上,并保证他们按照用户定义的方式运行和提供服务。简单来说,Kubernetes利用了多个工作节点(node)进行应用的部署和运行,使用Pod来封装容器。Pod中包含一个或多个紧密耦合的容器,可以共享网络和存储资源,Pod可以水平扩展,当一个或多个Pod失败时,可以进行自动替换。Kubernetes还提供了负载均衡、服务发现和伸缩等功能,以帮助应用程序更好地运行和扩展。

5.kubernetes组件

一个kubernetes集群主要是由控制节点(master)工作节点(node) 构成,每个节点上都会安装不同的组件。

master:集群的控制平面,负责集群的决策 ( 管理 )

ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制

Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上

ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等

Etcd :负责存储集群中各种资源对象的信息

node:集群的数据平面,负责为容器提供运行环境 ( 干活 )

Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器

KubeProxy : 负责提供集群内部的服务发现和负载均衡

Docker : 负责节点上容器的各种操作


下面,以部署一个nginx服务来说明kubernetes系统各个组件调用关系:

  1. 首先要明确,一旦kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中

  2. 一个nginx服务的安装请求会首先被发送到master节点的apiServer组件

  3. apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上

    在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer

  4. apiServer调用controller-manager去调度Node节点安装nginx服务

  5. kubelet接收到指令后,会通知docker,然后由docker来启动一个nginx的pod

    pod是kubernetes的最小操作单元,容器必须跑在pod中至此,

  6. 一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理
    这样,外界用户就可以访问集群中的nginx服务了


6.Kubernetes优缺点

Kubernetes的优点主要有以下几点:

  1. 弹性和高可靠性:Kubernetes通过节点的自动切换和Pod的自动重启等机制实现高可靠性,确保应用程序不会因为单个节点或者Pod的故障导致的中断。

  2. 高扩展性:Kubernetes支持水平扩展,可以扩展节点的数量以容纳更多的容器,在应用程序负载增大的情况下,可以通过添加节点进行扩展。

  3. 简化部署:Kubernetes抽象了容器和Pod等概念,简化了部署和管理容器化应用程序的过程,使得开发人员更加专注于应用程序本身。

然而,Kubernetes也存在一些缺点:

  1. 学习成本高:由于Kubernetes涉及到多个概念和组件,以及高度抽象的部署和管理方式,因此学习成本相对较高。

  2. 复杂性高:Kubernetes的部署和配置比较复杂,需要更多的人力和时间进行维护,管理容器数量较少的场景可能会过度负担。

  3. 运行成本高:由于Kubernetes需要在多个节点上运行,需要额外的网络和存储资源,因此相对于单节点方案,运行成本会增加。


二、Kubernetes环境部署

环境
主机名角色安装的软件IP地址系统版本
master管理节点Docker
kubeadm
kubelet
kubectl
192.168.179.13centos8
node1工作节点Docker
kubeadm
kubelet
kubectl
192.168.179.14centos8
node2工作节点Docker
kubeadm
kubelet
kubectl
192.168.179.15centos8
基本配置
//永久关闭防火墙和selinux(所有主机都做)
systemctl disable --now firewalld.service
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

//所有主机配置国内yum源(推荐使用阿里云源)
rm -rf /etc/yum.repos.d/*

curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo

sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo

yum clean all && yum makecache 


//配置主机名解析(所有主机都做)
[root@master ~]# vi /etc/hosts 
[root@master ~]# cat /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
#要添加的内容
192.168.179.13	master
192.168.179.14	node1
192.168.179.15	node2
[root@master ~]# 

//关闭swap分区(注释掉swap分区的那一行,所有主机都做)
[root@master ~]# vi /etc/fstab 
[root@master ~]# cat /etc/fstab 
(省略)
#注释swap分区那一行
#/dev/mapper/cs-swap     none                    swap    defaults        0 0
[root@master ~]# 


//将桥接的IPv4流量传递到iptables的链(所有主机都做)
[root@master ~]# vi /etc/sysctl.d/k8s.conf
[root@master ~]# cat /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
[root@master ~]# sysctl --system

//配置时间同步
--设置时区(所有主机都设置)
[root@master ~]# timedatectl set-timezone Asia/Shanghai 
--管理节点的配置
[root@master ~]# yum -y install chrony
[root@master ~]# vi /etc/chrony.conf 
[root@master ~]# cat /etc/chrony.conf 
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
pool time1.aliyun.com iburst   //将默认的时间同步服务器换成阿里云的(用此行内容替换原来的)
(省略)
[root@master ~]# systemctl enable chronyd.service 
[root@master ~]# systemctl restart chronyd.service 
--两个工作节点的配置
[root@node1 ~]# yum -y install chrony
[root@node1 ~]# vi /etc/chrony.conf 
[root@node1 ~]# cat /etc/chrony.conf 
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
pool master iburst  //将默认的时间同步服务器改为管理节点
(省略)
[root@node1 ~]# systemctl enable chronyd.service 
[root@node1 ~]# systemctl restart chronyd.service 

//配置免密登录(只在master管理节点上做)
--生成密钥
[root@master ~]# ssh-keygen -t rsa  (一直回车)
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:yqtCSSfFJId+z0yRPJX4rR6i4N1GFPilY+4aG3pxkFI root@master
The key's randomart image is:
+---[RSA 3072]----+
|  .+oo +..       |
|  .oE B o        |
| . o o B .       |
|  = = B . .      |
| . * X .S.       |
|  + ..O.o        |
| o ooBoo .       |
|  o.+++..        |
|  .o++.          |
+----[SHA256]-----+

--发送证书给所有节点(包括自己)
[root@master ~]# ssh-copy-id master
[root@master ~]# ssh-copy-id node1
[root@master ~]# ssh-copy-id node2

//安装基础工具包(所有主机都安装)
yum -y install vim wget

//重启所有主机
reboot
1.所有节点安装docker

安装docker

//安装docker依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2

//配置docker的yum源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

//安装docker
yum -y install docker-ce

//启动并设置docker开机自启
systemctl enable --now docker.service

//配置docker镜像的加速器(所有节点都配置)
[root@master ~]# vim /etc/docker/daemon.json
[root@master ~]# cat /etc/docker/daemon.json
{
   "registry-mirrors": ["https://5qsf7g11.mirror.aliyuncs.com"]
}
[root@master ~]# systemctl daemon-reload 
[root@master ~]# systemctl restart docker.service 
2.所有节点安装kubeadm、kubelet、kubectl
添加yum源

先添加一个kubernetes的yum源,再安装各软件包(所有主机)

//添加kubernetes的yum源
[root@master ~]# 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
[root@master ~]# yum makecache 

//安装kubeadm、kubelet和kubectl
[root@master ~]# yum -y install kubelet kubeadm kubectl

//设置开机自启(仅设置开机自启,千万不要启动!!!)
[root@master ~]# systemctl stop kubelet
[root@master ~]# systemctl enable kubelet
containerd配置

在 /etc/containerd/ 下面有一个 config.toml 的文件

//这个文件默认是没有很多功能的,所以我们不用这,而是重新生成一个
[root@master ~]# cat /etc/containerd/config.toml 
#   Copyright 2018-2022 Docker Inc.

#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at

#       http://www.apache.org/licenses/LICENSE-2.0

(省略)
//生成一个新的config.toml文件
[root@master ~]# containerd config default > /etc/containerd/config.toml

//修改拉取镜像的位置,默认位置是外网,正常情况访问不到。所以换成国内的
--在这个配置文件中找到sandbox_image = "registry.k8s.io/pause:3.6"这一行,把这行改为
  sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"
[root@master ~]# vim /etc/containerd/config.toml 
[root@master ~]# cat /etc/containerd/config.toml 
(省略)
    sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"
(省略)

//重启containerd服务并设置开机自启
[root@master ~]# systemctl restart containerd.service 
[root@master ~]# systemctl enable containerd.service 

//把这个改好的文件scp到另外两个工作节点
[root@master ~]# scp /etc/containerd/config.toml node1:/etc/containerd/
[root@master ~]# scp /etc/containerd/config.toml node2:/etc/containerd/

//在另外两个工作节点上重启containerd服务并设置开机自启
[root@node1 ~]# systemctl restart containerd.service && systemctl enable containerd.service 
[root@node2 ~]# systemctl restart containerd.service && systemctl enable containerd.service 
3.部署Kubernetes Master(管理节点)

只在master主机(管理节点)上操作

//初始化集群
[root@master ~]# kubeadm init \
  --apiserver-advertise-address=192.168.179.13 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.28.2 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16
  
//出现这行就代表初始化成功:Your Kubernetes control-plane has initialized successfully!

//初始化后生成的一些教程复制下来,写在一个文件里面保存起来,说不定以后会用到
[root@master ~]# vim k8s-init
[root@master ~]# cat k8s-init 
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.179.13:6443 --token 3codju.65fqz143cjxzfjcw \
	--discovery-token-ca-cert-hash sha256:9ffae8478fff2fd94274144066edc9d91f229b51b8e11663da8ce055da04028c 
[root@master ~]# 

//设置环境变量
[root@master ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" > /etc/profile.d/k8s.sh
[root@master ~]# source /etc/profile.d/k8s.sh
4.安装Pod网络插件(CNI)
//下载一个flannel资源模板文件
[root@master ~]# wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

//添加flannel资源
[root@master ~]# kubectl apply -f kube-flannel.yml 

//查看flannel资源
[root@master ~]# kubectl get -f kube-flannel.yml 
NAME                     STATUS   AGE
namespace/kube-flannel   Active   89s

NAME                     SECRETS   AGE
serviceaccount/flannel   0         89s

NAME                                            CREATED AT
clusterrole.rbac.authorization.k8s.io/flannel   2023-11-13T09:06:00Z

NAME                                                   ROLE                  AGE
clusterrolebinding.rbac.authorization.k8s.io/flannel   ClusterRole/flannel   89s

NAME                         DATA   AGE
configmap/kube-flannel-cfg   2      89s

NAME                             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/kube-flannel-ds   1         1         1       1            1           <none>          89s
[root@master ~]#   //资源没有问题

//查看k8s组件的pod
[root@master ~]# kubectl get pods -n kube-system
NAME                             READY   STATUS    RESTARTS   AGE
coredns-66f779496c-5thsr         1/1     Running   0          27m
coredns-66f779496c-nqjkx         1/1     Running   0          27m
etcd-master                      1/1     Running   0          27m
kube-apiserver-master            1/1     Running   0          27m
kube-controller-manager-master   1/1     Running   0          27m
kube-proxy-7dc82                 1/1     Running   0          27m
kube-scheduler-master            1/1     Running   0          27m
[root@master ~]#  //运行没有问题

//查看所有名称空间
[root@master ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   29m
kube-flannel      Active   4m8s
kube-node-lease   Active   29m
kube-public       Active   29m
kube-system       Active   29m
[root@master ~]#  //没有问题
5.加入Kubernetes Node

在两台工作节点上执行;node1和node2

//在node1和node2上执行
[root@node1 ~]# kubeadm join 192.168.179.13:6443 --token 3codju.65fqz143cjxzfjcw \
	--discovery-token-ca-cert-hash sha256:9ffae8478fff2fd94274144066edc9d91f229b51b8e11663da8ce055da04028c 

[root@node2 ~]# kubeadm join 192.168.179.13:6443 --token 3codju.65fqz143cjxzfjcw \
	--discovery-token-ca-cert-hash sha256:9ffae8478fff2fd94274144066edc9d91f229b51b8e11663da8ce055da04028c 


//在master上查看加入的node节点
[root@master ~]# kubectl get nodes
NAME     STATUS     ROLES           AGE   VERSION
master   Ready      control-plane   33m   v1.28.2
node1    Ready      <none>          87s   v1.28.2
node2    NotReady   <none>          36s   v1.28.2
[root@master ~]# 

//查看网络组件,在两台node上也跑起来了
[root@master ~]# kubectl get pods -n kube-flannel -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
kube-flannel-ds-7h6vp   1/1     Running   0          3m32s   192.168.179.14   node1    <none>           <none>
kube-flannel-ds-gmhpm   1/1     Running   0          10m     192.168.179.13   master   <none>           <none>
kube-flannel-ds-mhn7s   1/1     Running   0          2m41s   192.168.179.15   node2    <none>           <none>
[root@master ~]# 


6.测试Kubernetes 集群
//创建一个名字叫nginx,镜像为nginx,在default名称空间里面的pod
[root@master ~]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created

//查看pod状态,已经跑起来了,在内部使用容器ip访问
[root@master ~]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE    IP           NODE    NOMINATED NODE   READINESS GATES
nginx-7854ff8877-r277b   1/1     Running   0          3m6s   10.244.1.2   node2   <none>           <none>

//内部访问
[root@master ~]# curl 10.244.1.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>



//暴露端口号
[root@master ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed

//查看
[root@master ~]# kubectl get pod,svc
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-7854ff8877-r277b   1/1     Running   0          9m8s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        61m
service/nginx        NodePort    10.110.91.174   <none>        80:32597/TCP   94s
[root@master ~]# 

然后使用管理节点的ip加映射的端口号在浏览器访问

在这里插入图片描述


扩展:配置kubectl命令可以在node节点上运行

kubectl的运行是需要进行配置的,它的配置文件是$HOME/.kube,如果想要在node节点运行此命令,需要将master上的.kube文件复制到node节点上,即在master节点上执行下面操作:

  • 1.在node节点(工作节点)上创建一个用户
  • 2.在该用户的家目录中创建一个隐藏目录 .kube
  • 3.将控制节点上的/etc/kubernetes/admin.conf通过scp发送到node节点里上一步创建的目录中并命名为config
  • 4.在node节点修改config文的属主属组为第1步创建的用户

演示:

//在node节点上创建用户并设置密码
[root@node1 ~]# useradd k8s
[root@node1 ~]# echo "1"  | passwd --stdin k8s 
Changing password for user k8s.
passwd: all authentication tokens updated successfully.
[root@node1 ~]# 

//在node节点上创建隐藏目录
[root@node1 ~]# mkdir -p /home/k8s/.kube

//在控制节点上发送文件
[root@master ~]# scp /etc/kubernetes/admin.conf node1:/home/k8s/.kube/config
admin.conf                                 100% 5646     3.3MB/s   00:00    
[root@master ~]# 

//在node节点上修改/home/k8s/.kube/config的属主属组
[root@node1 ~]# chown k8s:k8s /home/k8s/.kube/config
[root@node1 ~]# ll /home/k8s/.kube/config
-rw------- 1 k8s k8s 5646 Nov 15 17:07 /home/k8s/.kube/config
[root@node1 ~]# 

//切换到第1步创建的用户,测试
[k8s@node1 ~]$ kubectl get namespace
NAME              STATUS   AGE
default           Active   2d
kube-flannel      Active   2d
kube-node-lease   Active   2d
kube-public       Active   2d
kube-system       Active   2d
wanf              Active   21m
[k8s@node1 ~]$ 
--可以使用
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐