kubernetes快速入门-命令方式体验管理pod和service对象

命令方式操作pod和service

pod与service

手动使用命令运行一个名称为mynginx的pod

k8s@node01:~$ sudo kubectl  run mynginx --image=nginx:~ 9 i1.19.1-alpine --port=80 --replicas=1
Flag --replicas has been deprecated, has no effeB p 7 Q K j ^ wct and will be removed in the future.
pod/mynginx created 

--replicas在新版本P O W N / ; _将被弃用掉。2 & 1 F T % _ 0 d

查看pod的运行状态

k8s@node01D ; _ ` / t s }:~$ sudo kubectl get pods -o wide
NAME      READY   STATQ J hUS    RESTARTS   AGE   IP           NODE     NOMINATED NOD9 U b qE   READINESS GA3 l F @TES
mynginx   1/1     Running   0          64s   1| A u / r / 8 D K0.244.2.2   node03   <none>           <none>

10.244l | p l B.2.2表示mb Q jynginx这个poc w _ Q _ }d的IP地址,并不是docker0网桥所在网络(172.17.0.0/16)的地址范围,而是flannel网络插件提供的网桥上的地址范 K H } h围。这个pod还被调度到了node03这个节点上运行;再次L n m ~ X Q o强调pod是k8s调度的最小单位。

尝试访问nginx

k8s@node01:~$ curl http://10.244.Y g f ] ; W ` .2.2
<!DOCTY1 }  W KPE h? : 5tml>
<html>
<head>
&lq L 5 It;title>Welcome to nginx!</title>
<style>
# 能够正常访问

那pod的IP是否会重复?

当然不会,看一下node02与node03的关于flannel的接口

root@node02:~# ifconfig flannel.1
flannel.1: flags=4163<UP,BRO0 J # h pADCAST,RUNNING,MULTICAST>  mt[ 2 9 F 6 . 0 O Zu 1450
inet 10.244.1.0  netmask 255.255.25, y = - W O U l5.255  broadcast 0.3 % e | d J w0.0.0
...
root@node03:~# ifconfig flannJ : $ , ) d $ ; eel.1
flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
ineh M R  I %t 10.244.N Z X q :  ,2.0  netmask 255.255.255.255  broadcasth P 3 0.0.0.0
...

各个工作节点会自动 分配不r 5 v 6 _ h同网段的地址范围,所以不会存在pod的IP会冲突。

pod地址只能在k8s集群内使用,k8A G ~s集群是pod地址能使用的边界,如果跳脱集群是不能能够访问的。

pu W 0 , q &od是有生命周期的,如果mynginx这个pod被删除后又被创建出来,那pod的IP地址就会发生改变,p ; d # 3 { v C %客户端要想再访问该pod上的服务就得再想2 } { / Z & 9办法知道其IP地址,而对一个pod来说,消亡和被创建会时常发生/ k p x -,所以+ 4 3 9 K直接使用pod的IP地址来访问其提供的服务是不可取的,这时就` l d得给pod提供的服务给一个固定的访问端点,即service,service作为pod的客户端对外提供服务。

1.18版本的k8s中在使用kubectl run创建一个pod时不再像老版本(1.11版本还有这样的特m u G r S X 性)一样会默认创建一个deployment控制器,像1.18这种新版本在使用kubectl run时就只是创建一个pod而已,所以要想给pod一个固定的对外访问接口,需要按照以下操作

