《云计算技术》实验三:安装docker和部署应用

/ 0评 / 0

1.安装docker

docker desktop需要win 10专业版,而我是家庭版。

先在网上找一个能用的密钥,把家庭版升级成未激活的专业版,然后用学校官网给的激活工具激活。

如果找不到能用的密钥,可以直接下载专业版镜像,重装系统再激活。

双击运行docker安装程序,自动完成安装,需要重启电脑。

发现出错。说我的CPU虚拟化没有开启。但是在任务管理器里显示我的虚拟化已开启,并且hyper-v也是启用的。

上次移动开发的实验,安装Android studio的时候遇到了不兼容的问题,修改了一些地方,可能与这些操作有关。

尝试改回原来的设置。

关闭Windows虚拟机监控程序平台。

在powershell已管理员身份执行:

bcdedit /set hypervisorlaunchtype auto

然后重启电脑。问题解决,docker成功运行,桌面右下角出现一个鲸鱼的小图标。

2.镜像加速

最快的应该是阿里云,到阿里云注册一个registry账号就能拿到一个镜像加速地址了。

右键小鲸鱼,选择settings,在docker engine里设置镜像,可以多设置几个。我添加了阿里云、官方、网易和七牛的镜像加速。

{
  "registry-mirrors": [
    "https://0y0s5vsb.mirror.aliyuncs.com",
    "https://registry.docker-cn.com",
    "https://hub-mirror.c.163.com",
    "https://reg-mirror.qiniu.com"
  ],
  "insecure-registries": [],
  "debug": true,
  "experimental": false
}

点击 Apply & Restart 应用并重启docker服务

3.验证

powershell中执行:

docker version
docker run hello-world

4.先部署指导书中的示例

先新建一个文件夹,在里面创建3个文件:Dockerfile.txt, requirement.txt, app.py

在文件中写入内容:

app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

requirement.txt

Flask
Redis

Dockerfile.txt

# Use an official Python runtime as a parent image
FROM python:3.7-alpine

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

然后执行指令:

docker build -t docker-whale -f ./Dockerfile.txt .
docker run -p 4000:80 docker-whale

然后在浏览器中访问localhost:4000

5.用Java写一个简单的web应用

参考网上的例子,写了一个web服务器。不过不管访问什么页面,都只能返回hello world。

一共就3个类

HttpServer.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class HttpServer extends Thread {

    public static final String ROOT = "./";

    private InputStream input;

    private OutputStream out;

    public HttpServer(Socket socket) {
        try {
            input = socket.getInputStream();
            out = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        String filePath = read();
        response(filePath);
    }

    private void response(String filePath) {
        StringBuffer index = new StringBuffer();
        index.append("HTTP /1.1 400 file not found /r/n");
        index.append("Content-Type:text/html \r\n");
        index.append("Content-Length:20 \r\n").append("\r\n");
        index.append("<h1 >Hello Docker.</h1>");
        try {
            out.write(index.toString().getBytes());
            out.flush();				out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private String read() {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        try {
            // 读取请求头, 如:GET /index.html HTTP/1.1
            String readLine = reader.readLine();
            String[] split = readLine.split(" ");
            if (split.length != 3) {
                return null;
            }
            System.out.println(readLine);
            return split[1];
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

WebServer.java

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class WebServer
{
    public void startServer(int port){
        try {
            @SuppressWarnings("resource")
            ServerSocket serverSocket = new ServerSocket(port);
            while(true){
                Socket socket = serverSocket.accept();
                new HttpServer(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

WebApp.java

public class WebApp {
    public static void main(String[] args) {
        new WebServer().startServer(8000);
    }
}

本地测试一下

build出class文件,遇到一点问题。

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: WebApp has been compiled by a more recent version of the Java Runtime (class file version 56.0), this version of the Java Runtime only recognizes class file versions up to 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

原因是IDE编译的用的是Java12,我电脑运行环境设置的是Java8.

把编译改成Java8,成功运行。

6.部署应用

为了区分显示效果,我把hello world改成了hello docker

把编译好的三个class文件拿出来,再创建一个Dockerfile

到docker hub上找一个合适的Java镜像。

我选择的是这个

先把这个镜像下载到本地,大概100多MB

docker pull openjdk:8-jdk-slim-buster

再看一下这个镜像的说明

知道大概的使用方法

以此作参考,写Dockerfile

#设置镜像
FROM openjdk:8-jdk-slim-buster
#复制文件
COPY . /usr/src/myapp
#设置工作路径
WORKDIR /usr/src/myapp
#开启端口
EXPOSE 8000
#执行的指令
CMD ["java", "WebApp"]

然后创建我们的镜像

docker build -t docker-lab -f ./Dockerfile .

之后启动容器

docker run -p 4000:8000 docker-lab

使用-p参数,将容器内部的8000端口映射到本机的4000端口

浏览器访问localhost:4000

发表评论

电子邮件地址不会被公开。 必填项已用*标注