K8S (使用步骤)

一、为什么要学习K8S

Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移你的应用、提供部署模式等。
负载均衡
自动部署和回滚
自我修复

**二、**架构图

三、如何搭建K8S集群

3.1安装K8S

|----|---------|-----------------|
| 序号 | 节点名称 | IP |
| 1 | master1 | 192.168.200.131 |
| 2 | worker1 | 192.168.200.132 |
| 3 | worker2 | 192.168.200.133 |

bash 复制代码
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 第一步:安装ntp服务
yum -y install ntp
# 第二步:开启开机启动服务
systemctl enable ntpd
# 第三步:启动服务
systemctl start ntpd
# 第四步:更改时区
timedatectl set-timezone Asia/Shanghai
# 第五步:启用ntp同步
timedatectl set-ntp yes
# 第六步:同步时间
ntpq -p

# 移除之前版本
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
                  
# 配置镜像源
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 指定版本安装 docker 
yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7  containerd.io-1.4.6

# 查看 docker 版本
[root@localhost ~]# docker -v
Docker version 20.10.7, build f0df350

# 设置开机自启并启动
systemctl enable docker --now

# 设置镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://docker.1ms.run",
    "https://ccr.ccs.tencentyun.com",
    "https://hub.xdark.top",
    "https://hub.fast360.xyz",
    "https://docker-0.unsee.tech",
    "https://docker.xuanyuan.me",
    "https://docker.tbedu.top",
    "https://docker.hlmirror.com",
    "https://doublezonline.cloud",
    "https://docker.melikeme.cn",
    "https://image.cloudlayer.icu",
    "https://dislabaiot.xyz",
    "https://freeno.xyz",
    "https://docker.kejilion.pro"
  ],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3.2 配置三台机器主机名

hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-worker1
hostnamectl set-hostname k8s-worker2

3.3 配置预备环境
bash 复制代码
# 在各个机器上都要设置
# 将 SELinux 设置为 permissive 模式
•enforcing:强制模式,代表 SELinux 运作中,且已经正确的开始限制 domain/type 了;
•permissive:宽容模式:代表 SELinux 运作中,不过仅会有警告讯息并不会实际限制 domain/type 的存取。这种模式可以运来作为 SELinux 的 debug 之用;
•disabled:关闭,SELinux 并没有实际运作。

sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

#关闭swap 占用
swapoff -a  
sed -ri 's/.*swap.*/#&/' /etc/fstab

# 可以使用命令查看是否关闭swap分区
free -m 

#允许 iptables 检查桥接流量,也能统计Ip6的数据流量
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 使配置生效
sudo sysctl --system
3.4 安装kubelet、kubeadm、kubectl
bash 复制代码
#配置k8s的yum源地址
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
   http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

#安装 kubelet,kubeadm,kubectl
sudo yum install -y kubelet-1.20.9 kubeadm-1.20.9 kubectl-1.20.9

#启动kubelet 
sudo systemctl enable kubelet
sudo systemctl start kubelet
sudo systemctl status kubelet
3.5 所有机器,配置域名映射
bash 复制代码
#所有机器添加master域名映射,以下需要修改为自己的,IP:主节点的IP
echo "192.168.200.131 k8s-master" >> /etc/hosts
# 修改每台主机的hosts 将每个服务器都要写上 master worker1 worker2 
vi /etc/hosts
192.168.200.131 k8s-master
192.168.200.132 k8s-worker1
192.168.200.133 k8s-worker2
# 如果添加成功 使用 ping k8s-master 能 ping 通
[root@bogon ~]# ping k8s-master
PING cluster-endpoint (192.168.200.181) 56(84) bytes of data.
64 bytes from cluster-endpoint (192.168.200.181): icmp_seq=1 ttl=64 time=0.584 ms
64 bytes from cluster-endpoint (192.168.200.181): icmp_seq=2 ttl=64 time=0.422 ms

# 上传镜像,并运行对应的shell 脚本,完成镜像导入!
3.6 主节点初始化
bash 复制代码
# 主节点初始化
# --image-repository 使用阿里云的镜像仓库
# 192.168.200.131 : 主节点的IP 
# k8s-cluster : 跟3.5步骤的域名映射一致
# 192.168.0.0 : 网络插件IP,如果你的电脑网段是192.168.xxx.xxx,那么这个IP需要更换
kubeadm init \
--apiserver-advertise-address=192.168.200.131 \
--control-plane-endpoint=k8s-master \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.20.9 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=172.32.0.0/16

# 命令注释:
# 这是一个用于初始化Kubernetes集群的命令,具体参数的含义如下:
--apiserver-advertise-address: 指定API服务器的公网IP地址。
--control-plane-endpoint: 指定控制平面节点的域名或IP地址。
--image-repository: 指定镜像仓库的地址。
--kubernetes-version: 指定要安装的Kubernetes版本。
--service-cidr: 指定服务网络的CIDR块,定义kubernetes服务的虚拟IP地址段,所有Service的ClusterIP将从该网段分配。
--pod-network-cidr: 指定Pod网络的CIDR块,定义Pod所在的网络地址,需与后续部署的网络查看配置的网段一致,否则Pod之间无法通信。
#所有网络范围不重叠

