Kubernetes是一种开源的容器编排工具,用于管理和编排云原生应用程序。它可以协调和管理运行在多个计算机集群上的Docker容器,自动进行容器部署、更新、扩容和负载均衡等操作,以确保应用程序的可用性和高可靠性。
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的运行环境
kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:
Kubernetes的工作原理可以简单地概括为:通过API服务器、etcd和调度器等组件,将容器化的应用程序部署到集群中的工作节点上,并保证他们按照用户定义的方式运行和提供服务。简单来说,Kubernetes利用了多个工作节点(node)进行应用的部署和运行,使用Pod来封装容器。Pod中包含一个或多个紧密耦合的容器,可以共享网络和存储资源,Pod可以水平扩展,当一个或多个Pod失败时,可以进行自动替换。Kubernetes还提供了负载均衡、服务发现和伸缩等功能,以帮助应用程序更好地运行和扩展。
一个kubernetes集群主要是由控制节点(master)、工作节点(node) 构成,每个节点上都会安装不同的组件。
master:集群的控制平面,负责集群的决策 ( 管理 )
ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制
Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上
ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等
Etcd :负责存储集群中各种资源对象的信息
node:集群的数据平面,负责为容器提供运行环境 ( 干活 )
Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器
KubeProxy : 负责提供集群内部的服务发现和负载均衡
Docker : 负责节点上容器的各种操作
下面,以部署一个nginx服务来说明kubernetes系统各个组件调用关系:
首先要明确,一旦kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中
一个nginx服务的安装请求会首先被发送到master节点的apiServer组件
apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上
在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer
apiServer调用controller-manager去调度Node节点安装nginx服务
kubelet接收到指令后,会通知docker,然后由docker来启动一个nginx的pod
pod是kubernetes的最小操作单元,容器必须跑在pod中至此,
一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理
这样,外界用户就可以访问集群中的nginx服务了
Kubernetes的优点主要有以下几点:
弹性和高可靠性:Kubernetes通过节点的自动切换和Pod的自动重启等机制实现高可靠性,确保应用程序不会因为单个节点或者Pod的故障导致的中断。
高扩展性:Kubernetes支持水平扩展,可以扩展节点的数量以容纳更多的容器,在应用程序负载增大的情况下,可以通过添加节点进行扩展。
简化部署:Kubernetes抽象了容器和Pod等概念,简化了部署和管理容器化应用程序的过程,使得开发人员更加专注于应用程序本身。
然而,Kubernetes也存在一些缺点:
学习成本高:由于Kubernetes涉及到多个概念和组件,以及高度抽象的部署和管理方式,因此学习成本相对较高。
复杂性高:Kubernetes的部署和配置比较复杂,需要更多的人力和时间进行维护,管理容器数量较少的场景可能会过度负担。
运行成本高:由于Kubernetes需要在多个节点上运行,需要额外的网络和存储资源,因此相对于单节点方案,运行成本会增加。
主机名 | 角色 | 安装的软件 | IP地址 | 系统版本 |
---|---|---|---|---|
master | 管理节点 | Docker kubeadm kubelet kubectl |
192.168.179.13 | centos8 |
node1 | 工作节点 | Docker kubeadm kubelet kubectl |
192.168.179.14 | centos8 |
node2 | 工作节点 | Docker kubeadm kubelet kubectl |
192.168.179.15 | centos8 |
//永久关闭防火墙和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
(省略)
# units generated from this file.
#
/dev/mapper/cs-root / xfs defaults 0 0
UUID=22d538b9-6f73-43c5-8d80-228f9bc1b20a /boot xfs defaults 0 0
#/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 ~]# 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
安装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
先添加一个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
在 /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
只在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
//下载一个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 ~]# //没有问题
在两台工作节点上执行;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 ~]#
//创建一个名字叫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的运行是需要进行配置的,它的配置文件是$HOME/.kube,如果想要在node节点运行此命令,需要将master上的.kube文件复制到node节点上,即在master节点上执行下面操作:
演示:
//在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 ~]$
--可以使用