第一章:kubernetes介绍

kubernetes(k8s)是2014年由Google公司基于Go语言编写的一款开源的容器集群编排系统,用于自动化容器的部署、扩缩容和管理;
kubernetes(k8s)是基于Google内部的Borg系统的特征开发的一个版本,集成了Borg系统大部分优势;

分水岭:1.24.0开始k8s使用containerd
官方地址:https://Kubernetes.io
代码托管平台:https://github.com/Kubernetes
除了k8s还有哪些容器编排系统?如:docker swarm、Openshift、Rancher、Mesos等

第二章:kubernetes集群部署

kubernetes集群规划:

方案一:

IP地址主机名称主机角色操作系统主机配置
192.168.109.137master01管理节点龙蜥8.62C4G
192.168.109.138master02管理节点龙蜥8.62C4G
192.168.109.139master03管理节点龙蜥8.62C4G
192.168.109.140node01工作节点龙蜥8.62C4G
192.168.109.141node02工作节点龙蜥8.62C4G
192.168.109.142k8s-ha01主负载均衡龙蜥8.61C1G
192.168.109.143k8s-ha02备负载均衡龙蜥8.61C1G

方案二:[实验采用方案二]

IP地址主机名称主机角色操作系统主机配置
192.168.109.137master-ha01管理节点/主负载均衡龙蜥8.102C4G
192.168.109.138master-ha02管理节点/备负载均衡龙蜥8.102C4G
192.168.109.139master03管理节点龙蜥8.102C4G
192.168.109.140node01工作节点龙蜥8.102C4G
192.168.109.141node02工作节点龙蜥8.102C4G

基于ansible部署【ansible主机:192.168.109.137】

EPEL源在龙蜥8.10上仅提供Ansible 9.2.0版本(对应ansible.noarch 9.2.0-1.el8),这是因为EPEL源的包版本与RHEL 8的软件生态保持一致,Ansible 9是RHEL 8/EPEL 8的最新稳定版(基于Ansible Core 2.16)。而Ansible 9.2.0版本 对应python3.12 龙蜥8.10默认的是python3.6 故采用如下pip安装方式

ansible 安装:

dnf install -y epel-release
方案:通过pip安装指定旧版本(推荐)
步骤1:安装系统依赖(旧版本Ansible需要)
# 安装编译依赖(Python开发库、OpenSSL等)
dnf install -y python36-devel openssl-devel gcc
步骤2:用pip3.6安装指定版本Ansible
龙蜥8.10默认的Python 3.6兼容Ansible 2.9(支持Python 3.5-3.8):
# 升级pip3.6(避免版本过低导致安装失败)
pip3.6 install --upgrade pip
# 安装Ansible 2.9(指定版本号)
pip3.6 install ansible==2.9.27
步骤3:验证安装
ansible --version
mkdir -pv /etc/ansible/
vim /etc/ansible/ansible.cfg
###基础设置
[defaults]
# 抑制 Python 警告
#warn_ignore = deprecation
# 抑制解释器发现警告(推荐 Ansible 2.9 版本使用)
interpreter_python = auto_legacy_silent
# 1. 主机清单文件路径(指定你的inventory文件,如inventory.ini)
inventory = ./hosts 
# 2. 默认远程用户(如root或专用ansible用户)
remote_user = root  
# 3. 执行Ansible时的默认模块(command/shell/raw,默认command)
module_name = command  
# 4. 并发执行的最大进程数(默认5,根据服务器性能调整)
forks = 10  
# 5. 超时时间(单位:秒,默认10秒,网络差时可增大)
timeout = 30

###权限与提权(Become)
[privilege_escalation]
# 是否允许提权(默认False,需开启)
become = True  
# 提权方式(sudo/su/pbrun等,默认sudo)
become_method = sudo  
# 提权后的目标用户(默认root)
become_user = root  
# 是否需要输入sudo密码(默认False,若sudo需密码则设为True)
become_ask_pass = False

