设为首页 收藏本站
查看: 1259|回复: 0

[经验分享] kubernetes简单介绍和实战

[复制链接]

尚未签到

发表于 2018-9-15 11:29:47 | 显示全部楼层 |阅读模式
kubernetes简单介绍和实战
  在本文中,我们从技术细节上对kubernetes进行简单运用介绍,利用一些yaml脚本层面上实例告诉大家kubernetes基本概念。Kubernetes以及它呈现出的编程范式值得你去使用和整合到自己的技术栈中。

kubernetes简单介绍

kubernetes起源
  Kubernetes最初认为是谷歌开源的容器集群管理系统,是Google多年大规模容器管理技术Borg或Omega的开源版本。准确来说的话,kubernetes更是一个全新的平台,一个全新的
  平台管理工具,它是专门为job和service设计。完全开放,2014年6月开始接受公开的commit,任何人都可以提供意见。由于kubernetes简化了开发、运维和管理负荷,越来越多
  的企业开始在生产环境使用,因此kubernetes得到了迅速的发展。

kubernetes功能


  • 基于容器的应用部署、维护和滚动升级
  • 负载均衡和服务发现
  • 跨机器和跨地区的集群调度
  • 自动伸缩
  • 无状态服务和有状态服务
  • 广泛的Volume支持
  • 插件机制保证扩展性
kubernetes核心组件
  Kubernetes主要由以下几个核心组件组成:


  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡
kubernetes环境部署
  如果只是为了了解kubernetes,可以使用minikube的方式进行单机安装,minikube 实际就是本地创建了一个虚拟机,里面运行了kubernetes 的一些必要的环境,相当于 k8s 的服务环境,创建 pod,service,deployment等都是在里面进行创建和管理。
  在本文中,我使用kubeadm方式安装kubernetes 1.10.0,具体kubernetes部署步骤:


  • 使用kubeadm方式安装kubernetes 1.10.0
  • Kubernetes集群添加/删除Node
  • Kubernetes Dashboard1.8.3部署
  • k8s原生的集群监控方案(Heapster+InfluxDB+Grafana)
  请注意:上述环境只是测试环境,生产环境部署大同小异。

kubernetes基本概念

Container
  Container(容器)是一种便携式、轻量级的操作系统级虚拟化技术。它使用 namespace 隔离不同的软件运行环境,并通过镜像自包含软件的运行环境,
  从而使得容器可以很方便的在任何地方运行。由于容器体积小且启动快,因此可以在每个容器镜像中打包一个应用程序。这种一对一的应用镜像关系拥有很多好处。使用容器,
  不需要与外部的基础架构环境绑定, 因为每一个应用程序都不需要外部依赖,更不需要与外部的基础架构环境依赖。完美解决了从开发到生产环境的一致性问题。
  容器同样比虚拟机更加透明,这有助于监测和管理。尤其是容器进程的生命周期由基础设施管理,而不是由容器内的进程对外隐藏时更是如此。最后,
  每个应用程序用容器封装,管理容器部署就等同于管理应用程序部署。
  在 Kubernetes 必须要使用 Pod 来管理容器,每个 Pod 可以包含一个或多个容器。

Pod

关于Pod的概念主要有以下几点:


  • Pod是kubernetes中你可以创建和部署的最小也是最简的单位。一个Pod代表着集群中运行的一个进程;
  • 在Kubrenetes集群中Pod的使用方式;
  • Pod中如何管理多个容器
理解Pod:
  上面已经说了“Pod是kubernetes中你可以创建和部署的最小也是最简的单位。一个Pod代表着集群中运行的一个进程。”Pod中封装着应用的容器(有的情况下是好几个容器),
  存储、独立的网络IP,管理容器如何运行的策略选项。Pod代表着部署的一个单位:kubernetes中应用的一个实例,可能由一个或者多个容器组合在一起共享资源。
  请注意:Docker是kubernetes中最常用的容器运行时,但是Pod也支持其他容器运行时。

Kubrenetes集群中Pod的两种使用方式:
  (1)一个Pod中运行一个容器
  “每个Pod中一个容器”的模式是最常见的用法;在这种使用方式中,你可以把Pod想象成是单个容器的封装,kuberentes管理的是Pod而不是直接管理容器。

实战:创建一个nginx容器
  

apiVersion: v1  
kind: Pod
  
