100% found this document useful (5 votes)
11 views

Download ebooks file Deploy Container Applications Using Kubernetes: Implementations with microk8s and AWS EKS Shiva Subramanian all chapters

AWS

Uploaded by

yangsuwerts
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (5 votes)
11 views

Download ebooks file Deploy Container Applications Using Kubernetes: Implementations with microk8s and AWS EKS Shiva Subramanian all chapters

AWS

Uploaded by

yangsuwerts
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

Download Full Version ebookmass - Visit ebookmass.

com

Deploy Container Applications Using Kubernetes:


Implementations with microk8s and AWS EKS Shiva
Subramanian

https://ebookmass.com/product/deploy-container-applications-
using-kubernetes-implementations-with-microk8s-and-aws-eks-
shiva-subramanian/

OR CLICK HERE

DOWLOAD NOW

Discover More Ebook - Explore Now at ebookmass.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

A Complete Guide to DevOps with AWS: Deploy, Build, and


Scale Services with AWS Tools and Techniques Osama Mustafa

https://ebookmass.com/product/a-complete-guide-to-devops-with-aws-
deploy-build-and-scale-services-with-aws-tools-and-techniques-osama-
mustafa/
ebookmass.com

Kubernetes Programming with Go: Programming Kubernetes


Clients and Operators Using Go and the Kubernetes API 1st
Edition Philippe Martin
https://ebookmass.com/product/kubernetes-programming-with-go-
programming-kubernetes-clients-and-operators-using-go-and-the-
kubernetes-api-1st-edition-philippe-martin/
ebookmass.com

Kubernetes Programming with Go: Programming Kubernetes


Clients and Operators Using Go and the Kubernetes API 1st
Edition Philippe Martin
https://ebookmass.com/product/kubernetes-programming-with-go-
programming-kubernetes-clients-and-operators-using-go-and-the-
kubernetes-api-1st-edition-philippe-martin-2/
ebookmass.com

Decision Making in Veterinary Practice Barry Kipperman

https://ebookmass.com/product/decision-making-in-veterinary-practice-
barry-kipperman/

ebookmass.com
Russia's Interventions in Ethnic Conflicts: The Case of
Armenia and Azerbaijan 1st ed. Edition James J. Coyle

https://ebookmass.com/product/russias-interventions-in-ethnic-
conflicts-the-case-of-armenia-and-azerbaijan-1st-ed-edition-james-j-
coyle/
ebookmass.com

L'Antre des Vipères (French Edition) Knight

https://ebookmass.com/product/lantre-des-viperes-french-edition-
knight/

ebookmass.com

The Second Age of Computer Science: From ALGOL Genes to


Neural Nets 1st Edition Subrata Dasgupta

https://ebookmass.com/product/the-second-age-of-computer-science-from-
algol-genes-to-neural-nets-1st-edition-subrata-dasgupta/

ebookmass.com

Informed choice: The role of knowledge in the willingness


to consume aquaculture products of different groups in
Germany Christina Hoerterer & Jessica Petereit & Gesche
Krause
https://ebookmass.com/product/informed-choice-the-role-of-knowledge-
in-the-willingness-to-consume-aquaculture-products-of-different-
groups-in-germany-christina-hoerterer-jessica-petereit-gesche-krause/
ebookmass.com

Teach Me Daddy: An Age Play Mafia Daddy Romance (Mafia


Daddies NYC Book 5) Zack Wish

https://ebookmass.com/product/teach-me-daddy-an-age-play-mafia-daddy-
romance-mafia-daddies-nyc-book-5-zack-wish/

ebookmass.com
E-book Catatan Faidah Ilmu di Bulan Ramadhan (Revisi) Abu
Ubaidah Yusuf Sidawi

https://ebookmass.com/product/e-book-catatan-faidah-ilmu-di-bulan-
ramadhan-revisi-abu-ubaidah-yusuf-sidawi/

ebookmass.com
CHAPTER 1

From VMs to Containers


In this chapter, we will explain the benefits of deploying an application via containers vs.
the traditional method of using VMs while observing the benefits containers offer over
the VMs for solving the same problem set.
In a large-scale environment, such as is typical in an enterprise setting, with
hundreds, if not thousands, of applications to be hosted and supported, the problem of
deploying and managing those applications via VMs can be categorized into two main
categories, namely:

1. Dependency hell: Of shared libraries, the OS, and application


packages

2. Efficiency and cost control: Efficient use of compute resources

Dependency Hell
Anyone who has installed Microsoft runtime libraries on a Windows VM running
multiple applications or had to upgrade a package system in Linux can tell you how
complex this can be.
Ever since computers made it into the business applications’ world, supporting
real-world applications and problem solving, there has always been the problem of
dependencies among the various components, both hardware and software, that
comprise the application stack.
The technical stack the application software is written on, for example, Java, has
versions; this Java version is designed to run on top of a specified set of runtime libraries,
which in turn run on top of an operating system; this specified operating system runs
on top of a specified hardware device. Any changes and updates for security and feature
enhancements must take into account the various interconnects, and when one breaks
compatibility, we enter the dependency hell.

1
© Shiva Subramanian 2023
S. Subramanian, Deploy Container Applications Using Kubernetes,
https://doi.org/10.1007/978-1-4842-9277-8_1
Chapter 1 From VMs to Containers

This task of updating system components was even more complicated when IT
systems were vertically scaled, where there was one underlying operating system and
many applications that ran on top of it. Each application might come with its own runtime
library requirements; an OS upgrade might not be compatible with the dependencies of
some applications running on top, creating technical debt and operational complexity.

Efficiency and Cost Control


One way a system admin can alleviate the first problem is by creating a separate
VM for each application, then scaling it, so the dependency of packages is reduced
in complexity. Virtual machines, with each virtual machine running an individual
application, were common in the days of virtualization. They still are.
The major drawback of such solutions is they essentially waste a lot of resources and
increase operational complexity of running large-scale systems. Imagine you are serving
a static website that gets millions and millions of hits during peak hours. How do you
quickly scale from 1 VM running a web server to 100 VMs running the same application?
Even if you did, now you have to apply patches and maintain the web farm of 100 VMs.
This decreases efficiency and increases the maintenance function as well as
increases the overall cost of providing the solution.
To illustrate the problem in finer detail and to allow us to compare solving the same
problem using containers, let us first deploy a simple static website using a VM.

The VM Way
Task: Suppose the developers have developed a static website which they have asked
you to host in your production environment.
As a seasoned systems engineer or administrator, you know how to do this. Easy!, you
say. I’ll create a VM, deploy a web server, and voilà! But what’s the fun in that? However,
let us still deploy the static website the traditional way and the container way. This way,
we will learn the similarities and differences between the two approaches. Thus

1) We will run a simple static website using virtual machine


technology.

2) We will run the same simple static website using container


technology.

2
Chapter 1 From VMs to Containers

We will then build increasingly complex container applications as our journey


progresses.
Set up a static website using a virtual machine.
Prerequisites

• Ubuntu 22.04 LTS

Note There are several virtual machine technologies available, such as the cloud,
ESXi host, VMware Workstation, Parallels, KVM, etc. Instructions for installing the
Linux operating system will vary widely depending on the virtualization software in
use; thus, we assume that the systems engineer/administrator is familiar with their
workstation setup.

The typical process involves the following:

1. Install the operating system.

2. Install the nginx (web server) application.

3. Deploy the application data (the web pages).

1. Install the operating system.

In my case, I’ve installed a vanilla Ubuntu 22.04 LTS operating


system, which we will be using.

It is a typical virtual machine with 1 or 2vCPUs with 2GB of


memory and ~10GB of HDD. The user shiva is an admin on the
VM; since we will be installing many packages later on, ensure
that the user you are using has admin rights on the VM via sudo,
etc. The installed OS is Ubuntu 22.04 LTS as shown in Listing 1-1.

We confirm the OS by running the following command:

lsb_release -s -d

Note The author has chosen to list plain command(s) only at the top of the listings
and the executed output and results right below it, making it easy to differentiate
between the command and the author’s illustrated outputs as shown in Listing 1-1.

3
Chapter 1 From VMs to Containers

Listing 1-1. Version confirmation and output

lsb_release -s -d

shiva@wks01:~$ lsb_release -s -d
Ubuntu 22.04 LTS
shiva@wks01:~$

2. Install the nginx (web server) application.


Now that the OS is ready, we need to install the nginx application;
again, there are many ways to install the nginx application per
nginx’s documentation website at https://nginx.org/en/linux_
packages.html – we can download the source code and compile
it, or we can utilize the packages that are readily available for our
operating system. In our case, we will install the package from the
package repo.

We first update our repos by running the command shown in


Listing 1-2; depending on your location and the mirror closest
to you, the output may slightly differ; as long as the repos are
updated, we should be good.

Listing 1-2. Package repo update and output

sudo apt-get update

shiva@wks01:~$ sudo apt-get update


Hit:1 http://us.archive.ubuntu.com/ubuntu jammy InRelease
Hit:2 http://us.archive.ubuntu.com/ubuntu jammy-updates InRelease
Get:3 http://us.archive.ubuntu.com/ubuntu jammy-backports InRelease
[99.8 kB]
Get:4 http://us.archive.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Fetched 210 kB in 0s (521 kB/s)
Reading package lists... Done
shiva@wks01:~$

The package name for nginx is just nginx; thus, we will install
nginx using the standard package manager command as shown in
Listing 1-3.

4
Chapter 1 From VMs to Containers

Note <SNIP> in the output section indicates the sections of the output snipped
out of the listing to maintain brevity; it does not impact the concepts we are
learning.

Listing 1-3. Installing nginx and abbreviated output

sudo apt-get install nginx -y

shiva@wks01:~$ sudo apt-get install nginx -y


Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  fontconfig-config fonts-dejavu-core libdeflate0 libfontconfig1 libgd3
libjbig0
  libjpeg-turbo8 libjpeg8 libnginx-mod-http-geoip2 libnginx-mod-http-
image-filter
<SNIP>
Setting up libnginx-mod-http-image-filter (1.18.0-6ubuntu14.4) ...
Setting up nginx-core (1.18.0-6ubuntu14.4) ...
* Upgrading binary nginx                                            [ OK ]
Setting up nginx (1.18.0-6ubuntu14.4) ...
Processing triggers for ufw (0.36.1-4build1) ...
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3) ...
Scanning processes...
Scanning linux images...
Running kernel seems to be up-to-date.
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
shiva@wks01:~$

