Docker服务编排04-K8S

1. Kubernetes简介

Kubernetes是Google基于Borg开源的容器编排调度引擎,作为CNCF(Cloud Native Computing Foundation)
最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,
定义服务的最终状态,Kubernetes 可以帮你将系统自动地达到和维持在这个状态。Kubernetes 作为云原生应用的基石,相当于一个云操作系统,其重要性不言而喻。
由于kubernetes文字读取来太长不好记,是用8代替8个字符“ubernete”而成的缩写,也被简称为k8s

1.1 k8s的整体架构图

架构图

  • 核心层:Kubernetes 最核心的功能,对外提供 API 构建高层的应用,对内提供插件式应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS 解析等)
  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态 Provision 等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy 等)
  • 接口层:kubectl 命令行工具、客户端 SDK 以及集群联邦
  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
    * Kubernetes 外部:日志、监控、配置管理、CI、CD、Workflow等
    * Kubernetes 内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

1.2 k8s的组件架构图

在这里插入图片描述
Kubernetes主要由以下几个核心组件组成(必须安装):

  1. etcd保存了整个集群的状态;
  2. apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  3. controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  4. scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  5. kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理,安装每台工作节点;
  6. kube-proxy负责为Service提供cluster内部的服务发现和负载均衡,安装在每台工作节点;

除了核心组件,还有一些推荐的Add-ons(选装):

  1. kube-dns负责为整个集群提供DNS服务,应该使用kubectl添加一个服务到容器,是一个发布的应用服务于
  2. Ingress Controller为服务提供外网入口
  3. Heapster提供资源监控
  4. Dashboard提供GUI
  5. Federation提供跨可用区的集群

1.3 k8s教程资源

k8s教程
k8s中文社区
bookstack k8s专区

2. 安装k8s

2.1 机器选择

主机ip主机名称
192.168.58.144swarm01
192.168.58.145swarm02
192.168.58.147swarm03

2.1 环境准备

为了简单部署,封装了一些脚本和程序可以一键安装master和worker
参考本人github https://github.com/lzeqian/kubernates-installer

3. kubectl命令

kubectl命令大全

3.1 检查各项服务是否正常启动

  • manager(58.144)
[root@swarm01 kubernates]# ./manager.sh status
etcd.service运行中
kube-apiserver.service运行中
kube-controller-manager.service运行中
kube-scheduler.service运行中
kube-calico.service运行中
  • worker(58.145,58.147)
[root@swarm02 kubernates-installer]# ./worker.sh status
kube-calico.service运行中
kubelet.service运行中

任何一台机器检测所有网络接入

[root@swarm02 kubernates-installer]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+----------------+-------------------+-------+----------+-------------+
| 192.168.58.144 | node-to-node mesh | up    | 10:10:14 | Established |
| 192.168.58.147 | node-to-node mesh | up    | 10:21:10 | Established |
+----------------+-------------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.

3.2 资源对象与基本概念解析

以下列举的内容都是 kubernetes 中的 Object,这些对象都可以在 yaml 文件中作为一种 API 类型来配置。具体每个对象以及点击超链接进入参考
通过 kubectl explain 对象名称比如(deploy)查看帮助

[root@swarm01 ~]# kubectl explain deploy
DESCRIPTION:
     DEPRECATED - This group version of Deployment is deprecated by
     apps/v1beta2/Deployment. See the release notes for more information.
     Deployment enables declarative updates for Pods and ReplicaSets.

FIELDS:
   apiVersion   <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#resources

   kind <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds

   metadata     <Object>
     Standard object metadata.

   spec <Object>
     Specification of the desired behavior of the Deployment.

   status       <Object>
     Most recently observed status of the Deployment.

所有对象包括:

我将它们简单的分类为以下几种资源对象:

类别名称
资源对象Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling
配置对象Node、Namespace、Service、Secret、ConfigMap、Ingress、Label、ThirdPartyResource、 ServiceAccount
存储对象Volume、Persistent Volume
策略对象SecurityContext、ResourceQuota、LimitRange

理解 kubernetes 中的对象

在 Kubernetes 系统中,Kubernetes 对象 是持久化的条目。Kubernetes 使用这些条目去表示整个集群的状态。特别地,它们描述了如下信息:

  • 什么容器化应用在运行(以及在哪个 Node 上)
  • 可以被应用使用的资源
  • 关于应用如何表现的策略,比如重启策略、升级策略,以及容错策略

