【Kubernetes】k8s入门及使用(从零开始做实例)【测试成功】

艺帆风顺 发布于 2025-04-03 24 次阅读


长按1. 需求分析

1.1 选择安装方式

1.minikube

2.使用kubeadm 是k8s官方推荐的安装k8s的方式 (推荐)

3.二进制安装

4.第3方的部署工具:rancher等

今天我们选择比较具有实用性的kubeadm的方式进行k8s的安装和部署。

1.2 集群的架构

1.单master多node
2.多master多node ——高可用( 3个master 3个node 1台负载均衡(nginx))

介于个人的硬件配置限制,今天进行第1种架构,希望以后有机会有能力和资源,我再来玩第二种架构。

1.3 实验环境

软件:CentOS 7.9 、Docker
硬件:2G/2C
1个master,2个node

2. 详细安装步骤(每台机器都要做!)

2.1 准备好三台虚拟机

1.重新创建虚拟机(可以先创建一台,再以此克隆两台,注意改名字)

2.配置静态ip
配置ip地址:vi /etc/sysconfig/network-scripts/ifcfg-ens33
配置好后,刷新网络服务:service network restart

3.改名字

hostnamectl set-hostname xxx
su - root

xxx:名字
su - root:重新登陆,切换刷新名字

jdmaster 192.168.1.7
jdnode-1 192.168.1.8
jdnode-2 192.168.1.9

使用固定的ip地址,防止后面因为ip地址的变化,导致整个集群异常。

2.2 关闭selinux和firewalld

1.这些步骤三台机器都是相同的,所以用XShell登入后,用一个工具,提高我们的操作效率(只需要在一台机器输入指令即可使三台机器执行相关指令)

2.关闭selinux和firewalld:
(1).永久关闭selinux:

vim /etc/selinux/config 
SELINUX=disabled

(2).临时关闭selinux

setenforce 0

(3).关闭防火墙:

service firewalld stop
systemctl disable firewalld

(4).顺便升级下所有的能升级的软件,提高系统的安全性

yum update -y

2.3 安装Docker

1.安装yum相关的工具,下载docker-ce.repo文件,执行以下命令

yum remove docker 
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine
yum install -y yum-utils -y
yum-config-manager 
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo

2.安装docker-ce软件
执行:

yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y

小讲解:

container engine 容器引擎
docker是一个容器管理的软件
docker-ce 是服务器端软件 server
docker-ce-cli 是客户端软件 client
docker-compose-plugin是compose插件,用来批量启动很多容器,在单台机器上 containerd.io 底层用来启动容器的

3.检查安装是否成功

[root@jdmaster ~]# docker version
Client: Docker Engine - Community
Version: 23.0.1
API version: 1.42
Go version: go1.19.5
Git commit: a5ee5b1
Built: Thu Feb 9 19:51:00 2023
OS/Arch: linux/amd64
Context: default
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

4.启动docker服务
启动:

systemctl start docker

通过查看进程,看看是否启动成功:

[root@jdmaster ~]# ps aux|grep docker
root 32922 0.1 2.6 1101972 50000 ? Ssl 15:39 0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 33051 0.0 0.0 112824 984 pts/0 S+ 15:41 0:00 grep --color=auto docker

5.设置docker服务开机启动