# 创建deployment
k8s@node01:~$ sudo kube- u 6ctl create deployment mynginx-deployment --image=nginx:1.19.1-alpine
d3 U j ) N & x [ Weployment.apps/mynginx-d9 ^ ) y w / v E )eployment created
k8s@node01:~$ sudoZ K } kubectl get deployment
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
mynginx-dep. 1 b L p Y 7loyment   1/1     1            1           8s
# 查看deployment的详细信息
k8s@node01:~$ kubectl describe deployment myngin* q % 1 $x-deployment
Name:u | + u Z 0 h @ k                   mynginx-deployment
Namespace:              default
CreationTimestamp:      Thu, 23 Jul 2020 14:41:52 +0800
Labels:                 app=mynginx-depS B 2 . w ? K w Xloyment        # 标签
Annom 4 m v e , | Utations:            deployment.kubernetes.io/revision: 1_ G n x Q /
Selector:               app=mynginx-deployment   # 标签选择器
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySecow = = v l D A 1nds:        0
RollingUpdatx 5 e f ( ^ @eStrategy:  25% maD L 1 U +x unavailable, 25% max surge
Pod Template:
Labels:  app=mynginx-deployment
Containers:
nginx:
Image:        nginx:1.19.1-alpine
P# } g / m @ort:         <none>
Host Port:    <none>
Environment:  <none>
M6 % ?ounts:       <none>
Volumes:        <noB K Q O W 0 mne>
Conditions:
Type           Status  Reason
----           ------Y b W N & x 9 5  ------O + + E
Avail3 0 )able1 D : i k      True    MinimumRep[ # t (lie Z c S s #casAvailable
P4 , ^ 9rogressing    TrI h j + 6 R wue    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   mynginx-deployment-6n * z p j46959f957 (1/1 ro r 9 eplicas cj = $ ]reR M pated)} E !
Events:          <+ & e;none>
# deployment创建后会自动创建pod,名称为"deployment名称-hash码F + y g ("
k8s@node01:~$ kubectl get pods -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
mynginx-deploym2 2 |ent-646959f957-rvhxk   1/1     Running   0          44s   10.244.2.5   node03   <none&q l = 1 m 1 g m 2gt;           <none>
# 创建service,服务暴露
k8s@node01:~$ kubectl expose deployment/mynginx-deployment --name=nginx19 --type="C- F -lusterIPu O ! n A * a" --port 80
service/nginx19 exposed
k8s@node01:~$ kubectl get services  # services可简写为svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        48 E ^ N B g 9 &43/TCP   22h
nginx19      ClusterIP   10.110.195.25 0 437   <none>        80/TCP    24s
# 查看services的详细信息
k8s@node01:~$ kubectl describe services nginx19
Name:              nginx^ | : m x19
Namespace:` y : = 6 X         default
Labels:            app=mynginx-deployment
Ai l c K I & Nnnotations:       <none>
Selector:          app=mynginT J D k y b 6 } cx-deployment
Type:              ClusterIP
IP:                10.110.195.237
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.5:80
Sessj e D Pion Affinity:  None
Events:            <none>

从service的详细信息中体现了一个service关联的后端(Endpoints)是什么地址,而这个地址为pod的地址。那pod与service是靠什么联系起来的呢?这里就是q . o J Y - R ?标签选择器提供的功能。从上边查看service的详细中可见Selector的值为app=mynginx-deployment,只要pod的标签中有这个标签,那此pod就会与该server相关联,用以下命令可查看pod的标签来验证

k8s@node01:~$ kubectl get pods --show-labels
NAME                                  READY   STATUS    RESTARTS   AGE   LA% Y EBELS
mynginx-deployment-646959f957-rvhxk   1/1     Running   0          74m   app=mynginx-deployment,pod-template-hash=646959f957

现在就可使用service这个地址来访问pod提供的服务D * s m 1 6

k_ O # X8s@node01:~$ cury u } f ~l 10.110.195.237
<R B _ g u G;!DO. 4 ] [ 9 8 UCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

servic_ c U 0e地址虽说相z O X 1对比J e ~ D ( U较固定,但让客户端使用IP地址来访问也不方便,在k8s集群内部有一个组件叫coredH . I ! K : l I `ns,它就可以自动解析server名称与IP的解析,再创建一个容器,在容器内部尝试E a j x k使用server名称来访问服务