5
Chapter 1 From VMs to Containers

Please note that your mileage may vary with respect to the
output messages due to variations in installed editions of the
operating system.

Confirm the nginx process is running as shown in Listing 1-4.

Listing 1-4. Confirming nginx is running

ps -ef | grep [n]ginx

shiva@wks01:~$ ps -ef | grep [n]ginx


root        2125       1  0 03:23 ?        00:00:00 nginx: master process /
usr/sbin/nginx -g daemon on; master_process on;
www-data    2128    2125  0 03:23 ?        00:00:00 nginx: worker process
shiva@wks01:~$

This marks the end of step 2, which is installing the web server;
now on to step 3.

3. Deploy the application data (the web pages).

Luckily, nginx comes with its own default index.html; thus, we do


not have to deploy anything special just to test the package. To
test, we can use curl and confirm the web server is returning the
web content as shown in Listing 1-5.

Listing 1-5. Browsing to the nginx default website using the command line

curl localhost

shiva@wks01:~$ curl localhost


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<SNIP>
<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>

6
Chapter 1 From VMs to Containers

<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>
shiva@wks01:~$

We have successfully deployed our static website using a VM.

The VM Way – Problem Summary


From a time-to-deploy an application perspective, we have taken ~30 minutes to install
the operating system and another ~5 minutes to update the package manager data and
install the actual package.
From a resource perspective, we have taken 2GB of memory and 10GB of HDD space.
Suppose we have to scale this horizontally to ten VMs; that would have required
20GB of memory (10VM×2GB/VM) and 100GB (10VM×10GB/VM) of HDD space, which
is an enormous amount of resources just for serving a static website.
Along comes the system administration overhead of managing these VMs, patching,
user management, IP addresses, and such.
Is there a better way?

Enter Containers
Welcome to the wonderful world of containers.
Containers solve both of the major problems associated with the VM way:

1. Dependency hell – no more

Containers provide us a way to package an application and all


its dependencies including the underlying operating system in
an automated way, which can then be run on top of a container
runtime and be scaled up or down horizontally quickly. Patching?
No problem. Build a new image; deploy the new image; let the

7
Chapter 1 From VMs to Containers

container management system (Kubernetes) take care of the rest.


New app release? No problem. Build a new image; test; deploy the
new image via Kubernetes. You get the idea.

Self-contain the application and its runtime, build an image,


deploy the image, and manage the image using K8S.

Here, container is a generic term capturing the essence of the


technology underpinning, which is to say the application and
related dependency components are all self-contained and won’t
impact the contents of another application in another container,
like a physical container where the contents of one container
cannot impact the contents of another container and the
container as a whole can be lifted, shifted, and moved easily.

Here, the term image refers to the binary format or artifact of the
technology container.

2. Efficiency and cost control

Unlike a traditional VM which contains a plethora of components


to enable general-purpose application development, a container
is purpose built and includes only the minimum needed OS
components such as the kernel and necessary shared libraries
to run the application process, no more, no less – meaning the
container images are compact both at the disk image level as well
as the memory footprint level.

Just like how a hypervisor is capable of running many VMs, the


container host (node) is capable of running as many container
images as its CPU, memory, and disk would allow, except,
instead of running full-blown VMs, containers run only the bare
minimum processes needed for the application.

FUN FACT: Google launches several billion containers per week.1


Expert advice: There are almost little or no technology controls that will prevent you
from building a container with two applications running within the same container. Be
aware, that’s bad design and breaks the basic tenant of a container. Don’t fear running

1
https://cloud.google.com/containers

8
Chapter 1 From VMs to Containers

each application in its own container as the resource required to run a container is
very minimal; you will not be conserving any resources and will be reintroducing the
dependency management complexity that got us here in the first place!

Summary
In this chapter, we learned about two of the major problems associated with deploying
and managing an application and how containers promise to solve both the problems,
enabling systems engineers to reduce complexity while increasing efficiency, scalability,
and reliability of hosting applications via containers.
In the next chapter, we will deploy a simple static application via container
technology, realizing for ourselves how easy it is to deploy and manage applications
deployed via containers.

9
CHAPTER 2

Container Hello-World
Continuing from where we left off in the VM world, the goal of this chapter is to set up
container technology in our workstation and run our first container, hello-world, and
nginx web server, using docker with the intent to learn the basics of containers.

Docker Technology
When we say containers, for many, Docker comes to mind, and with a good reason.
Docker is a popular container technology that allows for users and developers to
build and run containers. Since it is a good starting point and allows us to understand
containers better, let us build and run a few containers based on docker technology
before branching out into the world of Kubernetes.

Setting Up Our Workstation for Docker


Prerequisites
VM with Ubuntu 22.04

Container runtime (docker)

Container images (Docker Hub)

Notice that we said container runtime. Why is a container runtime needed? A


container is just a saved image that includes, among other things, the core OS, any
shared libraries, and application binaries – this container is then read by the container
runtime and launched as a running process, exposes the necessary ports so the
application can be accessed from outside the container, etc. – more on this later. For
now, go along with installing the CRI.

11
© Shiva Subramanian 2023
S. Subramanian, Deploy Container Applications Using Kubernetes,
https://doi.org/10.1007/978-1-4842-9277-8_2
Chapter 2 Container Hello-World

The astute reader will notice and ask: Why do we need a VM still? I thought we were
going with containers. The short answer is, yes, we still need a host machine to provide
compute, that is, the CPU, memory, and disk, for the containers to run; however, the
VM can be replaced with special-purpose host OSes that can be stripped down to a bare
minimum; we will learn more about compute nodes and observe these in later chapters.
First, let us install the docker package onto our workstation as shown in Listing 2-1.

Listing 2-1. Installing Docker via the CLI

sudo apt install docker.io -y

shiva@wks01:~$ sudo apt install docker.io -y


Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  bridge-utils containerd dns-root-data dnsmasq-base git git-man iptables
less liberror-perl libip6tc2
  libnetfilter-conntrack3 libnfnetlink0 libnftnl11 netcat netcat-openbsd
patch pigz runc ubuntu-fan
Suggested packages:
  ifupdown aufs-tools cgroupfs-mount | cgroup-lite debootstrap docker-doc
rinse <snip>  libip6tc2 libnetfilter-conntrack3 libnfnetlink0 libnftnl11
netcat netcat-openbsd patch pigz runc ubuntu-fan
0 upgraded, 20 newly installed, 0 to remove and 55 not upgraded.
Need to get 71.8 MB of archives.
After this operation, 312 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://us.archive.ubuntu.com/ubuntu jammy/universe amd64 pigz amd64
2.6-1 [63.6 kB]
<SNIP>
Processing triggers for libc-bin (2.35-0ubuntu3) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based
frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm
line 78.)
debconf: falling back to frontend: Readline

12
Chapter 2 Container Hello-World

Scanning processes...
Scanning linux images...
Running kernel seems to be up-to-date.
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
shiva@wks01:~$

The Docker package is installed; to confirm the same, run the command shown in
Listing 2-2.

Listing 2-2. Confirming the docker package is running

dpkg -l docker.io

shiva@wks01:~$ dpkg -l docker.io


Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/
Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version           Architecture Description
+++-==============-=================-============-========================
=========
ii  docker.io      20.10.12-0ubuntu4 amd64       Linux container runtime
shiva@wks01:~$

Confirming Docker Service Is Running


Since the docker.io package is installed, we can now start the docker service and confirm
it is running by the commands shown in Listing 2-3. Note that you might have to press
<q> at the end of the service docker status command to get back to the prompt.

Note Highlights in the output show the key elements we are looking for in the
output section.

13
Chapter 2 Container Hello-World

Listing 2-3. Verifying the Docker daemon is running

sudo service docker start


service docker status

shiva@wks01:~$ sudo service docker start


shiva@wks01:~$
shiva@wks01:~$ service docker status
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor
preset: enabled)
     Active: active (running) since Thu 2023-01-19 03:34:56 UTC;
1min 42s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 2637 (dockerd)
      Tasks: 7
     Memory: 29.8M
        CPU: 226ms
     CGroup: /system.slice/docker.service
             └─2637 /usr/bin/dockerd -H fd:// --containerd=/run/
containerd/containerd.sock

Jan 19 03:34:56 wks01 dockerd[2637]: time="2023-01-19T03:34:56.06639110


4Z" v<SNIP>
Jan 19 03:34:56 wks01 dockerd[2637]: time="2023-01-19T03:34:56.334554201Z"
level=info msg="API listen on /run/d>

NOTE - if needed, press <q> to get back to command prompt

shiva@wks01:~$

Notice docker is in active (running) state; this is good. We can now set this user up
for using docker.

14
Chapter 2 Container Hello-World

Setting Up Our User for Use with Docker


Since we installed docker as root via sudo (and it needs root), we need to grant our
regular user, shiva in my case, permissions to use the service. We do that by adding
ourselves to the group docker. Execute the command shown in Listing 2-4.

Note Unless noted otherwise, remarks starting with # are NOT part of the system
output; it is used by the author to highlight something being present or not present
as a form of explanation.

Listing 2-4. Adding a regular user to the docker group

sudo usermod -a -G docker shiva

shiva@wks01:~$ sudo usermod -a -G docker shiva


shiva@wks01:~$ # No output to show, next command confirms the group
addition

For this to take effect, you can log out and log back in or add the newly added group
to the current session by using the command shown in Listing 2-5.

Listing 2-5. Changing the acting primary group for the regular user

newgrp docker

shiva@wks01:~$ newgrp docker


shiva@wks01:~$ # No output

Before proceeding, we need to verify the group docker shows up in our session; we
can do that by executing the command shown in Listing 2-6.

Listing 2-6. Verifying the docker group is added to the session

id

shiva@wks01:~$ id
uid=1000(shiva) gid=112(docker) ­groups=112(docker),4(adm),24(cdrom),
27(sudo),30(dip),46(plugdev),110(lxd),1000(shiva)
shiva@wks01:~$

15
Chapter 2 Container Hello-World

At this point, we have met the first prerequisite of installing and running the CRI.
Now that we have installed the container runtime and the service is running,
we need an image to run. This act of running an image using a container runtime is
generally known as container, and the process of packaging an application to run inside
the container is generally known as containerizing an application. More on that later.
A simple hello-world application exists for the container world also; let us run that to
make sure our setup is working properly before moving ahead.