metadata:
  name: nginx-test
  labels:
  app: web
  
spec:
  containers:
  - name: front-end
  image: nginx:1.7.9
  ports:
  - containerPort: 80
  

创建Pod:  
kubectl create -f ./pod1-deployment\
  
查看Pod:
  
kubectl get po
  
查看Pod详细情况:
  
kubectl describe po nginx-test
  
进入到Pod(容器)内部:
  
kubectl exec -it nginx-test  /bin/bash
  

  (2)在一个Pod中同时运行多个容器
  说明:在一个Pod中同时运行多个容器是一种比较高级的用法。只有当你的容器需要紧密配合协作的时候才考虑用这种模式。
  一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位——一个容器共享文件,
  另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。

实战:在一个pod里放置两个容器:nginx与redis
  

apiVersion: v1  
kind: Pod
  
metadata:
  name: rss-site
  labels:
  app: web
  
spec:
  containers:
  - name: front-end
  image: nginx:1.7.9
  ports:
  - containerPort: 80
  - name: rss-reader
  image: redis
  ports:
  - containerPort: 88
  

创建Pod:  
kubectl create -f ./test-deployment
  
查看pod
  
kubectl get po
  
查看Pod详细情况
  
kubectl describe po rss-site
  
进入front-end内部:
  
kubectl exec -it rss-site  -c front-end /bin/bash
  
进入rss-reade内部:
  
kubectl exec -it rss-site  -c rss-reader  /bin/bash
  

  以上是关于Pod的简单介绍,如需了解更多,请参考Pod

Node
  Node 是 Pod 真正运行的主机,可以物理机,也可以是虚拟机。为了管理 Pod,每个 Node 节点上至少要运行 container runtime(比如 docker 或者 rkt)、kubelet 和 kube-proxy 服务。

Namespace
  Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services, replication controllers 和 deployments 等都是属于
  某一个 namespace 的(默认是 default),而 node, persistentVolumes 等则不属于任何 namespace。

Deployment
  我们既然有Pod了,为什么还要使用Deployment呢?这是因为实际工作中,我们很少会直接在kubernetes中创建单个Pod。因为Pod的生命周期是短暂的,用后即焚的实体。
  Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController 来方便的管理应用。
  你只需要在 Deployment 中描述想要的目标状态是什么,Deployment controller 就会帮你将 Pod 和ReplicaSet 的实际状态改变到你的目标状态。你可以定义一个全新的 Deployment 来创建
  ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。

什么是复制控制器(Replication Controller,RC)
  RC是K8s集群中最早的保证Pod高可用的API对象。通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;
  多于指定数目,RC就会杀死多余的Pod副本。即使在指定数目为1的情况下,通过RC运行Pod也比直接运行Pod更明智,因为RC也可以发挥它高可用的能力,保证永远有1个Pod在运行。RC是K8s较早期
  的技术概念,只适用于长期伺服型的业务类型,比如控制小机器人提供高可用的Web服务。

什么是副本集(Replica Set,RS)
  RS是新一代RC,提供同样的高可用能力,区别主要在于RS后来居上,能支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用。

Deployment典型的应用场景


  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用;如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision
  • 扩容和缩容,扩容Deployment以满足更高的负载
  • 暂停和继续Deployment,暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线
实战Deployment
  比如,我们这里定义一个简单的nginx应用:
  

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

创建deploy  
kubectl create -f ./nginx-deployment
  
查看deploy
  
kubectl get deploy --namespace=test
  
查看rs(副本集)
  
kubectl get rs --namespace=test
  
查看pods(容器组)
  
kubectl get po --namespace=test
  

  关于Deployment的应用还有很多,如:扩容、缩容、滚动升级、回滚应用等,这里由于篇幅的问题不再一一介绍,详见Deployment的应用

Label
  Label 是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上(key 最长不能超过 63 字节,value 可以为空,也可以是不超过 253 字节的字符串)。
  Label 不提供唯一性,并且实际上经常是很多对象(如 Pods)都使用相同的 label 来标志具体的应用。
  Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如 ReplicaSet 和 Service 用 label 来选择一组 Pod)。Label Selector 支持以下几种方式:


  • 等式,如 app=nginx 和 env!=production
  • 集合,如 env in (production, qa)
  • 多个 label(它们之间是 AND 关系),如 app=nginx,env=test
Service Account

Service account作用
  Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务。

