Kubernetes简介 Kubernetes 是 Google 团队发起的开源项目,它的目标是管理跨多个主机的容器,提供基本的部署,维护以及运用伸缩,主要实现语言为Go语言。Kubernetes 特性有:
易学:轻量级,简单,容易理解
便携:支持公有云,私有云,混合云,以及多种云平台
可拓展:模块化,可插拔,支持钩子,可任意组合
自修复:自动重调度,自动重启,自动复制
Kubernetes 构建于 Google 数十年经验,一大半来源于 Google 生产环境规模的经验。结合了社区最佳的想法和实践。在分布式系统中,部署,调度,伸缩一直是最为重要的也最为基础的功能。Kubernets 就是希望解决这一序列问题的。Kubernets 目前在GitHub进行维护。
目前,Kubenetes 支持在多种环境下的安装,包括本地主机(Fedora)、云服务(Google GAE、AWS 等)。然而最快速体验 Kubernetes 的方式显然是本地通过 Docker 的方式来启动相关进程。
下图展示了在单节点使用 Docker 快速部署一套 Kubernetes 的拓扑。
Minikube Minikube是一种工具,可以在本地轻松运行Kubernetes。 Minikube在笔记本电脑的VM中运行单节点Kubernetes集群,供那些希望尝试Kubernetes或者日常开发的用户使用,本节实验将基于Minikube来完成。
Minikube支持以下特性:
DNS
NodePorts
ConfigMaps and Secrets
Dashboards
Container Runtime: Docker, rkt, CRI-O and containerd
Enabling CNI (Container Network Interface)
Ingress
实验1. Minikube基本操作 1.1. 启动 Minikube 执行以下命令启动docker及minikube
1.2. 查看集群状态 可以使用kubectl CLI与集群进行交互。这是用于管理Kubernetes和在群集上运行的应用程序的主要方法。
可以通过以下方式发现群集及其运行状况的详细信息:
1 2 3 4 # kubectl cluster-info Kubernetes master is running at https://127.0.0.1:8443 To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
1.3. 查看集群节点 使用 kubectl get nodes 列出节点:
1 2 3 # kubectl get nodes NAME STATUS ROLES AGE VERSION 30b561aec9a2 Ready <none> 52s v1.8.0
如果节点标记为NotReady,则它仍在启动组件。此命令显示可用于托管应用程序的所有节点。现在我们只有一个节点,我们可以看到它的状态已准备好(它已准备好接受部署的应用程序)。
实验2. 通过 kubectl 部署容器 其群启动完成以后,可以使用 kubectl 进行部署容器操作
2.1 启动容器 执行以下命令启动一个nginx服务:
1 # kubectl run first-deployment --image=nginx:alpine --port=80
2.2 查看Pod状态 可以通过以下方式查看Pod状态:
1 2 3 4 # kubectl get pod NAME READY STATUS RESTARTS AGE first-deployment-84d55ddb97-pt6ws 1/1 Running 0 12s
当pod状态为 Running 时,说明 pod 启动完成,容器正在运行
2.3 暴漏服务端口 容器运行后,可以根据需要通过不同的网络选项进行暴露。 一种可能的解决方案是NodePort,它为容器提供动态端口:
1 # kubectl expose deployment first-deployment --port=80 --type=NodePort
如果节点标记为NotReady,则它仍在启动组件。此命令显示可用于托管应用程序的所有节点。现在我们只有一个节点,我们可以看到它的状态已准备好(它已准备好接受部署的应用程序)。
2.4 查找已分配的端口并执行HTTP请求 以下命令查找已分配的端口并执行HTTP请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # export PORT=$(kubectl get svc first-deployment -o go-template='{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}') # echo "$PORT" # curl localhost:$PORT <!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>
2.5 删除 nginx服务 1 2 # kubectl delete deploy/first-deployment deployment "first-deployment" deleted
实验3. 通过YAML文件部署容器 除了使用 kubectl 直接部署容器以外,还可以通过 YAML文件的方式部署容器。
3.1 创建 Deployment 最常见的Kubernetes对象之一是deployment对象。deployment对象定义了所需的容器规范,以及Kubernetes的其他部分用于发现和连接到应用程序的名称和标签。
查看 nginx-deployment.yaml 文件。该定义实现了基于nginx:alpine镜像启动容器,并开放容器的80端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # cat /k8s/nginx-deployment.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: webapp1 spec: replicas: 1 template: metadata: labels: app: webapp1 spec: containers: - name: webapp1 image: nginx:alpine ports: - containerPort: 80
使用以下命令部署 nginx-deployment.yaml
1 2 3 # cd /k8s # kubectl create -f nginx-deployment.yaml deployment "webapp1" created
查看deployment状态
1 2 3 # kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE webapp1 1 1 1 1 7s
查看详细信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # kubectl describe deployment webapp1 Name: webapp1 Namespace: default CreationTimestamp: Fri, 03 May 2019 14:07:14 +0000 Labels: app=webapp1 Annotations: deployment.kubernetes.io/revision=1 Selector: app=webapp1 Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 1 max unavailable, 1 max surge Pod Template: Labels: app=webapp1 Containers: webapp1: Image: katacoda/docker-http-server:latest Port: 80/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable OldReplicaSets: <none> NewReplicaSet: webapp1-65d887cc9f (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 56s deployment-controller Scaled up replica set webapp1-65d887cc9f to 1
3.2 创建 Service Kubernetes具有强大的网络功能,可控制应用程序的通信方式。 这些网络配置也可以通过YAML进行控制。
查看 nginx-service.yaml。该service将主机的30080端口映射到容器的80端口,服务选择标签为webapp1的所有应用程序。在部署多个副本或实例时,它们将根据此公共标签自动进行负载均衡。该服务通过NodePort提供应用服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # cat /k8s/nginx-service.yaml apiVersion: v1 kind: Service metadata: name: webapp1-svc labels: app: webapp1 spec: type: NodePort ports: - port: 80 nodePort: 30080 selector: app: webapp1
通过 kubectl 部署 service
1 2 # kubectl apply -f nginx-service.yaml service "webapp1-svc" created
查看 service 状态
1 2 3 4 5 # kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE first-deployment NodePort 10.99.229.208 <none> 80:30826/TCP 1m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3m webapp1-svc NodePort 10.110.18.126 <none> 80:30080/TCP 4s
查看 service 详细信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # kubectl describe svc webapp1-svc Name: webapp1-svc Namespace: default Labels: app=webapp1 Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"webapp1"},"name":"webapp1-svc","namespace":"default"},"spec":{"ports"... Selector: app=webapp1 Type: NodePort IP: 10.110.5.113 Port: <unset> 80/TCP TargetPort: 80/TCP NodePort: <unset> 30080/TCP Endpoints: 172.18.0.4:80 Session Affinity: None External Traffic Policy: Cluster Events: <none>
3.3 测试