Kubernetes 对象是 “目标性记录” —— 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。通过创建对象,可以有效地告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的,这就是 Kubernetes 集群的 期望状态。

与 Kubernetes 对象工作 —— 是否创建、修改,或者删除 —— 需要使用 Kubernetes API。当使用 kubectl 命令行接口时,比如,CLI 会使用必要的 Kubernetes API 调用,也可以在程序中直接使用 Kubernetes API。为了实现该目标,Kubernetes 当前提供了一个 golang 客户端库 ,其它语言库(例如Python)也正在开发中。

对象 Spec 与状态

每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 spec 和 对象 status。spec 必须提供,它描述了对象的 期望状态—— 希望对象所具有的特征。status 描述了对象的 实际状态,它是由 Kubernetes 系统提供和更新。在任何时刻,Kubernetes 控制平面一直处于活跃状态,管理着对象的实际状态以与我们所期望的状态相匹配。

例如,Kubernetes Deployment 对象能够表示运行在集群中的应用。当创建 Deployment 时,可能需要设置 Deployment 的 spec,以指定该应用需要有 3 个副本在运行。Kubernetes 系统读取 Deployment spec,启动我们所期望的该应用的 3 个实例 —— 更新状态以与 spec 相匹配。如果那些实例中有失败的(一种状态变更),Kubernetes 系统通过修正来响应 spec 和状态之间的不一致 —— 这种情况,启动一个新的实例来替换。

关于对象 spec、status 和 metadata 更多信息,查看 Kubernetes API Conventions。

描述 Kubernetes 对象

当创建 Kubernetes 对象时,必须提供对象的 spec,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如,名称)。当使用 Kubernetes API 创建对象时(或者直接创建,或者基于kubectl),API 请求必须在请求体中包含 JSON 格式的信息。更常用的是,需要在 .yaml 文件中为 kubectl 提供这些信息。 kubectl 在执行 API 请求时,将这些信息转换成 JSON 格式。

这里有一个 .yaml 示例文件,展示了 Kubernetes Deployment 的必需字段和对象 spec:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

一种创建 Deployment 的方式,类似上面使用 .yaml 文件,是使用 kubectl 命令行接口(CLI)中的 kubectl create 命令,传递 .yaml 作为参数。下面是一个示例:

复制代码

$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record

输出类似如下这样:

deployment "nginx-deployment" created

必需字段
在想要创建的 Kubernetes 对象对应的 .yaml 文件中,需要配置如下的字段:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类型
  • metadata - 帮助识别对象唯一性的数据,包括一个 name 字符串、UID 和可选的 namespace

也需要提供对象的 spec 字段。对象 spec 的精确格式对每个 Kubernetes 对象来说是不同的,包含了特定于该对象的嵌套字段。Kubernetes API 参考能够帮助我们找到任何我们想创建的对象的 spec 格式。

3.3 kubectl命令

通过k8s架构图知道,所有worker同城为node,每一次的发布叫做 deployment,启动的容器集合就是一个pod,
多个pod组成了一个service

创建对象

$ kubectl create -f ./my-manifest.yaml           # 创建资源
$ kubectl create -f ./my1.yaml -f ./my2.yaml     # 使用多个文件创建资源
$ kubectl create -f ./dir                        # 使用目录下的所有清单文件来创建资源
$ kubectl create -f https://git.io/vPieo         # 使用 url 来创建资源
$ kubectl run nginx --image=nginx                # 启动一个 nginx 实例
$ kubectl explain pods,svc                       # 获取 pod 和 svc 的文档
# 从 stdin 输入中创建多个 YAML 对象
$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: busybox-sleep
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - sleep
    - "1000000"
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox-sleep-less
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - sleep
    - "1000"
EOF
# 创建包含几个 key 的 Secret
$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: $(echo "s33msi4" | base64)
  username: $(echo "jane" | base64)
EOF

显示和查找资源

