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主要由以下几个核心组件组成(必须安装):


etcd保存了整个集群的状态;

apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;

controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;

scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;

kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理,安装每台工作节点;

kube-proxy负责为Service提供cluster内部的服务发现和负载均衡,安装在每台工作节点;

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


kube-dns负责为整个集群提供DNS服务,应该使用kubectl添加一个服务到容器,是一个发布的应用服务于

Ingress Controller为服务提供外网入口

Heapster提供资源监控

Dashboard提供GUI

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

Node

Namespace

Service

Volume

PersistentVolume

Deployment

Secret

StatefulSet

DaemonSet

ServiceAccount

ReplicationController

ReplicaSet

Job

CronJob

SecurityContext

ResourceQuota

LimitRange

HorizontalPodAutoscaling

Ingress

ConfigMap

Label

ThirdPartyResources

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


类别名称

资源对象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>


点赞(1377)

评论列表共有 0 条评论

立即
投稿
返回
顶部