[root@jdmaster ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

2.4 配置Docker使用systemd作为默认Cgroup驱动

每台服务器上都要操作,master和node上都要操作执行下面的脚本,会产生 /etc/docker/daemon.json文件。
执行:

cat EOF > /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

重启docker:

[rootjdnode-1 ~]# systemctl restart docker

查看:

[root@jdnode-1 ~]# cd /etc/docker
[root@jdnode-1 docker]# ls
daemon.json

2.5 关闭swap分区

因为k8s不想使用swap分区来存储数据,使用swap会降低性能。

swapoff -a # 临时关闭

执行:
永久修改:
方法1:

sed -i '/ swap / s/^(.*)$/#1/g' /etc/fstab

方法2:修改/etc/fstab,把SWAP那一行注释即可。

2.6 修改hosts文件

执行:

cat >> /etc/hosts  EOF 
192.168.1.7 jdmaster
192.168.1.8 jdnode-1
192.168.1.9 jdnode-2
EOF
[root@jdmaster docker]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.7 jdmaster
192.168.1.8 jdnode-1
192.168.1.9 jdnode-2

2.7 修改内核参数

修改内核参数,每台机器上(master和node),永久修改 追加到内核会读取的参数文件里。
执行:

cat EOF >>/etc/sysctl.conf 
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
vm.swappiness=0
EOF

让内核重新读取数据,加载生效
执行:

sysctl -p

2.8 安装kubeadm,kubelet和kubectl

集群里的每台服务器都需要安装。

kubeadm --》k8s的管理程序–》在master上运行的–》建立整个k8s集群,背后是执行了大量的脚本,帮助我们去启动k8s。

kubelet --》在node节点上用来管理容器的–》管理docker,告诉docker程序去启动容器。管理docker容器的,告诉docker程序去启动pod 一个在集群中每个节点(node)上运行的代理。它保证容器(containers)都 运行在 Pod 中。

kubectl–》在master上用来给node节点发号施令的程序,用来控制node节点的,告诉它们做什么事情的,是命令行操作的工具

2.8.1 添加kubernetes 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
2.8.2 安装并指定版本

最好指定版本,因为1.24的版本默认的容器运行时环境不是docker了。

yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6
2.8.3 设置开机自启

因为kubelet是k8s在node节点上的代理,必须开机要运行的。

systemctl enable kubelet

3. 部署Kubernetes Master

3.1 准备coredns:1.8.4的镜像

提前准备coredns:1.8.4的镜像,后面需要使用,需要在每台机器上下载镜像。
执行以下两条命令:

[root@jdmaster docker]# docker pull coredns/coredns:1.8.4
[root@jdmaster docker]# docker tag coredns/coredns:1.8.4 registry.aliyuncs.com/google_containers/coredns:v1.8.4

3.2 初始化

1.初始化操作只在master服务器上执行!!!
执行:

kubeadm init 
--apiserver-advertise-address=192.168.1.7
--image-repository registry.aliyuncs.com/google_containers
--service-cidr=10.1.0.0/16
--pod-network-cidr=10.244.0.0/16

小讲解:

192.168.1.7 是master的ip。
–service-cidr string
(Use alternative range of IP address for service VIPs. )(default “10.96.0.0/12”) 服务发布暴露–》dnat

–pod-network-cidr string
( Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node.)

2.完成初始化的新建文件和目录的操作,在master上完成。
耐心吧等几分钟,装好之后,按照提示:
执行这三条命令:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
[root@jdmaster docker]# mkdir -p $HOME/.kube
[root@jdmaster docker]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@jdmaster docker]# sudo chown $(id -u):$(id -g) $HOME/.kube/config

4. node节点部署

1.测试node节点能否和master通信:

[root@jdnode-1 docker]# ping jdmaster
PING jdmaster (192.168.1.7) 56(84) bytes of data.
64 bytes from jdmaster (192.168.1.7): icmp_seq=1 ttl=64 time=1.00 ms
64 bytes from jdmaster (192.168.1.7): icmp_seq=2 ttl=64 time=1.59 ms
64 bytes from jdmaster (192.168.1.7): icmp_seq=3 ttl=64 time=1.87 ms
^C
--- jdmaster ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 1.005/1.492/1.875/0.365 ms

2.执行:

[root@jdnode-1 docker]# kubeadm join 192.168.1.7:6443 --token xv2cjr.d0win422go1bf2km 
> --discovery-token-ca-cert-hash sha256:7a2c5fcf9acd321a0bccd13333e3430004e158988b272b60459b1cf6ed48dea0
[preflight] Running pre-flight checks
[WARNING SystemVerification]: this Docker version is not on the list of validated versions: 23.0.1. Latest validated version: 20.10
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

3.所有的node节点都需要加入到k8s集群里,查看集群里的机器:

[root@jdmaster docker]# kubectl get node
NAME STATUS ROLES AGE VERSION
jdmaster NotReady control-plane,master 15m v1.23.6
jdnode-1 NotReady none> 2m33s v1.23.6
jdnode-2 NotReady none> 2m33s v1.23.6

NotReady 说明master和node节点之间的通信还是有问题的,容器之间通信还没有准备好

5. 安装网络插件flannel(在master节点执行)

网络插件flannel实现master上的pod和node节点上的pod之间通信。
k8s里的网络插件:作用就是实现不同的宿主机之间的pod的通信
1.flannel—overlay
2.calico
注意:k8s在不停的升级更新,我们所使用的组件也需要使用比较新的版本,不然会导致安装和使用的过程出现异常!!!
需要索要kube-flannel.yaml 配置文件,代码太长。下载最新版本的flannel网络插件:https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