# Get commands with basic output
$ kubectl get services                          # 列出所有 namespace 中的所有 service
$ kubectl get pods --all-namespaces             # 列出所有 namespace 中的所有 pod
$ kubectl get pods -o wide                      # 列出所有 pod 并显示详细信息
$ kubectl get deployment my-dep                 # 列出指定 deployment
$ kubectl get pods --include-uninitialized      # 列出该 namespace 中的所有 pod 包括未初始化的
# 使用详细输出来描述命令
$ kubectl describe nodes my-node
$ kubectl describe pods my-pod
$ kubectl get services --sort-by=.metadata.name # List Services Sorted by Name
# 根据重启次数排序列出 pod
$ kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
# 获取所有具有 app=cassandra 的 pod 中的 version 标签
$ kubectl get pods --selector=app=cassandra rc -o \
  jsonpath='{.items[*].metadata.labels.version}'
# 获取所有节点的 ExternalIP
$ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'
# 列出属于某个 PC 的 Pod 的名字
# “jq”命令用于转换复杂的 jsonpath,参考 https://stedolan.github.io/jq/
$ sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
$ echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})
# 查看哪些节点已就绪
$ JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
 && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"
# 列出当前 Pod 中使用的 Secret
$ kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq

更新资源

 kubectl rolling-update frontend-v1 -f frontend-v2.json           # 滚动更新 pod frontend-v1
$ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2  # 更新资源名称并更新镜像
$ kubectl rolling-update frontend --image=image:v2                 # 更新 frontend pod 中的镜像
$ kubectl rolling-update frontend-v1 frontend-v2 --rollback        # 退出已存在的进行中的滚动更新
$ cat pod.json | kubectl replace -f -                              # 基于 stdin 输入的 JSON 替换 pod
# 强制替换,删除后重新创建资源。会导致服务中断。
$ kubectl replace --force -f ./pod.json
# 为 nginx RC 创建服务,启用本地 80 端口连接到容器上的 8000 端口
$ kubectl expose rc nginx --port=80 --target-port=8000
# 更新单容器 pod 的镜像版本(tag)到 v4
$ kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
$ kubectl label pods my-pod new-label=awesome                      # 添加标签
$ kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq       # 添加注解
$ kubectl autoscale deployment foo --min=2 --max=10                # 自动扩展 deployment “foo”

Scale 资源

kubectl scale --replicas=3 rs/foo                                 # Scale a replicaset named 'foo' to 3
$ kubectl scale --replicas=3 -f foo.yaml                            # Scale a resource specified in "foo.yaml" to 3
$ kubectl scale --current-replicas=2 --replicas=3 deployment/mysql  # If the deployment named mysql's current size is 2, scale mysql to 3
$ kubectl scale --replicas=5 rc/foo rc/bar rc/baz                   # Scale multiple replication controllers

删除资源

$ kubectl delete -f ./pod.json                                              # 删除 pod.json 文件中定义的类型和名称的 pod
$ kubectl delete pod,service baz foo                                        # 删除名为“baz”的 pod 和名为“foo”的 service
$ kubectl delete pods,services -l name=myLabel                              # 删除具有 name=myLabel 标签的 pod 和 serivce
$ kubectl delete pods,services -l name=myLabel --include-uninitialized      # 删除具有 name=myLabel 标签的 pod 和 service,包括尚未初始化的
$ kubectl -n my-ns delete po,svc --all                                      # 删除 my-ns namespace 下的所有 pod 和 serivce,包括尚未初始化的

与运行中的 Pod 交互

$ kubectl logs my-pod                                 # dump 输出 pod 的日志(stdout)
$ kubectl logs my-pod -c my-container                 # dump 输出 pod 中容器的日志(stdout,pod 中有多个容器的情况下使用)
$ kubectl logs -f my-pod                              # 流式输出 pod 的日志(stdout)
$ kubectl logs -f my-pod -c my-container              # 流式输出 pod 中容器的日志(stdout,pod 中有多个容器的情况下使用)
$ kubectl run -i --tty busybox --image=busybox -- sh  # 交互式 shell 的方式运行 pod
$ kubectl attach my-pod -i                            # 连接到运行中的容器
$ kubectl port-forward my-pod 5000:6000               # 转发 pod 中的 6000 端口到本地的 5000 端口
$ kubectl exec my-pod -- ls /                         # 在已存在的容器中执行命令(只有一个容器的情况下)
$ kubectl exec my-pod -c my-container -- ls /         # 在已存在的容器中执行命令(pod 中有多个容器的情况下)
$ kubectl top pod POD_NAME --containers               # 显示指定 pod 和容器的指标度量