Container Hello-World
Run the command to start our first container as shown in Listing 2-7. What this
command does is it instructs docker to find and run a container named hello-world; not
to worry, if this image is not present, docker is smart enough to download this image
from its default container repository and then run it. More on container repositories in
later chapters.

Listing 2-7. Run the hello-world container

docker run hello-world

shiva@wks01:~$ docker run hello-world


Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:aa0cc8055b82dc2509bed2e19b275c8f463506616377219d964222
1ab53cf9fe
Status: Downloaded newer image for hello-world:latest

Hello from Docker!


This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:


1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
3. The Docker daemon created a new container from that image which runs
the executable that produces the output you are currently reading.

16
Chapter 2 Container Hello-World

4. The Docker daemon streamed that output to the Docker client, which sent
it to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:


https://docs.docker.com/get-started/

shiva@wks01:~$

Notice, right below the status: line, the output says “Hello from Docker!”. This
confirms our docker setup is functioning correctly. The description from the output
further elaborates what happened in the background. Docker service pulled the image
from Docker Hub and ran it. Container images are stored in container repos and are
“pulled” by the runtime as necessary. More on container repos later.
Congratulations! You just ran your first container!
Now that we have our workstation set up, we can now run the nginx container using
the command shown in Listing 2-8. In this command, first we are stopping the nginx
that’s running on the Linux workstation we started in Chapter 1, then we are asking
docker to run the nginx container and map localhost port 80 to container port 80.
If the container image is not locally found, docker automatically downloads it and
then runs it.
The port 80 mapping is so we can access container port 80 from the localhost,
meaning our Linux workstation, on port 80.
Currently, we are just using all defaults; we can change the mapped ports, etc.; more
on this later.
Have two terminal windows open and run the command in one window; run the
sudo and docker commands shown in Listing 2-8 in one window and run the curl
command shown in Listing 2-9 in another window.

17
Chapter 2 Container Hello-World

Listing 2-8. Launching a stock nginx container via docker, terminal 1

sudo service nginx stop # stop nginx we installed in chapter 1


sudo update-rc.d -f nginx disable # disable this instance from starting
upon reboot
docker run -p 80:80 nginx

shiva@wks01:~$ sudo service nginx stop


shiva@wks01:~$ # No output
shiva@wks01:~$ sudo update-rc.d -f nginx disable
shiva@wks01:~$ # No output
shiva@wks01:~$ docker run -p 80:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
faef57eae888: Pull complete
<SNIP>
103501419a0a: Pull complete
Digest: sha256:08bc36ad52474e528cc1ea3426b5e3f4bad8a130318e3140d6cfe2
9c8892c7ef
Status: Downloaded newer image for nginx:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to
perform configuration
<SNIP>
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-­
processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/07/23 18:29:25 [notice] 1#1: using the "epoll" event method
2023/07/23 18:29:25 [notice] 1#1: nginx/1.25.1
2023/07/23 18:29:25 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/07/23 18:29:25 [notice] 1#1: OS: Linux 5.15.0-76-generic
2023/07/23 18:29:25 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/07/23 18:29:25 [notice] 1#1: start worker processes
2023/07/23 18:29:25 [notice] 1#1: start worker process 28

18
Chapter 2 Container Hello-World

Notice how the docker launched the nginx container; the container then started the
nginx worker threads; docker would have also mapped port 80 so that we can access the
default website. We can do that using curl on terminal 2, which we opened earlier, as
shown in Listing 2-9.

Listing 2-9. Accessing nginx running on the container via curl

shiva@wks01:~$ curl localhost


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
<SNIP>
<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>
shiva@wks01:~$

Notice how easy that was; in one command, we were able to deploy the static
website, the task that required a full VM install as we did in the previous chapter. The
memory and disk footprint is also very small when compared to a full VM. You can now
press CTRL+C on the terminal running the docker run command.

19
Chapter 2 Container Hello-World

Summary
In this chapter, you learned how to set up your workstation to begin working with
containers, installed Docker, and ran your first two container applications – the hello-­
world container and a web server – using the stock nginx container image, as well as
how to map a port on the container to your local workstation so that you can access the
services the container is providing.
In the next chapter, we’ll begin building on what you have learned so far, expanding
on learning more container basic commands and concepts using Docker.

Your Turn
Whatever your workstation flavor is, ensure docker is set up and running like we have
done here as well as run the two sample containers and ensure we receive the expected
results. The next chapters build on what we have set up here.

20
CHAPTER 3

Container Basics Using


Docker
In this chapter, we will expand from the previous chapter by learning more about
containers, where to find, download, run, and more importantly configure containers
so that we can access the services the containers provide for us. For example, in the
previous chapter, we ran the command docker run nginx. What happened behind
the scenes? Why did we have to map port 80:80? What if I wanted to run a different
application? Where do I find container images for that? We will take a closer look at these
topics here.
Let’s get to it, starting with where to find prebuilt containers.

Finding Prebuilt Containers


Just like how your OS provider provides you with a package repository that contains
various application packages, containers are available from various repositories, such
as Docker Hub. For the purposes of this exercise, we will use Docker Hub, but there are
many other repositories out there.
Go to https://hub.docker.com, which you can see in Figure 3-1.

21
© Shiva Subramanian 2023
S. Subramanian, Deploy Container Applications Using Kubernetes,
https://doi.org/10.1007/978-1-4842-9277-8_3
Chapter 3 Container Basics Using Docker

Figure 3-1. Docker Hub landing page

Note You are welcome to sign up for a free account (free for personal use).

Type in nginx at the top-left search bar; select the first result “nginx” under verified
content, which will bring you to the dialog shown in Figure 3-2.

Security Note As with any public repository, anyone can publish images;
please exercise caution when downloading and running images from unknown
sources. In the docker repository, known good images have the “DOCKER OFFICIAL
IMAGE” badge.

22
Chapter 3 Container Basics Using Docker

Figure 3-2. nginx container image

Notice the badge next to the nginx name field; this is the docker official image and
thus is more safe than an unofficial image. Select the “Tags” tab, as shown in Figure 3-3.

23
Chapter 3 Container Basics Using Docker

Figure 3-3. All the available TAGS are shown

You will see all the different flavors this image is available in, for example, you
can see the various OS/ARCH in the middle column. To pull a particular image; the
command shortcut is shown next to the container image; you can copy that shortcut to
the clipboard and paste in your terminal when we are ready to download. Right now,
we do not have to download this image yet - as we are only identifying the various nginx
container images available at hub.docker.com.
Notice the naming convention of the container images; stable-<something>, which
is typical in the container world, it indicates whether the image is experimental, beta
branch, stable, etc., and the alpine indicates the container was built with the Alpine
Linux as the base OS.

Expert Tip www.alpinelinux.org/ is a base OS optimized for building


container images, more on this later.

24
Chapter 3 Container Basics Using Docker

Let us now look at another container image that has the nginx application built-in. This
time it is from the Ubuntu software vendor. Now search again by typing “ubuntu/nginx” on
the search bar at the top left of the page, and select the result under “Verified Content” as
shown in Figure 3-4.

Figure 3-4. Results for the ubuntu/nginx image

Select the ubuntu/nginx shown on the search bar; we land on the official ubuntu/
nginx image page as shown in Figure 3-5.

25
Chapter 3 Container Basics Using Docker

Figure 3-5. Official ubuntu/nginx landing page

This is another container image built and published by Ubuntu. We will use this
image since this nginx container is built on top of the familiar Ubuntu operating system.
Similar to what you did previously, select the “Tags” tab, as shown in Figure 3-6, to
check out the container flavors available to us.

26
Chapter 3 Container Basics Using Docker

Figure 3-6. Image showing all the available tags for ubuntu/nginx

Notice the middle column, OS/ARCH; we see the architecture we need, which is
linux/amd64. Recall that from Chapter 1, our process architecture is x86_64. This is the
one we will be using.

Running the Image We Found


The command we’d need to pull and use this image, docker pull ubuntu/nginx:latest, is
display on the right-hand side of the screen shown in Figure 3-6, you can use the copy
icon to copy this command directly from the website and paste onto your terminal, or
you can type the command yourself.
Type the command as shown in Listing 3-1 in your terminal window; it tells
docker to download the ubuntu/nginx:latest image from the image hub to your local
workstation so that you can launch this container image from your workstation.

27
Chapter 3 Container Basics Using Docker

Listing 3-1. Downloading the nginx container based on Ubuntu

docker pull ubuntu/nginx:latest

shiva@wks01:~$ docker pull ubuntu/nginx:latest


latest: Pulling from ubuntu/nginx
e2e81a815547: Pull complete
7c0b7a3612f4: Pull complete
f7324d013584: Pull complete
3894566cf529: Pull complete
Digest: sha256:a27d1870851c03123e1b7f5f321a36578c711adc33508b36573
3c0182331339c
Status: Downloaded newer image for ubuntu/nginx:latest
docker.io/ubuntu/nginx:latest
shiva@wks01:~$

The output indicates docker found the image and pulled them in chunks; when all
the chunks are “Pull complete,” docker computes the Digest to confirm the image has
not been corrupted during the download process, then confirms the status with us and
exits without errors.
All we have done at this point is downloaded the container image to our workstation.
We can verify the image is present in our local workstation by running the code shown in
Listing 3-2, which gives us pertinent information toward the container images stored on
this workstation.

Listing 3-2. Listing container images stored in the local VM


docker image ls

shiva@wks01:~$ docker image ls


REPOSITORY     TAG      IMAGE ID      CREATED      SIZE
ubuntu/nginx   latest    047208ad86d4   6 days ago    142MB
nginx          latest    eea7b3dcba7e   7 days ago     187MB
hello-world    latest    9c7a54a9a43c   3 months ago   13.3kB
shiva@wks01:~$

28
Chapter 3 Container Basics Using Docker

Note Both nginx images are different; the plain nginx image is built and
maintained by the nginx vendor, while the ubuntu/nginx image is built and
maintained by Ubuntu. While in the previous chapter we used the nginx image
by nginx.com, in this chapter we are using the ubuntu/nginx image. There is no
preference with one over the other; as a systems engineer, you get to choose
which image you’d like to use; we have opted to continue with ubuntu/nginx. As
mentioned in the earlier SECURITY NOTE, care must be taken as to the source
of the image; here, both nginx.com and Ubuntu are well-established software
vendors.