Service account使用场景
  运行在pod里的进程需要调用Kubernetes API以及非Kubernetes API的其它服务。Service Account它并不是给kubernetes集群的用户使用的,而是给pod里面的进程使用的,它为pod提供必要的身份认证。

与User account区别


  • User account是为人设计的,而service account则是为了Pod中的进程
  • User account是跨namespace的,而service account则是仅局限它所在的namespace
实战命名空间
  

apiVersion: v1  
kind: Namespace
  
metadata:
  name: datagrand
  labels:
  name: test
  

创建namespace:test  
kubectl create -f ./test.yaml
  
查看命名空间test的sa
  
kubectl get sa -n test
  
查看命名空间test生成的default
  
kubectl get sa default -o yaml -n test
  
我们可以创建Deployment时,使用这个test命名空间了,如上例Deployment实战。
  

Service Account鉴权
  Service Account为服务提供了一种方便的认知机制,但它不关心授权的问题。可以配合RBAC来为Service Account鉴权:


  • 配置--authorization-mode=RBAC和--runtime-config=rbac.authorization.k  8s.io/v1alpha1

  • 配置--authorization-rbac-super-user=admin
  • 定义Role、ClusterRole、RoleBinding或ClusterRoleBinding
实战鉴权
  我们在Kubernetes Dashboard1.8.3部署中,碰到首次登入出现访问权限报错的问题,原因就是ServiceAccount的创建问题。
  

apiVersion: rbac.authorization.k8s.io/v1beta1  
kind: ClusterRoleBinding
  
metadata:
  name: kubernetes-dashboard
  labels:
  k8s-app: kubernetes-dashboard
  
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
  
subjects:
  - kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system
  

  Service Account介绍请参考博文

Secret

Secret介绍
  Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。

Secret类型


  • Opaque(default):任意字符串,base64编码格式的Secret,用来存储密码、密钥等
  • kubernetes.io/service-account-token:作用于ServiceAccount,就是kubernetes的Service Account中所说的。 即用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中
  • kubernetes.io/dockercfg: 作用于Docker registry,用户下载docker镜像认证使用。用来存储私有docker registry的认证信息
实战Opaque Secret类型
  

Opaque类型的数据是一个map类型,要求value是base64编码格式:  
创建admin账户
  
echo -n "admin" | base64
  
YWRtaW4=
  
echo -n "1f2d1e2e67df" | base64
  
MWYyZDFlMmU2N2Rm
  

创建secret.yaml  
cat >> secrets.yml   限于篇幅问题,我这里简单说一下emptyDir、nfs、PV和PVC。

实战--emptyDir

emptyDir说明
  EmptyDir类型的volume创建于pod被调度到某个宿主机上的时候,而同一个pod内的容器都能读写EmptyDir中的同一个文件。一旦这个pod离开了这个宿主机,EmptyDir中的数据就会被永久删除。所以目前EmptyDir类型的volume主要用作临时空间,比如Web服务器写日志或者tmp文件需要的临时目录。
  

apiVersion: v1  
kind: Pod
  
metadata:
  labels:
  name: test-emptypath
  role: master
  name: test-emptypath
  
spec:
  containers:
  - name: test-emptypath
  image: nginx:1.7.9
  volumeMounts:
  - name: log-storage
  mountPath: /tmp/
  volumes:
  - name: log-storage
  emptyDir: {}
  

实战使用共享卷的标准多容器Pod
  

apiVersion: v1  
kind: Pod
  
metadata:
  name: datagrand
  
spec:
  containers:
  - name: test1
  image: nginx:1.7.9
  volumeMounts:
  - name: log-storage
  mountPath: /usr/share/nginx/html
  - name: test2
  image: centos
  volumeMounts:
  - name: log-storage
  mountPath: /html
  command: ["/bin/sh","-c"]
  args:
  - while true;do
  data >> /html/index.html;
  sleep 1;
  done
  volumes:
  - name: log-storage
  emptyDir: {}
  

  简单解释下上面的内容:
  在这个例子中,我们定义了一个名为HTML的卷。它的类型是emptyDir,这意味着当一个Pod被分配到一个节点时,卷先被创建,并只要Pod在节点上运行时,这个卷仍存在。正如名字所说,它最初是空的。第一容器运行nginx的
  服务器并将共享卷挂载到目录/ usr /share/ nginx /html。第二容器使用centos的镜像,并将共享卷挂载到目录/HTML。每一秒,第二容器添加当前日期和时间到index.html文件中,它位于共享卷。当用户发出一个HTTP请求到Pod,
  nginx的服务器读取该文件并将其传递给响应请求的用户。
  更多volume实战,详见Kubernetes部分Volume类型介绍及yaml示例--emptyDir