与节点和集群交互

$ kubectl cordon my-node                                                # 标记 my-node 不可调度
$ kubectl drain my-node                                                 # 清空 my-node 以待维护
$ kubectl uncordon my-node                                              # 标记 my-node 可调度
$ kubectl top node my-node                                              # 显示 my-node 的指标度量
$ kubectl cluster-info                                                  # 显示 master 和服务的地址
$ kubectl cluster-info dump                                             # 将当前集群状态输出到 stdout                                    
$ kubectl cluster-info dump --output-directory=/path/to/cluster-state   # 将当前集群状态输出到 /path/to/cluster-state
# 如果该键和影响的污点(taint)已存在,则使用指定的值替换
$ kubectl taint nodes foo dedicated=special-user:NoSchedule

3.3 kube-proxy和kube-dns进行容器互连

安装kube-proxy和kube-dns参考 https://github.com/lzeqian/kubernates-installer
所有从机(145,146)安装kube-proxy (注意第一个参数 ip是当前执行机器的ip)

[root@swarm02 kubernates-installer]# ./worker/proxy.sh 192.168.58.145 192.168.58.144
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-proxy.service to /usr/lib/systemd/system/kube-proxy.service.
已经创建服务kube-proxy.service,停止服务使用 systemctl stop kube-proxy.service
也可以使用当前脚本 ./worker/proxy.sh stop|start|u
查看日志journalctl -f -u kube-proxy

主安装kube-dns

[root@swarm01 kubernates]# ./worker/dns.sh 192.168.58.144
No resources found.
configmap "kube-dns" created
serviceaccount "kube-dns" created
service "kube-dns" created
deployment "kube-dns" created
已经创建服务kube-dns,停止服务使用 kubectl delete -f conf/kube-dns.yaml
也可以使用当前脚本 ./worker/dns.sh u 卸载
查看日志 请先kubectl -n kube-system get pods -o wide 找到安装的主机 使用docker logs查看

Service介绍

Kubernetes Pod 是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束。
通过 ReplicationController 能够动态地创建和销毁 Pod(例如,需要进行扩缩容,或者执行 滚动升级)。
每个 Pod 都会获取它自己的 IP 地址,即使这些 IP 地址不总是稳定可依赖的。
这会导致一个问题:在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组 Pod 中的哪些 backend 呢?
具体service参考https://www.bookstack.cn/read/kubernetes-handbook/concepts-service.md

关于 Service

Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。
这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector(查看下面了解,为什么可能需要没有 selector 的 Service)实现的。

举个例子,考虑一个图片处理 backend,它运行了3个副本。这些副本是可互换的 —— frontend 不需要关心它们调用了哪个 backend 副本。
然而组成这一组 backend 程序的 Pod 实际上可能会发生变化,frontend 客户端不应该也没必要知道,而且也不需要跟踪这一组 backend 的状态。
Service 定义的抽象能够解耦这种关联。

对 Kubernetes 集群中的应用,Kubernetes 提供了简单的 Endpoints API,只要 Service 中的一组 Pod 发生变更,应用程序就会被更新。
对非 Kubernetes 集群中的应用,Kubernetes 提供了基于 VIP 的网桥的方式访问 Service,再由 Service 重定向到 backend Pod。

演示使用kube-proxy

创建一个nginx的deploy

[root@swarm01 kubernates]# kubectl run nginx --image=nginx 
deployment "nginx" created
[root@swarm01 kubernates]# kubectl get deploy
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     1         1         1            0           14s
[root@swarm01 kubernates]# kubectl get pods
NAME                   READY     STATUS              RESTARTS   AGE
nginx-8586cf59-p6zgx   0/1       ContainerCreating   0          21s
[root@swarm01 kubernates]# kubectl get pods -o wide
NAME                   READY     STATUS    RESTARTS   AGE       IP              NODE
nginx-8586cf59-p6zgx   1/1       Running   0          1m        172.20.105.69   192.168.58.145

pod默认会生成一个网桥ip nginx默认暴露80端口尝试访问

[root@swarm01 kubernates]# curl 172.20.105.69
<!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>

访问宿主机58.145上的80端口,显然无法访问

[root@swarm01 kubernates]# curl 192.168.58.145
curl: (7) Failed connect to 192.168.58.145:80; Connection refused