###SSH 连接配置
[ssh_connection]
# 1. 指定私钥文件路径(免密登录必备,避免每次输入密码)
private_key_file = ~/.ssh/id_rsa  
# 2. 控制持久连接(减少重复SSH握手,加速执行)
control_path = ~/.ssh/ansible-%%h-%%p-%%r  
control_path_dir = ~/.ssh/ansible-control-path  
pipelining = True  # 开启管道传输(加速模块执行)
# 3. 跳过SSH主机密钥检查(生产环境不建议,测试环境可临时开启)
# host_key_checking = False

###日志与调试
# 日志文件路径(记录Ansible执行过程,便于排障)
log_path = ./ansible.log  
# 输出详细程度(-v/-vv/-vvv,默认0,调试时可设为3)
verbosity = 1

###Facts 缓存(优化性能)
# 启用Facts缓存(支持jsonfile/redis/memcached,推荐jsonfile)
gathering = smart  # 仅收集新主机或Facts过期的主机
fact_caching = jsonfile  
fact_caching_connection = ./ansible_facts  # 缓存文件存储目录
fact_caching_timeout = 86400  # 缓存有效期(秒,默认24小时)

###其他实用配置
# 忽略不可达主机(默认False,批量执行时避免因单台主机失败中断)
ignore_unreachable = True  
# 忽略主机密钥变化(生产环境慎用,测试环境可临时开启)
# host_key_checking = False  
# 模块查找路径(自定义模块存放目录 ./library ```  )
# library =


vim /etc/ansible/hosts
[k8s]
192.168.109.137
192.168.109.138
192.168.109.139
192.168.109.140
192.168.109.141

查看:ansible k8s --list-host
# 匹配警告中包含"Python 3.6 is no longer supported"的内容
PYTHONWARNINGS="ignore:Python 3.6 is no longer supported" ansible k8s --list-host
永久屏蔽(写入 shell 配置)
# 编辑配置文件
echo 'export PYTHONWARNINGS="ignore:Python 3.6 is no longer supported"' >> ~/.bashrc
# 立即生效
source ~/.bashrc  

生产密钥:ssh-keygen
for ip in 192.168.109.{137..141};do ssh-copy-id $ip;done

第一步:配置本地dns解析

[root@test_01 ansible]# vim /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.109.137 master-ha01
192.168.109.138 master-ha02
192.168.109.139 master03
192.168.109.140 node01
192.168.109.141 node02

基于ansible下发hosts文件:

[root@test_01 ansible]# ansible k8s -m copy -a "src=/etc/hosts dest=/etc/"

第二步:开启 bridge 网桥过滤功能

理论逻辑:

bridge(桥接网络)是Linux系统中的一种虚拟网络设备,充当一个虚拟交换机,为集群内的容器提供网络通信功能,容器就可以通过bridge与其他容器或外部网络通信了。
/etc/sysctl.d/目录用于存放配置内核参数的文件,文件以.conf 结尾,这些文件会在系统启动时自动加载。

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

参数解释:
net.bridge.bridge-nf-call-ip6tables =1 //对网桥上的IPv6数据包通过iptables处理
net.bridge.bridge-nf-call-iptables =1 //对网桥上的IPv4数据包通过iptables理
net.ipv4.ip_forward = 1    //开启IPv4路由转发,来实现集群中的容器跨网络通信

由于开启bridge功能,需要加载br_netfilter模块使参数生效
modprobe br_netfilter && lsmod | grep br_netfilter

加载配置文件,使上述配置生效
sysctl -p /etc/sysctl.d/k8s.conf

实操流程:

ansible主机新建目录:
mkdir -pv /root/k8s-deploy/ && cd /root/k8s-deploy/
vim k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

[root@test_01 k8s-deploy]# ansible k8s -m copy -a "src=k8s.conf dest=/etc/sysctl.d/"
[root@test_01 k8s-deploy]# ansible k8s -m shell -a "modprobe br_netfilter && lsmod | grep br_netfilter"
[root@test_01 k8s-deploy]# ansible k8s -m shell -a "sysctl -p /etc/sysctl.d/k8s.conf"

第三步:安装IPVS代理模块

在k8s中Service有两种代理模式,一种是基于iptables的,一种是基于ipvs,两者对比ipvs模式性能更高效,如果想要使用ipvs模式,需要手动载入ipvs模块。
ipset和ipvsadm是网络管理和负载均衡相关的软件包,提供ip_vs 模块
###dnf install -y ipset ipvsadm