实战--NFS卷

NFS卷说明
  nfs 卷允许将现有的 NFS(网络文件系统)共享挂载到你的容器中。不像 emptyDir,当删除 Pod 时,nfs 卷的内容被保留,卷仅仅是被卸载。这意味着 NFS 卷可以预填充数据,并且可以在 pod 之间“切换”数据。 NFS 可以被多个写入者同时挂载。

NFS卷使用注意


  • 请先部署好自己的NFS服务
  • 在使用共享之前,必须运行自己的NFS服务器并运行共享
实战pod内的文件共享
  

apiVersion: v1  
kind: Pod
  
metadata:
  name: nginx-test
  labels:
  app: nginx
  
spec:
  containers:
  - name: nginx
  image: nginx:1.7.9
  ports:
  - containerPort: 80
  volumeMounts:
  #Mount the path to the container
  - mountPath: "/tmp/"
  name: pv0003
  volumes:
  - name: pv0003
  nfs:
  #fixed:This ip is the address of the nfs server
  server: 192.168.246.169
  #fixed:This path is shared externally by the nfs server
  path: "/data"
  

  更多volume实战,详见Kubernetes部分Volume类型介绍及yaml示例--NFS(网络数据卷)

实战PV和PVC
  nfs 作为 k8s 的网络存储驱动,可以满足持久存储业务的需求,支持多节点读写。下面是两个Pod同时使用一个持久性volume实例。
  

#创建PV  
apiVersion: v1
  
kind: PersistentVolume
  
metadata:
  name: nfs-pv
  
spec:
  capacity:
  storage: 4Gi
  accessModes:
  - ReadWriteMany
  nfs:
  server: 192.168.246.168  ##NFS服务器的ip地址
  path: "/data"  ##NFS服务器上的共享目录
  

#创建PVC  
apiVersion: v1
  
kind: PersistentVolumeClaim
  
metadata:
  name: nfs-pvc
  
spec:
  accessModes:
  - ReadWriteMany
  storageClassName: ""
  resources:
  requests:
  storage: 3Gi
  

#创建Deployment  
apiVersion: apps/v1
  
kind: Deployment
  
metadata:
  name: nginx-deployment
  labels:
  app: nginx
  
spec:
  replicas: 2
  selector:
  matchLabels:
  app: nginx
  template:
  metadata:
  labels:
  app: nginx
  spec:
  containers:
  - name: nginx
  image: nginx:1.7.9
  volumeMounts:
  - mountPath: "/wtf"
  name: datadir
  volumes:
  - name: datadir
  persistentVolumeClaim:
  claimName: nfs-pvc
  

  更多PV和PVC实战,详见实战kubernetes持久性卷使用

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

什么是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。

定义Service

有selector的单端口Service
  一个 Service 在 Kubernetes 中是一个 REST 对象,和 Pod 类似。 像所有的 REST 对象一样, Service 定义可以基于 POST 方式,请求 apiserver 创建新的实例。 例如,假定有一组 Pod,它们对外暴露了 9376 端口,同时还被打上 "app=MyApp" 标签。
  

kind: Service  
apiVersion: v1
  
metadata:
  name: my-service
  
spec:
  selector:
  app: MyApp
  ports:
  - protocol: TCP
  port: 80
  targetPort: 9376
  

  上述配置将创建一个名称为 “my-service” 的 Service 对象,它会将请求代理到使用 TCP 端口 9376,并且具有标签 "app=MyApp" 的 Pod 上。 这个 Service 将被指派一个 IP 地址(通常称为 “Cluster IP”),它会被服务的代理使用(见下面)。 该 Service 的 selector 将会持续评估,处理结果将被 POST 到一个名称为 “my-service” 的 Endpoints 对象上。
  需要注意的是, Service 能够将一个接收端口映射到任意的 targetPort。 默认情况下,targetPort 将被设置为与 port 字段相同的值。 可能更有趣的是,targetPort 可以是一个字符串,引用了 backend Pod 的一个端口的名称。 但是,实际指派给该端口名称的端口号,在每个 backend Pod 中可能并不相同。 对于部署和设计 Service ,这种方式会提供更大的灵活性。 例如,可以在 backend 软件下一个版本中,修改 Pod 暴露的端口,并不会中断客户端的调用。
  Kubernetes Service 能够支持 TCP 和 UDP 协议,默认 TCP 协议。

