前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2. 使用Kubernetes和Docker

2. 使用Kubernetes和Docker

作者头像
yeedomliu
发布2019-09-29 16:32:42
9720
发布2019-09-29 16:32:42
举报
文章被收录于专栏:yeedomliuyeedomliu

1. 内容

  • 使用Docker创建、运行及共享容器镜像
  • 在本地部署单节点的Kubernetes集群
  • 配置和使用命令行客户端——kubectl
  • 在Kubernetes上部署应用并进行水平伸缩

2. 创建、运行及共享容器镜像

介绍

深入学习前,先看看如何创建一个简单的应用、打包成容器镜像、在远程集群或本地集群运行

步骤简介

  • 安装Docker并运行第一个“Hello World”容器
  • 创建一个简单的php应用并部署在Kubernetes
  • 把应用打包成可以独立运行的容器镜像
  • 基于镜像运行容器
  • 把镜像推送到Docker Hub,这样任何人在任何地方都可以使用

安装并运行Docker

  • 安装:https://docs.docker.com/docker-for-mac/install/
  • 运行Hello World容器
    • busybox是一个集成最常用linux命令的linux系统容器镜像
    • 使用docker run命令指定镜像名字、执行命令(可选),如图所示
    • 通过一个命令就运行了一个完整的“应用”,而不用做其它的事情
    • 重要的是应用是在容器内部执行的,完全独立于基于其他主机上运行的进程
  • 背后原理
    • 执行docker run命令(docker run busybox echo "Hello World")后,docker会检查busybox:latest镜像是否已经存在本机,如果没有会从http://docker.io的镜像中心拉取
    • 镜像下载到本机后,docker基于这个镜像创建一个容器并在容器中运行命令
    • echo命令输出后,进程终止,容器停止运行
  • 运行其它镜像
    • 如果想运行其它镜像可以在hub.docker.com网站搜索
    • 然后像这样运行镜像docker run <image>
  • 容器镜像的版本管理
    • docker支持同一镜像的多个版本,每个版本必须有唯一的tag名,当没有显式指定tag时,docker默认指定为latest
    • 运行别的版本镜像docker run <image>:<tag>

创建一个简单的php应用

  • 这个应用程序输出当前时间
  • 应用运行在容器中,看到的是自己的主机名而不是宿主机名,即使它像其它进程一样运行在宿主机上
  • 这在后面非常有用,当应用部署在Kubernetes上进行伸缩时(复制应用到多个节点),它的请求切换到了应用的不同实例上

为镜像创建Dockerfile

  • 把应用打包成镜像,首先需要创建名为Dockerfile的文件,它包含了一系列构建镜像时执行的指令
  • Dockerfile和index.php在同一目录
  • Dockerfile内容如下
  • FROM定义了基础镜像,使用了7-zts-alpine3.9版本
  • ADD是把index.php从本地文件夹添加到镜像的/目录
  • EXPOSE声明暴露的端口号
  • WORKDIR指定默认工作目录
  • CMD默认执行的命令,意思是用php启动一个web服务器,端口为8080

构建容器镜像

  • 运行docker命令(docker build -t php:local .)来构建镜像
  • 构建过程不是用Docker客户端完成,而将整个目录上传到Docker守护进程(Docker客户端和守护进程可以不在一台机器上)
  • 构建过程中,Docker首次会从公开镜像仓库(Docker Hub)拉取基础镜像(php:7-zts-alpine3.9)
  • 最后一个.是告诉Docker是基于当前目录,构建名为php、标签为local的镜像;Docker会在目录中寻找Dockerfile,然后基于其中指令构建镜像
代码语言:javascript
复制
使用docker images命令查看生成的镜像
$ docker images 
php    local                b26e7de6427c        9 hours ago         64.7MB
php    7-zts-alpine3.9 0adbdb1b2250        2 weeks ago         64.7MB
  • 构建镜像过程
  • 镜像分层
    • 镜像不是一个大的二进制块,而由多层组成的,在busybox例子中,每一层有一行Pull complete,不同镜像可能会共享分层,这会让存储和传输变得更高效
    • Dockerfile每一条单独的指令都会创建一个新层