Pay attention to the REPOSITORY column – it indicates the name of the container
image; the TAG column indicates the version, either a number or latest available; IMAGE
ID is the unique identifier (hash); CREATED indicates when the container was originally
created (not when it was locally created on our workstation); and SIZE indicates the size
of the container image.
Notice that the entire nginx container based off of the Ubuntu OS is ONLY
140MB. Compare that with the VM that we created in Chapter 2, which was several GB in
size – see the compactness of the containers!
An astute reader would have noticed that we cannot run the container yet, unlike the
hello-world container we ran, because hello-world did not provide any running service/
port. Here, as is typical with a web server, we need to expose a port that the web server
can run on. As shown in Figure 3-7, the “Usage” section on the “Overview” page provides
the information on how to pass the port number to the container.

29
Chapter 3 Container Basics Using Docker

Figure 3-7. Usage instructions on how to expose the port on the container

30
Chapter 3 Container Basics Using Docker

Exposing Ports (Services) the Pod Has to Offer


The command that allows us to expose the port is similar to how we ran the hello-world:

docker run

-d: For running the container in the background.

--name: The name we would like to give the container; it is


arbitrary; you can call it nginx01 to indicate the first instance of
nginx01 we are about to launch.

-e: The environment variable we would like to pass to the


container; in this case, they are passing TZ=UTC. You can skip
this, leave it as is, or customize it to your local timezone.

-p: The port to expose, <localhost port>:<maps to this


container port>.

then the image name of the container we would like to launch.


So the final command looks like this:

docker run -d --name nginx01 -e TZ=EDT -p 8080:80 ubuntu/nginx:latest

Before running this command, let us check and ensure if 8080 is free on the local
machine; the command in Listing 3-3 lists all the listening ports on the Linux machine.
If we find 8080 here, then that means some other process is using that port; if we don’t
see 8080, then it is available for us to use. Since we do not see 8080 in the output in
Listing 3-3, we are free to use it for our container.

Listing 3-3. Confirming port 8080 is not in use using the ss command

ss -ntl

shiva@wks01:~$ ss -ntl
State    Recv-Q   Send-Q       Local Address:Port        Peer Address:Port
   Process
LISTEN   0       4096         127.0.0.53%lo:53               0.0.0.0:*
LISTEN   0       128                0.0.0.0:22               0.0.0.0:*

31
Chapter 3 Container Basics Using Docker

LISTEN   0       4096             127.0.0.1:46433            0.0.0.0:*


LISTEN   0       511                0.0.0.0:80               0.0.0.0:*
LISTEN   0       128                   [::]:22                  [::]:*
LISTEN   0       511                   [::]:80                  [::]:*
shiva@wks01:~$

lsof is another popular way to see if any process is using port 8080; run it as shown
in Listing 3-4. The lack of output from the command indicates that no other process is
using port 8080, so we can utilize this port.

Listing 3-4. Confirming port 8080 is not in use via the lsof command

lsof -i:8080

shiva@wks01:~$ lsof -i:8080


shiva@wks01:~$

Finally, when we launch our container, we will be connecting to port 8080, where our
nginx will be running; before making any changes, let us document the before picture by
connecting to port 8080 with the curl command as shown in Listing 3-5. The expected
output is an error, since nothing should be running on 8080 at this time.

Listing 3-5. Confirming nothing is accessible in port 8080 prior to


launching service on this port as we expect to see the website on this port
after we launch the container

curl localhost:8080

shiva@wks01:~$ curl localhost:8080


curl: (7) Failed to connect to localhost port 8080 after 0 ms:
Connection refused
shiva@wks01:~$

We have confirmed nothing is running on 8080, and thus it is free to use; we also
confirmed curl is not able to connect to 8080 yet.
Now we are ready to launch the container and expose the ports; run the command
we just learned including all the command-line options to name the container and pass
the port to be exposed, the image to be run, and any optional parameters like timezone
as shown in Listing 3-6.

32
Chapter 3 Container Basics Using Docker

Listing 3-6. Launching the ubuntu/nginx container

docker run -d --name nginx01 -e TZ=EDT -p 8080:80 ubuntu/nginx:latest

shiva@wks01:~$ docker run -d --name nginx01 -e TZ=EDT -p 8080:80 ubuntu/


nginx:latest
b51b6f4a593438c69b0c4ee234dd2b321f09adb2f026b1f564139ee6dfd1c664
shiva@wks01:~$

The command in Listing 3-6 exited showing the a hash value (this is the CONTAINER
ID) and without any other errors, meaning it completed successfully. We can now
confirm if the container is running as expected using the docker ps command, as shown
in Listing 3-7, which shows information about all the running containers.

Listing 3-7. Confirming the container is running

docker ps

shiva@wks01:~$ docker ps
CONTAINER ID   IMAGE                COMMAND                    CREATED      
      STATUS          PORTS                                  NAMES
b51b6f4a5934   ubuntu/nginx:latest   "/docker-entrypoint...."   26 seconds
ago   Up 25 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx01
shiva@wks01:~$

Here, we can see the container we launched is UP for 25 seconds, and we have
mapped 8080 on the localhost to 80 on the container, where the web server is running.
We can also confirm this is the container we launched by comparing the output hash
value displayed when we launched the container with the CONTAINER ID column on
the docker ps output, though the CONTAINER ID column is truncated due to display
space constraints, up to the characters displayed - they match.

Testing the Container


If the container started successfully and the mapping of port 8080->80 is successful, then
we should see port 8080 listening on our workstation, which we can verify as shown in
Listing 3-8.
We execute the same command that we used to list all the LISTENing ports as shown
in Listing 3-8.
33
Chapter 3 Container Basics Using Docker

Listing 3-8. Confirming port 8080 is listening

ss -ntl | grep [8]080

shiva@wks01:~$ ss -ntl | grep [8]080


LISTEN 0      4096       0.0.0.0:8080       0.0.0.0:*
LISTEN 0      4096            [::]:8080       [::]:*
shiva@wks01:~$

Notice that this time around, we do see something listening on port 8080, which is
what we asked docker to do – map localhost port 8080 to the container port 80; that’s
what is shown in the output of the docker ps command:

0.0.0.0:8080->80/tcp

We have confirmed the container process is listening on port 8080; now, we can
conduct an end-to-­end test by connecting to port 8080 via CURL. If the web server is
running on the container, then we should see the website’s default landing page, which
we can do using our familiar curl command as shown in Listing 3-9.

Listing 3-9. Accessing the nginx container web server via curl

curl localhost:8080

shiva@wks01:~$ curl localhost:8080


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>

34
Chapter 3 Container Basics Using Docker

<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>
shiva@wks01:~$

Curl connected to port 8080, which docker redirected to port 80 on the nginx
container it is running, which in turn served the web page which was then provided to
curl, which is what we see as the output in Listing 3-9!
Want to launch another web server instance? Easy. Let us name our container
instance nginx02, map 8081 to 80, and launch – the following command accomplishes
this; we are just changing the name and port number to be unique; thus, the command
then becomes

docker run -d --name nginx02 -e TZ=EDT -p 8081:80 ubuntu/nginx:latest

We can run it on our system as shown in Listing 3-10; notice how easy it is to launch
another instance of the nginx web server, one command.

Listing 3-10. Launching a second instance of the ubuntu/nginx container

docker run -d --name nginx02 -e TZ=EDT -p 8081:80 ubuntu/nginx:latest

shiva@wks01:~$ docker run -d --name nginx02 -e TZ=EDT -p 8081:80 ubuntu/


nginx:latest
5e25f3c059ece70e68360432d1ca481de36927c2ff95e853d689745d20b683eb
shiva@wks01:~$

The command completed successfully; let us confirm with docker ps that the second
container is running as shown in Listing 3-11.

35
Chapter 3 Container Basics Using Docker

Listing 3-11. Confirming both ubuntu/nginx containers are running

docker ps

shiva@wks01:~$ docker ps
CONTAINER ID   IMAGE                COMMAND                    CREATED      
      STATUS          PORTS                                  NAMES
5e25f3c059ec   ubuntu/nginx:latest   "/docker-entrypoint...."   18 seconds
ago   Up 17 seconds   0.0.0.0:8081->80/tcp, :::8081->80/tcp   nginx02
b51b6f4a5934   ubuntu/nginx:latest   "/docker-entrypoint...."   5 minutes
ago   Up 5 minutes    0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx01
shiva@wks01:~$

We now see two instances running; both are UP and docker is exposing the ports we
requested for it to map.
Let us confirm both ports 8080 and 8081 are listening on the localhost with the
command shown in Listing 3-12.

Listing 3-12. Confirming both service ports are listening

ss -ntl4 | grep [8]08

shiva@wks01:~$ ss -ntl4 | grep [8]08


LISTEN 0      4096       0.0.0.0:8080       0.0.0.0:*
LISTEN 0      4096       0.0.0.0:8081       0.0.0.0:*
shiva@wks01:~$

We notice both 8080 and 8081 are listening.


We can now use CURL to connect to both 8080 and 8081 to confirm web servers are
running on both ports as shown in Listing 3-13; this is a simple confirmation that both
containers are running and serving content via nginx as they should.

Listing 3-13. Confirming we can access a website on both service ports via curl

curl localhost:8080
curl localhost:8081

shiva@wks01:~$ curl localhost:8080


<!DOCTYPE html>
<html>

36
Chapter 3 Container Basics Using Docker

<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
[SNIP]
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

shiva@wks01:~$ curl localhost:8081


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
[SNIP]
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
shiva@wks01:~$

Both web servers are running; no reinstall of OS or anything, just run the container.
The astute reader would be wondering, I can do this in an OS too, launching nginx as
separate processes under various ports and scaling out that way. While that is possible,
we will read more about the benefits of containers as we go along further in the chapters.
For one, if one container crashes, it is not going to impact the other containers; if you
would like to patch the underlying OS and need to reboot, if you run all the nginx
processes in a single VM, you will have to reboot all the web servers at once. However, in
containers, you can restart containers individually on a rolling basis; thus, downtime is
low, just to name a few.
37
Chapter 3 Container Basics Using Docker

Summary
In this chapter, we have learned how to find a prebuilt containers we would like to run
from hub.docker.com, how to identify the correct architecture, and how to formulate
runtime parameters for an image and run them under docker.
We also met our goal of launching the static website under docker, in a containerized
fashion.
In the next chapter, I’ll show you how to build your container image and run it.

Your Turn
Another popular web server is Apache HTTPD – very similar to nginx. The image name
is ubuntu/apache2. Try running this inside your docker setup.