接下来使用命令给deploy创建一个service 查看kubectl expose帮助

[root@swarm01 kubernates]# kubectl expose --help
Expose a resource as a new Kubernetes service.   导出资源为一个service

Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector for that
resource as the selector for a new service on the specified port. A deployment or replica set will be exposed as a
service only if its selector is convertible to a selector that service supports, i.e. when the selector contains only
the matchLabels component. Note that if no port is specified via --port and the exposed resource has multiple ports, all
will be re-used by the new service. Also if no labels are specified, the new service will re-use the labels from the
resource it exposes. 

执行命令(–target-port表示容器nginx的端口是80 port表示service暴露的ip)

[root@swarm01 kubernates]# kubectl expose deploy nginx --type=NodePort --port=8888 --target-port=80
service "nginx" exposed

查看该service详细

[root@swarm01 kubernates]# kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.68.0.1       <none>        443/TCP          12d
nginx        NodePort    10.68.154.112   <none>        8888:25887/TCP   20s
[root@swarm01 kubernates]# kubectl describe services nginx
Name:                     nginx
Namespace:                default
Labels:                   run=nginx
Annotations:              <none>
Selector:                 run=nginx
Type:                     NodePort
IP:                       10.68.154.112
Port:                     <unset>  8888/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  25887/TCP
Endpoints:                172.20.105.69:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

Kubernetes集群里有三种IP地址,分别如下:

  • Node IP:Node节点的IP地址,即物理网卡的IP地址,对应NodePort默认随机。
  • Pod IP:Pod的IP地址,即docker容器的IP地址,此为虚拟IP地址,Endpoints表示podip,对应Endpoints后面的端口是80,对应命令行 --target-port。
  • Cluster IP:Service的IP地址,此为虚拟IP地址,Ip就是Cluster Ip,对应是Service对外暴露地址:8888 ,对应命令行 --port。

此时访问serviceip:8888端口 curl 10.68.154.112:8888,发现主机没有安装kube-proxy无法访问,其他两台worker
节点是可以访问的,这就是kube-proxy代理的作用,同时我们看到service上有一个NodePort是25887,这个端口
是在安装可kube-proxy主机上暴露的端口,可以直接使用宿主机:NodePort来访问服务,适合前端应用
在所有安装kube-proxy主机上查看是否暴露了25887端口,可以看到端口都是kube-proxy暴露

[root@swarm02 kubernates-installer]# netstat -nlp | grep 25887   
tcp6       0      0 :::25887                :::*                    LISTEN      9956/kube-proxy     
[root@swarm02 kubernates-installer]# curl 192.168.58.147:25887
<!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>

如果使用yaml方式发布service可以定义nodePort默认是随机的,如果觉得写yaml太难记只要知道意义可以
通过命令创建后 使用 -o yaml获取格式保存 比如之前定义的nginx
获取pods

[root@swarm01 kubernates]# kubectl get pods
NAME                   READY     STATUS    RESTARTS   AGE
nginx-8586cf59-p6zgx   1/1       Running   0          1h
[root@swarm01 kubernates]# kubectl get pods nginx-8586cf59-p6zgx -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: 2019-02-13T04:09:05Z
  generateName: nginx-8586cf59-
  labels:
    pod-template-hash: "41427915"
    run: nginx
  name: nginx-8586cf59-p6zgx
  namespace: default
  ownerReferences:
  - apiVersion: extensions/v1beta1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: nginx-8586cf59
    uid: 1ab808fe-2f45-11e9-951c-000c299075c5
  resourceVersion: "151962"
  selfLink: /api/v1/namespaces/default/pods/nginx-8586cf59-p6zgx
  uid: 1ac3537a-2f45-11e9-951c-000c299075c5
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: nginx
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
  dnsPolicy: ClusterFirst
  nodeName: 192.168.58.145
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  terminationGracePeriodSeconds: 30
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2019-02-13T04:09:06Z
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: 2019-02-13T04:10:45Z
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: 2019-02-13T04:09:06Z
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://ab0b2481313526692b23884a1a2dab9fd4ed11d621d417844cffb25bba167081
    image: nginx:latest
    imageID: docker-pullable://nginx@sha256:dd2d0ac3fff2f007d99e033b64854be0941e19a2ad51f174d9240dda20d9f534
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2019-02-13T04:10:44Z
  hostIP: 192.168.58.145
  phase: Running
  podIP: 172.20.105.69
  qosClass: BestEffort
  startTime: 2019-02-13T04:09:06Z