[root@test_01 k8s-deploy]# ansible k8s -m shell -a "dnf install -y ipset ipvsadm"

将需要加载的ipvs相关模块写入到文件中
/etc/modules-1oad.d/目录主要用于在系统启动时加载用户自定义的内核模块,这个目录中的文件以.conf 结尾,文件中指定需要加载的内核模块。

cd /root/k8s-deploy
vim /root/k8s-deploy/ip_vs.conf
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack

[root@test_01 k8s-deploy]# ansible k8s -m copy -a "src=ip_vs.conf dest=/etc/modules-load.d/"

加载模块生效(这个文件会在下次系统启动时自动生效)
###systemctl restart systemd-modules-load.service
[root@test_01 k8s-deploy]# ansible k8s -m shell -a "systemctl restart systemd-modules-load.service"

过滤模块,验证是否成功加载
###lsmod | grep ip_vs

[root@test_01 k8s-deploy]# ansible k8s -m shell -a "lsmod | grep ip_vs"

第四步:关闭SWAP分区
为了保证kubelet正常工作,k8s强制要求禁用,否则集群初始化失败
###swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab

[root@test_01 k8s-deploy]# ansible k8s -m shell -a "swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab"

第五步:Docker 环境准备 

参考:https://blog.csdn.net/NG_cheng119/article/details/159472335?spm=1001.2014.3001.5501

添加阿里云docker-ce仓库
[root@test_01 k8s-deploy]# ansible k8s -m shell -a "dnf install -y yum-utils" 
[root@test_01 k8s-deploy]# ansible k8s -m shell -a "yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo"

安装docker软件包
yum list --showduplicates docker-ce

理论逻辑:
dnf install -y docker-ce-20.10.24-3.el8.x86_64
启用Docker Cgroup用于限制容器的资源使用量,如CPU、内存资源
#step 1:创建/etc/docker目录
mkdir -pv /etc/docker
#step 2:配置Cgroup和镜像加速器
cat >/etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
    "https://docker.1ms.run",
    "https://docker.m.daocloud.io",
    "https://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}
EOF

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

实操流程:
 

docker 安装:
[root@test_01 k8s-deploy]# ansible k8s -m shell -a "dnf install -y docker-ce-20.10.24-3.el8.x86_64" 
[root@test_01 k8s-deploy]# ansible k8s -m shell -a "mkdir -pv /etc/docker"
[root@test_01 k8s-deploy]# cd /root/k8s-deploy/
[root@test_01 k8s-deploy]# vim /root/k8s-deploy/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
    "https://docker.1ms.run",
    "https://docker.m.daocloud.io",
    "https://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

[root@test_01 k8s-deploy]# ansible k8s -m copy -a "src=daemon.json dest=/etc/docker/"
[root@test_01 k8s-deploy]# ansible k8s -m shell -a "systemctl enable docker --now"

第六步:负载均衡环境准备 

haproxy:为apiserver提供代理,集群的管理请求通过VIP进行接收,haproxy将所有管理请求轮询转发到每个master节点上。
Keepalived:为haproxy提供vip (192.168.109.150)在二个haproxy之间提供主备,实现代理故障自动切换。

以下操作只需要在master-ha01、master-ha02配置:
1.安装haproxy 和 keepalived 软件包:
dnf install -y haproxy keepalived
2.修改haproxy配置文件,文件内容在master-ha01、master-ha02节点一样
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg_bak
echo "" > /etc/haproxy/haproxy.cfg
vim /etc/haproxy/haproxy.cfg

global
    maxconn     2000
    ulimit-n 16384
    log 127.0.0.1 local0 err
    stats timeout 30s
defaults
    log                     global
    mode                    http
    option                  httplog
    timeout connect         5000
    timeout client          5000
    timeout server          5000
    timeout http-request    15s
    timeout http-keep-alive 15s

frontend monitor-in
    bind *:33305
    mode http
    option httplog
    monitor-uri /monitor