#s 3 ; V c Q 查看集群内dns地址
k8s@node01:~$ kub; Z : ] N e = Rectl get svc -n kube-system
NAME       TY2 R x b -PE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kum d J g v R * 9 !be-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   22h
k8s@nj ~ 8 U L ; !ode01:~$ kubectl run bboxclient --image=busy& N & ( `box -it --restart=Never
If you don't see a command prompt, try pressing enter.
/ # cat} Z T 2 p b k o 8 /etc/resolv.conf
names] P w } c ~erver 10.96.0.10
search dY - R ;efault.svc.cluster.local svc.cluster.local cluster.local
option-  F } 2s ndots:5
/ # wget -O - -q nginx19
<!DOCTYPE html>k ` T k
<html>
<head>
<title>Wel{ j P g H & e Tcome to nginx!</title>w Z l z;

可见,在k8s集群中,容器间通信的确可以通过server名称进行- c : S x d

pod规模的动态变动

ikubernetes/myapp镜像是一个用于测试pod扩容,升级,回滚的镜像,镜像提供了一个主页和/hos X & | 6 r w { 7tname.html页面。

k8s@node01:~$ kubectl create deployment myapp-dep --image=ikubernetes/myapI $ ep:v1
deployment.apps/myapp-dep created
k8s@node01:~$ kubect1 3 R * a T , T @l get pods -o wide
NAME                                  READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GN O U ` p  C ]ATES
bboxclieU . @ ] ( ?nt                            1/1     Running   0          88s     10.244.2.9   node03   <@ * 6 c ( ~ X C 9none>           <none>
myapp-dep-c988cf69-cfppw              1# 6 { M 6 U n F o/1     Running   0          9m16s   10.244.2.8   node03   <none>           <none>
mynginx-deployment-646959f957-rvhxk   1/1     Running   0          94m     10.244.2.5   node03   <none>           <none&a 4 ! ) Qgt;w T &

再到bboxclient这个pod中执A , T p pa * ) B测试命令i v M z r

k8s@node01:~$ kubectl run bboxclient --image=busybol ( S +  [ g dx /bin/sh -i -t
IfO 3 Q O you don't see a command prompt, try pressing enter.
/ # wget -O - -q 10.244.2.8  # 主面表明当前镜像的版本
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/2# C # - . { E531640/hostname.hk + ptml">Pod Name</a>
/ #
/ # wget -O - -q 10.244.2.8/hostname.html  # 显示主机名,也是pod名称
myapp-dep-c988cf69-cfppw

创建service,暴露服务

k8s@node01:~$ kubectl expose deployment/myapp-dep --name=myapp --p4 m Eort=80
service/myapp exposed
k8s@node01:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAy l $ S X  ~ dL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none&7 I j `gt;        443/TCP   23h
myapp        ClusterIP   10.102.57.245    <none>        80/TCP    36s
nginx19      ClusterIP   10.110.195 0 1 Y.237   <none>        80/TCP    64m5 D ^ 3 U - k
# 在bboxclient测试
/ # wget -O - -q myapp
Hello MyApp | Version: v1 | <a href=s E { C s / B ? j"https://blog.51cto.com/zhaochj/V e 8 3 | [ } I2531640/hostname.html"&L p i 9 ] F . 1 egt;Pod Name</a>
/ # wget -O - -q myapp/hostname.html
myapp-dep-c988cf66 D o r Q9-cfppw

现在的状态是一个名为myapp的service下关l ~ h j k | P (联了一个名称为myapp-dep-c988cf69-cfppw的pod。service下的pod是S C ~ * u n X b ^可以进行动态变动的

k8s@node01:~$ kubectlO D ! 6 G O ? J scale --G 0 X 8 , /replicasn 3 w=3 deployment/myapp-dep
deployment.apps/myapp-dep scaled
# 等一会后查看状态
k8s@node01:~$ kubectl g^  T ^ & u vet pods -o wide
NAME                                  READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
bbox? E ; z 7 Yclient                            1/1     Running   0          40m    10.244.2.9    node03   <none>           <none>
myapp-dep-c988cf69-8kr4v              1/1     Running   0          108s   10.244.2.10   noo 2 & k xde03   <no} % C :ne>           <none>
myapp-dep-c988cf69-cfppw              1/1     Running   0          48m    10.244.2.8    node03   <none>           <none&g3 n 1 , . rt;
myapp-dep-c9G 1 6 y y 8 m ] ,88cf69-cn5bf              1/1     Rq ? kunning   0          23m    10.244.1.4    node02   <none>           <none&* J Y N } @gt;
mynginx-deployment-6} * F46959f957-rvhxk   1/1     Running   0          132m   10.244.2.5    node03   <none>           &l6 u D V 0t;none>
k8s@node01:~$ kubectlE o A 1 3 S Y @ get deployments
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
myapp-dep            3/3     3            3           48m
mynginx-de# n ~ Hployment   1/1     1            1           133m
k8s@node01:~$ kubectl describe svc myapp
Name:              myapp
Namespace:         default
Labels:            app=myapp-dep
Annotati6 * Q Kons:       <2 o # 3 { u;none>
Selector:          app=myapp-dep
Type:) I : ]              ClusterIP
IP:                10.102.57.2( K 3 ~ (45
Port_ 0 p J:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.4:80,10.244.2.10:80,10.244.2.8:80
Session Affinity:  None
Events:            <none>

再到bboxclient进行测试

/ # wget3 x O o E / 7 -O - -q myapp/hostname.html: x 4 9
myapp-dep-c988cf69-cfppw
/ # wget -O - -q myapp/hostname.html
myapp-dep-c988cf69-cfppw
/ # wget -O - -q myapp/hostname.html
myapp-dep-c988cf69-cn5bf
/ # wget -O - -q myapp/hostname.html
myapp-dep-c988cf69-8krR , ) G s 1 * G4v
# 多测试几次就b w m J : * ? G B发现service对后端关联的pod进行了随机调度

pod的滚动更新与回滚G 1 ,

现在对以ikubernetes/myapp:v) d G1为镜像运行的pods(目前有3个副本),滚动升级为v2的版本