38
CHAPTER 4

Building Our First


Container Image
In this chapter, we will learn how to build our own container. This is important because
publicly available containers usually contain popular open source software such as
nginx or apache2/httpd, while our enterprise software typically is closed source and/
or proprietary. Thus, learning how to build our own container will help us package our
enterprise software for deployment in the container paradigm.
This process is logically similar to how you’d build a binary from source code. In that,
the source code defines the logic in a high level programming language, the compiler
converts that into machine language, which results in the binary that we can execute in
a given operating system. Similarly, we define the container image build steps in what
is called a Dockerfile (source code), then execute the docker build command, which
creates the container image based on the instructions in the Dockerfile, which can then
be run by the docker/container run time.

Building Our Container Image


Let us continue with our static-website example in which we need a customized
container image that publishes our own index.html – this time, not using the prebuilt
docker image, but by building our own container image, with our own index.html file.
Our ingredients are

• A containerized base OS

• Ubuntu nginx package

• Our own index.html file

• Dockerfile that puts all these together


39
© Shiva Subramanian 2023
S. Subramanian, Deploy Container Applications Using Kubernetes,
https://doi.org/10.1007/978-1-4842-9277-8_4
Chapter 4 Building Our First Container Image

A Containerized Base OS
As we saw in the previous chapters, we go to https://hub.docker.com and search
for Ubuntu 22.04. Search for “Ubuntu” in the top-left search bar and hit enter
(Figure 4-1).

Figure 4-1. Searching for ubuntu images

We are presented with the “Ubuntu DOCKER OFFICIAL IMAGE.” Let us


investigate it further, as usual, by checking out the summary and tag pages as shown
in Figure 4-2.

40
Random documents with unrelated
content Scribd suggests to you:
bond to unite the body of the Church with its Head[578],” will perhaps
be admitted. According to the same author, St Paul teaches that “by
Baptism man is incorporated with Christ, and puts on Christ, so that
the sacramental washing does away with all natural distinctions or
race;—Greek and Jew, slave and free, men and women, are one in
Christ, members of His body, children of God and of the seed of
Abraham[579].” He tells us also that the same Apostle “not only
divides man into body and spirit, but distinguishes in the bodily
nature, the gross, visible, bodily frame, and a hidden, inner, ‘spiritual’
body not subject to limits of space or cognizable by the senses; this
last, which shall hereafter be raised, is alone fit for and capable of
organic union with the glorified body of Christ, of substantial
incorporation with it[580].” If Döllinger in the XIXth century could thus
interpret St Paul’s words, is it extraordinary that the author of the
Pistis Sophia should put the same construction on similar statements
some sixteen centuries earlier? So the late Dr Hatch, writing of
baptism in this connection, says: “The expressions which the more
literary ages have tended to construe metaphorically were taken
literally. It was a real washing away of sins; it was a real birth into a
new life; it was a real adoption into a divine sonship[581].”
If this be so, it seems to follow that the Mystery of the Ineffable One
must be the other and the greatest of the Christian sacraments.
Jesus tells His disciples that it is the “One and unique word,” and
that the soul of one who has received it “after going forth from the
body of matter of the Archons” will become “a great flood of light”
and will fly into the height, no power being able to restrain it, nor
even to know whither it goes. He continues:

“It shall pass through all the Places of the Archons and all the
Places of the emanations of light, nor shall it make any
announcement nor defence nor give in any symbol; for no Power
of the Archons nor of the emanations of light can draw nigh to
that soul. But all the Places of the Archons and of the
emanations of light shall sing praises, being filled with fear at the
flood of light which clothes that soul, until it shall have passed
through them all, and have come into the Place of the
inheritance of the mystery which it has received, which is the
mystery of the sole Ineffable One, and shall have become united
with his members[582].”

He goes on to explain that the recipient of this mystery shall be


higher than angels, archangels, and than even all the Powers of the
Treasure-house of Light and those which are below it:

“He is a man in the Cosmos; but he is a king in the light. He is a


man in the Cosmos, but he is not of the Cosmos, and verily I say
unto you, that man is myself and I am that man.”
“And, in the dissolution of the Cosmos, when the universe shall
be caught up, and when the number of perfect souls shall be
caught up, and when I am become king in the middle of the last
Parastates, and when I am king over all the emanations of light,
and over the Seven Amen, and the Five Trees, and the Three
Amen, and the Nine Guards, and over the Boy of a Boy, that is to
say the Twin Saviours, and when I am king over the Twelve
Saviours and all the numbers of perfect souls who have received
the mystery of light, then all the men who have received the
mystery of that Ineffable One shall be kings with me, and shall sit
on my right hand and on my left in my kingdom. Verily I say unto
you, Those men are I and I am those men. Wherefore I said unto
you aforetime: You shall sit upon thrones on my right hand and
on my left in my kingdom and shall reign with me. Wherefore I
have not spared myself, nor have I been ashamed to call you my
brethren and my companions, seeing that you will be fellow-
kings with me in my kingdom. These things, therefore, I said unto
you, knowing that I should give unto you the mystery of that
Ineffable One, and that mystery is I and I am that mystery[583].”

That this is the supreme revelation up to which the author of the


Pistis Sophia has been leading all through the book, there can hardly
be any doubt. Its position shortly before the close of the book[584], the
rhapsodic and almost rhythmical phrases with which the approach to
it is obscured rather than guarded, and the way in which directly the
revelation is made, the author falls off into merely pastoral matters
relating to the lesser mysteries, all show that the author has here
reached his climax. But does this revelation mean anything else than
that Jesus is Himself the victim which is to be received in the
Sacrament or μυστήριον of the Altar? That the Christians of the first
centuries really thought that in the Eucharist they united themselves
to Christ by receiving His Body and Blood there can be no question,
and the dogma can have come as no novelty to those who, like the
Ophites, had combined with Christianity the ideas which we have
seen current among the Orphics as to the sacramental efficacy of
the homophagous feast and the eating of the quivering flesh of the
sacrifice which represented Dionysos. Döllinger gives the views of
the primitive Church concisely when he says it is “because we all eat
of one Eucharistic bread, and so receive the Lord’s body, that we all
become one body, or as St Paul says, we become members of His
body, of His flesh, and of His bones.” “We are nourished by
communion,” he continues, “with the substance of His flesh and
blood, and so bound to the unity of His body, the Church; and thus
what was begun in Baptism is continued and perfected in the
Eucharist[585].” Thus, Justin Martyr, who lived in the reign of
Antoninus Pius, says “the food which is blessed by the prayer of His
word, and from which our blood and flesh by transmutation are
nourished, is the flesh and blood of that Jesus who was made
flesh[586].” That the same idea was realized by the heretics may be
gathered from what has been said above as to the wonder-working
celebration of the Eucharist by Marcus, when the wine was made to
change visibly into blood before the eyes of the recipient[587].
It is plain also that the Pistis Sophia does not look upon this perfect
union as within the reach of all. Basilides, the first of the Egyptian
Gnostics, had said that not one in a thousand or two in ten thousand
were fit to be admitted to the higher mysteries, and the same phrase
is repeated by Jesus Himself in one of the later documents of the
MS. of which the Pistis Sophia forms part[588]. Those who were
worthy of admission to the mysteries of the Ineffable One and of the
First Mystery were the pneumatics or spiritual men predestined to
them from before their birth. For the others, the psychic or animal
men, there were the mysteries “of the light,” which are, so to speak,
the first step on the ladder of salvation[589]. These are nowhere
described in the Pistis Sophia or first document of the book, the
hearer being therein always referred for their details to the two great
Books of Jeû mentioned above, “which Enoch wrote when I (i.e.
Jesus) spoke with him from the tree of knowledge and from the tree
of life, which were in the Paradise of Adam[590].” It is here expressly
said that Jesus’ own disciples have no need of them; but their effect
is described as purifying the body of matter, and transforming their
recipient into “light” of exceeding purity. On the death of one who has
taken them all, his soul traverses the different heavens repeating the
passwords, giving in the defences, and exhibiting the symbols
peculiar to each mystery until it reaches the abode assigned to its
particular degree of spiritual illumination. These mysteries of the light
are open to the whole world and there is some reason for thinking
they are the sacraments of the Catholic Church, the members of
which body, Irenaeus says, the “heretics” (Qy the Valentinians?) held
not to be saved but to be only capable of salvation[591]. If the recipient
of these lesser mysteries dies before complete initiation, he has to
undergo a long and painful series of reincarnations, his soul being
sent back into the Sphere of Destiny and eventually into this world by
the Virgin of Light, who will, however, take care that it is placed in a
“righteous” body which shall strive after the mysteries until it finds
them. But the way to these lower mysteries is the complete
renunciation of this world. Man naturally and normally is entirely hylic
or material, being, as Jesus tells His disciples in the Pistis Sophia,
“the very dregs of the Treasure-house, of the Places of those on the
Right Hand, in the Middle, and on the Left Hand, and the dregs of
the Unseen Ones and of the Archons, and, in a word, the dregs of
them all[592].” Hence it is only by the cleansing grace of the mysteries
that he can hope to escape the fate which is coming upon the
Kerasmos, and to obtain these, he must avoid further pollution.

“Wherefore preach you to the whole race of men, saying:


Slacken not day and night until ye find the cleansing mysteries.
Say unto them: Renounce the world and all the matter that is
therein; for whoso buys and sells in the world and eats and
drinks in its matter, and lives in all its cares and all its
conversations, takes unto himself other matter as well as his own
matter.... Wherefore I said unto you aforetime: Renounce the
whole world and all the matter that is therein lest ye add other
matter to your own matter. Wherefore preach ye to the whole
race of men ... cease not to seek day and night and stay not your
hand until ye find the cleansing mysteries which will cleanse you
so as to make you pure light, that ye may go into the heights and
inherit the light of my kingdom[593].”

We see, then, that the author of the Pistis Sophia really


