本文使用自己利用VirtubalBox搭建的集群环境,暂时只有一个Master、一个Node。如果想了解集群的搭建,可以参考我的文章以及。
0. 目标
在命令行下使用 kubectl 命令创建并管理部署。
1. 检查环境
检查本地的环境信息。
[root@devops-101 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSIONdevops-101 Ready master 7h v1.11.1devops-102 Ready6h v1.11.1
2. 命令行方式创建部署
创建Tomcat部署,设置两个副本。
$ kubectl run docker.io/tomcat --replicas=2 --labels="app=tomcat" --image=docker.io/tomcat --port=8080deployment.apps/tomcat created[root@devops-101 ~]# kubectl get deploymentNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEtomcat 2 2 2 2 6m[root@devops-101 ~]# kubectl get podsNAME READY STATUS RESTARTS AGEtomcat-858b8c476d-vnm98 1/1 Running 0 6mtomcat-858b8c476d-xl5xl 1/1 Running 0 6m
创建部署之后,可以看到容器已经运行了,但是默认情况下,容器只能内部互相访问,如果需要对外提供服务,有以下几种方式:
- ClusterIP,默认的方式,通过集群IP来对外提供服务,这种方式只能在集群内部访问。
- NodePort,利用NAT技术在Node的指定端口上提供对外服务。外部应用通过:的方式访问。
- LoadBalancer,利用外部的负载均衡设施进行服务的访问。
- ExternalName,这是1.7版本之后 kube-dns 提供的功能。
2.1 端口映射,向外部暴露服务
在Kubernetes中Pod有其自己的生命周期,Node发生故障时,ReplicationController或者ReplicationSet会将Pod迁移到其他节点中以保持用户希望的状态。
[root@devops-101 ~]# kubectl expose deployment/tomcat --type="NodePort" --port 8080service/tomcat exposed
查看service被映射到哪个端口。
[root@devops-101 ~]# kubectl get serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1443/TCP 8htomcat NodePort 10.98.152.28 8080:32050/TCP 7s
因为知道被调度到了102节点,手工通过浏览器打开 http://192.168.0.102:32050
检查服务是否能够正常访问。
3. 基于YAML文件创建部署
首先编辑Yaml文件
apiVersion: v1kind: Podmetadata: #元数据信息 name: tomcat-c #kubectl get pods 和 登陆容器显示的名字 labels: #标签,可以作为查询条件 kubectl get pods -l app=tomcat node=devops-103spec: #规格 containers: #容器 - name: tomcat #容器名称 image: docker.io/tomcat #使用的镜像 ports: - containerPort: 8080 env: #设置env,登陆到容器中查看环境变量, DEME_GREETING 的值是 "hello from the enviroment" - name:GREETING value: "hello from the environment"
然后创建Pod。
[root@devops-101 ~]# kubectl create -f tomcat.yaml pod/tomcat-ccb created[root@devops-101 ~]# kubectl get podsNAME READY STATUS RESTARTS AGEtomcat-858b8c476d-vnm98 1/1 Running 2 21htomcat-858b8c476d-xl5xl 1/1 Running 3 21htomcat-ccb 1/1 Running 0 34s
4. 扩容部署
在扩容之前,我把devops-102节点也加入到集群中。
[root@devops-101 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSIONdevops-101 Ready master 9h v1.11.1devops-102 Ready8h v1.11.1devops-103 Ready 7h v1.11.1
然后再执行扩容动作。
[root@devops-101 ~]# kubectl scale deployments/tomcat --replicas=3deployment.extensions/tomcat scaled[root@devops-101 ~]# kubectl get deploymentsNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEtomcat 3 3 3 2 1h[root@devops-101 ~]# kubectl get podsNAME READY STATUS RESTARTS AGEtomcat-858b8c476d-cfrtt 0/1 ContainerCreating 0 2mtomcat-858b8c476d-vnm98 1/1 Running 0 1htomcat-858b8c476d-xl5xl 1/1 Running 0 1h[root@devops-101 ~]# kubectl describe pod tomcat-858b8c476d-cfrttName: tomcat-858b8c476d-cfrttNamespace: defaultNode: devops-103/192.168.0.103Start Time: Tue, 24 Jul 2018 18:29:51 +0800Labels: app=tomcat pod-template-hash=4146470328Annotations:Status: PendingIP: Controlled By: ReplicaSet/tomcat-858b8c476dContainers: tomcat: Container ID: Image: docker.io/tomcat Image ID: Port: 8080/TCP Host Port: 0/TCP State: Waiting Reason: ContainerCreating Ready: False Restart Count: 0 Environment: Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-trvqv (ro)Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True Volumes: default-token-trvqv: Type: Secret (a volume populated by a Secret) SecretName: default-token-trvqv Optional: falseQoS Class: BestEffortNode-Selectors: Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300sEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m default-scheduler Successfully assigned default/tomcat-858b8c476d-cfrtt to devops-103 Normal Pulling kubelet, devops-103 pulling image "docker.io/tomcat"
5. 缩容
[root@devops-101 ~]# kubectl scale deployments/tomcat --replicas=2deployment.extensions/tomcat scaled[root@devops-101 ~]# kubectl get podsNAME READY STATUS RESTARTS AGEtomcat-858b8c476d-vnm98 1/1 Running 0 1htomcat-858b8c476d-xl5xl 1/1 Running 0 1h
6. 标签功能
创建部署的时候,kubectl会自动帮我们打一个标签,这里是app=tomcat
。
[root@devops-101 ~]# kubectl describe deploymentName: tomcatNamespace: defaultCreationTimestamp: Tue, 24 Jul 2018 16:35:08 +0800Labels: app=tomcatAnnotations: deployment.kubernetes.io/revision=1Selector: app=tomcatReplicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailableStrategyType: RollingUpdateMinReadySeconds: 0RollingUpdateStrategy: 25% max unavailable, 25% max surgePod Template: Labels: app=tomcat Containers: tomcat: Image: docker.io/tomcat Port: 8080/TCP Host Port: 0/TCP Environment:Mounts: Volumes: Conditions: Type Status Reason ---- ------ ------ Progressing True NewReplicaSetAvailable Available True MinimumReplicasAvailableOldReplicaSets: NewReplicaSet: tomcat-858b8c476d (2/2 replicas created)Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 18m deployment-controller Scaled up replica set tomcat-858b8c476d to 3 Normal ScalingReplicaSet 4m deployment-controller Scaled down replica set tomcat-858b8c476d to 2
可以使用标签来查询资源,包括Pods和Services。
[root@devops-101 ~]# kubectl get pods -l app=tomcatNAME READY STATUS RESTARTS AGEtomcat-858b8c476d-vnm98 1/1 Running 0 1htomcat-858b8c476d-xl5xl 1/1 Running 0 1h[root@devops-101 ~]# kubectl get services -l app=tomcatNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEtomcat NodePort 10.98.152.288080:32050/TCP 1h
可以给Pods打上自定义的标签。
[root@devops-101 ~]# kubectl label --overwrite pod tomcat-858b8c476d-vnm98 node=devops-102# 这里用了--overwrite属性是因为之前标错了[root@devops-101 ~]# kubectl describe pods tomcat-858b8c476d-vnm98Name: tomcat-858b8c476d-vnm98Namespace: defaultNode: devops-102/192.168.0.102Start Time: Tue, 24 Jul 2018 16:35:08 +0800Labels: app=tomcat node=devops-102 pod-template-hash=4146470328Annotations:Status: RunningIP: 10.244.2.6Controlled By: ReplicaSet/tomcat-858b8c476dContainers: tomcat: Container ID: docker://9f3aa2d3d6c1937d4209a44820c1cd06f7eaf8796848c759e19410358aea4866 Image: docker.io/tomcat Image ID: docker-pullable://docker.io/tomcat@sha256:87ad70ceaafd5c71301b081b37ca2795bd6c7c1a5599a8c92c9447bbd225ae47 Port: 8080/TCP Host Port: 0/TCP State: Running Started: Tue, 24 Jul 2018 16:35:37 +0800 Ready: True Restart Count: 0 Environment: Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-trvqv (ro)Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-trvqv: Type: Secret (a volume populated by a Secret) SecretName: default-token-trvqv Optional: falseQoS Class: BestEffortNode-Selectors: Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300sEvents:
7. 删除部署
$ kubectl delete pod-name