更换saltstack master服务器

1. 拷贝原来服务器的pki ,上传到要迁移的服务器服务器

[root@master salt]# tar -zcf pki.tar.gz pki/

[root@master salt]# ls
1.py  master  pki  pki.tar.gz

2.重启master服务(新服务器)

[root@bogon master]# /etc/init.d/salt-master restart

Stopping salt-master daemon:                               [确定]

Starting salt-master daemon:                                 [确定]

3.更改minion端配置文件

minion手动一台一台更改效率低

[root@minion salt]# vim /etc/salt/minion

master:ip地址改为要迁移的ip

批量更改:

在master端(旧)

[root@master salt]# salt '*' cmd.run "sed -i 's/128/131/' /etc/salt/minion"

minion1.lgl.com:

minion2.lgl.com:

4.验证

[root@master salt]# salt '*' cmd.run 'cat /etc/salt/minion | grep master'

5.重启master服务

[root@master salt]# salt '*' service.restart salt-minion

minion1.lgl.com:

    True

minion2.lgl.com:

    True

CentOS 6.7安装部署SaltStack配置管理工具

1.saltStack 服务架构介绍

SaltStack 是一种基于C/S架构的服务模式,在SaltStack架构中服务器端叫作Master,客户端叫作Minion,传统C/S架构为:客户端发送请求给服务器端,服务器端接收到请求并且处理完成后再返回给客户端。在SaltStack架构中不仅有传统的C/S架构服务模式,而且有消息队列中的发布与订阅(pub/sub)服务模式。这使得SaltStack应用场景更加丰富。目前在实际环境中一般使用SaltStack的C/S架构进行配置管理。

在Master和Minion端都是以守护进程的模式运行,一直监听配置文件里面定义的ret_port(接受minion请求,默认端口号:4506)和publish_port(发布消息,默认端口号:4505)的端口。当Minion运行时会自动连接到配置文件里面定义的Master地址ret_port端口进行连接认证。默认客户端请求id是socket.getfqdn()取到的值,也可以在Minion启动之前修改Minion的id值。

2.安装部署

[root@zabbix salt]# cat /etc/redhat-release
CentOS release 6.7 (Final)

安装 epel yum源

在 Master 端和 Minion 端都需要安装 epel 的 yum源

rpm -ivh http://mirrors.zju.edu.cn/epel/6/x86_64/epel-release-6-8.noarch.rpm

3.安装 Master 端

yum -y install salt-master
/etc/init.d/salt-master start

Starting salt-master daemon: [确定]

chkconfig salt-master on

SaltStack Master 端版本号

[root@SaltStack-Master ~]# salt-master --version
salt-master 2015.5.10 (Lithium)

4.安装 minion 端

yum -y install salt-minion
sed -i 's/#master: salt/master: 192.168.10.10/g' /etc/salt/minion # 指定 master 的ip地址
/etc/init.d/salt-minion start
chkconfig salt-minion on

SaltStack Minion 端版本号

[root@SaltStack-Minion-node01 ~]# salt-minion --version
salt-minion 2015.5.10 (Lithium)

5.C/S认证

salt-key -L 查看当前需要接受的keys(master和minions都需要把服务开启)。

系统管理

-A参数,该参数意思是接受所有认证主机的认证,也可以使用 -a id名 只认证单独的主机

系统管理

如果对客户端信任,可以让master自动接受请求,在master端/etc/salt/master配置

    auto_accept: True

6、命令执行

测试master和minion之间的通信是否正常

系统管理

True代表正常,*代表所有主机,也可以选择单台或者按组及正则进行匹配等

命令执行使用cmd.run参数

系统管理

rsync实用的文件同步命令介绍

sync是Linux系统下的文件同步和数据传输工具,可用于同步文件、代码发布

1.安装.

yum install -y xinetd yum insatll -y rsync

2.配置

打开rsync功能vim /etc/xinetd.d/rsync

service rsync
{
        disable = no    #把yes改成no
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID

}

编辑主配置文件vim /etc/rsyncd.conf服务端