有selector的多端口Service
  很多 Service 需要暴露多个端口。对于这种情况,Kubernetes 支持在 Service 对象中定义多个端口。 当使用多个端口时,必须给出所有的端口的名称,这样 Endpoint 就不会产生歧义,例如:
  

kind: Service  
apiVersion: v1
  
metadata:
  name: my-service
  
spec:
  selector:
  app: MyApp
  ports:
  - name: http
  protocol: TCP
  port: 80
  targetPort: 9376
  - name: https
  protocol: TCP
  port: 443
  targetPort: 9377
  

没有 selector 的 Service
  Service 抽象了该如何访问 Kubernetes Pod,但也能够抽象其它类型的 backend,例如:


  • 希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。
  • 希望服务指向另一个 Namespace 中或其它集群中的服务。
  • 正在将工作负载转移到 Kubernetes 集群,和运行在 Kubernetes 集群之外的 backend。
  根据以上的应用场景,我们都能够定义没有selector的Service,如下:
  

kind: Service  
apiVersion: v1
  
metadata:
  name: my-service
  
spec:
  ports:
  - protocol: TCP
  port: 80
  targetPort: 9376
  

  由于这个 Service 没有 selector,就不会创建相关的 Endpoints 对象。可以手动将 Service 映射到指定的 Endpoints:
  

kind: Endpoints  
apiVersion: v1
  
metadata:
  name: my-service
  
subsets:
  - addresses:
  - ip: 10.0.0.3  ##Endpoint IP = PodIP + ContainerPort
  ports:
  - port: 9376
  

  注意:Endpoint IP 地址不能是 loopback(127.0.0.0/8)、 link-local(169.254.0.0/16)、或者 link-local 多播(224.0.0.0/24)。
  访问没有 selector 的 Service,与有 selector 的 Service 的原理相同。请求将被路由到用户定义的 Endpoint(该示例中为 10.0.0.3:9376)。

发布服务 —— 服务类型
  对一些应用(如 Frontend)的某些部分,可能希望通过外部(Kubernetes 集群外部)IP 地址暴露 Service。
  Kubernetes ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。
  Type 的取值以及行为如下:


  • ClusterIP 通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
  • NodePort 通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。
  • LoadBalancer 使用云提供商的负载均衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
  • ExternalName 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。 没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。