frontend k8s-master
    bind 0.0.0.0:16443
    bind 127.0.0.1:16443
    mode tcp
    option tcplog
    tcp-request inspect-delay 5s
    default_backend k8s-master

backend k8s-master
    mode tcp
#    option tcplog
    option tcp-check
    balance     roundrobin
    default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
    server      master-ha01 192.168.109.137:6443 check
    server      master-ha02 192.168.109.138:6443 check
    server      master03 192.168.109.139:6443 check

语法验证:
haproxy -f /etc/haproxy/haproxy.cfg -c


启动:
systemctl enable haproxy --now

修改keepalived配置:
master-ha01 主节点配置内容如下:
vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived
  
global_defs {
   router_id LVS_DEVEL
   script_user root
   enable_script_security
}


vrrp_script chk_haproxy {
   script "/etc/keepalived/check_haproxy.sh"
   interval 5
   weight -5
   fall 2
   rise 1
}

vrrp_instance VI_1 {
    state MASTER
    interface ens160
    virtual_router_id 150
    priority 100
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.109.150/24
    }

    track_script {
        chk_haproxy
    }
}

添加健康检查脚本,赋权

vim /etc/keepalived/check_haproxy.sh

#!/bin/bash

COUNT=`ps -C haproxy | grep -v "PID" | wc -l`
if [ $COUNT -eq 0 ];then
        systemctl stop keepalived
fi

chmod +x /etc/keepalived/check_haproxy.sh

语法检查:

[root@master-ha01 keepalived]# keepalived -t -f /etc/keepalived/keepalived.conf

启动keepalived:

systemctl enable keepalived --now

同样操作,master-ha02 备节点配置内容如下:稍微修改一下配置文件

! Configuration File for keepalived
  
global_defs {
   router_id LVS_DEVEL
   script_user root
   enable_script_security
}


vrrp_script chk_haproxy {
   script "/etc/keepalived/check_haproxy.sh"
   interval 5
   weight -5
   fall 2
   rise 1
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens160
    virtual_router_id 150
    priority 90
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.109.150/24
    }

    track_script {
        chk_haproxy
    }
}

第七步:配置kubernetes仓库

1.24版本开始,完全移除了内置的dockershim组件,K8s原生不再直接支持Docker作为容器运行时,如果还要用Docker的话,必须用第三方的cri-dockerd适配器才行。对,资料里明确说1.24之后dockershim彻底没了。

所以我们这里kubeadm 要选择1.24之前的最后一个稳定版本测试,dnf list --showduplicates kubeadm -y 选定的是1.23.17-0

集群部署方式:
kubeadm部署方式:kubeadm是一个快速搭建kubernetes的集群工具;
二进制包部署方式:从官网下载每个组件的二进制包,依次安装,部署,麻烦;
其他部署方式:Rancher\kubeSphere\sealos\kuboard\RKE2等

实验采用的是 kubeadm部署方式 阿里云YUM仓库

配置kubernetes仓库
官网参考:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
阿里云仓库:https://developer.aliyun.com/mirror/
https://developer.aliyun.com/mirror/kubernetes?spm=a2c6h.13651102.0.0.7bc21b11Oa6dm2
旧版配置方法

目前由于kubernetes官方变更了仓库的存储路径以及使用方式,旧版 kubernetes 源只更新到 1.28 部分版本,后续更新版本请使用 新源配置方法 进行配置。
CentOS / RHEL / Fedora
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
setenforce 0
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet

ps: 由于官网未开放同步方式, 可能会有索引gpg检查失败的情况, 这时请用 yum install -y --nogpgcheck kubelet kubeadm kubectl 安装

[root@master-ha01 ~]# cd /root/k8s-deploy/
[root@master-ha01 k8s-deploy]# vim /root/k8s-deploy/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg

[root@master-ha01 k8s-deploy]# ansible k8s -m copy -a "src=kubernetes.repo dest=/etc/yum.repos.d/"

安装集群相关软件包:
kubeadm:用于初始化集群,并配置集群所需的组件并生成对应的安全证书和令牌;
kubelet:负责与Master节点通信,并根据 Master节点的调度决策来创建、更新和删除Pod,同时维护Node节点上的容器状态;
kubectl:用于管理k8集群的一个命令行工具;

