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:

[root@jdnode-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.

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>

命名空间: 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/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  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.yaml
deployment.apps/my-nginx created
[root@jdmaster pod]# kubectl get pod
NAME                         READY   STATUS              RESTARTS   AGE
jdnginx                      1/1     Running             0          128m
k8s-nginx-6d779d947c-6ndll   1/1     Running             0          146m
k8s-nginx-6d779d947c-f2ngw   1/1     Running             0          146m
k8s-nginx-6d779d947c-jhl5t   1/1     Running             0          146m
k8s-nginx-6d779d947c-xzm9x   1/1     Running             0          146m
my-nginx-cf54cdbf7-4lcx4     1/1     Running             0          8s
my-nginx-cf54cdbf7-b6tw7     1/1     Running             0          8s
my-nginx-cf54cdbf7-fh5ws     0/1     ContainerCreating   0          8s
[root@jdmaster pod]# 

第二大步:

[root@jdmaster pod]# vim my_service.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  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 svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.1.0.1      <none>        443/TCP          5h25m
my-nginx     NodePort    10.1.162.15   <none>        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,引出负载均衡)
都访问成功:
在这里插入图片描述
在这里插入图片描述

Logo

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

更多推荐