运行容器镜像

  • 运行应用容器
    • 运行命令docker run --name php-container -p 8000:8000 -d php:local
    • 这条命令告知Docker是基于php:local镜像创建一个名为php-container的容器,本机8000端口映射到容器的8000的端口,-d表示后台运行
  • 访问应用
    • 运行命令$ curl http://localhost:8000
    • 通过http://localhost:8000访问应用,输出当前运行时间。应用是运行在容器中,与其他应用隔离
  • 列出所有运行中的容器
    • 运行命令docker ps
代码语言:javascript
复制
命令结果
CONTAINER ID   IMAGE    COMMAND   CREATED   STATUS   PORTS       NAMES
2b3eb8cbab22   php:local "docker-php-entrypoi…"   2 minutes ago   Up 2 minutes    0.0.0.0:8000->8000/tcp   php-container

  • 获取容器信息
    • 运行命令docker inspect php-container会打印出包含容器底层信息的长json

探索运行容器的内部

  • 在已有的容器内部运行shell
    • 在php-container容器执行ls -al /,命令和主容器进程有相同的命名空间
    • -i:确保标准输入流保持开放,需要在shell中输入命令
    • -t:分配一个伪终端(TTY)
    • 运行命令docker exec -it php-container ls -al /
代码语言:javascript
复制
输出结果
$ docker exec -it php-container ls -al /
total 68
drwxr-xr-x    1 root     root          4096 May 28 23:13 .
drwxr-xr-x    1 root     root          4096 May 28 23:13 ..
-rwxr-xr-x    1 root     root             0 May 28 23:13 .dockerenv
drwxr-xr-x    1 root     root          4096 May 11 03:27 bin
drwxr-xr-x    5 root     root           340 May 28 23:13 dev
drwxr-xr-x    1 root     root          4096 May 28 23:13 etc
drwxr-xr-x    1 root     root          4096 May 11 03:04 home
-rw-r--r--    1 root     root            33 May 28 23:12 index.php
  • 从内部探索容器
    • 进入容器命令docker exec -it php-container sh
代码语言:javascript
复制
查看容器里运行的进程
# ps -ef
PID   USER     TIME  COMMAND
  1   root     0:00  /usr/local/bin/php -S 0.0.0.0:8000
  7   root     0:00  sh
 12   root     0:00  ps -ef
  • 容器的文件系统也是独立的
代码语言:javascript
复制
执行ls -al /命令查看
# ls -al /
total 68
drwxr-xr-x    1 root     root          4096 May 29 03:58 .
drwxr-xr-x    1 root     root          4096 May 29 03:58 ..
-rwxr-xr-x    1 root     root             0 May 29 03:58 .dockerenv
drwxr-xr-x    1 root     root          4096 May 11 03:27 bin
drwxr-xr-x    5 root     root           340 May 29 03:58 dev
drwxr-xr-x    1 root     root          4096 May 29 03:58 etc
drwxr-xr-x    1 root     root          4096 May 11 03:04 home
-rw-r--r--    1 root     root            33 May 28 23:12 index.php
drwxr-xr-x    1 root     root          4096 May 11 03:27 lib
drwxr-xr-x    5 root     root          4096 May  9 20:49 media
drwxr-xr-x    2 root     root          4096 May  9 20:49 mnt
drwxr-xr-x    2 root     root          4096 May  9 20:49 opt
dr-xr-xr-x  262 root     root             0 May 29 03:58 proc
drwx------    1 root     root          4096 May 29 03:59 root
drwxr-xr-x    2 root     root          4096 May  9 20:49 run
drwxr-xr-x    2 root     root          4096 May  9 20:49 sbin
drwxr-xr-x    2 root     root          4096 May  9 20:49 srv
dr-xr-xr-x   13 root     root             0 May 29 03:58 sys
drwxrwxrwt    1 root     root          4096 May 11 03:27 tmp
drwxr-xr-x    1 root     root          4096 May 11 03:27 usr
drwxr-xr-x    1 root     root          4096 May 11 03:04 var