[root@master-ha01 k8s-deploy]# dnf list --showduplicates kubeadm -y
[root@master-ha01 k8s-deploy]# ansible k8s -m shell -a "dnf install -y kubeadm-1.23.17-0 kubelet-1.23.17-0 kubectl-1.23.17-0"

kubelet启用Cgroup控制组,用于限制容器资源使用,如CPU、内存资源
cat > /etc/sysconfig/kubelet << EOF
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
EOF
设置kubelet开机自启,集群初始化时kubelet会随着集群启动
systemctl enable kubelet

[root@master-ha01 ~]# cd /root/k8s-deploy/
[root@master-ha01 k8s-deploy]# vim /root/k8s-deploy/kubelet
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"

[root@master-ha01 k8s-deploy]# ansible k8s -m copy -a "src=kubelet dest=/etc/sysconfig/"
[root@master-ha01 k8s-deploy]# ansible k8s -m shell -a "systemctl enable kubelet"

查看集群所需镜像:
在master-ha01节点查看集群所需镜像文件
kubeadm config images list

k8s集群初始化
在master-ha01节点生成初始化集群的配置文件
[root@master-ha01 ~]# cd /root/k8s-deploy/
kubeadm config print init-defaults > kube-init.yaml
配置文件需要修改如下内容

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.109.137
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  imagePullPolicy: IfNotPresent
  name: master-ha01
  taints: null
---
apiServer:
  certSANs:
  - 192.168.109.150
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: 192.168.109.150:16443
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.23.0
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
scheduler: {}

通过配置文件初始化集群:
[root@master-ha01 k8s-deploy]# kubeadm init --config kube-init.yaml --upload-certs

参数说明:

init                            //初始化集群
--config                    //基于配置文件初始化
--upload-certs          //将管理节点的证书加密后上传到kubeadm-certsSecret中,在高可用集群场景下,其他管理节点节点可以从该Secret中下载并使用这些证书,而不需要手动拷贝证书到其他管理节点。

初始化成功后,根据提示准备集群管理员配置文件:
master-ha01配置kubectl权限:
第一种:
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
第二种:[推荐]
临时生效
export KUBECONFIG=/etc/kubernetes/admin.conf
永久生效
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /root/.bash_profile
source /root/.bash_profile

master-ha02、master03 加入控制节点:
  kubeadm join 192.168.109.150:16443 --token abcdef.0123456789abcdef \
        --discovery-token-ca-cert-hash sha256:b24f95efb472ca432f07632a8c4ad1fb055d3c696b5e8ef3112193ee7396eed1 \
        --control-plane --certificate-key fb4f44ce842bcc0ac7b566080fa638b0672a7cd9f5620e320c3c456e5532406f
然后按提示添加kubectl权限

node01、node02 加入工作节点:
kubeadm join 192.168.109.150:16443 --token abcdef.0123456789abcdef \
        --discovery-token-ca-cert-hash sha256:b24f95efb472ca432f07632a8c4ad1fb055d3c696b5e8ef3112193ee7396eed1

第八步:部署Pod网络Calico
Flannel 的覆盖网络模型会导致额外的封装和解封装开销,从而影响网络性能。对于较小的集群或对性能要求不高的场景,这可能并不是一个严重的问题。
master01节点下载Calico文件
[root@master-ha01 k8s-deploy]# cd /root/k8s-deploy/
[root@master-ha01 k8s-deploy]# wget https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/calico.yaml

创建Calico网络:
[root@master-ha01 k8s-deploy]# kubectl apply -f calico.yaml

验证集群节点状态
查看集群节点状态是否为Ready

[root@master-ha01 k8s-deploy]# kubectl get pod -n kube-system

部署nginx测试集群:
在master-ha01节点上部署nginx
vim nginx.yml

# Deployment:定义Nginx的副本和容器配置
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 256Mi


---


# Service:暴露服务供外部访问
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080  # 固定节点端口,范围必须是30000-32767
  type: NodePort

[root@master-ha01 ~]# kubectl apply -f nginx.yml 
deployment.apps/nginx-deployment created
service/nginx-service created
[root@master-ha01 ~]# 

更多推荐