contemplated the formation of a Church within a Church, where a
group of persons claiming for themselves special illumination should
rule over the great body of the faithful, these last being voluntarily set
apart from all communion with their fellows[594]. This was so close a
parallel to what actually occurred in Egypt in the IVth century, when
the whole male population was said with some exaggeration to have
embraced the monastic life[595], and submitted themselves to the rule
of an ambitious and grasping episcopate, as to give us a valuable
indication as to the authorship and date of the book. It may be said
at the outset that the conception of the universe which appears
throughout is so thoroughly Egyptian that it must have been written
for Egyptian readers, who alone could have been expected to
understand it without instruction. The idea of the Supreme Being as
an unfathomable abyss was, as has been said in Chapter II, a very
old one in Egypt, where one of the oldest cosmogonies current made
Nu or the sea of waters the origin of both gods and men[596]. So was
the peculiar theory that the lesser gods were the limbs or members
of the Supreme[597]. An Ogdoad[598] or assembly of eight gods
arranged in syzygies or couples was also well known in the time of
the early dynasties, as was the Dodecad of twelve gods which
Herodotus knew, and which M. Maspero refers on good evidence to
the time of the Pyramid-Builders[599]. So was the view that men and
other material things were made from the tears of the celestial
powers[600], a notion well known to Proclus the Neo-Platonist, who
attributed it to the legendary Orpheus[601]. Not less Egyptian—
perhaps in its origin exclusively Egyptian—is the view that the
knowledge of the places of the world after death and their rulers was
indispensable to the happiness of the dead. “Whosoever,” says M.
Maspero in commenting upon some funerary texts of the Ramesside
period, “knows the names of these (gods) while still on earth and is
acquainted with their places in Amenti, will arrive at his own place in
the other world and will be in all the places reserved for those who
are justified[602].” The resemblance between the system of the Pistis
Sophia and the doctrines of the Egyptian religion in the days of the
Pharaohs has been pointed out in detail by the veteran Egyptologist
the late Prof. Lieblein and has been approved by M. Maspero[603]. It
extends to particular details as well as to general ideas, as we see
from the ritual inscribed on the tombs at Thebes, where each “circle”
or division of the next world is said to have its own song and its own
“mystery,” an idea often met with in the Pistis Sophia[604]. Even the
doctrine in the Pistis Sophia that the dead had to exhibit a “seal” as
well as a “defence” to the guardians of the heavenly places is
explained by the Egyptian theory that no spell was effective without
an amulet, which acted as a kind of material support to it[605]. The
greater part of the allusions in the Pistis Sophia are in fact
unintelligible, save to those with some acquaintance with the
religious beliefs of the Pharaonic Egyptians.
At the same time it is evident that the MS. of the Pistis Sophia that
has come down to us is not the original form of the book. All the
scholars who have studied it are agreed that the Coptic version has
been made from a Greek original by a scribe who had no very
profound acquaintance with the first-named tongue[606]. This appears
not only from the frequent appearance in it of Greek words following
Coptic ones of as nearly as possible the same meaning; but from the
fact that the scribe here and there gives us others declined
according to the rules not of Coptic but of Greek accidence. We must
therefore look for an author who, though an Egyptian and acquainted
with the native Egyptian religion, would naturally have written in
Greek; and on the whole there is no one who fulfils these
requirements so well as Valentinus himself. The fact that the author
never quotes from the Gospel according to St John indicates that it
had not come to his knowledge; for the opening chapter of St John’s
Gospel contains many expressions that could easily on the Gnostic
system of interpretation be made to accord with the Valentinian
theology, and is in fact so used by later writers of the same school as
the author of the Pistis Sophia[607]. Now the first direct and
acknowledged quotation from St John’s Gospel that we have is that
made by Theophilus, who was made bishop of Antioch in A.D. 170,
and the generally received opinion is that this Gospel, whenever
written, was not widely known long before this date[608]. The only
founders of Gnostic sects of Egyptian birth prior to this were
Basilides and Valentinus, and of these two, Valentinus is the more
likely author, because he, unlike his predecessor, evidently taught for
general edification, and possessed, as the Fathers agree, a
numerically large following. We have, moreover, some reason for
thinking that Valentinus actually did write a book with some such title
as the Sophia. Tertullian, in his declamation against the Valentinians,
quotes a sentence from “the Wisdom (Lat. Sophia) not of Valentinus
but of Solomon[609].” It has been suggested that he is here referring
to some saying of the Valentinian aeon Sophia; but no writings would
in the nature of things be attributed to her, and, as M. Amélineau
points out, it is more natural to think that he was here comparing a
book with a book[610]. This figure of rhetoric was a favourite one with
Tertullian, for in his treatise De Carne Christi we find him quoting in
like manner the Psalms—“not the Psalms of Valentinus, the
apostate, heretic, and Platonist, but the Psalms of David[611].” The
fact that the story in the British Museum MS. is called Pistis Sophia
instead of Sophia only need not hinder us from identifying this with
the work presumably referred to by Tertullian, because this title is, as
has been said, the work of another scribe than those who
transcribed the original; and Pistis Sophia is sometimes spoken of in
the MS. itself as Sophia only[612]. Moreover, there is some reason for
thinking that certain of the Fathers and even their Pagan adversaries
had seen and read the story of Pistis Sophia. The allusion quoted
above from Origen to gates opening of their own accord seems to
refer to one of its episodes, and Tertullian, in the treatise in which he
says he is exposing the original tenets of the sect[613], uses many
expressions that he can hardly have borrowed from any other
source. Thus, he speaks of Sophia “breaking away from her
spouse[614]” which is the expression used by Pistis Sophia in her first
Metanoia and is in no way applicable to the Valentinian Sophia of
Irenaeus or Hippolytus. He again speaks of the same Sophia as
being all but swallowed up and dissolved in “the substance” evidently
of Chaos, which is the fate which Pistis Sophia anticipates for herself
in the MS. Tertullian, like the Pistis Sophia, also assigns to the
psychic substance the place of honour or right hand in the quasi-
material world, while the hylic is relegated in both to the left hand[615].
The Paradise of Adam is said by him to be fixed by Valentinus
“above the third heaven[616]” as it is in the Pistis Sophia, if, as we may
suppose, the soul of the protoplast dwelt in the same place as that of
Elijah. The name of Ecclesia or the Church is given not only to a
particular aeon in the Pleroma, but also to the divine power breathed
into man from a higher world in both Tertullian and the Pistis
Sophia[617], and, in the treatise De Carne Christi, Tertullian alludes
contemptuously to an heretical doctrine that Christ possessed “any
new kind of flesh miraculously obtained from the stars[618],” which
seems to refer to the taking by Jesus in the opening of the Pistis
Sophia of a body from “Barbelo” the goddess or Triple Power set
over matter and inspiring the benefic planet Venus. For all which
reasons it seems probable that in the Pistis Sophia we have the
translation of an authentic work by Valentinus.
The Pistis Sophia, however, is not the only work in the British
Museum MS. The first and second books of it, as they are called by
the annotator, come to an end, rather abrupt but evidently
intentional, on the 252nd page of the MS. There then appears the
heading in the hand of the annotator “Part of the Texts of the
Saviour[619],” and on this follow two pages dealing with the
“members” of the Ineffable One, as to which it is expressly said that
only a partial revelation is made[620]. These seem to have slipped out
of their proper place, and are followed by two discontinuous extracts
from another treatise, the second of which is also headed by the
annotator “Part of the Texts of the Saviour.” This second part, which
we shall venture to take before the other, is evidently the introduction
to or the commencement of a new treatise, for it begins with the
statement that “After they had crucified Our Lord Jesus He rose from
the dead on the third day,” and that His disciples gathered round
Him, reminding Him that they had left all to follow Him[621]. Jesus
“standing on the shore of the sea Ocean,” then makes invocation to
the “Father of every Fatherhood, boundless light,” in a prayer
composed of Egyptian and Hebrew words jumbled together after the
fashion of the spells in the Magic Papyri[622]. He then shows the
disciples the “disk of the sun” as a great dragon with his tail in his
mouth drawn by four white horses and the disk of the moon like a
ship drawn by two white steers[623]. The two steering oars of this last
are depicted as a male and a female dragon who take away the light
from the rulers of the stars among whom they move. Jesus and His
disciples are then translated to the place called the “Middle Way[624].”
He there describes how the Archons of Adamas rebelled and
persisted in engendering and bringing forth “rulers and archangels
and angels and ministers and decans.” We further hear, for the first
time, that the Twelve Aeons, instead of being, as in the Pistis
Sophia, all under the rule of Adamas, are divided into two classes,
one Jabraoth ruling over six of them and Sabaoth Adamas over the
other six; that Jabraoth and his subjects repented and practised “the
mysteries of the light,” including, as we have seen, abstinence from
generation[625], whereupon they were taken up by Jeû to the light of
the sun between the “places of the middle and those of the left.”
“Sabaoth Adamas,” on the other hand, with his subjects to the
number of 1800, were bound to the sphere, 360 powers being set
over them, the 360 being controlled by the five planets Saturn, Mars,
Mercury, Venus, and Jupiter. Jesus then describes in great detail the
different tortures in the Middle Way and two other hells called Chaos
and Amenti, wherein the souls of uninitiated men who commit sins
are tormented between their incarnations[626], the final punishment
being in the worst cases annihilation. He then affords His disciples a
vision of “fire and water and wine and blood” which He declares He
brought with Him on His Incarnation, and celebrates a sacrament
which He calls “the baptism of the First Oblation,” but which seems
to be a peculiar form of the Eucharist with invocations in the jargon
alluded to above, and a thaumaturgic conversion of the wine used in
it into water and vice versâ[627]. There are several lacunae in this part
of the MS., and the tortures for certain specified sins are differently
given in different places, so that it is probable that with the Part of
the Texts of the Saviour has here been mixed extracts from another
document whose title has been lost[628].
The remaining document of the British Museum MS., being the third
in order of place, was probably taken from the same book as that
last described, and was placed out of its natural order to satisfy the
pedantry of the scribes, the rule in such cases being that the longer
document should always come first. Like its successor, it deals
largely with the “punishments” of the souls who have not received
the mysteries of the light, and introduces a new and still more terrible
hell in the shape of the “Dragon of Outer Darkness” which it declares
to be a vast dragon surrounding the world, having his tail in his
mouth, and containing twelve chambers, wherein the souls of the
uninitiated dead are tortured after their transmigrations are ended
until they reach the annihilation reserved for them at the last
judgment[629]. There is also given here a very curious account of
man’s invisible part, which is said to be made up of the “Power”
infused into it by the Virgin of Light which returns to its giver after
death[630], and the Moira or Fate which it derives from the Sphere of
Destiny and has as its sole function to lead the man it inhabits to the
death he is predestined to die[631]. Then there is the Counterfeit of the
Spirit, which is in effect a duplicate of the soul proper and is made
out of the matter of the wicked Archons. This not only incites the soul
to sin, but follows it about after death, denouncing to the powers set
over the punishments the sins it has induced the soul to commit[632].
All these punishments, to describe which is evidently the purpose of
all the extracts from the Texts of the Saviour here given, are escaped
by those who have received the mysteries.
The Texts of the Saviour therefore clearly belong to a later form of
Gnosticism than the Pistis Sophia properly so called. The author’s
intention is evidently to frighten his readers with the fate reserved for
those who do not accept the teaching of the sect. For this purpose
the division of mankind into pneumatic, psychic, and hylic is
ignored[633], and this is especially plain in certain passages where the
torments after death of those who follow “the doctrines of error” are
set forth. Magic, which has been spoken of with horror in the Pistis
Sophia, is here made use of in the celebration of the rites described,
and the miraculous power of healing the sick and raising the dead,
though said to be of archontic, i.e. diabolic, origin is here
recommended as a means to be employed under certain safeguards
for the purpose of converting “the whole world[634].” Even the duration
of the punishments and the different bodies into which the souls of
the men are to be cast are made to depend upon the relative
positions of the stars and planets which seem to be interpreted
according to the rules of the astrology of the time,—a so-called
science, which is spoken of scornfully in the Pistis Sophia itself[635].
Yet it is evident that the author or authors of the Texts of the Saviour
are acquainted with the book which precedes it; for in a description
of the powers which Jeû, who appears in both as the angelic
arranger of the Kerasmos, “binds” in the five planets set to rule over
it, we learn that he draws a power from “Pistis Sophia, the daughter
of Barbelo” and binds it in the planet Venus or Aphrodite[636]. As this
is the only reference to her, and receives no further explanation, it is
plain that the writer assumed his readers to be well acquainted with
Pistis Sophia’s history, and Jeû, Melchisidek, Adamas, and
Jaldabaoth, now one of the torturers in Chaos, appear, as we have
seen, in both works. The author of the Texts of the Saviour also
shows himself the avowed opponent of the Pagan deities still
worshipped in the early Christian centuries, as is evidenced by his
making not only the Egyptian Typhon, but Adonis, Persephone, and
Hecate, fiends in hell. Oddly enough, however, he gives an
explanation of the myth of the two springs of memory and oblivion
that we have seen in the Orphic gold plates in the following passage,
which may serve as an example of the style of the book:

“Jesus said: When the time set by the Sphere of Destiny[637] for a
man that is a persistent slanderer to go forth from the body is
fulfilled, there come unto him Abiuth and Charmon, the receivers
of Ariel[638], and lead forth his soul from the body, that they may
take it about with them for three days, showing it the creatures of
the world. Thereafter they drag it into Amenti unto Ariel that he
may torment it in his torments for eleven months and twenty-one
days. Thereafter they lead it into Chaos unto Jaldabaoth and his
forty-nine demons, that each of his demons may set upon it for
eleven months and twenty-one days with whips of smoke.
Thereafter they lead it into rivers of smoke and seas of fire that
they may torment it therein eleven months and twenty-one days.
Thereafter they lead it on high into the Middle Way that each of
the Archons of the Middle Way may torment it with his own
torments another eleven months and twenty-one days. And
thereafter they lead it unto the Virgin of Light who judges the
righteous and the sinners, and she shall judge it. And when the
Sphere is turned round, she delivers it to her receivers that they
may cast it forth among the Aeons of the Sphere. And the
servants of the Sphere lead it into the water which is below the
Sphere, that the boiling steam may eat into it, until it cleanse it
thoroughly. Then Jaluha the receiver of Sabaoth Adamas,
bearing the cup of oblivion delivers it to the soul, that it may drink
therein and forget all the places and the things therein through
which it has passed[639]. And it is placed in an afflicted body
wherein it shall spend its appointed time[640].”

The object of the cup of oblivion is obviously that the wicked man
may learn nothing from the torments he has endured. In the case of
the righteous but uninitiated dead, the baleful effect of this cup will
be annulled by “the Little Sabaoth the Good” who will administer to
him another cup “of perception and understanding and wisdom”
which will make the soul seek after the mysteries of light, on finding
which it will inherit light eternal.
It would be easy to see in these features of the Texts of the Saviour
the work of Marcus the magician who, as was said in a former
chapter, taught, according to the Fathers, a corrupted form of the
doctrine of Valentinus for his own interested purposes[641]. The
distinguishing feature about his celebration of the Eucharist is the
same as that given in the Texts of the Saviour, and as Clement of
Alexandria was acquainted with a sect in his day which substituted
water for wine therein[642], it is probable that Marcosians were to be
found during the latter part of the IInd century in Egypt. It is also to
be noted that the annotator has written upon the blank leaf which
separates the first and second books of the Pistis Sophia a
cryptogram concealing, apparently, the names of the Ineffable One
and the other higher powers worshipped by Valentinus, and this
seems to be constructed in much the same way as the isopsephisms
and other word-puzzles attributed by Irenaeus to Marcus[643]. The
mixture of Hebrew names and words with Egyptian ones in the
prayer of Jesus given in the Texts of the Saviour would agree well
with what the last-named Father says about Marcus being a Jew,
and a prayer which he represents Marcus as making over the head
of a convert baptized into his sect is couched in a jargon of the same
character[644]. On the other hand, the opening sentence of the book
calls Jesus “our Lord,” which Irenaeus tells us the Valentinians
carefully abstained from doing[645], and the long and detailed
description of the different hells and their tortures is much more
Egyptian than Jewish[646]. The remark attributed to Basilides as to
one in a thousand and two in ten thousand being worthy to take the
higher mysteries is here put into the mouth of Jesus, and perhaps it
would be safer to attribute for the present the Texts of the Saviour
not to Marcus himself, but to some later Gnostic who fused together
his teaching with that of the earlier and more disinterested
professors of Egyptian Gnosticism.
The same remarks apply with but little modification to some other
fragments of Gnostic writings which have come down to us. In the
Bodleian Library at Oxford is to be seen a MS. written on papyrus,
which was brought to this country by the Abyssinian traveller, Bruce.
This also is in the Sahidic dialect of Coptic, and although it has been
badly damaged and the ink is rapidly disappearing in the damp
climate of Oxford, yet a copy taken nearly a century ago by Woide
makes its decipherment possible in most places. The Bruce
Papyrus, like the British Museum parchment MS., contains more
than one document. Unfortunately the arrangement of the leaves is
by no means certain, and the two scholars who have studied it most
thoroughly differ almost as widely as possible as to the order of its
contents. M. Amélineau, a celebrated Egyptologist and Coptic
scholar, who published in 1882 a copy of the text with a French
translation in the Notices et Extraits of the Académie des
Inscriptions, considers that the treatises contained in it are only two
in number, the first being called by the author in what seems to be its
heading The Book of the Knowledge of the Invisible God and the
second The Book of the Great Word in Every Mystery. Dr Carl
Schmidt, of the University of Berlin, on the other hand, who, like M.
Amélineau, has studied the Papyrus at Oxford, thinks that he can
distinguish in the Bruce Papyrus no less than six documents, of
which the first two are according to him the two books of Jeû referred
to in the Pistis Sophia, two others, fragments of Gnostic prayers, the
fifth a fragment on the passage of the soul through the Archons of
the Middle Way, and the sixth, an extract from an otherwise unknown
Gnostic work which he does not venture to identify further[647]. To
enter into the controversy raised by this diversity of opinion would
take one outside the limits of the present work; but it may be said
that at least one, and that the most important, of the documents in
question must be later than the Pistis Sophia. Not only does this—
which M. Amélineau calls the Book of the Knowledge of the Invisible
God and Dr Schmidt “Unbekanntes Altgnostisches Werk”—quote the
opening words of St John’s Gospel: “In the beginning was the Word
and the Word was with God, and the Word was God without whom
nothing was made[648],” which, as has been said, the author of the
Pistis Sophia was unable to do; but it mentions in briefer form than
this last the heavenly origin of the souls of the Twelve Apostles[649].
There is also in the same document a description of what appears to
be the “emanation of the universe,” in which the following passage
occurs:

“And He [i.e. the Ineffable One] heard them [a prayer by the


lesser powers is referred to]. He sent them powers capable of
discernment, and knowing the arrangement of the hidden Eons.
He sent them according to the arrangement of those who are
hidden[650]. He established their Orders according to the orders of
the Height, and according to the hidden arrangement they began
from below upward in order that the building might unite them.
He created the aëry earth as a place of habitation for those who
had gone forth, in order that they might dwell thereon until those
which were below them should be made strong. Then he created
the true habitation within it[651], the Place of Repentance
(Metanoia) within it, the Place of Repentance within it, the
antitype of Aerodios[652]. Then [he created] the Place of
Repentance within it, the antitype of Autogenes (Self-begotten
or, perhaps, ‘of his own kind’). In this Place is purification in the
name of Autogenes who is god over them and powers were set
there over the source of the waters which they make to go forth
(?). Here are the names of the powers who are set over the
Water of Life: Michar and Micheu, and they are purified in the
name of Barpharanges[653]. Within these are the Aeons of
Sophia. Within these is the true Truth. And in this Place is found
Pistis Sophia, as also the pre-existent Jesus the Living,
Aerodios, and his Twelve Aeons[654].”

What is intended to be conveyed by this it is difficult to say in the