执行:

kubectl apply -f kube-flannel.yml

过程:

[root@jdmaster ~]# kubectl apply -f kube-flannel.yml 
namespace/kube-flannel 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@jdmaster ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
jdmaster Ready control-plane,master 140m v1.23.6
jdnode-1 Ready none> 127m v1.23.6
jdnode-2 Ready none> 127m v1.23.6

[root@jdmaster ~]# kubectl get ns
NAME STATUS AGE
default Active 140m
kube-flannel Active 81s
kube-node-lease Active 140m
kube-public Active 140m
kube-system Active 140m


[root@jdmaster ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6d8c4cb4d-cdvnk 0/1 ContainerCreating 0 140m
coredns-6d8c4cb4d-s6tjq 0/1 ContainerCreating 0 140m
etcd-jdmaster 1/1 Running 0 140m
kube-apiserver-jdmaster 1/1 Running 0 140m
kube-controller-manager-jdmaster 1/1 Running 0 140m
kube-proxy-6k7r8 1/1 Running 0 127m
kube-proxy-jplmn 1/1 Running 0 140m
kube-proxy-pdjqm 1/1 Running 0 127m
kube-scheduler-jdmaster 1/1 Running 0 140m

[root@jdmaster ~]# kubectl get pod -n kube-flannel
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-9h229 0/1 Init:1/2 0 50s
kube-flannel-ds-x44k8 0/1 Init:1/2 0 50s
kube-flannel-ds-zh298 0/1 Init:1/2 0 50s

[root@jdmaster ~]# kubectl get pod -n kube-flannel -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-flannel-ds-9h229 1/1 Running 0 5m4s 192.168.1.7 jdmaster none> none>
kube-flannel-ds-x44k8 1/1 Running 0 5m4s 192.168.1.9 jdnode-2 none> none>
kube-flannel-ds-zh298 1/1 Running 0 5m4s 192.168.1.8 jdnode-1 none> none>

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

  • 24

  • 25

  • 26

  • 27

  • 28

  • 29

  • 30

  • 31

  • 32

  • 33

  • 34

  • 35

  • 36

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

命名空间:namespace 用来做资源隔离的
default 是默认存放业务pod的,业务pod在创建的时候,可以自己去指定到那个命名空间,如果不指定就会在default

6 使用pod

6.1 使用pod(一)

deployment 控制器:专门负责在k8s里安装部署pod。
kubectl create deployment 创建部署控制器:
举个栗子:

kubectl create deployment k8s-nginx --image=nginx -r 8

k8s-nginx 是控制器的名字

–image=nginx 指定控制器去启动pod使用的镜像

-r 8 启动8个nginx的pod

-r, --replicas=1: Number of replicas to create. Default is 1.

副本控制器replicaSet(rs):作用就是监控pod副本的数量,如果某个node节点挂了,这个节点上的pod也会挂了,这个时候,副本控制器就会在其他的node节点上启动新的pod,数量总数达到副本控制器当时设置的数量 。即,高可用。

[root@jdmaster ~]# kubectl create deployment k8s-nginx --image=nginx -r 4
deployment.apps/k8s-nginx created

[root@jdmaster ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
k8s-nginx-6d779d947c-6ndll 1/1 Running 0 26s 10.244.1.5 jdnode-2 none> none>
k8s-nginx-6d779d947c-f2ngw 1/1 Running 0 26s 10.244.1.6 jdnode-2 none> none>
k8s-nginx-6d779d947c-jhl5t 1/1 Running 0 26s 10.244.2.5 jdnode-1 none> none>
k8s-nginx-6d779d947c-xzm9x 1/1 Running 0 26s 10.244.2.4 jdnode-1 none> none>

若要删除pod:

[root@scmaster flannel]# kubectl delete deployment k8s-nginx
deployment.apps "k8s-nginx" deleted
[root@scmaster flannel]# kubectl get pod
No resources found in default namespace.
[root@scmaster flannel]#

6.2 使用pod(二)

一个简单示例

[root@jdmaster pod]# vim nginx.yaml

内容如下:

apiVersion: v1
kind: Pod
metadata:
name: jdnginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

启动pod:

[root@jdmaster pod]# kubectl apply -f nginx.yaml
pod/jdnginx created
[root@jdmaster pod]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
jdnginx 1/1 Running 0 2m8s 10.244.2.6 jdnode-1 none> none>

进入容器内部:

[root@jdmaster pod]# kubectl exec -it jdnginx -- bash
root@jdnginx:/#
root@jdnginx:/# exit
exit

7. 流程详解


Pod 是 Kubernetes 中最小的可部署单元,通常包含一个或多个容器。Pod 的启动流程通常可以分为以下几个步骤:

创建 Pod:通过 Kubernetes API 或命令行工具创建 Pod 对象,并指定 Pod 的名称、标签、容器等信息。

Pod 调度:Kubernetes 调度器会将 Pod 调度到集群中的某个节点上。调度器会考虑节点的资源、标签、Pod 的需求等因素,选择最合适的节点。

创建容器:一旦 Pod 被调度到节点上,Kubernetes 就会创建容器并启动应用程序。如果 Pod 包含多个容器,则会依次创建每个容器。

Pod 生命周期:Pod 有三种生命周期阶段,分别是 Pending、Running 和 Succeeded/Failed。在 Pending 阶段,Kubernetes 正在为 Pod 分配资源。在 Running 阶段,Pod 中的容器正在运行。在 Succeeded/Failed 阶段,Pod 中的所有容器已经完成或失败。

容器状态:在 Pod 运行期间,Kubernetes 会监控容器的状态,例如容器的运行状态、资源使用情况、日志输出等信息。如果容器出现故障或崩溃,Kubernetes 会自动重启容器。

Pod 清理:当一个 Pod 不再需要时,Kubernetes 会自动清理 Pod 对象及其关联的资源,例如容器、存储卷等。
总之,Pod 的启动流程是一个复杂的过程,涉及到 Pod 的创建、调度、容器创建、生命周期管理、容器状态监控和清理等多个方面。Kubernetes 提供了丰富的工具和功能,可以帮助用户轻松地管理和部署 Pod,提高应用程序的可用性和稳定性。

8. 可发布的案例(可访问的serevice)

启动pod,然后创建service发布出去
第一大步:

    [root@jdmaster pod]# vim my_nginx.yaml
    apiVersion: apps/v1kind: Deploymentmetadata: name: my-nginxspec: selector: matchLabels: run: my-nginx replicas: 3 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80



    [root@jdmaster pod]# kubectl apply -f my_nginx.yamldeployment.apps/my-nginx created[root@jdmaster pod]# kubectl get podNAME READY STATUS RESTARTS AGEjdnginx 1/1 Running 0 128mk8s-nginx-6d779d947c-6ndll 1/1 Running 0 146mk8s-nginx-6d779d947c-f2ngw 1/1 Running 0 146mk8s-nginx-6d779d947c-jhl5t 1/1 Running 0 146mk8s-nginx-6d779d947c-xzm9x 1/1 Running 0 146mmy-nginx-cf54cdbf7-4lcx4 1/1 Running 0 8smy-nginx-cf54cdbf7-b6tw7 1/1 Running 0 8smy-nginx-cf54cdbf7-fh5ws 0/1 ContainerCreating 0 8s[root@jdmaster pod]#

    第二大步:

      [root@jdmaster pod]# vim my_service.yaml
      apiVersion: v1kind: Servicemetadata: name: my-nginx labels: run: my-nginxspec: type: NodePort ports: - port: 8080 targetPort: 80 protocol: TCP name: http selector: run: my-nginx



      [root@jdmaster pod]# kubectl apply -f my_service.yaml service/my-nginx created[root@jdmaster pod]# kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.1.0.1 443/TCP 5h25mmy-nginx NodePort 10.1.162.15 8080:32581/TCP 100s

      访问发布的pod

      我们只要随便访问k8s集群里的任何一台node节点服务器,包括master

      浏览器访问 http://192.168.1.7:32581
      访问 http://192.168.1.8:32581
      访问 http://192.168.1.5:32581(尽管master没有启动pod,引出负载均衡)
      都访问成功:

      希望本篇文章能对读者有所帮助,欢迎扫描下方二维码关注本号,更多内容持续更新中。

        版权声明:本文内容来自CSDN:日 近 长 安 远,遵循CC 4.0 BY-SA版权协议上原文接及本声明。本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行可。原文链接:https://blog.csdn.net/Stephen_Daa/article/details/129667991如有涉及到侵权,请联系,将立即予以删除处理。在此特别鸣谢原作者的创作。此篇文章的所有版权归原作者所有,与本公众号无关,商业转载建议请联系原作者,非商业转载请注明出处。