NodePort 类型
  如果设置 type 的值为 "NodePort",Kubernetes master 将从给定的配置范围内(默认:30000-32767)分配端口,每个 Node 将从该端口(每个 Node 上的同一端口)代理到 Service。该端口将通过 Service 的 spec.ports
  • .nodePort 字段被指定。
      如果需要指定的端口号,可以配置 nodePort 的值,系统将分配这个端口,否则调用 API 将会失败(比如,需要关心端口冲突的可能性)。

    kubernetes实战--edusoho平台创建

    文件目录结构
      

    # pwd  
    /data
      
    # tree -L 3
      
    .
      
    ├── mysql
      
    │   ├── conf
      
    │   │   └── my.cnf
      
    │   └── data
      
    │       ├── auto.cnf
      
    │       ├── edusoho
      
    │       ├── ibdata1
      
    │       ├── ib_logfile0
      
    │       ├── ib_logfile1
      
    │       ├── mysql
      
    │       └── performance_schema
      
    ├── nginx
      
    │   ├── conf
      
    │   │   └── nginx.conf
      
    │   ├── edusoho
      
    │   │   ├── api
      
    │   │   ├── app
      
    │   │   ├── bootstrap
      
    │   │   ├── plugins
      
    │   │   ├── src
      
    │   │   ├── vendor
      
    │   │   ├── vendor_user
      
    │   │   └── web
      
    │   └── log
      
    │       └── error.log
      
    ├── php
      
    │   ├── log
      
    │   │   └── php-fpm.log
      
    │   ├── php-fpm.conf
      
    │   ├── php.ini
      
    │   └── www.conf
      

    Pod的yaml文件
      

    apiVersion: v1  
    kind: Pod
      
    metadata:
      name: lamp-edusoho
      labels:
      app: lamp-edusoho
      
    restartPolicy: Always
      
    spec:
      containers:
      - name: nginx
      abels:
      app: lamp-nginx
      image: dockerhub.datagrand.com/global/nginx:v1
      ports:
      - containerPort: 80
      volumeMounts:
      - name: datadir
      mountPath: "/var/log/nginx/error.log"
      subPath: ./nginx/log/error.log
      - name: datadir
      mountPath: "/etc/nginx/nginx.conf"
      subPath: ./nginx/conf/nginx.conf
      - name: datadir
      mountPath: "/usr/share/nginx/html"
      subPath: ./nginx/edusoho
      - name: php
      image: dockerhub.datagrand.com/global/php:v1
      ports:
      - containerPort: 9000
      volumeMounts:
      - mountPath: /usr/local/php/etc/php-fpm.conf
      name: datadir
      subPath: ./php/php-fpm.conf
      - mountPath: /usr/local/php/etc/php-fpm.d/www.conf
      name: datadir
      subPath: ./php/www.conf
      - mountPath: /usr/local/php/etc/php.ini
      name: datadir
      subPath: ./php/php.ini
      - mountPath: /usr/local/php/var/log/php-fpm.log
      name: datadir
      subPath: ./php/log/php-fpm.log
      - mountPath: /usr/share/nginx/html
      name: datadir
      subPath: ./nginx/edusoho
      - name: mysql
      image: dockerhub.datagrand.com/global/mysql:5.6
      ports:
      - containerPort: 3306
      env:
      - name: MYSQL_ROOT_PASSWORD
      value: "123456"
      - name: MYSQL_DATABASE
      value: "edusoho"
      - name: MYSQL_USER
      value: "edusoho"
      - name: MYSQL_PASSWORD
      value: "edusoho"
      args: ['--character-set-server=utf8']
      volumeMounts:
      - name: datadir
      mountPath: "/var/lib/mysql"
      subPath: ./mysql/data
      - name: datadir
      mountPath: "/etc/my.cnf"
      subPath: ./mysql/conf/my.cnf
      volumes:
      - name: datadir
      persistentVolumeClaim:
      claimName: nfs-pvc
      

    PV的yaml文件
      

    apiVersion: v1  
    kind: PersistentVolume
      
    metadata:
      name: nfs-pv
      
    spec:
      capacity:
      storage: 4Gi
      accessModes:
      - ReadWriteMany
      nfs:
      server: 192.168.246.168  ##NFS服务器的ip地址
      path: "/data"  ##NFS服务器上的共享目录
      

    PVC的yaml文件
      

    apiVersion: v1  
    kind: PersistentVolumeClaim
      
    metadata:
      name: nfs-pvc
      
    spec:
      accessModes:
      - ReadWriteMany
      storageClassName: ""
      resources:
      requests:
      storage: 3Gi
      

    Service的yaml文件
      

    apiVersion: v1  
    kind: Service
      
    metadata:
      name: edusoho
      labels:
      app: edusoho
      
    spec:
      type: NodePort
      ports:
      - port: 80
      nodePort: 32756
      selector:
      app: lamp-edusoho
      

    命令汇总
      

    查看Pod  
    kubectl get po -o wide
      
    查看Service
      
    kubectl get svc
      
    进入容器内部某个应用,如这里的nginx
      
    kubectl exec -it lamp-edusoho -c nginx /bin/bash
      

    访问安装Edusoho平台
      

    http://192.168.246.168:32756/install/start-install.php  
    说明:这里的192.168.246.168是kubernetes的node节点IP,32756是Service中定义的nodePort。
      

    参考文档


    • kubernetes概念--Service
    • kubernetes 官网教程
    • Kubernetes中的Persistent Volume解析



  • 运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
    2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
    3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
    4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
    5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
    6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
    7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
    8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

    所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-583352-1-1.html 上篇帖子: centos7 使用二进制包搭建kubernetes 1.11 集群 下篇帖子: 如何构建Kubernetes CI/CD流水线
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码加入运维网微信交流群X

    扫码加入运维网微信交流群

    扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

    扫描微信二维码查看详情

    客服E-mail:kefu@iyunv.com 客服QQ:1061981298


    QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


    提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


    本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



    合作伙伴: 青云cloud

    快速回复 返回顶部 返回列表