absence of the context; but the Pistis Sophia mentioned is evidently
the heroine of the book of that name, and the abrupt mention of her
name without explanation shows, as in the Texts of the Saviour, that
the author supposed his readers to be acquainted with her story.
While this part of the Papyrus may possibly be an attempt by some
later writer to fulfil the promise to tell His disciples at some future
time the “emanation of the universe” frequently made by Jesus in the
Pistis Sophia, it cannot be earlier in date than this last-named
document.
Another large fragment in the Bruce Papyrus is also connected with
that which has been called above the Texts of the Saviour, and helps
to link up this with the system of the Pistis Sophia proper. In the first
part of the Texts of the Saviour (i.e. the fourth document in the British
Museum book), Jesus, as has been mentioned, celebrates with
prodigies a sacrament which He calls the “Baptism of the first
Oblation”; and He tells them at the same time that there is also a
baptism of perfumes, another baptism of the Holy Spirit of Light, and
a Spiritual Chrism, besides which He promises them “the great
mystery of the Treasure-house of Light and the way to call upon it so
as to arrive thither,” a “baptism of those who belong to the Right
Hand,” and of “those who belong to the Middle” and other matters.
These promises are in some sort fulfilled in that part of the Bruce
Papyrus which Dr Schmidt will have it is “the Second Book of
Jeû[655],” where Jesus celebrates with accompanying prodigies three
sacraments which He calls the Baptism of Fire of the Virgin of the
Treasure-house of Light, the Baptism of the Holy Spirit, and a
“mystery” which is said to take away from His disciples “the
wickedness of the archons[656].” The details of these vary but very
slightly from the “Baptism of the First Oblation” celebrated by Jesus
in the Texts of the Saviour, and seem to have been written in
continuation and as an amplification of it. But the Texts of the
Saviour, as we have seen, also mention Pistis Sophia in such a way
as to presuppose an acquaintance with her history; and the
presumption that the author of the Bruce Papyrus had read the book
bearing her name is confirmed by the repetition in it of the names of
Jeû, here called “the Great Man, King of the great aeon of light,” the
Great Sabaoth the Good, the Great Iao the Good, Barbelo[657], the
Great Light, and all the “Amens,” “Twin Saviours,” “Guardians of
Veils” and the rest who are classed together in the Pistis Sophia as
the great emanations of light, and mentioned in a connection which
shows them to have the same functions in all these documents[658].
When we add to these the repetition of the tradition, formally stated
for the first time in the Pistis Sophia, that Jesus spent twelve years
with His disciples between His Resurrection and His Ascension[659],
there can be little doubt that this part of the Papyrus Bruce also is
subsequent to the Pistis Sophia. Similar arguments, which are only
omitted here for the sake of greater clearness, apply to all the rest of
Dr Schmidt’s documents, and it follows that none of the contents of
the Papyrus can be considered as any part of the “Books of Jeû”
mentioned in the Pistis Sophia[660], which, therefore, remains the
parent document on which all the others are based. As to their
absolute date, it seems impossible to arrive at any useful conclusion.
Both M. Amélineau and Dr Schmidt are agreed that the Coptic
Papyrus is a translation from Greek originals; and M. Amélineau
does not put this too far forward when he suggests that it was made
in the IInd and IIIrd century of our era[661]. Dr Schmidt is probably
nearer the mark when he puts the actual transcription of the Papyrus
as dating in the earliest instance from the Vth century. His earliest
date for any of the Greek originals is the first half of the IIIrd
century[662].
If now we put these later documents—the Texts of the Saviour and
those contained in the Bruce Papyrus—side by side, we notice a
marked, if gradual, change of tendency from the comparatively
orthodox Christianity of the Pistis Sophia proper. In the Texts of the
Saviour notably, the fear of hell and its punishments is, as we have
seen, present throughout, and seems to be the sanction on which
the author relies to compel his readers to accept his teaching. In the
documents of the Bruce Papyrus this is also to be found in more
sporadic fashion, nearly the whole of the book being occupied by the
means by which men are to escape the punishment of their sins.
These methods of salvation are all of them what we have earlier
called gnostical or magical, and consist simply in the utterance of
“names” given us in some sort of crypto-grammatic form, and the
exhibition of “seals” or rather impressions (χαρακτῆρες) here
portrayed with great attention to detail, which, however, remain
utterly meaningless for us. Thus to quote again from what Dr
Schmidt calls the Second Book of Jeû, Jesus imparts to His disciples
the “mystery” of the Twelve Aeons in these words:

“When you have gone forth from the body and come into the
First Aeon, the Archons of that Aeon will come before you. Then
stamp upon yourselves this seal AA, the name of which is
zôzesê. Utter this once only. Take in your two hands this number,
1119. When you have stamped upon yourselves this seal and
have uttered its name once only, speak these defences; ‘Back!
Protei Persomphôn Chous, O Archons of the First Aeon, for I
invoke Êazazêôzazzôzeôz.’ And when the Archons of the First
Aeon shall hear that name, they will be filled with great fear, they
will flee away to the West, to the Left Hand, and you will enter
in[663]”:

and the same process with different names and seals is to be


repeated with the other eleven aeons. This is, of course, not religion,
such as we have seen in the writings of Valentinus, nor even the
transcendental mysticism of the Pistis Sophia, but magic, and magic
of a peculiarly Egyptian form. The ancient Egyptian had always an
intense fear of the world after death, and from the first conceived a
most gloomy view of it. The worshippers of Seker or Socharis, a god
so ancient that we know him only as a component part of the triune
or syncretic divinity of late dynastic times called Ptah-Seker-Osiris,
depicted it as a subterranean place deprived of the light of the sun,
hot and thirsty, and more dreary than even the Greek Hades or the
Hebrew Sheol.
“The West is a land of sleep and darkness heavy, a place where
those who settle in it, slumbering in their forms, never wake to
see their brethren; they never look any more on their father and
their mother, their heart leaves hold of their wives and children.
The living water which earth has for every one there, is foul here
where I am; though it runs for every one who is on earth, foul is
for me the water which is with me. I do not know any spot where
I would like to be, since I reached this valley! Give me water
which runs towards me, saying to me, ‘Let thy jug never be
without water’; bring to me the north wind, on the brink of water,
that it may fan me, that my heart may cool from its pain. The god
whose name is Let Complete Death Come, when he has
summoned anybody to him, they come to him, their hearts
disturbed by the fear of him; for there is nobody dares look up to
him from amongst gods and men, the great are to him as the
small and he spares not [those] who love him, but he tears the
nursling from the mother as he does the old man, and everyone
who meets him is filled with affright[664].”

The priests took care that such a picture did not fade from want of
reproduction and, true to the genius of their nation, elaborated it until
its main features are almost lost to us under the mass of details[665].
Especially was this the case with the religion of the Sun-God Ra,
who after his fusion with Amon of Thebes at the establishment of the
New Empire came to overshadow all the Egyptian cults save that of
Osiris. The tombs of the kings at Thebes are full of pictures of the
land of this Amenti or the West, in which horror is piled upon horror,
and book after book was written that there should be no mistake
about the fate lying in wait for the souls of men[666]. In these we see
the dead wandering from one chamber to another, breathing a heavy
and smoke-laden air[667], and confronted at every step by frightful
fiends compounded from the human and bestial forms, whose office
is to mutilate, to burn, and to torture the soul. The means of escape
open to the dead was, under the XXth dynasty, neither the
consciousness of a well-spent life nor the fatherly love of the gods,
but the knowledge of passwords and mysterious names[668]. Every
chamber had a guardian who demanded of the dead his own name,
without repeating which the soul was not allowed to enter[669]. Every
fiend had to be repelled by a special exorcism and talisman[670], and
every “circle” through which the dead passed had its own song and
“mystery,” which it behoved the dead to know[671]. Only thus could he
hope to win through to the Land of Osiris, where he might enjoy a
relative beatitude and be free to go about and visit the other
heavenly places[672]. For this purpose, the map, so to speak, of the
route was engraved on the walls of the tombs of those who could
afford it, and the necessary words to be said written down. Those
who were not so rich or so lucky were thought to be parcelled out,
like the fellahin of that day, or the villeins of feudal times, in colonies
among the different districts of the lower world, where they flourished
or perished according to the number of talismans or “protections”
that they possessed[673]. “If ever,” says M. Maspero, “there were in
Pharaonic Egypt mysteries and initiates, as there were in Greece
and in Egypt under the Greeks, these books later than the Book of
the Other World and the Book of the Gates are books of mystery and
of initiates[674].” Thereafter, he goes on to say, the ancient popular
religion disappeared more and more from Egypt, to give place to the
overmastering sense of the terrors of death[675] and the magical
means by which it was sought to lighten them.
It is to the survival of these ideas that books like the Texts of the
Saviour and those in the Papyrus Bruce must be attributed. The
Gnostic Christianity of Valentinus, direct descendant as it was of the
amalgam of Christianity with pre-Christian faiths which the Ophites
had compounded, no sooner reached the great mass of the Egyptian
people than it found itself under their influence. In this later Gnostic
literature we hear no more of the Supreme Father of Valentinus,
“who alone” in his words, “is good”; no more weight is laid upon the
Faith, Hope, and Love who were the first three members of his
Heavenly Man; and the Jesus in whom were summed up all the
perfections of the Godhead becomes transformed into a mere
mystagogue or revealer of secret words and things. All expectation
of the immediate arrival of the Parusia or Second Coming, when the
world is to be caught up and all wickedness to be destroyed, has
passed into the background, as has also the millennium in which the
faithful were, in accordance with a very early belief in Egypt, to share
the felicity of those who had been kings on earth[676]. Instead we
have only appeals to the lowest motives of fear and the selfish desire
to obtain higher privileges than ordinary men. Even the avoidance of
crime has no other sanction, and complete withdrawal from the world
is advocated on merely prudential grounds; while rejection of the
mysteries is the unpardonable sin:

“When I have gone unto the light” (says the Jesus of the Texts of
the Saviour to His disciples) “preach unto the whole world,
saying: Renounce the whole world and the matter that is therein,
all its cares, its sins, and in a word all its conversation, that ye
may be worthy of the mysteries of the light, that ye may be saved
from all the torments which are in the judgments. Renounce
murmuring, that ye may be worthy of the mysteries of the light,
that ye may escape the judgment of that dog-faced one....
Renounce wrath, that ye may be worthy of the mysteries of the
light, that ye may be saved from the fire of the seas of the
dragon-faced one.... Renounce adultery, that ye may be worthy
of the mysteries of the kingdom of light, that ye may be saved
from the seas of sulphur and pitch of the lion-faced one.... Say
unto them that abandon the doctrines of truth of the First Mystery
‘Woe unto you, for your torment shall be worse than that of all
men, for ye shall dwell in the great ice and frost and hail in the
midst of the Dragon of the Outer Darkness, and ye shall escape
no more from the world from that hour unto evermore, but ye
shall be as stones therein, and in the dissolution of the universe
ye shall be annihilated, so that ye exist no more for ever[677]’.”

The priests who engraved the horrors of the next world on the walls
of the royal tombs at Thebes would probably have written no
differently.
Gnosticism then, in Egypt soon relapsed into the magic from which it
was originally derived; and we can no longer wonder that the Fathers
of the Church strove as fiercely against it as they did. In the age
when books like the Texts of the Saviour and the fragments in the
Papyrus Bruce could be written, the methods of Clement of
Alexandria, who treated Valentinus and his school as Christians bent
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookmass.com

You might also like