# 常见问题: /proc/sys/net/ipv4/ip_forward contents are not set to 1z
# 将master节点-work节点都执行
echo "1" > /proc/sys/net/ipv4/ip_forward

# 常见问题: modprobe: FATAL: Module nf_conntrack_ipv4 not found
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- br_netfilter
EOF

# 所有网络范围不重叠
# 操作成功日志(保存好日志)
Your Kubernetes control-plane has initialized successfully!

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/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join k8s-cluster:6443 --token llqz9p.qbgs9kmckdv3bem4 \
    --discovery-token-ca-cert-hash sha256:7d486d205dbe6c7a7463c5c4954dcb36afd092befcbd480b9b1bf92199081948 \
    --control-plane 

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join k8s-cluster:6443 --token llqz9p.qbgs9kmckdv3bem4 \
    --discovery-token-ca-cert-hash sha256:7d486d205dbe6c7a7463c5c4954dcb36afd092befcbd480b9b1bf92199081948 

保存好上面的启动成功的日志

3.7 部署网络插件
bash 复制代码
curl https://docs.projectcalico.org/v3.20/manifests/calico.yaml -O

# 注意,主节点初始时,如果修改 --pod-network-cidr=192.168.0.0/16
# 原有配置是注释掉的 3888 3889
# - name: CALICO_IPV4POOL_CIDR
#   value: "192.168.0.0/16"
# calico.yaml ip 也需要修改
- name: CALICO_IPV4POOL_CIDR
  value: "172.32.0.0/16"
#应用这个配置文件
kubectl apply -f calico.yaml

3.8 创建worker节点

使用上面保存的日志(不要用我的,连不上的)

bash 复制代码
kubeadm join k8s-cluster:6443 --token llqz9p.qbgs9kmckdv3bem4 \
    --discovery-token-ca-cert-hash sha256:7d486d205dbe6c7a7463c5c4954dcb36afd092befcbd480b9b1bf92199081948 

问题解决:

bash 复制代码
# 如果出现这个错误,解决方案
    [ERROR DirAvailable--etc-kubernetes-manifests]: /etc/kubernetes/manifests is not empty
    [ERROR FileAvailable--etc-kubernetes-kubelet.conf]: /etc/kubernetes/kubelet.conf already exists
    [ERROR Port-10250]: Port 10250 is in use
    [ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists
kubeadm reset

令牌过期:

bash 复制代码
[root@localhost ~]# kubeadm token create --print-join-command
kubeadm join cluster-kubendpoint:6443 --token k3z6hm.7dptca591imod2mn     --discovery-token-ca-cert-hash sha256:d66cffb305f0274c9984ef1fe1447245655d3094922cbcb61dbd64ada619455f 
3.9 验证集群状态
bash 复制代码
[root@k8s-master ~]# kubectl get nodes
NAME          STATUS   ROLES                  AGE    VERSION
k8s-master    Ready    control-plane,master   104m   v1.20.9
k8s-worker1   Ready    <none>                 101m   v1.20.9
k8s-worker2   Ready    <none>                 101m   v1.20.9
bash 复制代码
kubectl get node # 查询节点状态
kubectl get pod -A #查询K8S部署的所有pod
kubectl get pod -A -o wide #打印详细信息,查看pod在哪个节点部署
kubectl apply -f 部署文件.yaml # 向K8S中部署资源
kubectl version # K8S版本

3.10 部署k8s的可视化界面(deshboard)

在浏览器访问:
https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
vi recommended.yaml #复制粘贴上述配置文件

bash 复制代码
将配置文件中的这两个镜像
image: kubernetesui/dashboard:v2.3.1
image: kubernetesui/metrics-scraper:v1.0.6
替换为下面的两个
image: registry.cn-hangzhou.aliyuncs.com/google_containers/dashboard:v2.3.1
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-scraper:v1.0.6

kubectl apply -f recommended.yaml

修改服务网络 [root@localhost ~]# kubectl edit svc kubernetes-

bash 复制代码
# 修改服务网络
[root@localhost ~]# kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
# 文件第29行 type: ClusterIP 改为 type: NodePort
# 查询对外暴露的端口
[root@localhost ~]# kubectl get svc -A |grep kubernetes-dashboard
kubernetes-dashboard   dashboard-metrics-scraper   ClusterIP   10.96.22.70    <none>        8000/TCP                 31m
kubernetes-dashboard   kubernetes-dashboard        NodePort    10.96.61.107   <none>        443:30282/TCP            31m

记住这里的443:30282/TCP,咱们肯定不一样
测试访问:
https://192.168.200.131:30282 #端口改为上面的端口号

创建访问账号 才能访问

bash 复制代码
#创建访问账号,准备一个yaml文件; vi dash-user.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard·

应用文件

bash 复制代码
kubectl apply -f dash-user.yaml

获取令牌

bash 复制代码
#获取访问令牌
kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"

将令牌粘贴到输入框中点击登录

登录后界面

bash 复制代码
开机自启动:
systemctl enable kubelet
systemctl enable docker
systemctl disable firewalld

核心实战

4.1 资源创建方式

在Kubernetes(k8s)中,所有的内容都被抽象为资源,用户通过操作这些资源来管理Kubernetes集群。

  • Pod资源
  • Service资源
  • Volume资源
4.1.1 命令行

使用以下语法从终端窗口运行 kubectl 命令:

bash 复制代码
kubectl [command] [TYPE] [NAME] [flags]

其中 command、 TYPE、 NAME 和 flags 分别是:

  • command:指定要对一个或多个资源执行的操作 ,例如 create、get、describe、delete。
  • TYPE:指定资源类型。资源类型不区分大小写, 可以指定单数、复数或缩写形式。
  • NAME:指定资源的名称 。名称区分大小写。 如果省略名称,则显示所有资源的详细信息。例如:kubectl get pods。
  • flags: 指定可选的参数。例如,使用 -s 或 --server 参数指定 Kubernetes API 服务器的地址和端口。
    常用命令
bash 复制代码
# 创建 命名空间
kubectl create ns dev
​
# 创建 Nginx 服务器
kubectl run pod --image=nginx -n dev 
​
# 查询default命名空间中pod
kubectl get pod 
​
# 查询所有命名空间中pod
kubectl get pod -A
​
# 查询指定命名空间中pod
kubectl get pod -n dev 
​
# 删除 pod
kubectl delete pod pod -n dev 
4.1.2 YAML
bash 复制代码
# 创建YAML文件
vim nginx.yaml
# 编辑文件
apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: dev
spec:
  containers:
  - name: nginx-containers
    image: nginx
  
# 创建 pod
kubectl apply -f nginx.yaml
​
# 删除 pod
kubectl delete -f nginx.yaml 

4.2 Namespace

Namespace是K8S中的一种非常重要资源,它的主要作用是用来实现 资源隔离。可以隔离不同用户、项目或环境之间的资源,以确保资源的合理使用和安全性。Namespace可以用于区分不同的用户、租户、环境和项目,以便更好地管理集群资源。在创建pod时,可以指定pod到特定的Namespace。
K8S提供了几个默认的Namespace,例如default、kube-system和kube-public。default命名空间用于未指定Namespace的对象,kube-system主要用于运行系统级资源,存放Kubernetes一些组件的。
命令方式操作命名空间

bash 复制代码
kubectl get ns 
kubectl create ns hello
kubectl delete ns hello

YAML方式操作命令空间

bash 复制代码
# 创建YAML文件
vim ns-dev.yaml
# 编辑文件
apiVersion: v1  # 版本信息
kind: Namespace # 资源类型
metadata: # 元数据的意思
  name: dev
  
# 创建命名空间
kubectl apply -f ns-dev.yaml
​
# 删除命名空间
kubectl delete -f ns-dev.yaml 

注意:删除命名空间时,该命名空间下的所有资源都会被删除

4.3 Pod

Pod 是可以在 K8S中创建和管理的、最小的可部署的计算单元。我们可以理解Pod就是容器的封装,一个Pod中可以有 多个容器

4.3.1 Pod基本操作
bash 复制代码
# 创建 Pod
kubectl run mynginx --image=nginx
​
# 查看default名称空间的Pod ,指定-A属性查询所有名称空间下的Pod
kubectl get pod 
​
# 描述
kubectl describe pod 你自己的Pod名字
​
# 删除
kubectl delete pod Pod名字
​
# 查看Pod的运行日志
kubectl logs Pod名字
​
# 每个Pod - k8s都会分配一个ip
kubectl get pod -owide

集群中的任意一个机器以及任意的应用都能通过Pod分配的IP来访问这个Pod,截止目前,我们创建的Pod还不能外部访问

4.3.2 创建多容器Pod

创建单容器Yaml示例

bash 复制代码
# 单个容器描述文件 vi mynginx.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: mynginx
  name: mynginx
#  namespace: default
spec:
  containers:
  - image: nginx
    name: mynginx

创建多容器Yaml示例

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: myapp
  name: myapp
spec:
  containers:
  - image: nginx
    name: nginx
  - image: tomcat:8.5.68
    name: tomcat

使用命令查看会发现有两个容器被创建

root@k8s-master \~\]# kubectl describe pod myapp ##### **4.3.3 Pod内部原理** ![](https://i-blog.csdnimg.cn/direct/b0afedfc19d14669995862b51d9acba9.png) ##### **4.3.4 Pod自我恢复演示** 了解 ,其实我们通过停止或者删除的方式模拟容器崩溃,K8S会帮我们修复容器 ##### **4.3.5 Pod资源配置** 容器中的程序在运行时需要占用一定的资源,如CPU和内存等。如果不限制某个容器的资源使用,它可能会消耗大量的资源,导致其他容器无法正常运行。为了解决这个问题,Kubernetes提供了资源配额机制,主要通过"resources"选项来实现。该机制包含两个子选项: * limits:用于限制容器运行时的最大资源占用。当容器的资源使用超过这个限制时,容器将被终止并重新启动。 * requests:用于设置容器所需的最小资源。如果环境中提供的资源不足,容器将无法启动。 ```bash apiVersion: v1 kind: Pod metadata: name: pod-test spec: containers: - name: nginx image: nginx resources: # 资源配额 limits: # 限制上限 cpu: "1" memory: "1Gi" requests: # 限制下限 cpu: "1" memory: "100Mi" ``` #### **4.4 Deployment** Deployment代表执行一次部署, **可以部署多个pod** 、 **控制Pod**,使Pod拥有多副本、自愈、扩缩容等能力 ![](https://i-blog.csdnimg.cn/direct/eb8d410bc89e4e6ea3f8fce66f3c03cf.png) ##### **4.4.1 常规操作** ```bash # 创建一次部署 kubectl create deployment mytomcat --image=tomcat:8.5.68 ​ # 创建一个3个副本的部署 kubectl create deployment my-dep --image=nginx --replicas=3 ​ # 获取部署信息 kubectl get deployment kubectl get deploy ​ # 删除部署 kubectl delete deployment mytomcat ``` Yaml创建部署 vi mynginxapp.yaml ```bash apiVersion: apps/v1 kind: Deployment metadata: labels: app: mynginx name: mynginxapp spec: replicas: 1 selector: matchLabels: app: mynginx template: metadata: labels: app: mynginx spec: containers: - image: nginx name: nginx ``` ##### **4.4.2 自愈\&故障转移** 自愈是指k8s帮我们修复应用,比如我们pod内部容器,宕机了,这时候k8s感知到会尝试重启。 故障转移,是指我们k8s集群可能有一台机器宕机了,这个时候,k8s帮我们把宕机节点应用重新部署到其他worker节点上。 ```bash # 演示pod、deployment 区别 # deployment 部署一个tomcat kubectl create deployment mytomcat1 --image=tomcat:8.5.68 # pod kubectl run mynginx --image=nginx [root@k8s-master ~]# kubectl get pod NAME READY STATUS RESTARTS AGE mynginx 1/1 Running 0 34s mytomcat1-7c9898f454-pl9kz 1/1 Running 0 3m59s ​ kubectl delete pod mynginx kubectl delete pod mytomcat1-7c9898f454-pl9kz ​ ``` ##### **4.4.3 多副本** ```bash kubectl create deployment my-dep --image=nginx --replicas=3 # 通过yaml文件可以指定多副本 replicas: 3 ​ # 监控pod -删除一个pod的时候,会自动创建一个pod watch -n 1 kubectl get pod ``` ##### **4.4.4 扩缩容pod** > kubectl scale --replicas=5 deployment/my-dep ##### **4.4.5 滚动更新** 灰度发布: ```bash kubectl set image deployment/my-dep nginx=nginx:1.16.1 --record kubectl rollout status deployment/my-dep ``` ##### **4.4.6 版本回退** ```bash #历史记录 kubectl rollout history deployment/my-dep ​ #查看某个历史详情 kubectl rollout history deployment/my-dep --revision=2 ​ #回滚(回到上次) kubectl rollout undo deployment/my-dep ​ #回滚(回到指定版本) kubectl rollout undo deployment/my-dep --to-revision=2 ``` #### **4.5 Service** 在Kubernetes中,Pod是运行应用程序的容器,然而,由于Pod的 **IP地址是动态分配的**,因此直接使用Pod的IP地址进行服务访问并不方便。为了解决这个问题,Kubernetes引入了Service资源。 Service资源可以聚合提供相同服务的多个Pod,并为它们提供一个统一的入口地址。这样,通过访问Service的入口地址,就可以访问到后台的Pod服务,而无需关心每个Pod的IP地址的变化。这使得服务的访问更加稳定和可靠,同时也提供了更好的可扩展性,因为可以轻松地增加或减少提供服务的Pod数量。 ![](https://i-blog.csdnimg.cn/direct/69f504873d6f4a1099f22ccbe60dc2ed.png) ##### **4.5.1 ClusterIP** ```bash # 等同于没有--type的 kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP ​ # 查看创建的service kubectl get svc ​ # 访问 curl 10.96.226.54:8000 #ip为service的ip 能够看到负载均衡效果了 curl my-dep.default.svc:8000 # 必须在pod中访问! ​ # 部署一个tomat服务,在它的内部访问nginx curl 10.96.226.54:8000 ​ # Yaml apiVersion: v1 kind: Service metadata: labels: app: my-dep name: my-dep spec: ports: - port: 8000 protocol: TCP targetPort: 80 selector: app: my-dep type: ClusterIP ``` ##### **4.5.2 NodePort** 暴露服务,集群外部可以访问,NodePort范围在 30000-32767 之间 ```bash # 暴露服务 kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort ​ #Yaml apiVersion: v1 kind: Service metadata: labels: app: my-dep name: my-dep spec: ports: - port: 8000 nodeport: 30088 #指定绑定的node的端口 targetPort: 80 selector: app: my-dep type: NodePort ``` ```bash [root@k8s-master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 46h my-dep NodePort 10.96.226.54 8000:32615/TCP 33m ​ 浏览器访问:192.168.200.131:32615 ``` **port、targetPort、nodeport区别** node: 服务器 nodeport: node节点的端口 port: service的端口 taggetport:容器的端口 ![](https://i-blog.csdnimg.cn/direct/cd57f85ca67443d58af3b111b9dc651d.png) #### **4.6 Ingress** Ingress是一个资源类型,用于实现用域名的方式访问K8S集群内部的应用。类似微服务的网关功能,提供请求路由、流量控制等功能 API: [https://kubernetes.github.io/ingress-nginx/](https://kubernetes.github.io/ingress-nginx/ "https://kubernetes.github.io/ingress-nginx/") ![](https://i-blog.csdnimg.cn/direct/d6407177ce3a43a180e6ed3674574b0c.png) ##### **4.6.1 Ingress安装** 参考资料Yaml中ingress.yaml ```bash [root@k8s-master ~]# kubectl apply -f ingress.yaml namespace/ingress-nginx created serviceaccount/ingress-nginx created configmap/ingress-nginx-controller created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx created service/ingress-nginx-controller-admission created service/ingress-nginx-controller created deployment.apps/ingress-nginx-controller created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created serviceaccount/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created role.rbac.authorization.k8s.io/ingress-nginx-admission created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created ​ # 查询是否安装成功 [root@k8s-master ~]# kubectl get svc -A NAME TYPE CLUSTER-IP PORT(S) kubernetes ClusterIP 10.96.0.1 443/TCP ingress-nginx-controller NodePort 10.96.255.50 80:32653/TCP,443:31308/TCP ingress-nginx-controller-admission ClusterIP 10.96.95.128 443/TCP kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP ``` ##### **4.6.2 测试案例** 创建命令空间 ```bash apiVersion: v1 kind: Namespace metadata: name: dev ``` 创建服务 vim ingress-demo.yaml ```bash # Order 服务部署 apiVersion: apps/v1 kind: Deployment metadata: name: order-deployment namespace: dev spec: replicas: 2 selector: matchLabels: app: order template: metadata: labels: app: order spec: containers: - image: nginx name: nginx ​ --- ​ # User服务部署 apiVersion: apps/v1 kind: Deployment metadata: name: user-deployment namespace: dev spec: replicas: 2 selector: matchLabels: app: user template: metadata: labels: app: user spec: containers: - image: nginx name: nginx ​ --- ​ # Item服务部署 apiVersion: apps/v1 kind: Deployment metadata: name: item-deployment namespace: dev spec: replicas: 2 selector: matchLabels: app: item template: metadata: labels: app: item spec: containers: - image: nginx name: nginx --- ​ apiVersion: v1 kind: Service metadata: name: order-service namespace: dev spec: selector: app: order type: ClusterIP ports: - port: 8201 targetPort: 80 ​ --- ​ apiVersion: v1 kind: Service metadata: name: user-service namespace: dev spec: selector: app: user type: ClusterIP ports: - port: 8202 targetPort: 80 --- ​ apiVersion: v1 kind: Service metadata: name: item-service namespace: dev spec: selector: app: item type: ClusterIP ports: - port: 8203 targetPort: 80 ``` ##### **4.6.3 域名访问** vi ingress-rule.yaml ```bash apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-domain namespace: dev spec: ingressClassName: nginx rules: - host: "order.llyb.com" http: paths: - pathType: Prefix path: "/" backend: service: name: order-service port: number: 8201 - host: "user.llyb.com" http: paths: - pathType: Prefix path: "/" # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404 backend: service: name: user-service port: number: 8202 - host: "item.llyb.com" http: paths: - pathType: Prefix path: "/" # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404 backend: service: name: item-service port: number: 8203 ``` kubectl get pods -A item1 :kubectl exec -it item-deployment-fd5ddbd57-4nbkd /bin/bash -n dev item2: kubectl exec -it item-deployment-fd5ddbd57-6zkjn /bin/bash -n dev echo 'item1' \> /usr/share/nginx/html/index.html echo 'item2' \> /usr/share/nginx/html/index.html echo 'order1' \> /usr/share/nginx/html/index.html echo 'order2' \> /usr/share/nginx/html/index.html echo 'user1' \> /usr/share/nginx/html/index.html echo 'user2' \> /usr/share/nginx/html/index.html 配置host文件 C:\\Windows\\System32\\drivers\\etc 192.168.200.131 order.llyb.com user.llyb.com item.llyb.com 测试 访问不同的域名,进入不同的服务,并且支持负载均衡 端口号通过 kubectl get svc -A 找ingress-nginx-controller 服务80对应的端口号 item.llyb .com:32592 就会出现item1 或item2 ##### **4.6.4 路径重写** Ingress 路径重写是指在 Kubernetes 的 Ingress 资源中,通过修改或映射原始的路径,使其指向一个特定的服务。路径重写可以帮助您自定义 URL 结构,使其更具有可读性、可维护性和搜索引擎优化(SEO)友好性。 在 Ingress 资源中,您可以使用 rules 字段来定义路径重写规则。每个规则都包含一个主机和一组路径,这些路径将根据特定的规则映射到后端服务。 示例代码 vi ingress-rule.yaml [http://item.llyb.com:32592/api/hello](http://item.atguigu.com:32592/api/hello "http://item.llyb.com:32592/api/hello") @GetMapping("hello") ```bash apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: # nginx的ingress控制器使用这个注解来修改URL重写规则,会将请求路径中的第二个斜杠及其后面的部分重写到目标路径的开始位置 nginx.ingress.kubernetes.io/rewrite-target: /$2 name: ingress-rewrite namespace: dev spec: ingressClassName: nginx rules: - host: "item.llyb.com" http: paths: - pathType: Prefix path: "/api(/|$)(.*)" backend: service: name: item-service port: number: 8203 ``` ##### **4.6.5 流量控制** Ingress流量控制是K8S集群中用于保护后端服务的重要技术之一。通过合理配置Ingress流量控制,您可以确保服务的稳定性和可用性,并避免过载或拒绝服务攻击。 ```bash apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: # 限制每秒只允许一个请求访问 nginx.ingress.kubernetes.io/limit-rps: "1" name: ingress-rps namespace: dev spec: ingressClassName: nginx rules: - host: "index.llyb.com" http: paths: - pathType: Prefix path: "/" backend: service: name: item-service port: number: 8203 ``` #### **4.7 Storage** 容器中的文件在磁盘上是临时存放的,这给在容器中运行较重要的应用带来一些问题。 当容器崩溃或停止时会出现一个问题。此时容器状态未保存, 因此在容器生命周期内创建或修改的所有文件都将丢失。 在崩溃期间,kubelet 会以干净的状态重新启动容器。 当多个容器在一个 Pod 中运行并且需要共享文件时,会出现另一个问题。 跨所有容器设置和访问共享文件系统具有一定的挑战性。 Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。 ##### **4.7.1 NFS安装** NFS(Network File System)是一种用于在网络上共享文件系统的协议和文件系统协议族。它最初由Sun Microsystems开发,用于在操作系统之间共享文件和目录。NFS允许计算机之间通过网络透明地访问和操作远程文件系统,就像它们是本地文件一样。 ![](https://i-blog.csdnimg.cn/direct/e83eed78db2a414ebd14b71b19850a35.png) 具体安装步骤: 三台机器都要执行命令 yum install -y nfs-utils 主节点执行命令 ```bash #nfs主节点 配置共享规则 echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports ​ mkdir -p /nfs/data systemctl enable rpcbind --now systemctl enable nfs-server --now #配置生效 exportfs -r ``` 工作节点执行命令 ```bash # 查看远程主机上可用的NFS showmount -e 192.168.200.131 ​ # 执行以下命令挂载 nfs 服务器上的共享目录到本机路径 /root/nfsmount mkdir -p /nfs/data ​ # 挂载一个远程的NFS(Network File System)共享目录 mount -t nfs 192.168.200.131:/nfs/data /nfs/data ``` **测试效果** 写入一个测试文件,如果其他的机器能访问到我们创建的文件表示配置成功。 ```bash echo "hello nfs server" > /nfs/data/test.txt ``` ##### **4.7.2 PV \& PVC** PV:持久卷( **Persistent Volume**),将应用需要持久化的数据保存到指定位置 PVC:持久卷申明( **Persistent Volume Claim**),申明需要使用的持久卷规格 PV是集群中配置的存储资源,它是对底层的共享存储的一种抽象。PV可以被多个PVC所使用,而PVC必须与对应的PV建立关系。PV和PVC是Kubernetes抽象出来的一种存储资源,它们为容器提供了持久化的存储空间。 PVC是用户存储的请求,它是一种持久卷请求于存储需求的一种声明。PVC的使用逻辑是:在pod中定义一个存储卷(该存储卷类型为PVC),定义的时候直接指定大小,pvc必须与对应的pv建立关系,pvc会根据定义去pv申请,而pv是由存储空间创建出来的。 ![](https://i-blog.csdnimg.cn/direct/7117762b19434cf78c2f5851580bedda.png) 创建PV池 ```bash #nfs主节点 mkdir -p /nfs/data/01 mkdir -p /nfs/data/02 mkdir -p /nfs/data/03 ``` 创建PV vi volume-pv.yaml ```bash apiVersion: v1 kind: PersistentVolume metadata: name: pv01-10m spec: capacity: storage: 10M accessModes: - ReadWriteMany storageClassName: nfs nfs: path: /nfs/data/01 server: 192.168.200.131 --- apiVersion: v1 kind: PersistentVolume metadata: name: pv02-1gi spec: capacity: storage: 1Gi accessModes: - ReadWriteMany storageClassName: nfs nfs: path: /nfs/data/02 server: 192.168.200.131 --- apiVersion: v1 kind: PersistentVolume metadata: name: pv03-3gi spec: capacity: storage: 3Gi accessModes: - ReadWriteMany storageClassName: nfs nfs: path: /nfs/data/03 server: 192.168.200.131 ``` 查看节点: kubectl get pv **原生方式数据挂载** mkdir -p /nfs/data/nginx-pv vi nginx-pv-demo.yaml ```bash apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-pv-demo name: nginx-pv-demo spec: replicas: 2 selector: matchLabels: app: nginx-pv-demo template: metadata: labels: app: nginx-pv-demo spec: containers: - image: nginx name: nginx volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html nfs: server: 192.168.200.131 path: /nfs/data/nginx-pv ``` 在这个目录 /nfs/data/nginx-pv 创建 index.html 随便写点内容 ! kubectl get pods -A -owide curl 172.32.126.29 就可以看到当前写的数据了!说明挂载成功! **使用PVC方式数据挂载** 创建PVC vi pvc.yaml ```bash apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nginx-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 200Mi storageClassName: nfs ``` 部署绑定PVC vi nginx-deploy-pvc.yaml ```bash apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-deploy-pvc name: nginx-deploy-pvc spec: replicas: 2 selector: matchLabels: app: nginx-deploy-pvc template: metadata: labels: app: nginx-deploy-pvc spec: containers: - image: nginx name: nginx volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: nginx-pvc ``` ```bash [root@k8s-master ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv01-10m 10M RWX Retain Available nfs 44m pv02-1gi 1Gi RWX Retain Bound default/nginx-pvc nfs 44m pv03-3gi 3Gi RWX Retain Available nfs 44m [root@k8s-master ~]# ``` **PV状态说明** * Pending:表示目前该 PV 在后端存储系统中还没创建完成。 * Available:表示可用状态,还未被任何 PVC 绑定。 * Bound:表示 PVC 已经被 PVC 绑定。 * Released:表示已经绑定的 PVC 已经被删掉了,但资源还未被集群重新声明。 * Failed:表示回收失败。 ##### **4.7.3 ConfigMap** 抽取应用配置,并且可以自动更新。用来存储一些配置信息,比如配置文件的内容、环境变量、命令参数等。在 Pod 运行时,ConfigMap 中的数据可以被挂载到 Pod 中,供容器内的应用使用。 示例Nginx使用ConfigMap ```bash # 创建一个nginx kubectl run mynginx --image=nginx ​ # 进入容器内部 kubectl exec -it mynginx /bin/bash -n default ​ # 创建一个文件夹 /root/config/yaml mkdir -p /root/config/yaml ​ # 在root目录下创建configmap [root@k8s-master ~]# kubectl create configmap my-nginx-conf --from-file=config/yaml/ ​ # 查看 kubectl get cm # 删除 kubectl delete cm my-nginx-config # 查看详细信息 kubectl get cm -oyaml ​ # 创建configmap的yaml文件 vi my-nginx-conf.yaml ​ apiVersion: v1 kind: ConfigMap metadata: name: my-nginx-conf namespace: default data: default.conf: |+ server { listen 80; listen [::]:80; server_name localhost; ​ #access_log /var/log/nginx/host.access.log main; ​ location / { root /usr/share/nginx/html; index index.html index.htm; } ​ #error_page 404 /404.html; ​ # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } ​ # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} ​ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} ​ # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } ​ mycustom.conf: | # haha # 创建pod关联configmap vi myconfigmap.yaml ​ apiVersion: v1 kind: Pod metadata: name: nginx-cm spec: containers: - image: nginx name: mynginx volumeMounts: - name: conf mountPath: /etc/nginx/conf.d volumes: - name: conf configMap: name: my-nginx-conf # 进入容器测试配置文件格式 root@nginx-cm:/etc/nginx/conf.d# ls default.conf mycustom.conf # 修改配置文件实时更新 kubectl edit cm my-nginx-conf root@nginx-cm:/etc/nginx/conf.d# cat mycustom.conf # haha # update 111111 ``` ##### **4.7.4 Secret** Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod 的定义或者 容器镜像 中来说更加安全和灵活。 创建secret ```bash ##命令格式 kubectl create secret docker-registry regcred \ --docker-server=<你的镜像仓库服务器> \ --docker-username=<你的用户名> \ --docker-password=<你的密码> \ --docker-email=<你的邮箱地址> kubectl create secret docker-registry mqx-docker \ --docker-server=registry.cn-hangzhou.aliyuncs.com \ --docker-username=243620922@qq.com \ --docker-password=Ts123456 \ --docker-email=243620922@qq.com ``` 创建Pod使用私有镜像 ```bash ##命令格式 kubectl create secret docker-registry regcred \ --docker-server=<你的镜像仓库服务器> \ --docker-username=<你的用户名> \ --docker-password=<你的密码> \ --docker-email=<你的邮箱地址> kubectl create secret docker-registry mqx-docker \ --docker-server=registry.cn-hangzhou.aliyuncs.com \ --docker-username=243620922@qq.com \ --docker-password=Ts123456 \ --docker-email=243620922@qq.com ``` 测试访问 curl 192.168.126.43:8080/hello?name=111 ##### **总结:** ```bash 相关命令: kubectl get nodes -A kubectl get pods -A -o wide kubectl apply -f xxx.yaml kubectl delete -f xxx.yaml namespace: 操作 kubectl create ns hello kubectl delete ns hello pod:操作 默认是在default 命名空间下 kubectl run mynginx --image=nginx -n dev kubectl delete pod [pod_name] -n dev[命名空间] deployment:操作 自我修复扩缩容pod kubectl create deployment mytomcat --image=tomcat:8.5.68 kubectl delete deployment mytomcat kubectl delete deployment my-dep 灰度发布: kubectl rollout history deployment/my-dep 1:没有指定nginx 版本: 2:指定1.16.1 3: 指定1.18.1 kubectl rollout undo deployment/my-dep --to-revision=2 service:主要负载均衡pod,还可以对外暴露地址和端口 --type:ClusterIP (只能内部访问) --type:NodePort (通过浏览器访问) kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort Ingress:使用域名的形式访问集群内部; 还可以限流 kubectl apply -f ingress.yaml; kubectl apply -f ingress-rule.yaml; kubectl delete -f ingress-rule.yaml; kubectl get ingress -A -n kubectl delete ingress ingress_name; Storage: 数据存储与挂载(共享文件与目录) NFS: 共享文件或目录 PV/PVC 挂载磁盘位置 configMap 动态更新配置信息 与 Pod 挂载 secret 保存个人敏感信息 与 Pod 挂载 ``` 结论: 1. 以后项目部署的时候,不应该单独使用pod,应该使用deployment多节点部署! ##### **项目部署到K8S 上:** ```bash 1. 上传target目录下的jar 到 worker1 节点中的/root/build目录下 2. 进入到/root/build目录下执行: docker build -f DockerFile -t demo:1.0 . 测试: docker run -P --rm demo:1.0 docker ps | grep demo 查看端口号 3. 将worker1节点的镜像打包 docker save demo:1.0 |gzip > demo.tar.gz 4. 在worker1 节点执行 scp demo.tar.gz root@192.168.200.133:/root 5. 到 192.168.200.133 执行加载镜像 docker load -i demo.tar.gz 6. 在master节点编写 demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-demo spec: replicas: 3 selector: matchLabels: app: my-demo template: metadata: labels: app: my-demo spec: containers: - name: demo image: demo:1.0 --- apiVersion: v1 kind: Service metadata: managedFields: - apiVersion: v1 name: my-demo namespace: default spec: ports: port: 8080 protocol: TCP targetPort: 8080 selector: app: my-demo type: NodePort 执行文件: kubectl apply -f demo.yaml 7.确认pod正常运行 kubectl get pod 8.查看svc端口 kubectl get svc 9.访问 curl http://192.168.200.132:32586/hello ```

相关推荐
浅拾光º3 小时前
Docker部署的MySQL,如何一键备份Docker中的MySQL?
mysql·docker·容器
胡斌附体3 小时前
docker离线部署gpt-oss-20b流程,从下载到安装再到可以使用
gpt·docker·容器·大模型·部署·记录·离线
二宝哥5 小时前
云原生docker在线yum安装
运维·docker·容器
老马爱知5 小时前
《红色脉络:一部PLMN在中国的演进史诗 (1G-6G)》 第11篇 | 核心网演进终局:从EPC到5GC——微服务与“云原生”
微服务·云原生·核心网·nfv·epc·5g核心网·sba架构
超龄超能程序猿5 小时前
云原生网关Higress介绍与部署指南
服务器·容器
simon_skywalker5 小时前
阿里云云原生挑战官方用例SPL
阿里云·云原生·kubernetes
二宝哥5 小时前
云原生docker离线二进制安装
运维·docker·容器
hello_25012 小时前
k8s安全机制解析:RBAC、Service Account与安全上下文
java·安全·kubernetes
JanelSirry12 小时前
VMware+RockyLinux+ikuai+docker+cri-docker+k8s 自用 实践笔记(一)
linux·docker·kubernetes