uid = nobody       #目录或文件的属主属组为nobody,同步的时候报错权限不足检查目录文件的所属用户组
gid = nobody
use chroot = yes
max connections = 30
pid file=/var/run/rsyncd.pid
log file=/var/log/rsyncd.log
list = no
[data]    #同步项 模块     【同步项不需要再服务端添加】
path = /usr/local/hero_all_backup/           
hosts allow = 192.168.50.146  
read only = yes

启动即可

rsync –daemon

3.使用.

 rsync -avz aaa.txt 192.168.0.162::data
  • -v, –verbose 详细模式输出

  • -a, –archive 归档模式,表示以递归方式传输文件,并保持所有文件属性

  • -z, 对备份的文件在传输时进行压缩处理

  • –-delete 删除那些DST中SRC没有的文件

  • –-exclude= 指定排除不需要传输的文件模式

4.其他.

rsync -avz --delete /tmp/2/ /var/spool/clientmqueue/ 

同步/tmp/2空目录到/var/spool/clientmqueue/ 即删除/var/spool/clientmqueue/目录下的无用文件。

rsync -avz --delete --exclude=".svn" --exclude="*.swp"

同步的时候排除.svn和.swp的隐藏文件

centos7系统下配置nginx php-fpm负载均衡

三台Centos7服务器

主:192.168.199.174
从:192.168.199.170
从:192.168.199.191

均全新最小化安装,都关闭了防火墙和SELINUX

第一步

先在 主服务器 上安装Nginx,可以在改配置前直接开启服务访问看看有没有问题,然后利用Nginx做请求转发

yum -y install nginx
systemctl start nginx.service
vi /etc/nginx/conf.d/default.conf

default.conf 修改后,删掉了注释部分