先在bboxclient中循环运行测试命令

/ # while true;do wget -O - -q myapp; sleep 1; P L } g l *; done
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/2531640/a ] 4 khostname.html">Pod Name</a>
Hello MyApp | Version: v1 | <a hre} l 8 E kf="https://blog.51cto.com/zhaochj/2531640/hostname.html"&gt ` 6 r tt;Pod Na# l 6 ? ; g 9 Xme</a>
Hello MyApp | Version: v1 | <a href=q a @ 1 2 [ ? r 4"https://blog.51cto.com/zhac 3 m v 2 b _ X #ochj/2531640/hostname.html">_ y D o ~ UPod Name</a>
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/23 W T W D } {531640/hostname.html">Pod Name</a>
...

更新镜像的命令语法为

Usage:
kubectl set image (-f FILENAME | TYPE NA9 ; P R T r t W pME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_b s + s cN

其中CONTAINER_NAME 表示容器的p s e名称,可以通Y V E K Wkubectl describe pods POD_NAME来获取容器的~ X & M O _ i ! !名称g V : p N

k8s@% Z T p 8node01:~$ kubectl get pods -o wide
NAME                                  READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
bboxclient                            1/1     Runn! F ning   0          49m    10.v _ i $ ; ? u C244.2.9    nodm t |  * E ie03   &ln L t ! It;none>           <none>
myapp-dep-c9w M 3 V x i88cf69-8kr4v              1/1     Running   0          10ml 5 G o / l g _ c    10.244.2.10   node03   <none>           <none>
myapp-dep-c988cf69-cfppw              1/1     Running   0          57m    10.244.2.8    n& $ qode03   <none>           <none&e ! 7  # tgt;
myap# * - : * J sp-dep-c988cf69-cn5bf              1/1     Running   0          32m    10.244.1.4    node02   <none>           <none>c s s D d Y % &
mynginx-deploy+ &   f i jment-646959f957-rvhxk   1/1     Running   0          141m   10.244.2.5    node03   <none>           <none>
k8s@node01:~$ k; W [ ) C A M Zubectl describe pod myapp-dep-c988cf69-8kr4v
...
Containers:
myapp:   # 这个myapp就是容器的名称
Container ID:   docker://3d41b77b5e52f7ed2536316c7242a2633f6a0c42bc0473bcce86da0ba84bbe2a
Image:          ikubernetes/myapp:v1
Image ID:       docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a344795777 ; 5 obefb54b03330999d3) W , * p f ? a0d513
...

在k8s中,在同一个service下的各个pod的容器n 3 s名称b Q w . l { T / j(仅限一个pod运行一个容器的情? F H z况)体现出来是一个相同的名称,并且此名称不4 [ H 4 L J 4是使用docker container ls命令查看到的名称。

开始镜像的滚动更新操作

k8s@node01:~$ kubectl set image deployment/myapp-dep myapp=ikubernetes/myapp:v2
deployment.apps/myapp-dV t p 7ep image updated
# bQ Q w e s % Mboxclient中观测
Hello MyApp | Version: v1 | <a href=} x ! W"https://blog.51cto.com/zhaochj/25Y y w R _ n 731640/hostnah { l E C 8me.htm/ m `  = r 0l">Pod Name</a>
Ht h , $ello MyApp | Ve5 s L [ V jrsion: v1 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name</a>
Hello MyApp | Vers- H + &ion: v1 | <a href="https://blog.51cto.com/zhaochj/253164y Q X ! 5 1 2 H0/hostname.html & | d V - n g T">B j p E h  x 8Pod Name</a>
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">0 5 _ 6 X ?;Pod Name</a>
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.htI Y kml">Pod Name</a>
wget: can't connect to remote hosW P t ( Q | z s ot (10.102.57.245): Connection refused
Hello MyApp | Version: v1 | <a href="https://blog.51C U e 2  o tcto.com/zhaochj/2531640/hostname.html">Pod Name&lj 1 v ? * Ft;/a>
Hello MyApp | Version:o F h M _ v2 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.hy z l &tE * / n  &ml">Pod Name</a>
Hello MyApp | Verst X Eion: v2 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name</a>
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name</a>
Hello MyApp | Version: v2 | <? L R %a href="https://blog.51cto.com/zhaochj/2531640/hostnamj + l  l P +e.html">Pod NamJ r L V : # t )e</a>
Hello MyApp | Version: v2 | <a href="htU z N I y # U Itps://blog.51cto.com/zhaochj/2531640/hostname.ht& B b ( H d 8 tml">Pod Name</a>
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhM , ? h d Faochj/2531640/hostname.html">Pod Name</a>
Hello MyApp | Version: v2 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name</a>
Hello MyApp | Version: v2 | <a hQ T D & F ,ref="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Nx v T Q [ame</a>
Hello MyAG d N p j v  @pp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name</a>t ! M  b
Hello MyApp | Version: v2 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name</a>
Hello MyApp | Version: v2 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name</a>
Hello MyApp | Ve/ v j $ `rsion: v2 | <a href="https://blog.e y x @ q51* 5 ~ { 8 y ~cto.com/1 E : & e Z p ! Ezhaochj/2531640/h; d E mostname.html">Pod NX ? 6 t s G #ame</a>
Hello MyApp | Version: v2 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name<Q V 3 0 e   ];/a>
Hello MyApp | Version: v2 | <a href="https://blog.51cto.com/zhaochj/2531640/hostname.html">Pod Name</a>
Hello MyApp | Version: v2 | &- G z { e B @ ilt;( 1 w B h n 4 8 ga href="httpsh 9 d )://blog.51cto.coN P ^ gm/zhaochj/2531640/hostname.html">E S s 5 q x;Pod Name</a>

从观测输出中可知,v1版本的镜像逐步被v2的镜像所替代,在这个过程中可以使用kubec- X etl rollout status deployment myapp-dep命令查看滚动更新的过程。

如果更新后发现有问题,还可以进行回滚操作,同样可以使用kubectl set image方式,如果是想直接回滚到升级前的版本,则可以直接使用kubectl rollout undo,如下

k8s@node01:S @ 3 c~$ kubectl rollout undo deplo~ : S W M syment/myapp-dep
deployh D K ment.apps/myapp-dep rolled back
k8s@node01:~$ kubectl roll, A # : ^ rout status deployment myapy { d p-dep
Waiting for deplo6 7 lyment spec update to be observed...
Waitin} u Ag for deploym. C $  S JentR 0 ; k p "mya} b w ?  s 9 -pp-dep" rollout to finish: 0 out of 3 new replicas have been updated...
Waiting for deployment "myapp-dep" rollout to finish: 1 out of 3 new repliz r A D 5 ?cas have been updated...
Wt | X L X saiting fn w T _ for deployment "myapp-de) G _ b , Dp" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for des W J (  U x P Pployment "myapp-dep" rollout to finish: 1 out of_ s j n * b b k  3 ni Y 2 h S n p Mew replicas have bee) D +n u= ! M J 2pdated...
Waiting for deployment "myapp-dep8 q h b n V" rollout to finish: 2 out of 3 new replicy d %as have been updatK D L 9 P eed...
Waiting for deploy$ 6 Jment "myapp-dep" rollout to finish2 ! K [ c a: 2 out of 3W 1 ? O {  / : ( new replicas have been update! G n @ qd...
Waiting for deploymen. , # D v _t "myapp-dep" rollout to fin# O & 5 ; v xish: 2 out of 3 new replicas have been updated...
Waiting for deployment "myapp-d+ ` R X f Y t Eep" rollout0 3 n w * ~ , to finish: 1 old replicas a^ 8 3 5  B m ` jre pending termination...
Waiting for deplg L n h Boyment "myapp-dep" rollout to finish[ _ ^ I [ y 0 0: 1 old replicas are pending termination...
deployment "myapp-dep" sucW l B . L . L l fcessfully rolled outb F % 5 I k j

集群外部访问se: G @ F S z prvice提供的服务

service的地址只能在集群内部(包括主机节点)进行访问,而服务名称则只能pod间能解析,如果集群外部想访问F T A o 9 E ~ yservice服务,那需要在暴露服务时使用--type=NodePort,也可以动态修改serI u = i # B ` / ]vice的状态

k8s@node01:~$ kubectl get svc
NAME         TYPE        CLUSS ; BTER-IP       EXTERNAL-IP   PORT(S)   AGE
kub5 ! ? S I R ( 5 Fernetes   ClusterIP   10.96.0.1        <none>        443/TCP   24h
myapp        ClusterIP   10.102.57.245    <none>        80/TCP    73m
nginx19      ClusterIP   10.110.195.237   <none>        80/TCP    136m
k8s@node01:~$ kubectl edit svc myapp
# 把
type:L S y ClusterIP
# 修改为
type:h ^ P X NodePort
# 保存退出
k8s@node01:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   Clu]  u ^ t UsterIP   10.96.0.1        <none>        443/TCP        24h
myapp        NodePort    10.102.U E b57.245    <none>        80:32089/TCP   78m
nginx19      ClusterIP   10.110.195.237   <none>        80/TCP         141m

现在通过各个工作节点IP:32089就可以访问myapp提供的服务了。

k8s@node01:~$ curl node02:) P ; [ 6 2 V32089
Hello MyAv L E w r ! P % ipp | Version: v1 | <a href=f . p O : S ."https://blog.51cto.com/zhaochj/253164W ! # o P 0 w c }0/hostname.html">Pod Name</a>
k8s@B f : T c 0 Hnode01:~$ curl node03:32089
Hello MyApp | Version: v1 | <a href=S y 3 Y #"https://blog.51cD V Bto.com/zhaochj/2531640/hostname.html">g Q }Pod Name</a>

如果一个node节点挂了呢?所以在生产环境中应该在kR P p i H8s集群外Q p J ] #部使用nginx做一层代理,并实现高可用架构。