保存yaml

[root@swarm01 kubernates]# kubectl get pods nginx-8586cf59-p6zgx -o yaml>nginx-pods.yaml
[root@swarm01 kubernates]# more nginx-pods.yaml

参考这个模板稍作修改 (修改名字 label等)

apiVersion: v1
kind: Pod
metadata:
  nodeName: 192.168.58.145
  dnsPolicy: ClusterFirst
  schedulerName: default-scheduler
  securityContext: {}
  creationTimestamp: 2019-02-13T04:09:05Z
  generateName: nginx-8586cf59-
    pod-template-hash: "41427915"
apiVersion: v1
kind: Pod
metadata:
  labels:
    myapp: nginx
  name: nginx
  namespace: default
  ownerReferences:
  - apiVersion: extensions/v1beta1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: nginx-8586cf59
    uid: 1ab808fe-2f45-11e9-951c-000c299075c5
  resourceVersion: "151962"
  selfLink: /api/v1/namespaces/default/pods/nginx-8586cf59-p6zgx
  uid: 1ac3537a-2f45-11e9-951c-000c299075c5
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: nginx
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
  restartPolicy: Always

发布pod

[root@swarm01 kubernates]# kubectl create -f nginx-pods.yaml
pod "nginx" created

查看发布的nginx pod

[root@swarm01 kubernates]# kubectl get pods
NAME                   READY     STATUS    RESTARTS   AGE
nginx                  1/1       Running   0          15s

同理可以将通过命令(expose)创建的yaml导出保存

[root@swarm01 kubernates]# kubectl get svc nginx -o yaml               
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2019-02-13T04:29:38Z
  labels:
    run: nginx
  name: nginx
  namespace: default
  resourceVersion: "153318"
  selfLink: /api/v1/namespaces/default/services/nginx
  uid: f99d4da1-2f47-11e9-951c-000c299075c5
spec:
  clusterIP: 10.68.154.112
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 25887
    port: 8888
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

针对模块稍作修改(执行port和宿主机port[nodePort])
针对所有label是myapp=nginx的pod

apiVersion: v1
kind: Service
metadata:
  labels:
    run: nginx
  name: nginx
  namespace: default
spec:
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 20000
    port: 8888
    protocol: TCP
    targetPort: 80
  selector:
    myapp: nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

发布测试端口

[root@swarm01 kubernates]# kubectl create -f nginx-service.yaml
service "nginx" created
[root@swarm01 kubernates]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.68.0.1       <none>        443/TCP          12d
nginx        NodePort    10.68.154.112   <none>        8888:20000/TCP   7s
[root@swarm01 kubernates]# curl 192.168.58.145:20000
<!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>

演示使用kube-dns

kube-dns提供pod间通过名称访问的能力
创建一个pods

kubectl run eureka  --image=springcloud/eureka 

找到所在的机器

[root@swarm01 ~]# kubectl get pods -o wide
NAME                      READY     STATUS    RESTARTS   AGE       IP              NODE
eureka-5f8dd7ff49-55rc2   1/1       Running   0          15s       172.20.105.74   192.168.58.145
nginx                     1/1       Running   0          21m       172.20.105.70   192.168.58.145

进入58.145 找到容器id

[root@swarm02 ~]# docker ps -a
CONTAINER ID        IMAGE                                                        COMMAND                  CREATED             STATUS              PORTS               NAMES
ed48b6b7d5f2        springcloud/eureka                                           "java -jar /app.jar"     17 seconds ago      Up 15 seconds                           k8s_eureka_eureka-5f8dd7ff49-55rc2_default_80455bb8-2f57-11e9-951c-000c299075c5_0

进入容器内部

[root@swarm02 ~]# docker exec -it ed48b6b7d5f2 bash

执行
curl nginx:8888 访问
这里注意 这时pods间访问,应该是连接service的port 8888

root@eureka-5f8dd7ff49-55rc2:/# curl nginx:8888
<!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>

也可以使用宿主机ip访问20000端口

root@eureka-5f8dd7ff49-55rc2:/# curl 192.168.58.145:20000 
<!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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值