upstream myServer{
    server 192.168.199.170:9000 max_fails=3 fail_timeout=10s;
    server 192.168.199.191:9000 max_fails=3 fail_timeout=10s;
}
server {
    listen       80;
    server_name  localhost;
    location / {
        root   /home/wwwroot;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
    location ~ .php$ {
        root           /home/wwwroot;
        fastcgi_pass   myServer;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

重新启动 Nginx 服务,顺便实时查看 Nginx 的日志,以便了解访问情况

systemctl restart nginx.service
tail -f /var/log/nginx/error.log /var/log/nginx/access.log

第二步

在 从服务器 上安装PHP

# 安装一些需要的东西
yum -y install wget libxml2-devel libtool
# 下载PHP
wget -O php-7.1.7.tar.gz http://php.net/get/php-7.1.7.tar.gz/from/this/mirror
# 复制一份到另一个从服务器,输入yes和191的密码
scp php-7.1.7.tar.gz [email protected]:/usr/local
# 将PHP安装包放到/usr/local目录
mv php-7.1.7.tar.gz /usr/local


# 从这里起,两台从服务器执行操作都一样
# 另一台服务器记得先执行上面yum 的那一行
# 进入/usr/local 目录
cd /usr/local
# 解压PHP安装包
tar -xvf php-7.1.7.tar.gz
# 进入PHP安装文件夹目录
cd php-7.1.7
# 安装PHP
./configure --enable-fpm
make && make install
# 复制和重命名配置文件
cp php.ini-development ../php/php.ini
cp ../etc/php-fpm.conf.default ../etc/php-fpm.conf
mv ../etc/php-fpm.d/www.conf.default ../etc/php-fpm.d/www.conf
# 创建fpm的软链接放入bin目录下,方便随处可用
ln -s sapi/fpm/php-fpm ../bin/php-fpm

修改 /usr/local/etc/php-fpm.conf 配置文件,在最后一行

include=/usr/local/etc/php-fpm.d/*.conf

修改 /usr/local/etc/php-fpm.d/www.conf 配置文件

listen = 0.0.0.0:9000
request_terminate_timeout = 0

以上操作在两台从服务器操作好后,分别启动PHP-FPM

php-fpm

第三步

开始测试

首先分别在两台从服务器上创建测试文件

cd /home
mkdir wwwroot
cd wwwroot
vi 1.php
<?php
// 这里的170换成当前从服务器的IP
// 比如191那台,这里就写191
echo("170");

浏览器打开:http://192.168.199.174/1.php

  • 第一次打开:170

  • 第一次刷新:191

  • 第二次刷新:170

  • 第三次刷新:191

与此同时,主服务器那边 nginx 的 error.log 没有变化,而 access.log 文件一直在记录各种成功的请求。

第四步:

配合 Laravel 的优雅链接设置

先修改 主服务器 的 /etc/nginx/conf.d/default.conf

# 就改了这一个 location 里的东西
location / {
    root   /home/wwwroot;
    index  index.html index.htm;
    # 就加了下面一段
    try_files $uri $uri/ /index.php?$query_string;
}

然后在 从服务器 的 /home/wwwroot 目录下建立 index.php 文件

<?php
echo '填170或191 <br />';
var_dump($_REQUEST);
echo '<hr />';
var_dump($_SERVER);

然后OK了,自己去测试吧。

用openresty实现动态upstream反向代理

前言

此文的读者定义为对openresty有一定了解的读者。

openresty:
https://github.com/openresty/lua-nginx-module

此文要讲什么

大家都知道openresty可以用ngx.location.capture和ngx.exec来实现内部跳转,
下面要讲怎么将ngx.location.capture和ngx.exec与upstream模块结合起来,实现一个动态的upstream。

下面的演示中:

80端口表示首次请求入口
8080端口表示upstream的出口

直接上配置和源码

配置: conf/nginx.conf

    worker_processes  1;  
    error_log logs/error.log;  
    events {  
        worker_connections 1024;  
    }  

    http {  

        log_format  main  '$msec $status $request $request_time '  
                          '$http_referer $remote_addr [ $time_local ] '  
                          '$upstream_response_time $host $bytes_sent '  
                          '$request_length $upstream_addr';  

        access_log  logs/access.log main buffer=32k flush=1s;  


        upstream remote_hello {  
            server 127.0.0.1:8080;  
        }  

        upstream remote_world {  
            server 127.0.0.1:8080;  
        }  

        server {  
            listen 80;  

            location /capture {  
                content_by_lua '  
                    local test = require "lua.test"  
                    test.capture_test()  
                ';  
            }  

            location /exec {  
                content_by_lua '  
                    local test = require "lua.test"  
                    test.exec_test()  
                ';  
            }  

            location /upstream {  
                internal;  

                set $my_upstream $my_upstream;  
                set $my_uri $my_uri;  
                proxy_pass http://$my_upstream$my_uri;  
            }  
        }  


        server {  
            listen 8080;  
            location /hello {  
                echo "hello";  
            }  

            location /world {  
                echo "world";  
            }  
        }  
    }  

源码: lua/test.lua

    local _M = { _VERSION = '1.0' }  

    function _M:capture_test()  
        local res = ngx.location.capture("/upstream",  
            {  
                 method = ngx.HTTP_GET,  
                 vars = {  
                     my_upstream = "remote_hello",  
                     my_uri = "/hello",  
                 },  
            }  
        )  
        if res == nil or res.status ~= ngx.HTTP_OK then  
            ngx.say("capture failed")  
            return  
        end  
        ngx.print(res.body)  
    end  

    function _M:exec_test()  
        ngx.var.my_upstream = "remote_world"  
        ngx.var.my_uri = "/world"  
        ngx.exec("/upstream")  
    end  

    return _M  

运行效果

未分类

OpenResty json 删除转义符

OpenResty 中删除 json 中的转义符

cjson 在 encode 时 “/” 会自动添加转义符 “”; 在 decode 时也会自动将转义符去掉。工作中有个特殊需求,需要手工删除转义符。记录备忘,代码如下:

#! /usr/bin/env lua
json = require "cjson"

result = {}
result["stream"] = "lufei"
result["app"] = "live/cartoon"
oldStr = json.encode(result)
local from, to, err = ngx.re.find(oldStr, [[\]])
ngx.say(from, to)
newStr, n, err = ngx.re.gsub(oldStr, [[\/]], [[/]])
ngx.say("oldStr: "..oldStr)
ngx.say("newStr: "..newStr )
t = json.decode(newStr)
ngx.say(t["app"])
dill@bunbun:~/openresty-test/locations$ curl -i localhost:6699/test
HTTP/1.1 200 OK
Server: openresty/1.11.2.2
Date: Wed, 19 Jul 2017 04:38:07 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive

1313
oldStr: {"app":"live/cartoon","stream":"lufei"}
newStr: {"app":"live/cartoon","stream":"lufei"}
live/cartoon

openresty设置用于access_log的自定义变量

期望:在access_log打印自定义变量define_error_code

nginx配置:

    worker_processes  1;  

    events {  
        worker_connections  1024;  
    }  


    http {  

        log_format main '[$time_local] $request $status $remote_addr $define_error_code';  

        server {  
            listen       80;  

            location / {  
                set $define_error_code '';  
                content_by_lua_block {  
                    ngx.var.define_error_code = 9527  
                    ngx.say("hello world")  
                }  
            }  

            access_log logs/access.log main;  
            error_log logs/error.log;  
        }  

    }  

测试结果:

未分类

CentOS Nginx安装配置Let’s Encrypt CA证书

  • 创建存放整数的目录
mkdir /data/www/ssl
  • 创建 CSR 文件

接着就可以生成 CSR(Certificate Signing Request,证书签名请求)文件了。在这之前,还需要创建域名私钥(一定不要使用上面的账户私钥),根据证书不同类型,域名私钥也可以选择 RSA 和 ECC 两种不同类型。以下两种方式请根据实际情况二选一。

  1. 创建 RSA 私钥(兼容性好):
openssl genrsa 4096 > domain.key
  1. 创建 ECC 私钥(部分老旧操作系统、浏览器不支持。优点是证书体积小):
#secp256r1
openssl ecparam -genkey -name secp256r1 | openssl ec -out domain.key
#secp384r1
openssl ecparam -genkey -name secp384r1 | openssl ec -out domain.key

有了私钥文件,就可以生成 CSR 文件了。在 CSR 中推荐至少把域名带 www 和不带 www 的两种情况都加进去,其它子域可以根据需要添加(目前一张证书最多可以包含 100 个域名):

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr
执行这一步时,如果提示找不到 /etc/ssl/openssl.cnf 文件,请看看 /usr/local/openssl/ssl/openssl.cnf 是否存在。如果还是不行,也可以使用交互方式创建 CSR(需要注意 Common Name 必须为你的域名):
openssl req -new -sha256 -key domain.key -out domain.csr
  • 添加nginx配置,支持验证服务

我们知道,CA 在签发 DV(Domain Validation)证书时,需要验证域名所有权。传统 CA 的验证方式一般是往 [email protected] 发验证邮件,而 Let’s Encrypt 是在你的服务器上生成一个随机验证文件,再通过创建 CSR 时指定的域名访问,如果可以访问则表明你对这个域名有控制权。首先创建用于存放验证文件的目录,例如:

mkdir /data/www/challenges/

然后配置一个 HTTP 服务监听80端口,以 Nginx 为例:

server {
    listen 80;
    # listen [::]:80 default_server;

    server_name www.yoursite.com yoursite.com;
    location ^~ /.well-known/acme-challenge/ {
        alias /home/xxx/www/challenges/;
        try_files $uri =404;
    }

    location / {
        return 301 https://$server_name$request_uri;
    }
}

以上配置优先查找 ~/www/challenges/ 目录下的文件,如果找不到就重定向到 HTTPS 地址。这个验证服务以后更新证书还要用到,建议一直保留。

  • 获取网站证书

先把 acme-tiny 脚本保存到之前的 ssl 目录:

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

指定账户私钥、CSR 以及验证目录,执行脚本:

python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir ~/www/challenges/ &gt; ./signed.crt

如果一切正常,当前目录下就会生成一个 signed.crt,这就是申请好的证书文件。
如果你把域名 DNS 解析放在国内,这一步很可能会遇到类似这样的错误:

ValueError: Wrote file to /home/xxx/www/challenges/oJbvpIhkwkBGBAQUklWJXyC8VbWAdQqlgpwUJkgC1Vg, but couldn't download http://www.yoursite.com/.well-known/acme-challenge/oJbvpIhkwkBGBAQUklWJXyC8VbWAdQqlgpwUJkgC1Vg

尝试更改到国外的dns

搞定网站证书后,还要下载 Let’s Encrypt 的中间证书。配置 HTTPS 证书时既不要漏掉中间证书,也不要包含根证书。在 Nginx 配置中,需要把中间证书和网站证书合在一起:

wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem &gt; intermediate.pem
cat signed.crt intermediate.pem &gt; chained.pem

为了后续能顺利启用 OCSP Stapling,我们再把根证书和中间证书合在一起:

wget -O - https://letsencrypt.org/certs/isrgrootx1.pem &gt; root.pem
cat intermediate.pem root.pem &gt; full_chained.pem
  • 配置nginx监听443端口
server {
    listen 443;
    client_max_body_size 4G; 
    server_name chinachenshun.com www.chinachenshun.com sdchenshun.com www.sdchenshun.com; 

    ssl on; 
    ssl_session_timeout 5m; 
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA; 
    ssl_session_cache shared:SSL:50m; 
    ssl_prefer_server_ciphers on; 
    ssl_certificate /data/www/ssl/chained.pem; 
    ssl_certificate_key /data/www/ssl/domain.key;
    ........
  • 配置自动更新

Let’s Encrypt 签发的证书只有 90 天有效期,需要写个自动更新的脚本叫做update_ca.sh,放到crontab执行定时任务,脚本如下:

#!/bin/bash
         cd /home/xxx/www/ssl/
         python acme_tiny.py --account-key account.key --csr domain.csr --acme-dir /home/xxx/www/challenges/ &gt; signed.crt || exit
         wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem &gt; intermediate.pem
         cat signed.crt intermediate.pem &gt; chained.pem
         service nginx reload

         vim /etc/crontab 加入以下内容,一个月执行一次:
         0 0 1 * * nobody /home/xxx/update_ca.sh &gt;/dev/null 2&gt;&amp;1

注意,为了安全,crond执行的用户角色是nobody,所以相关联的文件属组需要改成nobody,这样才有权限执行相应的读写。

saltstack快速批量安装nginx

本文讲介绍

使用sls安装nginx,并管理nginx的配置文件,当nginx配置文件被修改时,自动更新配置文件,并重启nginx

在master端上配置nginx.sls文件

 mkdir -p /srv/salt/nginx
 cd /srv/salt/nginx/
vim init.sls
nginx:
  pkg:
    - installed
  service:
    - running
    - enable: True
    - reload: True
    - watch:
      - pkg: nginx
      - file: /etc/nginx/nginx.conf
      - file: /etc/nginx/conf.d/default.conf
/etc/nginx/nginx.conf:
  file.managed:
    - source: salt://etc/nginx/nginx.conf
    - user: root
    - group: root
    - mode: 644
/etc/nginx/conf.d/default.conf:
  file.managed:
    - source: salt://etc/nginx/conf.d/default.conf
    - user: root
    - group: root
    - mode: 644

文件讲解

  • nginx: 这是要安装的包名,也是sls文件的id,不能重复
  • pkg: pkg是包管理模块,对应/usr/lib/python2.6/site-packages/salt/states下的模块pkg.py
  • installed installed是pkg模块下的函数,id(nginx)作为installed的参数进行调用
  • service: service是服务模块,对应/usr/lib/python2.6/site-packages/salt/states下的模块service.py, 由于service是一个key,其下的running, require, watch是列表形式的值,因此service之后有冒号
  • running running是service.py模块下的函数,id(nginx)作为running的参数进行调用
  • enable: True
  • reload: True
  • watch: watch: 表示对文件$file的监控,当master 向minion传递$file时,新的$file与minion上原有文件不一致时,会重启nginx服务
  • pkg: nginx
  • file: /etc/nginx/nginx.conf
  • file: /etc/nginx/conf.d/default.conf
  • /etc/nginx/nginx.conf: 这一行同样是id不能重复:表示传递到minion时所处的位置,同时也作为file.managed函数的参数
  • file.managed:
  • file.py模块的managed函数,下面的source,user, group, mode都是managed函数的参数
  • source: salt://etc/nginx/nginx.conf
  • source 是managed函数的参数,指定要传递到minion端的源文件. –
  • salt://etc/nginx/nginx.conf 表示/etc/nginx/nginx.conf在/srv/salt之下,/srv/salt是saltstack的根目录
  • user: root
    表示文件的属主
  • group: root
    表示文件的属组
  • mode: 644
    表示文件的权限

开始配置

1:在master端上安装nginx,方便生成nginx的配置文件

 yum -y install nginx

2:创建nginx同步目录

mkdir /srv/salt/etc/nginx/conf.d -p

3:拷贝nginx的配置文件到/srv/salt/etc/nginx/目录下

cp /etc/nginx/nginx.conf /srv/salt/etc/nginx/

4:拷贝default.conf配置文件到/srv/salt/nginx/conf.d/目录下

cp /etc/nginx/conf.d/default.conf /srv/salt/etc/nginx/conf.d/

5:开始安装

 salt '*' state.sls nginx

6:测试是否安装成功

salt '*' cmd.run 'rpm -qa | grep nginx'

接下来实现配置更新

手动更新配置文件

在master端将默认端口更改为8080
vim /srv/salt/etc/nginx/conf.d/default.conf

 listen       8080 default_server;

在minion端执行指令,观察
salt-call state.sls nginx

自动更新配置文件

定义pillar的主目录,同时创建pillar目录(master端)

vim /etc/salt/master   #找到以下内容取消注释
pillar_roots:
  base:
    - /srv/pillar
pillar_opts: True
mkdir -p /srv/pillar

定义入口文件top.sls

入口文件的作用一般是定义pillar的数据覆盖被控主机的有效范围,’*’代表任意主机,默认从 base 标签开始解析执行,下一级是操作的目标

cat /srv/pillar/top.sls
base:
  '*':
    - nginx    #指代的是nginx.sls文件

定义nginx文件,每分钟更新一次

install -d /srv/pillar/nginx
cd nginx/
cat init.sls
schedule:
 nginx:
    function: state.sls
    minutes: 1
    args:
        - 'nginx'
刷新被控主机的pillar信息
salt '*' saltutil.refresh_pillar
查看上面定义的nginx.sls数据项,出现以下内容表示成功
salt '*' pillar.data
192.168.31.166:
    ----------
    schedule:
        ----------
        nginx:
            ----------
            args:
                - nginx
            function:
                state.sls
            minutes:
                1
192.168.31.188:
    ----------
    schedule:
        ----------
        nginx:
            ----------
            args:
                - nginx
            function:
                state.sls
            minutes:
                1

测试

在master端将默认端口更改为666
vim /srv/salt/etc/nginx/conf.d/default.conf
 listen       666 default_server;
一分钟后在minion端查看端口:
netstat -tnl

Kubernetes(k8s)部署并测试nginx service

创建2个pod的nginx service

[root@node1 data]#  kubectl run nginx –replicas=2 –labels="run=load-balancer-example" –image=nginx:1.9  –port=80
deployment "nginx" created
[root@node1 yaml]# kubectl get pod –all-namespaces -o wide|grep nginx
default       nginx-3431010723-6kv1z                  1/1       Running   2          1h        10.244.5.6      node5
default       nginx-3431010723-bw22q                  1/1       Running   2          1h        10.244.3.14     node4
[root@node1 kube-config]# kubectl expose deployment nginx –type=NodePort –name=example-service
service "example-service" exposed
[root@node1 kube-config]# kubectl describe svc example-service
Name:            example-service
Namespace:        default
Labels:            run=load-balancer-example
Annotations:        <none>
Selector:        run=load-balancer-example
Type:            NodePort
IP:            10.105.170.116
Port:            <unset>    80/TCP
NodePort:        <unset>    30457/TCP
Endpoints:        10.244.3.14:80,10.244.5.6:80
Session Affinity:    None
Events:            <none>

测试nginx服务

[root@node1 yaml]# curl 10.105.170.116:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>

浏览器访问都能显示nginx welcome界面

http://172.172.20.14:30457
http://172.172.20.15:30457

http://nodes:30457

Nginx