前言
既然k8s集群机已经搭建好,那就要试用一下,在dashboard的工作负载中没有任何东西,点击现在就部署容器应用,进入官方文档链接,就是本文所要做的事情。
目标
- 创建一个nginx deployment
- 用kubectl列出此deployment的一些信息
- 更新deployment
- 把程序发布出去,在宿主机能够访问
开始之前
在开始之前,已经搭建了一个k8s集群,搭建集群链接在fedora server 28上基于Kubeadm搭建Kubernetes v1.10.3全记录,并且在命令行中kubectl可以与集群进行交互。
k8s服务器版本必须是v1.9或者更高,可以使用 kubectl version -o yaml 查看版本。
[wangxianfeng@k8s-m1 ~]$ kubectl version -o yaml
clientVersion:
buildDate: 2018-05-21T09:17:39Z
compiler: gc
gitCommit: 2bba0127d85d5a46ab4b778548be28623b32d0b0
gitTreeState: clean
gitVersion: v1.10.3
goVersion: go1.9.3
major: "1"
minor: "10"
platform: linux/amd64
serverVersion:
buildDate: 2018-05-21T09:05:37Z
compiler: gc
gitCommit: 2bba0127d85d5a46ab4b778548be28623b32d0b0
gitTreeState: clean
gitVersion: v1.10.3
goVersion: go1.9.3
major: "1"
minor: "10"
platform: linux/amd64
创建并开放一个nginx deployment
可以用k8s Deployment运行一个应用程序,可以用YAML文件定义一个Deployment,以下文件用一个YAML文件定义了一个nginx docker镜像:
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template: # create pods using pod definition in this template
metadata:
# unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is
# generated from the deployment name
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent #或者使用Never,默认Always
ports:
- containerPort: 80
保存文件名为deployment.yaml
用yaml文件创建一个Deployment
$ kubectl apply -f deployment.yaml
deployment.apps "nginx-deployment" created
列出此Deployment的一些信息
kubectl describe deployment nginx-deployment
输出如下:
[wangxianfeng@k8s-m1 k8s]$ kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sat, 26 May 2018 04:34:25 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision=1
kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},"spec":{"replicas":2,"selecto...
Selector: app=nginx
Replicas: 2 desired | 2 updated | 2 total | 0 available | 2 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-666865b5dd (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 1m deployment-controller Scaled up replica set nginx-deployment-666865b5dd to 2
列出此deployment创建的pods
kubectl get pods -l app=nginx
输出如下:
[wangxianfeng@k8s-m1 k8s]$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-666865b5dd-89d45 0/1 Pending 0 4m
nginx-deployment-666865b5dd-kwl5t 0/1 Pending 0 4m
pod的状态为Pending
列出pod的信息
kubectl describe pod nginx-deployment-666865b5dd-89d45
nginx-deployment-666865b5dd-89d45 为上边列出的pod中的一个。
输出如下:
[wangxianfeng@k8s-m1 k8s]$ kubectl describe pod nginx-deployment-666865b5dd-89d45
Name: nginx-deployment-666865b5dd-89d45
Namespace: default
Node: <none>
Labels: app=nginx
pod-template-hash=2224216188
Annotations: <none>
Status: Pending
IP:
Controlled By: ReplicaSet/nginx-deployment-666865b5dd
Containers:
nginx:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-dqzwh (ro)
Conditions:
Type Status
PodScheduled False
Volumes:
default-token-dqzwh:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-dqzwh
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 36s (x26 over 6m) default-scheduler 0/2 nodes are available: 2 node(s) had taints that the pod didn't tolerate.
得到错误信息如下:
0/2 nodes are available: 2 node(s) had taints that the pod didn't tolerate.
搜索此错误信息,也有人问过这个问题:
Kubeadm and the Risks of Scheduling Pods on Master Node (Pods always Pending)
运行以下命令可以解决:
kubectl taint nodes --all node-role.kubernetes.io/master-
但是,带来了一个问题,就是在master节点上运行节工作负载。先不考虑,那么多了,先运行起来再说吧。
[wangxianfeng@k8s-m1 k8s]$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-666865b5dd-89d45 1/1 Running 0 29m
nginx-deployment-666865b5dd-kwl5t 1/1 Running 0 29m
现在状态全部都是running了。对比以下pod的输出(pod的2个副本一个在k8s-m1上,一个在k8s-n1上):
k8s-m1上的pod信息:
[wangxianfeng@k8s-m1 k8s]$ kubectl describe pod nginx-deployment-666865b5dd-kwl5t
Name: nginx-deployment-666865b5dd-kwl5t
Namespace: default
Node: k8s-m1/192.168.2.186
Start Time: Sat, 26 May 2018 04:52:55 +0800
Labels: app=nginx
pod-template-hash=2224216188
Annotations: <none>
Status: Running
IP: 10.244.0.4
Controlled By: ReplicaSet/nginx-deployment-666865b5dd
Containers:
nginx:
Container ID: docker://9aa9847e92dbeea296e5ba7872a391325d1c4800ff1ae0e426b993686ea67695
Image: nginx
Image ID: docker-pullable://nginx@sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sat, 26 May 2018 04:53:37 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-dqzwh (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-dqzwh:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-dqzwh
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 15m (x57 over 30m) default-scheduler 0/2 nodes are available: 2 node(s) had taints that the pod didn't tolerate.
Normal SuccessfulMountVolume 12m kubelet, k8s-m1 MountVolume.SetUp succeeded for volume "default-token-dqzwh"
Normal Pulling 12m kubelet, k8s-m1 pulling image "nginx"
Normal Pulled 11m kubelet, k8s-m1 Successfully pulled image "nginx"
Normal Created 11m kubelet, k8s-m1 Created container
Normal Started 11m kubelet, k8s-m1 Started container
k8s-n1上的pod信息:
[wangxianfeng@k8s-m1 k8s]$ kubectl describe pod nginx-deployment-666865b5dd-89d45
Name: nginx-deployment-666865b5dd-89d45
Namespace: default
Node: k8s-n1/192.168.2.189
Start Time: Sat, 26 May 2018 04:52:57 +0800
Labels: app=nginx
pod-template-hash=2224216188
Annotations: <none>
Status: Running
IP: 10.244.1.4
Controlled By: ReplicaSet/nginx-deployment-666865b5dd
Containers:
nginx:
Container ID: docker://504e8bc1a6231655644c497e7a132fb6465d916fe459b5937ee53c800af54be8
Image: nginx
Image ID: docker-pullable://nginx@sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sat, 26 May 2018 04:53:35 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-dqzwh (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-dqzwh:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-dqzwh
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 18m (x57 over 33m) default-scheduler 0/2 nodes are available: 2 node(s) had taints that the pod didn't tolerate.
Normal SuccessfulMountVolume 15m kubelet, k8s-n1 MountVolume.SetUp succeeded for volume "default-token-dqzwh"
Normal Pulling 15m kubelet, k8s-n1 pulling image "nginx"
Normal Pulled 14m kubelet, k8s-n1 Successfully pulled image "nginx"
Normal Created 14m kubelet, k8s-n1 Created container
Normal Started 14m kubelet, k8s-n1 Started container
更新deployment
可以用一个新的YAML文件更新一个deployment,复制deployment.yaml文件为deployment_update.yaml,编辑deployment_update.yaml文件,更新nginx镜像版本为1.8
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template: # create pods using pod definition in this template
metadata:
# unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is
# generated from the deployment name
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8 # Update the version of nginx to 1.8
ports:
- containerPort: 80
应用更新
[wangxianfeng@k8s-m1 k8s]$ kubectl apply -f deployment_update.yaml
deployment.apps "nginx-deployment" configured
查看deployment新创建的pods信息
kubectl get pods -l app=nginx
输出如下:
[wangxianfeng@k8s-m1 k8s]$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-cf7f48d4c-dchd7 1/1 Running 0 1m
nginx-deployment-cf7f48d4c-m4hg4 1/1 Running 0 1m
查看一个详细的信息:
[wangxianfeng@k8s-m1 k8s]$ kubectl describe pod nginx-deployment-cf7f48d4c-dchd
Name: nginx-deployment-cf7f48d4c-dchd7
Namespace: default
Node: k8s-n1/192.168.2.189
Start Time: Sat, 26 May 2018 05:17:35 +0800
Labels: app=nginx
pod-template-hash=793904807
Annotations: <none>
Status: Running
IP: 10.244.1.5
Controlled By: ReplicaSet/nginx-deployment-cf7f48d4c
Containers:
nginx:
Container ID: docker://79e4a3ec93024455130ceaeb8babd3e6be3221f4a044f8f1b7695a59d279fd60
Image: nginx:1.8
Image ID: docker-pullable://nginx@sha256:c97ee70c4048fe79765f7c2ec0931957c2898f47400128f4f3640d0ae5d60d10
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sat, 26 May 2018 05:18:21 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-dqzwh (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-dqzwh:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-dqzwh
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 1m default-scheduler Successfully assigned nginx-deployment-cf7f48d4c-dchd7 to k8s-n1
Normal SuccessfulMountVolume 1m kubelet, k8s-n1 MountVolume.SetUp succeeded for volume "default-token-dqzwh"
Normal Pulling 1m kubelet, k8s-n1 pulling image "nginx:1.8"
Normal Pulled 1m kubelet, k8s-n1 Successfully pulled image "nginx:1.8"
Normal Created 1m kubelet, k8s-n1 Created container
Normal Started 1m kubelet, k8s-n1 Started container
可以看到nginx容器镜像已经变成了1.8版本。
增加副本数量
可以在YAML文件中简单修改副本的数量来扩展Deployment的pod。复制deployment.yaml文件为deployment_scale.yaml,编辑deployment_scale.yaml文件,把replicas修改为4:
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 4 # tells deployment to run 4 pods matching the template
template: # create pods using pod definition in this template
metadata:
# unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is
# generated from the deployment name
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx # nginx版本还修改为latest,我比较喜欢用新版本
ports:
- containerPort: 80
应用更新,查看pods信息(中间过程也都贴了,期间有pod创建,有pod销毁,最后有4个状态为running):
[wangxianfeng@k8s-m1 k8s]$ kubectl apply -f deployment_scale.yaml
deployment.apps "nginx-deployment" configured
[wangxianfeng@k8s-m1 k8s]$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-666865b5dd-h4d4l 0/1 ContainerCreating 0 11s
nginx-deployment-666865b5dd-wmlmk 0/1 ContainerCreating 0 10s
nginx-deployment-cf7f48d4c-dchd7 1/1 Running 0 8m
nginx-deployment-cf7f48d4c-m4hg4 1/1 Running 0 9m
nginx-deployment-cf7f48d4c-mv5vf 0/1 ContainerCreating 0 12s
[wangxianfeng@k8s-m1 k8s]$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-666865b5dd-h4d4l 1/1 Running 0 30s
nginx-deployment-666865b5dd-wmlmk 1/1 Running 0 29s
nginx-deployment-666865b5dd-xwnds 0/1 ContainerCreating 0 11s
nginx-deployment-666865b5dd-zntfs 0/1 ContainerCreating 0 8s
nginx-deployment-cf7f48d4c-dchd7 0/1 Terminating 0 8m
nginx-deployment-cf7f48d4c-m4hg4 1/1 Running 0 9m
[wangxianfeng@k8s-m1 k8s]$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-666865b5dd-h4d4l 1/1 Running 0 33s
nginx-deployment-666865b5dd-wmlmk 1/1 Running 0 32s
nginx-deployment-666865b5dd-xwnds 0/1 ContainerCreating 0 14s
nginx-deployment-666865b5dd-zntfs 0/1 ContainerCreating 0 11s
nginx-deployment-cf7f48d4c-dchd7 0/1 Terminating 0 8m
nginx-deployment-cf7f48d4c-m4hg4 1/1 Running 0 9m
[wangxianfeng@k8s-m1 k8s]$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-666865b5dd-h4d4l 1/1 Running 0 50s
nginx-deployment-666865b5dd-wmlmk 1/1 Running 0 49s
nginx-deployment-666865b5dd-xwnds 1/1 Running 0 31s
nginx-deployment-666865b5dd-zntfs 1/1 Running 0 28s
删除一个Deployment
根据deployment的名字进行删除:
kubectl delete deployment nginx-deployment
查看pod运行在哪个节点上
kubectl get pods -l app=nginx -o wide
根据lable进行筛选,-o 表示输出格式,wide表示多输出一些信息,如IP,pod运行在哪个节点上等等。其他输出格式可以选择yaml,json等。具体参考Overview of kubectl
查看pod的IP信息
kubectl get pods -l app=nginx -o yaml|grep podIP
用service连接应用
官方文档链接Connecting Applications with Services
创建一个Service
kubectl expose deployment/nginx-deployment
此语句根据名称为nginx-deployment的deployment创建了一个service,也可以使用yaml文件创建service,并进行更多的定制化,等价于以下yaml文件:
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
app: nginx
使用 kubectl create -f 进行创建。
创建完成之后,通过以下命令查看是否创建成功:
kubectl get svc nginx-deployment
输出类似如下:
[wangxianfeng@k8s-m1 k8s]$ kubectl get svc nginx-deployment
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-deployment ClusterIP 10.102.140.205 <none> 80/TCP 10m
可以看到该服务监听在80端口,集群IP是10.102.140.205。
可以通过describe命令查看service的pod详情:
kubectl describe svc nginx-deployment
输出类似如下:
[wangxianfeng@k8s-m1 k8s]$ kubectl describe svc nginx-deployment
Name: nginx-deployment
Namespace: default
Labels: app=nginx
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP: 10.102.140.205
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.0.6:80,10.244.0.8:80,10.244.0.9:80 + 1 more...
Session Affinity: None
Events: <none>
访问Service
Kubernetes支持2中主要的模型用于查找服务:环境变量和DNS。
环境变量
pod运行的时候kubelet会添加一些环境变量,可以用以下命令查看pod的环境变量:
[wangxianfeng@k8s-m1 k8s]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-666865b5dd-h4d4l 1/1 Running 0 1h
nginx-deployment-666865b5dd-wmlmk 1/1 Running 0 1h
nginx-deployment-666865b5dd-xwnds 1/1 Running 0 1h
nginx-deployment-666865b5dd-zntfs 1/1 Running 0 1h
[wangxianfeng@k8s-m1 k8s]$ kubectl exec nginx-deployment-666865b5dd-h4d4l -- printenv | grep SERVICE
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
环境变量中并没有Service的相关信息,因为创建pod在创建Service之前。先把nginx-deployment的replicas改成0,然后再改成4,再看看pod的节点分布情况:
kubectl scale deployment nginx-deployment --replicas=0; kubectl scale deployment nginx-deployment --replicas=4;
这些分布比较均匀了:
[wangxianfeng@k8s-m1 k8s]$ kubectl get pods -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-666865b5dd-kb9gc 1/1 Running 0 57s 10.244.1.7 k8s-n1
nginx-deployment-666865b5dd-m77lv 1/1 Running 0 57s 10.244.0.12 k8s-m1
nginx-deployment-666865b5dd-m9kcd 1/1 Running 0 57s 10.244.0.14 k8s-m1
nginx-deployment-666865b5dd-z6jld 1/1 Running 0 57s 10.244.0.13 k8s-m1
再次查看环境变量,已经有了Service相关信息:
[wangxianfeng@k8s-m1 k8s]$ kubectl exec nginx-deployment-666865b5dd-kb9gc -- printenv | grep SERVICE
KUBERNETES_SERVICE_PORT_HTTPS=443
NGINX_DEPLOYMENT_SERVICE_HOST=10.102.140.205
KUBERNETES_SERVICE_HOST=10.96.0.1
NGINX_DEPLOYMENT_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT=443
DNS
使用如下命令查看是否已经在运行dns服务
kubectl get services kube-dns --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 1d
运行一个curl的docker容器进行测试
kubectl run curl --image=radial/busyboxplus:curl -i --tty
[wangxianfeng@k8s-m1 k8s]$ kubectl run curl --image=radial/busyboxplus:curl -i --tty
If you don't see a command prompt, try pressing enter.
[ root@curl-775f9567b5-knshg:/ ]$ nslookup nginx-deployment
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve 'nginx-deployment'
从宿主机访问Service(Exposing the Service)
两种方式:NodePorts and LoadBalancers
用以下命令查看是否已经开放了nodeport及是否具有外部IP
kubectl get svc nginx-deployment -o yaml | grep nodePort -C 5
kubectl get nodes -o yaml | grep ExternalIP -C 1
现在编辑Service,添加nodePort。首先删除nginx-deployment
kubectl delete svc nginx-deployment
创建文件nginx_service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 8080
protocol: TCP
targetPort: 80
selector:
app: nginx
使用如下命令创建Service:
kubectl create -f nginx_service.yaml
再看看是不是已经有了nodeport:
[wangxianfeng@k8s-m1 k8s]$ kubectl get svc nginx-deployment -o yaml | grep nodePort -C 5
uid: 62db4297-6078-11e8-a407-0211322b88e3
spec:
clusterIP: 10.109.119.99
externalTrafficPolicy: Cluster
ports:
- nodePort: 32494
port: 8080
protocol: TCP
targetPort: 80
selector:
app: nginx
现在访问宿主机的32494端口即可访问Service了:
curl http://192.168.2.186:32494
浏览器里边看一把
现在把NodePort改成LoadBalancer试试。
[wangxianfeng@k8s-m1 k8s]$ kubectl get svc nginx-deployment -o yaml | grep nodePort -C 5
uid: 85b913ad-6079-11e8-a407-0211322b88e3
spec:
clusterIP: 10.111.180.9
externalTrafficPolicy: Cluster
ports:
- nodePort: 32123
port: 8080
protocol: TCP
targetPort: 80
selector:
app: nginx
差不多,不知道啥区别,不管了。
文章评论