停止和删除容器

  • 停止命令
    • 执行docker stop php-container
代码语言:javascript
复制
使用docker ps -a查看容器,发现状态已经是Exited
$ docker ps -a
CONTAINER ID   IMAGE    COMMAND    CREATED  STATUS   PORTS     NAMES
c113cc387a6d   php:local "docker-php-entrypoi…"   8 minutes ago   Exited(137) 56 seconds ago   php-container
  • 删除容器命令 docker rm php-container

向镜像仓库推送镜像

  • 介绍
    • 目前构建的镜像只能本机使用,为了在任何机器上都能使用,可以把镜像推送到外部的镜像仓库,如Docker Hub(http://hub.docker.com)
  • 使用附加标签标注镜像
    • 在Docker Hub注册个账号,把镜像重命名标签
    • 重命名镜像标签docker tag php:local yeedom/php:v1
代码语言:javascript
复制
查看镜像docker images
$ docker images
REPOSITORY     TAG       IMAGE ID            CREATED             SIZE
php            local     9ed8b05c3334        13 hours ago        64.7MB
yeedom/php     v1        9ed8b05c3334        13 hours ago        64.7MB
  • 向Docker Hub推送镜像
代码语言:javascript
复制
推送前先登录
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: yeedom
Password:
Login Succeeded
代码语言:javascript
复制
推送镜像
国外网络可能不稳定,失败了可以多试几次
$ docker push yeedom/php:v1
The push refers to repository [docker.io/yeedom/php]
d281f172ef70: Pushed
8a1be1ed4590: Mounted from library/php
b39144a13ab7: Mounted from library/php
060efcf419e8: Mounted from library/php
f38edf0edb30: Mounted from library/php
0b0394abec4c: Mounted from library/php
21f626200b4c: Mounted from library/php
414e112bbb2c: Mounted from library/php
3575e617b5f4: Mounted from library/php
f1b5933fe4b5: Mounted from library/php
v1: digest: sha256:448c8eeca87506bbc6d41190073acdcab094aa0b0bd3c2551c4ced947f422ebb size: 2409
  • 在不同机器上运行镜像
代码语言:javascript
复制
运行命令$ docker run -p 8000:8000 -d yeedom/php:v1
$ docker run -p 8000:8000 -d yeedom/php:v1
Unable to find image 'yeedom/php:v1' locally
v1: Pulling from yeedom/php
Digest: sha256:448c8eeca87506bbc6d41190073acdcab094aa0b0bd3c2551c4ced947f422ebb
Status: Downloaded newer image for yeedom/php:v1
a0d96dc65d6795ba5542754bd3a07e424da672960f545f5cf36e14fa02cac46f
代码语言:javascript
复制
删除镜像docker rmi yeedom/php:v1
$ docker rmi yeedom/php:v1
Untagged: yeedom/php:v1
Untagged: yeedom/php@sha256:448c8eeca87506bbc6d41190073acdcab094aa0b0bd3c2551c4ced947f422ebb

3. 配置Kubernetes集群

用Minikube运行一个本地单节点Kubernetes集群

  • 介绍
    • 要在Kubernetes运行应用,首先要设置集群
    • 使用Minikube是运行Kubernetes集群最简单、最快捷的方法,它是构建单节点集群的工具,对于测试Kubernetes和本地开发应用都非常有用
    • Minikube在VM中通过VirtualBox、KVM或hyperkit来运行Kubernetes,所以启动Kubernetes集群之前,还需要安装VM
  • 安装文档:因为minikube国内安装有点特殊,请参考文档
  • 使用Minikube启动一个Kubernetes集群
    • 运行命令minikube start
  • 获取集群概览
    • 每个节点运行着Docker、kubelet、kube-proxy
    • Kubectl:向运行在主节点上的Kubernetes API服务器发出REST请求以与集群交互
    • 交互图
  • 列出集群节点
代码语言:javascript
复制
命令kubectl get nodes
$ kubectl get nodes
NAME       STATUS    ROLES     AGE       VERSION
minikube   Ready     <none>    43m       v1.14.2
  • 查看对象更多信息查看对象更多信息查看对象更多信息查看对象更多信息
  • 命令$ kubectl describe node minikube
  • 内容比较多,如输出节点的状态、CPU、内存数据、系统信息、运行容器的节点
    • 如果不指定节点名称则会打印所有节点信息

为kubectl配置别名和命令行补齐

  • 配置别名
  • 使命令行补齐
    • 使用kube-shell,带命令补齐和高亮

4. 在Kubernetes上运行第一个应用

介绍

正常来说,部署一个Kubernetes程序需要包含部署的所有组件描述的配置文件,因为第一次使用,所以用最简单的方法运行Kubernetes程序

部署php应用

代码语言:javascript
复制
运行命令
kube-shell> kubectl run php-container --image=yeedom/php:v1 --port=8000 --generator=run/v1
replicationcontroller "php-container" created
  • 参数解释
    • —image:容器镜像
    • —port:端口
    • —generator:创建一个ReplicationController
  • 介绍pod
    • 一个pod是一组紧密相关的容器,运行在同一个工作节点和linux命名空间中
    • 每个pod就像一个独立的逻辑机器,有自己的ip、主机名、进程等,运行一个独立的应用程序
    • 一个pod的所有容器运行在同一个逻辑机器上,也可以出现在不同的节点上
    • 和Docker启动容器不同,Kubernetes不直接处理单个容器,它使用多个共存容器的理念,这组容器叫作pod
    • pod
    • 关系图
  • 列出pod
代码语言:javascript
复制
命令
$ kubectl describe pod php-container-mdkmq
Name:               php-container-mdkmq
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               minikube/10.0.2.15
Start Time:         Thu, 30 May 2019 07:58:10 +0800
Labels:             run=php-container
Annotations:        <none>
Status:             Running
…………………………
代码语言:javascript
复制
$ kubectl get pods
NAME                  READY     STATUS              RESTARTS   AGE
php-container-mdkmq   0/1       ContainerCreating   0          7
  • 幕后发生的事情
    • ReplicationController对象创建一个新的pod
    • 调度器将其调度到一个工作节点上
    • kubectl看到pod被调度到节点上,就告知Docker拉取镜像
    • 创建容器
    • 构建镜像并推送到Docker Hub
    • 运行kubectl命令时,向Kubernetes API服务器发送http请求在集群中创建一个新的ReplicationController对象

访问web应用

  • 介绍:每个pod在集群内有自己的ip,要让pod从外部访问,需要通过服务对象公开它,要创建一个特殊的LoadBalance类型的服务
  • 创建一个服务对象
    • 命令
代码语言:javascript
复制
$ kubectl expose rc php-container --type=LoadBalancer --name php-service
service "php-service" exposed
  • 列出服务
    • 命令kubectl get service
代码语言:javascript
复制
$ kubectl get service
NAME         TYPE          CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
kubernetes   ClusterIP     10.96.0.1      <none>        443/TCP         37d
php-service  LoadBalancer  10.105.206.79  localhost     8000:32040/TCP  6s
  • 使用外部ip访问服务
    • 命令
代码语言:javascript
复制
$ curl http://localhost:8000
  • 查看服务
    • 命令
代码语言:javascript
复制
$ kubectl get service php-service
NAME          TYPE          CLUSTER-IP     EXTERNAL-IP  PORT(S)         AGE
php-service   LoadBalancer  10.105.206.79  localhost    8000:32040/TCP  3m

系统的逻辑部分

  • ReplicationController、pod和服务如何组合在一起
    • 如之前所说,Kubernetes没有直接创建和使用容器,它的基本构件是pod
    • 但你也没有直接创建pod,而是通过kubectl run命令创建了ReplicationController,它用于创建pod实例
    • 为了能使pod能从集群外部访问,需要创建一个服务对外暴露
  • pod和它的容器
    • 在系统中最重要最基本的组件是pod
    • 它只包含一个容器,但是通常一个pod可包含任意数量的容器
    • pod有自己的私有ip和主机名
  • ReplicationController的角色
    • 通常,rc用于创建pod多个副本并让它保持运行
    • 如果pod有任何原因消失或停止,那么rc将拉起或重新创建新的pod
  • 为什么需要服务
    • 解决不断变化的pod ip地址,pod可能因为故障而停止,这时会有新pod替换
    • 固定的ip和端口对外提供服务
    • 服务表示一组或多组提供相同服务的pod,到达服务ip和端口的请求会转发到该服务的一个容器ip和端口

水平伸缩应用

  • 增加期望的副本数
    • Kubernetes的一个主要好处是可简单地处理部署,我们把运行实例数量增加到三个
    • 查看rc
代码语言:javascript
复制
kubectl get rc
NAME            DESIRED   CURRENT   READY     AGE
php-container   1         1         1         52m
代码语言:javascript
复制
kubectl get pod
NAME                  READY     STATUS    RESTARTS   AGE
php-container-xlhzh   1/1       Running   0          53m
代码语言:javascript
复制
kubectl scale rc php-container --replicas=3
replicationcontroller "php-container" scaled
代码语言:javascript
复制
kubectl get pods
NAME                  READY     STATUS    RESTARTS   AGE
php-container-f879k   1/1       Running   0          5s
php-container-n2pwj   1/1       Running   0          5s
php-container-xlhzh   1/1       Running   0          54m
  • 当切换到服务时请求切换到所有pod上
    • 多次请求服务,会落到不同的pod上
代码语言:javascript
复制
$ curl http://localhost:8000
php-container-n2pwj
2019-05-30 13:23:38

$ curl http://localhost:8000
php-container-xlhzh
2019-05-30 13:23:50

$ curl http://localhost:8000
php-container-f879k
2019-05-30 13:23:54

查看应用运行在哪个节点上

  • 介绍:在Kubernetes世界中,pod运行在哪个节点上不重要,只要它被调度到一个可以提供pod正常运行所需的cpu和内存的节点就可以了
  • 列出pod时显示pod IP和pod的节点:会显示pod的ip和运行的节点
代码语言:javascript
复制
    kubectl get pod -o wide
    NAME                  READY     STATUS    RESTARTS   AGE       IP           NODE
    php-container-f879k   1/1       Running   0          50m       10.1.1.102   docker-for-desktop
    php-container-n2pwj   1/1       Running   0          50m       10.1.1.101   docker-for-desktop
    php-container-xlhzh   1/1       Running   0          1h        10.1.1.100   docker-for-desktop
代码语言:javascript
复制
kubectl describe pod php-container-f879k
Name:           php-container-f879k
Namespace:      default
Node:           docker-for-desktop/192.168.65.3
Start Time:     Thu, 30 May 2019 21:10:32 +0800
Labels:         run=php-container
Annotations:    <none>
Status:         Running
IP:             10.1.1.102
Controlled By:  ReplicationController/php-container

5. 小结

  • 拉取、运行镜像
  • 把应用打包到容器镜像,并且推送到公开镜像仓库让大家可以使用
  • 进入运行中的容器并检查运行环境
  • 为kubectl命令行工具设置别名和tab补全
  • 在Kubernetes集群中列出查看节点、pod、服务和ReplicationController
  • 在Kubernetes中运行容器并可以在集群外部访问
  • 了解pod、ReplicationController和服务是关联的基础场景
  • 通过改变ReplicationController的副本数对应用进行水平伸缩
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yeedomliu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 内容
    • 2. 创建、运行及共享容器镜像
      • 介绍
      • 步骤简介
      • 安装并运行Docker
      • 创建一个简单的php应用
      • 为镜像创建Dockerfile
      • 构建容器镜像
      • 运行容器镜像
      • 探索运行容器的内部
      • 停止和删除容器
      • 向镜像仓库推送镜像
    • 3. 配置Kubernetes集群
      • 用Minikube运行一个本地单节点Kubernetes集群
      • 为kubectl配置别名和命令行补齐
    • 4. 在Kubernetes上运行第一个应用
      • 介绍
      • 部署php应用
      • 访问web应用
      • 系统的逻辑部分
      • 水平伸缩应用
      • 查看应用运行在哪个节点上
    • 5. 小结
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档